<s> HOST_WIDE_INT compute_frame_size ( HOST_WIDE_INT size ) { int regno ; HOST_WIDE_INT total_size ; HOST_WIDE_INT var_size ; HOST_WIDE_INT args_size ; HOST_WIDE_INT extra_size ; HOST_WIDE_INT gp_reg_rounded ; HOST_WIDE_INT gp_reg_size ; HOST_WIDE_INT fp_reg_size ; long mask ; int fp_inc ; long fp_bits ; gp_reg_size = 0 ; fp_reg_size = 0 ; mask = 0 ; extra_size = IQ2000_STACK_ALIGN ( ( 0 ) ) ; var_size = IQ2000_STACK_ALIGN ( size ) ; args_size = IQ2000_STACK_ALIGN ( current_function_outgoing_args_size ) ; if ( args_size == 0 && current_function_calls_alloca ) args_size = 4 * UNITS_PER_WORD ; total_size = var_size + args_size + extra_size ; for ( regno = GP_REG_FIRST ; regno <= GP_REG_LAST ; regno ++ ) { if ( MUST_SAVE_REGISTER ( regno ) ) { gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } if ( current_function_calls_eh_return ) { unsigned int i ; for ( i = 0 ; ; ++ i ) { regno = EH_RETURN_DATA_REGNO ( i ) ; if ( regno == ( int ) INVALID_REGNUM ) break ; gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } fp_inc = 2 ; fp_bits = 3 ; gp_reg_rounded = IQ2000_STACK_ALIGN ( gp_reg_size ) ; total_size += gp_reg_rounded + IQ2000_STACK_ALIGN ( fp_reg_size ) ; if ( total_size == extra_size && ! profile_flag ) total_size = extra_size = 0 ; total_size += IQ2000_STACK_ALIGN ( current_function_pretend_args_size ) ; cfun -> machine -> total_size = total_size ; cfun -> machine -> var_size = var_size ; cfun -> machine -> args_size = args_size ; cfun -> machine -> extra_size = extra_size ; cfun -> machine -> gp_reg_size = gp_reg_size ; cfun -> machine -> fp_reg_size = fp_reg_size ; cfun -> machine -> mask = mask ; cfun -> machine -> initialized = reload_completed ; cfun -> machine -> num_gp = gp_reg_size / UNITS_PER_WORD ; if ( mask ) { unsigned long offset ; offset = ( args_size + extra_size + var_size + gp_reg_size - GET_MODE_SIZE ( gpr_mode ) ) ; cfun -> machine -> gp_sp_offset = offset ; cfun -> machine -> gp_save_offset = offset - total_size ; } else { cfun -> machine -> gp_sp_offset = 0 ; cfun -> machine -> gp_save_offset = 0 ; } cfun -> machine -> fp_sp_offset = 0 ; cfun -> machine -> fp_save_offset = 0 ; return total_size ; } </s>

Typical stack layout should looks like this after the function 's prologue : | | -- ^ | | \ | | | arguments saved | Increasing | | on the stack | addresses PARENT arg pointer - > | | / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | - space for argument split between regs & stack -- CHILD | | \ < -- ( return address here ) | | other call | | saved registers | | / -- frame pointer - > | | \ ___ | | local | | | variables |f | | / |r -- |a | | \ |m | | outgoing |e | | arguments | | Decreasing ( hard ) frame pointer | | / | | addresses and stack pointer - > | | / _|_ | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- V


<s> void final_prescan_insn ( rtx insn , rtx opvec [ ] ATTRIBUTE_UNUSED , int noperands ATTRIBUTE_UNUSED ) { if ( dslots_number_nops > 0 ) { rtx pattern = PATTERN ( insn ) ; int length = get_attr_length ( insn ) ; if ( length == 0 || ( iq2000_load_reg != 0 && reg_mentioned_p ( iq2000_load_reg , pattern ) ) || ( iq2000_load_reg2 != 0 && reg_mentioned_p ( iq2000_load_reg2 , pattern ) ) || ( iq2000_load_reg3 != 0 && reg_mentioned_p ( iq2000_load_reg3 , pattern ) ) || ( iq2000_load_reg4 != 0 && reg_mentioned_p ( iq2000_load_reg4 , pattern ) ) ) fputs ( "\tnop\n" , asm_out_file ) ; else dslots_load_filled ++ ; while ( -- dslots_number_nops > 0 ) fputs ( "\tnop\n" , asm_out_file ) ; iq2000_load_reg = 0 ; iq2000_load_reg2 = 0 ; iq2000_load_reg3 = 0 ; iq2000_load_reg4 = 0 ; } if ( ( GET_CODE ( insn ) == JUMP_INSN || GET_CODE ( insn ) == CALL_INSN || ( GET_CODE ( PATTERN ( insn ) ) == RETURN ) ) && NEXT_INSN ( PREV_INSN ( insn ) ) == insn ) { rtx nop_insn = emit_insn_after ( gen_nop ( ) , insn ) ; INSN_ADDRESSES_NEW ( nop_insn , - 1 ) ; } if ( TARGET_STATS && ( GET_CODE ( insn ) == JUMP_INSN || GET_CODE ( insn ) == CALL_INSN ) ) dslots_jump_total ++ ; } </s>

If defined , a C statement to be executed just prior to the output of assembler code for INSN , to modify the extracted operands so they will be output differently . Here the argument OPVEC is the vector containing the operands extracted from INSN , and NOPERANDS is the number of elements of the vector which contain meaningful data for this insn . The contents of this vector are what will be used to convert the insn template into assembler code , so you can change the assembler output by changing the contents of the vector . We use it to check if the current insn needs a nop in front of it because of load delays , and also to update the delay slot statistics .


"function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, "

Handle the FUNCTION_ARG_ADVANCE macro . Update the data in CUM to advance over an argument of mode MODE and data type TYPE . TYPE is null for libcalls where that information may not be available .


<s>
void
gen_conditional_branch
(
rtx
operands
[
]
,
enum
rtx_code
test_code
)
{
enum
cmp_type
type
=
branch_type
;
rtx
cmp0
=
branch_cmp
[
0
]
;
rtx
cmp1
=
branch_cmp
[
1
]
;
enum
machine_mode
mode
;
rtx
reg
;
int
invert
;
rtx
label1
,
label2
;
switch
(
type
)
{
case
CMP_SI
:
case
CMP_DI
:
mode
=
type
==
CMP_SI
SImode
:
DImode
;
invert
=
0
;
reg
=
gen_int_relational
(
test_code
,
NULL_RTX
,
cmp0
,
cmp1
,
&
invert
)
;
if
(
reg
)
{
cmp0
=
reg
;
cmp1
=
const0_rtx
;
test_code
=
NE
;
}
else
if
(
GET_CODE
(
cmp1
)
==
CONST_INT
&&
INTVAL
(
cmp1
)
!=
0
)
cmp1
=
force_reg
(
mode
,
cmp1
)
;
break
;
case
CMP_SF
:
case
CMP_DF
:
reg
=
gen_reg_rtx
(
CCmode
)
;
emit_insn
(
gen_rtx_SET
(
VOIDmode
,
reg
,
gen_rtx_fmt_ee
(
test_code
==
NE
EQ
:
test_code
,
CCmode
,
cmp0
,
cmp1
)
)
)
;
test_code
=
test_code
==
NE
EQ
:
NE
;
mode
=
CCmode
;
cmp0
=
reg
;
cmp1
=
const0_rtx
;
invert
=
0
;
break
;
default
:
abort_with_insn
(
gen_rtx_fmt_ee
(
test_code
,
VOIDmode
,
cmp0
,
cmp1
)
,
"bad test"
)
;
}
label1
=
gen_rtx_LABEL_REF
(
VOIDmode
,
operands
[
0
]
)
;
label2
=
pc_rtx
;
if
(
invert
)
{
label2
=
label1
;
label1
=
pc_rtx
;
}
emit_jump_insn
(
gen_rtx_SET
(
VOIDmode
,
pc_rtx
,
gen_rtx_IF_THEN_ELSE
(
VOIDmode
,
gen_rtx_fmt_ee
(
test_code
,
mode
,
cmp0
,
cmp1
)
,
label1
,
label2
)
)
)
;
}
</s>

Emit the common code for doing conditional branches . operand [ 0 ] is the label to jump to . The comparison operands are saved away by cmp { si , di , sf , df } .


"\ninit_cumulative_args, fntype = 0x%.8lx"

Handle the INIT_CUMULATIVE_ARGS macro . Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE . For a library call , FNTYPE is 0 .


<s> static int iq2000_address_cost ( rtx addr ) { switch ( GET_CODE ( addr ) ) { case LO_SUM : return 1 ; case LABEL_REF : return 2 ; case CONST : { rtx offset = const0_rtx ; addr = eliminate_constant_term ( XEXP ( addr , 0 ) , & offset ) ; if ( GET_CODE ( addr ) == LABEL_REF ) return 2 ; if ( GET_CODE ( addr ) != SYMBOL_REF ) return 4 ; if ( ! SMALL_INT ( offset ) ) return 2 ; } case SYMBOL_REF : return SYMBOL_REF_FLAG ( addr ) ? 1 : 2 ; case PLUS : { rtx plus0 = XEXP ( addr , 0 ) ; rtx plus1 = XEXP ( addr , 1 ) ; if ( GET_CODE ( plus0 ) != REG && GET_CODE ( plus1 ) == REG ) plus0 = XEXP ( addr , 1 ) , plus1 = XEXP ( addr , 0 ) ; if ( GET_CODE ( plus0 ) != REG ) break ; switch ( GET_CODE ( plus1 ) ) { case CONST_INT : return SMALL_INT ( plus1 ) ? 1 : 2 ; case CONST : case SYMBOL_REF : case LABEL_REF : case HIGH : case LO_SUM : return iq2000_address_cost ( plus1 ) + 1 ; default : break ; } } default : break ; } return 4 ; } </s>

Provide the costs of an addressing mode that contains ADDR .


<s> int iq2000_adjust_insn_length ( rtx insn , int length ) { if ( simplejump_p ( insn ) || ( ( GET_CODE ( insn ) == JUMP_INSN || GET_CODE ( insn ) == CALL_INSN ) ) ) length += 4 ; return length ; } </s>

Return the length of INSN . LENGTH is the initial length computed by attributes in the machine-description file .


<s> static void iq2000_annotate_frame_insn ( rtx insn , rtx dwarf_pattern ) { RTX_FRAME_RELATED_P ( insn ) = 1 ; REG_NOTES ( insn ) = alloc_EXPR_LIST ( REG_FRAME_RELATED_EXPR , dwarf_pattern , REG_NOTES ( insn ) ) ; } </s>

Make INSN frame related and note that it performs the frame-related operation DWARF_PATTERN .


<s> int iq2000_can_use_return_insn ( void ) { if ( ! reload_completed ) return 0 ; if ( regs_ever_live [ 31 ] || profile_flag ) return 0 ; if ( cfun -> machine -> initialized ) return cfun -> machine -> total_size == 0 ; return compute_frame_size ( get_frame_size ( ) ) == 0 ; } </s>

Return nonzero if this function is known to have a null epilogue . This allows the optimizer to omit jumps to jumps if no stack was created .


<s> int iq2000_check_split ( rtx address , enum machine_mode mode ) { if ( GET_MODE_SIZE ( mode ) > ( unsigned ) UNITS_PER_WORD ) return 0 ; if ( ( GET_CODE ( address ) == SYMBOL_REF ) || ( GET_CODE ( address ) == CONST && GET_CODE ( XEXP ( XEXP ( address , 0 ) , 0 ) ) == SYMBOL_REF ) || GET_CODE ( address ) == LABEL_REF ) return 1 ; return 0 ; } </s>

Return nonzero if we split the address into high and low parts .


<s> static void iq2000_emit_frame_related_store ( rtx mem , rtx reg , HOST_WIDE_INT offset ) { rtx dwarf_address = plus_constant ( stack_pointer_rtx , offset ) ; rtx dwarf_mem = gen_rtx_MEM ( GET_MODE ( reg ) , dwarf_address ) ; iq2000_annotate_frame_insn ( emit_move_insn ( mem , reg ) , gen_rtx_SET ( GET_MODE ( reg ) , dwarf_mem , reg ) ) ; } </s>

Emit a move instruction that stores REG in MEM . Make the instruction frame related and note that it stores REG at ( SP + OFFSET ) .


<s> void iq2000_expand_epilogue ( void ) { HOST_WIDE_INT tsize = cfun -> machine -> total_size ; rtx tsize_rtx = GEN_INT ( tsize ) ; rtx tmp_rtx = ( rtx ) 0 ; if ( iq2000_can_use_return_insn ( ) ) { emit_jump_insn ( gen_return ( ) ) ; return ; } if ( tsize > 32767 ) { tmp_rtx = gen_rtx_REG ( Pmode , IQ2000_TEMP1_REGNUM ) ; emit_move_insn ( tmp_rtx , tsize_rtx ) ; tsize_rtx = tmp_rtx ; } if ( tsize > 0 ) { if ( frame_pointer_needed ) { emit_insn ( gen_blockage ( ) ) ; emit_insn ( gen_movsi ( stack_pointer_rtx , hard_frame_pointer_rtx ) ) ; } save_restore_insns ( 0 ) ; if ( current_function_calls_eh_return ) { rtx eh_ofs = EH_RETURN_STACKADJ_RTX ; emit_insn ( gen_addsi3 ( eh_ofs , eh_ofs , tsize_rtx ) ) ; tsize_rtx = eh_ofs ; } emit_insn ( gen_blockage ( ) ) ; if ( tsize != 0 || current_function_calls_eh_return ) { emit_insn ( gen_addsi3 ( stack_pointer_rtx , stack_pointer_rtx , tsize_rtx ) ) ; } } if ( current_function_calls_eh_return ) { emit_move_insn ( gen_rtx_REG ( Pmode , HARD_FRAME_POINTER_REGNUM ) , stack_pointer_rtx ) ; emit_insn ( gen_rtx_USE ( VOIDmode , gen_rtx_REG ( Pmode , HARD_FRAME_POINTER_REGNUM ) ) ) ; emit_jump_insn ( gen_eh_return_internal ( ) ) ; } else emit_jump_insn ( gen_return_internal ( gen_rtx_REG ( Pmode , GP_REG_FIRST + 31 ) ) ) ; } </s>

Expand the epilogue into a bunch of separate insns .


<s> const char * iq2000_fill_delay_slot ( const char * ret , enum delay_type type , rtx operands [ ] , rtx cur_insn ) { rtx set_reg ; enum machine_mode mode ; rtx next_insn = cur_insn ? NEXT_INSN ( cur_insn ) : NULL_RTX ; int num_nops ; if ( type == DELAY_LOAD || type == DELAY_FCMP ) num_nops = 1 ; else num_nops = 0 ; next_insn = NEXT_INSN ( cur_insn ) ; while ( next_insn != 0 && ( GET_CODE ( next_insn ) == NOTE || GET_CODE ( next_insn ) == CODE_LABEL ) ) next_insn = NEXT_INSN ( next_insn ) ; dslots_load_total += num_nops ; if ( TARGET_DEBUG_C_MODE || type == DELAY_NONE || operands == 0 || cur_insn == 0 || next_insn == 0 || GET_CODE ( next_insn ) == CODE_LABEL || ( set_reg = operands [ 0 ] ) == 0 ) { dslots_number_nops = 0 ; iq2000_load_reg = 0 ; iq2000_load_reg2 = 0 ; iq2000_load_reg3 = 0 ; iq2000_load_reg4 = 0 ; return ret ; } set_reg = operands [ 0 ] ; if ( set_reg == 0 ) return ret ; while ( GET_CODE ( set_reg ) == SUBREG ) set_reg = SUBREG_REG ( set_reg ) ; mode = GET_MODE ( set_reg ) ; dslots_number_nops = num_nops ; iq2000_load_reg = set_reg ; if ( GET_MODE_SIZE ( mode ) > ( unsigned ) ( UNITS_PER_WORD ) ) iq2000_load_reg2 = gen_rtx_REG ( SImode , REGNO ( set_reg ) + 1 ) ; else iq2000_load_reg2 = 0 ; return ret ; } </s>

Returns an operand string for the given instruction 's delay slot , after updating filled delay slot statistics . We assume that operands [ 0 ] is the target register that is set . In order to check the next insn , most of this functionality is moved to FINAL_PRESCAN_INSN , and we just set the global variables that it needs .


<s> rtx iq2000_function_value ( tree valtype , tree func ATTRIBUTE_UNUSED ) { int reg = GP_RETURN ; enum machine_mode mode = TYPE_MODE ( valtype ) ; int unsignedp = TYPE_UNSIGNED ( valtype ) ; mode = promote_mode ( valtype , mode , & unsignedp , 1 ) ; return gen_rtx_REG ( mode , reg ) ; } </s>

Return register to use for a function return value with VALTYPE for function FUNC .


<s> static bool iq2000_handle_option ( size_t code , const char * arg , int value ATTRIBUTE_UNUSED ) { switch ( code ) { case OPT_mcpu_ : if ( strcmp ( arg , "iq10" ) == 0 ) iq2000_tune = PROCESSOR_IQ10 ; else if ( strcmp ( arg , "iq2000" ) == 0 ) iq2000_tune = PROCESSOR_IQ2000 ; else return false ; return true ; case OPT_march_ : return ( strcmp ( arg , "default" ) == 0 || strcmp ( arg , "DEFAULT" ) == 0 || strcmp ( arg , "iq2000" ) == 0 ) ; default : return true ; } } </s>


<s> int iq2000_initial_elimination_offset ( int from , int to ATTRIBUTE_UNUSED ) { int offset ; compute_frame_size ( get_frame_size ( ) ) ; if ( ( from ) == FRAME_POINTER_REGNUM ) ( offset ) = 0 ; else if ( ( from ) == ARG_POINTER_REGNUM ) ( offset ) = ( cfun -> machine -> total_size ) ; else if ( ( from ) == RETURN_ADDRESS_POINTER_REGNUM ) { if ( leaf_function_p ( ) ) ( offset ) = 0 ; else ( offset ) = cfun -> machine -> gp_sp_offset + ( ( UNITS_PER_WORD - ( POINTER_SIZE / BITS_PER_UNIT ) ) * ( BYTES_BIG_ENDIAN != 0 ) ) ; } return offset ; } </s>

Implement INITIAL_ELIMINATION_OFFSET . FROM is either the frame pointer , argument pointer , or return address pointer . TO is either the stack pointer or hard frame pointer .


<s> static struct machine_function * iq2000_init_machine_status ( void ) { struct machine_function * f ; f = ggc_alloc_cleared ( sizeof ( struct machine_function ) ) ; return f ; } </s>

Allocate a chunk of memory for per-function machine-dependent data .


Return a nonzero value if XINSN is a legitimate address for a memory operand of the indicated MODE . STRICT is nonzero if this function is called during reload .


<s> char * iq2000_output_conditional_branch ( rtx insn , rtx * operands , int two_operands_p , int float_p , int inverted_p , int length ) { static char buffer [ 200 ] ; enum rtx_code code = GET_CODE ( operands [ 0 ] ) ; int need_z_p ; const char * op1 = "%z2" ; const char * op2 = ( two_operands_p ? ",%z3" : ",%." ) ; const char * comp = ( float_p ? "%F0" : "%C0" ) ; const char * inverted_comp = ( float_p ? "%W0" : "%N0" ) ; iq2000_branch_likely = ( final_sequence && INSN_ANNULLED_BRANCH_P ( insn ) ) ; if ( ! two_operands_p ) { switch ( code ) { case GTU : code = NE ; break ; case LEU : code = EQ ; break ; case GEU : code = EQ ; op1 = "%." ; break ; case LTU : code = NE ; op1 = "%." ; break ; default : break ; } } need_z_p = ( ! float_p && code != EQ && code != NE ) ; if ( need_z_p ) op2 = "" ; buffer [ 0 ] = '\0' ; switch ( length ) { case 4 : case 8 : if ( float_p ) sprintf ( buffer , "b%s%%?\t%%Z2%%1" , inverted_p ? inverted_comp : comp ) ; else sprintf ( buffer , "b%s%s%%?\t%s%s,%%1" , inverted_p ? inverted_comp : comp , need_z_p ? "z" : "" , op1 , op2 ) ; return buffer ; case 12 : case 16 : { const char * target = ( ( iq2000_branch_likely || length == 16 ) ? ".+16" : ".+12" ) ; char * c ; c = strchr ( buffer , '\0' ) ; if ( float_p ) sprintf ( c , "b%s\t%%Z2%s" , inverted_p ? comp : inverted_comp , target ) ; else sprintf ( c , "b%s%s\t%s%s,%s" , inverted_p ? comp : inverted_comp , need_z_p ? "z" : "" , op1 , op2 , target ) ; strcat ( c , "\n\tnop\n\tj\t%1" ) ; if ( length == 16 ) strcat ( buffer , "\n\tnop" ) ; return buffer ; } default : gcc_unreachable ( ) ; } return 0 ; } </s>

Output assembly instructions to perform a conditional branch . INSN is the branch instruction . OPERANDS [ 0 ] is the condition . OPERANDS [ 1 ] is the target of the branch . OPERANDS [ 2 ] is the target of the first operand to the condition . If TWO_OPERANDS_P is nonzero the comparison takes two operands ; OPERANDS [ 3 ] will be the second operand . If INVERTED_P is nonzero we are to branch if the condition does not hold . If FLOAT_P is nonzero this is a floating-point comparison . LENGTH is the length ( in bytes ) of the sequence we are to generate . That tells us whether to generate a simple conditional branch , or a reversed conditional branch around a ` jr ' instruction .


<s> static bool iq2000_pass_by_reference ( CUMULATIVE_ARGS * cum , enum machine_mode mode , tree type , bool named ATTRIBUTE_UNUSED ) { int size ; if ( cum && targetm . calls . must_pass_in_stack ( mode , type ) ) { CUMULATIVE_ARGS temp ; temp = * cum ; if ( FUNCTION_ARG ( temp , mode , type , named ) != 0 ) return 1 ; } if ( type == NULL_TREE || mode == DImode || mode == DFmode ) return 0 ; size = int_size_in_bytes ( type ) ; return size == - 1 || size > UNITS_PER_WORD ; } </s>

Return true when an argument must be passed by reference .


<s> int iq2000_reg_mode_ok_for_base_p ( rtx reg , enum machine_mode mode ATTRIBUTE_UNUSED , int strict ) { return ( strict ? REGNO_MODE_OK_FOR_BASE_P ( REGNO ( reg ) , mode ) : GP_REG_OR_PSEUDO_NONSTRICT_P ( REGNO ( reg ) , mode ) ) ; } </s>

Return nonzero if REG is valid for MODE .


<s> static bool iq2000_return_in_memory ( tree type , tree fntype ATTRIBUTE_UNUSED ) { return ( ( int_size_in_bytes ( type ) > ( 2 * UNITS_PER_WORD ) ) || ( int_size_in_bytes ( type ) == - 1 ) ) ; } </s>

Worker function for TARGET_RETURN_IN_MEMORY .


<s> static void iq2000_select_rtx_section ( enum machine_mode mode , rtx x ATTRIBUTE_UNUSED , unsigned HOST_WIDE_INT align ) { mergeable_constant_section ( mode , align , 0 ) ; } </s>

Choose the section to use for the constant rtx expression X that has mode MODE .


<s> static void iq2000_select_section ( tree decl , int reloc ATTRIBUTE_UNUSED , unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED ) { if ( TARGET_EMBEDDED_DATA ) { if ( ( TREE_CODE ( decl ) == VAR_DECL && TREE_READONLY ( decl ) && ! TREE_SIDE_EFFECTS ( decl ) && DECL_INITIAL ( decl ) && ( DECL_INITIAL ( decl ) == error_mark_node || TREE_CONSTANT ( DECL_INITIAL ( decl ) ) ) ) || TREE_CODE ( decl ) != VAR_DECL ) readonly_data_section ( ) ; else data_section ( ) ; } else { if ( ( TREE_CODE ( decl ) == VAR_DECL && TREE_READONLY ( decl ) && ! TREE_SIDE_EFFECTS ( decl ) && DECL_INITIAL ( decl ) && ( DECL_INITIAL ( decl ) == error_mark_node || TREE_CONSTANT ( DECL_INITIAL ( decl ) ) ) ) || TREE_CODE ( decl ) != VAR_DECL ) readonly_data_section ( ) ; else data_section ( ) ; } } </s>

Choose the section to use for DECL . RELOC is true if its value contains any relocatable expression . Some of the logic used here needs to be replicated in ENCODE_SECTION_INFO in iq2000.h so that references to these symbols are done correctly .


<s> static void iq2000_setup_incoming_varargs ( CUMULATIVE_ARGS * cum , enum machine_mode mode ATTRIBUTE_UNUSED , tree type ATTRIBUTE_UNUSED , int * pretend_size , int no_rtl ) { unsigned int iq2000_off = ! cum -> last_arg_fp ; unsigned int iq2000_fp_off = cum -> last_arg_fp ; if ( ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) ) { int iq2000_save_gp_regs = MAX_ARGS_IN_REGISTERS - cum -> arg_words - iq2000_off ; int iq2000_save_fp_regs = ( MAX_ARGS_IN_REGISTERS - cum -> fp_arg_words - iq2000_fp_off ) ; if ( iq2000_save_gp_regs < 0 ) iq2000_save_gp_regs = 0 ; if ( iq2000_save_fp_regs < 0 ) iq2000_save_fp_regs = 0 ; * pretend_size = ( ( iq2000_save_gp_regs * UNITS_PER_WORD ) + ( iq2000_save_fp_regs * UNITS_PER_FPREG ) ) ; if ( ! ( no_rtl ) ) { if ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) { rtx ptr , mem ; ptr = plus_constant ( virtual_incoming_args_rtx , - ( iq2000_save_gp_regs * UNITS_PER_WORD ) ) ; mem = gen_rtx_MEM ( BLKmode , ptr ) ; move_block_from_reg ( cum -> arg_words + GP_ARG_FIRST + iq2000_off , mem , iq2000_save_gp_regs ) ; } } } } </s>

Worker function for TARGET_SETUP_INCOMING_VARARGS .


<s> void iq2000_va_start ( tree valist , rtx nextarg ) { int int_arg_words ; int gpr_save_area_size ; int_arg_words = current_function_args_info . arg_words ; if ( int_arg_words < 8 ) gpr_save_area_size = ( 8 - int_arg_words ) * UNITS_PER_WORD ; else gpr_save_area_size = 0 ; nextarg = plus_constant ( nextarg , - gpr_save_area_size ) ; std_expand_builtin_va_start ( valist , nextarg ) ; } </s>


<s> void override_options ( void ) { target_flags &= ~ MASK_GPOPT ; iq2000_isa = IQ2000_ISA_DEFAULT ; iq2000_print_operand_punct [ '?' ] = 1 ; iq2000_print_operand_punct [ '#' ] = 1 ; iq2000_print_operand_punct [ '&' ] = 1 ; iq2000_print_operand_punct [ '!' ] = 1 ; iq2000_print_operand_punct [ '*' ] = 1 ; iq2000_print_operand_punct [ '@' ] = 1 ; iq2000_print_operand_punct [ '.' ] = 1 ; iq2000_print_operand_punct [ '(' ] = 1 ; iq2000_print_operand_punct [ ')' ] = 1 ; iq2000_print_operand_punct [ '[' ] = 1 ; iq2000_print_operand_punct [ ']' ] = 1 ; iq2000_print_operand_punct [ '<' ] = 1 ; iq2000_print_operand_punct [ '>' ] = 1 ; iq2000_print_operand_punct [ '{' ] = 1 ; iq2000_print_operand_punct [ '}' ] = 1 ; iq2000_print_operand_punct [ '^' ] = 1 ; iq2000_print_operand_punct [ '$' ] = 1 ; iq2000_print_operand_punct [ '+' ] = 1 ; iq2000_print_operand_punct [ '~' ] = 1 ; gpr_mode = SImode ; init_machine_status = iq2000_init_machine_status ; } </s>

Set global variables as needed for the options enabled .


"PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."

"PRINT_OPERAND_ADDRESS, invalid insn #2"

"PRINT_OPERAND_ADDRESS, invalid insn #1"

Print the operand address represented by the rtx addr


<s> static int symbolic_expression_p ( rtx x ) { if ( GET_CODE ( x ) == SYMBOL_REF ) return 1 ; if ( GET_CODE ( x ) == CONST ) return symbolic_expression_p ( XEXP ( x , 0 ) ) ; if ( UNARY_P ( x ) ) return symbolic_expression_p ( XEXP ( x , 0 ) ) ; if ( ARITHMETIC_P ( x ) ) return ( symbolic_expression_p ( XEXP ( x , 0 ) ) || symbolic_expression_p ( XEXP ( x , 1 ) ) ) ; return 0 ; } </s>

Return 1 if X contains a symbolic expression . We know these expressions will have one of a few well defined forms , so we need only check those forms .


<s> void gen_conditional_branch ( rtx operands [ ] , machine_mode mode ) { enum rtx_code test_code = GET_CODE ( operands [ 0 ] ) ; rtx cmp0 = operands [ 1 ] ; rtx cmp1 = operands [ 2 ] ; rtx reg ; int invert ; rtx label1 , label2 ; invert = 0 ; reg = gen_int_relational ( test_code , NULL_RTX , cmp0 , cmp1 , & invert ) ; if ( reg ) { cmp0 = reg ; cmp1 = const0_rtx ; test_code = NE ; } else if ( GET_CODE ( cmp1 ) == CONST_INT && INTVAL ( cmp1 ) != 0 ) cmp1 = force_reg ( mode , cmp1 ) ; label1 = gen_rtx_LABEL_REF ( VOIDmode , operands [ 3 ] ) ; label2 = pc_rtx ; if ( invert ) { label2 = label1 ; label1 = pc_rtx ; } emit_jump_insn ( gen_rtx_SET ( VOIDmode , pc_rtx , gen_rtx_IF_THEN_ELSE ( VOIDmode , gen_rtx_fmt_ee ( test_code , VOIDmode , cmp0 , cmp1 ) , label1 , label2 ) ) ) ; } </s>

Emit the common code for doing conditional branches . operand [ 0 ] is the label to jump to . The comparison operands are saved away by cmp { si , di , sf , df } .


<s> static void iq2000_emit_frame_related_store ( rtx mem , rtx reg , HOST_WIDE_INT offset ) { rtx dwarf_address = plus_constant ( Pmode , stack_pointer_rtx , offset ) ; rtx dwarf_mem = gen_rtx_MEM ( GET_MODE ( reg ) , dwarf_address ) ; iq2000_annotate_frame_insn ( emit_move_insn ( mem , reg ) , gen_rtx_SET ( GET_MODE ( reg ) , dwarf_mem , reg ) ) ; } </s>

Emit a move instruction that stores REG in MEM . Make the instruction frame related and note that it stores REG at ( SP + OFFSET ) .


"function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, "

Advance the argument of type TYPE and mode MODE to the next argument position in CUM .


<s>
rtx
iq2000_legitimize_address
(
rtx
xinsn
,
rtx
old_x
ATTRIBUTE_UNUSED
,
machine_mode
mode
)
{
if
(
TARGET_DEBUG_B_MODE
)
{
GO_PRINTF
(
"\n========== LEGITIMIZE_ADDRESS\n"
)
;
GO_DEBUG_RTX
(
xinsn
)
;
}
if
(
iq2000_check_split
(
xinsn
,
mode
)
)
{
return
gen_rtx_LO_SUM
(
Pmode
,
copy_to_mode_reg
(
Pmode
,
gen_rtx_HIGH
(
Pmode
,
xinsn
)
)
,
xinsn
)
;
}
if
(
GET_CODE
(
xinsn
)
==
PLUS
)
{
rtx
xplus0
=
XEXP
(
xinsn
,
0
)
;
rtx
xplus1
=
XEXP
(
xinsn
,
1
)
;
enum
rtx_code
code0
=
GET_CODE
(
xplus0
)
;
enum
rtx_code
code1
=
GET_CODE
(
xplus1
)
;
if
(
code0
!=
REG
&&
code1
==
REG
)
{
xplus0
=
XEXP
(
xinsn
,
1
)
;
xplus1
=
XEXP
(
xinsn
,
0
)
;
code0
=
GET_CODE
(
xplus0
)
;
code1
=
GET_CODE
(
xplus1
)
;
}
if
(
code0
==
REG
&&
REG_MODE_OK_FOR_BASE_P
(
xplus0
,
mode
)
&&
code1
==
CONST_INT
&&
!
SMALL_INT
(
xplus1
)
)
{
rtx
int_reg
=
gen_reg_rtx
(
Pmode
)
;
rtx
ptr_reg
=
gen_reg_rtx
(
Pmode
)
;
emit_move_insn
(
int_reg
,
GEN_INT
(
INTVAL
(
xplus1
)
&
~
0x7fff
)
)
;
emit_insn
(
gen_rtx_SET
(
VOIDmode
,
ptr_reg
,
gen_rtx_PLUS
(
Pmode
,
xplus0
,
int_reg
)
)
)
;
return
plus_constant
(
Pmode
,
ptr_reg
,
INTVAL
(
xplus1
)
&
0x7fff
)
;
}
}
if
(
TARGET_DEBUG_B_MODE
)
GO_PRINTF
(
"LEGITIMIZE_ADDRESS could not fix.\n"
)
;
return
xinsn
;
}
</s>

For the IQ2000 , transform : memory ( X + < large int > ) into : Y = < large int > & ~0x7fff ; Z = X + Y memory ( Z + ( < large int > & 0x7fff ) ) ;


<s> static bool iq2000_pass_by_reference ( cumulative_args_t cum_v , machine_mode mode , const_tree type , bool named ATTRIBUTE_UNUSED ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; int size ; if ( cum && targetm . calls . must_pass_in_stack ( mode , type ) ) { CUMULATIVE_ARGS temp ; temp = * cum ; if ( iq2000_function_arg ( pack_cumulative_args ( & temp ) , mode , type , named ) != 0 ) return 1 ; } if ( type == NULL_TREE || mode == DImode || mode == DFmode ) return 0 ; size = int_size_in_bytes ( type ) ; return size == - 1 || size > UNITS_PER_WORD ; } </s>


A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand that is a memory reference whose address is ADDR . ADDR is an RTL expression .


<s> static section * iq2000_select_section ( tree decl , int reloc ATTRIBUTE_UNUSED , unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED ) { if ( TARGET_EMBEDDED_DATA ) { if ( ( TREE_CODE ( decl ) == VAR_DECL && TREE_READONLY ( decl ) && ! TREE_SIDE_EFFECTS ( decl ) && DECL_INITIAL ( decl ) && ( DECL_INITIAL ( decl ) == error_mark_node || TREE_CONSTANT ( DECL_INITIAL ( decl ) ) ) ) || TREE_CODE ( decl ) != VAR_DECL ) return readonly_data_section ; else return data_section ; } else { if ( ( TREE_CODE ( decl ) == VAR_DECL && TREE_READONLY ( decl ) && ! TREE_SIDE_EFFECTS ( decl ) && DECL_INITIAL ( decl ) && ( DECL_INITIAL ( decl ) == error_mark_node || TREE_CONSTANT ( DECL_INITIAL ( decl ) ) ) ) || TREE_CODE ( decl ) != VAR_DECL ) return readonly_data_section ; else return data_section ; } } </s>


<s> static void iq2000_setup_incoming_varargs ( cumulative_args_t cum_v , machine_mode mode ATTRIBUTE_UNUSED , tree type ATTRIBUTE_UNUSED , int * pretend_size , int no_rtl ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; unsigned int iq2000_off = ! cum -> last_arg_fp ; unsigned int iq2000_fp_off = cum -> last_arg_fp ; if ( ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) ) { int iq2000_save_gp_regs = MAX_ARGS_IN_REGISTERS - cum -> arg_words - iq2000_off ; int iq2000_save_fp_regs = ( MAX_ARGS_IN_REGISTERS - cum -> fp_arg_words - iq2000_fp_off ) ; if ( iq2000_save_gp_regs < 0 ) iq2000_save_gp_regs = 0 ; if ( iq2000_save_fp_regs < 0 ) iq2000_save_fp_regs = 0 ; * pretend_size = ( ( iq2000_save_gp_regs * UNITS_PER_WORD ) + ( iq2000_save_fp_regs * UNITS_PER_FPREG ) ) ; if ( ! ( no_rtl ) ) { if ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) { rtx ptr , mem ; ptr = plus_constant ( Pmode , virtual_incoming_args_rtx , - ( iq2000_save_gp_regs * UNITS_PER_WORD ) ) ; mem = gen_rtx_MEM ( BLKmode , ptr ) ; move_block_from_reg ( cum -> arg_words + GP_ARG_FIRST + iq2000_off , mem , iq2000_save_gp_regs ) ; } } } } </s>


"\t.word\t0x00000000\t\t# <static chain value>\n"


<s> void final_prescan_insn ( rtx_insn * insn , rtx opvec [ ] ATTRIBUTE_UNUSED , int noperands ATTRIBUTE_UNUSED ) { if ( dslots_number_nops > 0 ) { rtx pattern = PATTERN ( insn ) ; int length = get_attr_length ( insn ) ; if ( length == 0 || ( iq2000_load_reg != 0 && reg_mentioned_p ( iq2000_load_reg , pattern ) ) || ( iq2000_load_reg2 != 0 && reg_mentioned_p ( iq2000_load_reg2 , pattern ) ) || ( iq2000_load_reg3 != 0 && reg_mentioned_p ( iq2000_load_reg3 , pattern ) ) || ( iq2000_load_reg4 != 0 && reg_mentioned_p ( iq2000_load_reg4 , pattern ) ) ) fputs ( "\tnop\n" , asm_out_file ) ; else dslots_load_filled ++ ; while ( -- dslots_number_nops > 0 ) fputs ( "\tnop\n" , asm_out_file ) ; iq2000_load_reg = 0 ; iq2000_load_reg2 = 0 ; iq2000_load_reg3 = 0 ; iq2000_load_reg4 = 0 ; } if ( ( JUMP_P ( insn ) || CALL_P ( insn ) || ( GET_CODE ( PATTERN ( insn ) ) == RETURN ) ) && NEXT_INSN ( PREV_INSN ( insn ) ) == insn ) { rtx_insn * tmp = insn ; while ( NEXT_INSN ( tmp ) && NOTE_P ( NEXT_INSN ( tmp ) ) && NOTE_KIND ( NEXT_INSN ( tmp ) ) == NOTE_INSN_CALL_ARG_LOCATION ) tmp = NEXT_INSN ( tmp ) ; rtx_insn * nop_insn = emit_insn_after ( gen_nop ( ) , tmp ) ; INSN_ADDRESSES_NEW ( nop_insn , - 1 ) ; } if ( TARGET_STATS && ( JUMP_P ( insn ) || CALL_P ( insn ) ) ) dslots_jump_total ++ ; } </s>

If defined , a C statement to be executed just prior to the output of assembler code for INSN , to modify the extracted operands so they will be output differently . Here the argument OPVEC is the vector containing the operands extracted from INSN , and NOPERANDS is the number of elements of the vector which contain meaningful data for this insn . The contents of this vector are what will be used to convert the insn template into assembler code , so you can change the assembler output by changing the contents of the vector . We use it to check if the current insn needs a nop in front of it because of load delays , and also to update the delay slot statistics .


<s> static void abort_with_insn ( rtx insn , const char * reason ) { error ( reason ) ; debug_rtx ( insn ) ; fancy_abort ( __FILE__ , __LINE__ , __FUNCTION__ ) ; } </s>

Abort after printing out a specific insn .


<s> HOST_WIDE_INT compute_frame_size ( HOST_WIDE_INT size ) { int regno ; HOST_WIDE_INT total_size ; HOST_WIDE_INT var_size ; HOST_WIDE_INT args_size ; HOST_WIDE_INT extra_size ; HOST_WIDE_INT gp_reg_rounded ; HOST_WIDE_INT gp_reg_size ; HOST_WIDE_INT fp_reg_size ; long mask ; gp_reg_size = 0 ; fp_reg_size = 0 ; mask = 0 ; extra_size = IQ2000_STACK_ALIGN ( ( 0 ) ) ; var_size = IQ2000_STACK_ALIGN ( size ) ; args_size = IQ2000_STACK_ALIGN ( crtl -> outgoing_args_size ) ; if ( args_size == 0 && cfun -> calls_alloca ) args_size = 4 * UNITS_PER_WORD ; total_size = var_size + args_size + extra_size ; for ( regno = GP_REG_FIRST ; regno <= GP_REG_LAST ; regno ++ ) { if ( MUST_SAVE_REGISTER ( regno ) ) { gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } if ( crtl -> calls_eh_return ) { unsigned int i ; for ( i = 0 ; ; ++ i ) { regno = EH_RETURN_DATA_REGNO ( i ) ; if ( regno == ( int ) INVALID_REGNUM ) break ; gp_reg_size += GET_MODE_SIZE ( gpr_mode ) ; mask |= 1L << ( regno - GP_REG_FIRST ) ; } } gp_reg_rounded = IQ2000_STACK_ALIGN ( gp_reg_size ) ; total_size += gp_reg_rounded + IQ2000_STACK_ALIGN ( fp_reg_size ) ; if ( total_size == extra_size && ! profile_flag ) total_size = extra_size = 0 ; total_size += IQ2000_STACK_ALIGN ( crtl -> args . pretend_args_size ) ; cfun -> machine -> total_size = total_size ; cfun -> machine -> var_size = var_size ; cfun -> machine -> args_size = args_size ; cfun -> machine -> extra_size = extra_size ; cfun -> machine -> gp_reg_size = gp_reg_size ; cfun -> machine -> fp_reg_size = fp_reg_size ; cfun -> machine -> mask = mask ; cfun -> machine -> initialized = reload_completed ; cfun -> machine -> num_gp = gp_reg_size / UNITS_PER_WORD ; if ( mask ) { unsigned long offset ; offset = ( args_size + extra_size + var_size + gp_reg_size - GET_MODE_SIZE ( gpr_mode ) ) ; cfun -> machine -> gp_sp_offset = offset ; cfun -> machine -> gp_save_offset = offset - total_size ; } else { cfun -> machine -> gp_sp_offset = 0 ; cfun -> machine -> gp_save_offset = 0 ; } cfun -> machine -> fp_sp_offset = 0 ; cfun -> machine -> fp_save_offset = 0 ; return total_size ; } </s>

Typical stack layout should looks like this after the function 's prologue : | | -- ^ | | \ | | | arguments saved | Increasing | | on the stack | addresses PARENT arg pointer - > | | / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - | | - space for argument split between regs & stack -- CHILD | | \ < -- ( return address here ) | | other call | | saved registers | | / -- frame pointer - > | | \ ___ | | local | | | variables |f | | / |r -- |a | | \ |m | | outgoing |e | | arguments | | Decreasing ( hard ) frame pointer | | / | | addresses and stack pointer - > | | / _|_ | -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- V


<s> void final_prescan_insn ( rtx_insn * insn , rtx opvec [ ] ATTRIBUTE_UNUSED , int noperands ATTRIBUTE_UNUSED ) { if ( dslots_number_nops > 0 ) { rtx pattern = PATTERN ( insn ) ; int length = get_attr_length ( insn ) ; if ( length == 0 || ( iq2000_load_reg != 0 && reg_mentioned_p ( iq2000_load_reg , pattern ) ) || ( iq2000_load_reg2 != 0 && reg_mentioned_p ( iq2000_load_reg2 , pattern ) ) || ( iq2000_load_reg3 != 0 && reg_mentioned_p ( iq2000_load_reg3 , pattern ) ) || ( iq2000_load_reg4 != 0 && reg_mentioned_p ( iq2000_load_reg4 , pattern ) ) ) fputs ( "\tnop\n" , asm_out_file ) ; else dslots_load_filled ++ ; while ( -- dslots_number_nops > 0 ) fputs ( "\tnop\n" , asm_out_file ) ; iq2000_load_reg = 0 ; iq2000_load_reg2 = 0 ; iq2000_load_reg3 = 0 ; iq2000_load_reg4 = 0 ; } if ( ( JUMP_P ( insn ) || CALL_P ( insn ) || ( GET_CODE ( PATTERN ( insn ) ) == RETURN ) ) && NEXT_INSN ( PREV_INSN ( insn ) ) == insn ) { rtx_insn * nop_insn = emit_insn_after ( gen_nop ( ) , insn ) ; INSN_ADDRESSES_NEW ( nop_insn , - 1 ) ; } if ( TARGET_STATS && ( JUMP_P ( insn ) || CALL_P ( insn ) ) ) dslots_jump_total ++ ; } </s>


<s> void gen_conditional_branch ( rtx operands [ ] , machine_mode mode ) { enum rtx_code test_code = GET_CODE ( operands [ 0 ] ) ; rtx cmp0 = operands [ 1 ] ; rtx cmp1 = operands [ 2 ] ; rtx reg ; int invert ; rtx label1 , label2 ; invert = 0 ; reg = gen_int_relational ( test_code , NULL_RTX , cmp0 , cmp1 , & invert ) ; if ( reg ) { cmp0 = reg ; cmp1 = const0_rtx ; test_code = NE ; } else if ( GET_CODE ( cmp1 ) == CONST_INT && INTVAL ( cmp1 ) != 0 ) cmp1 = force_reg ( mode , cmp1 ) ; label1 = gen_rtx_LABEL_REF ( VOIDmode , operands [ 3 ] ) ; label2 = pc_rtx ; if ( invert ) { label2 = label1 ; label1 = pc_rtx ; } emit_jump_insn ( gen_rtx_SET ( pc_rtx , gen_rtx_IF_THEN_ELSE ( VOIDmode , gen_rtx_fmt_ee ( test_code , VOIDmode , cmp0 , cmp1 ) , label1 , label2 ) ) ) ; } </s>


"\ninit_cumulative_args, fntype = 0x%.8lx"

Handle the INIT_CUMULATIVE_ARGS macro . Initialize a variable CUM of type CUMULATIVE_ARGS for a call to a function whose data type is FNTYPE . For a library call , FNTYPE is 0 .


<s> static int iq2000_address_cost ( rtx addr , machine_mode mode , addr_space_t as , bool speed ) { switch ( GET_CODE ( addr ) ) { case LO_SUM : return 1 ; case LABEL_REF : return 2 ; case CONST : { rtx offset = const0_rtx ; addr = eliminate_constant_term ( XEXP ( addr , 0 ) , & offset ) ; if ( GET_CODE ( addr ) == LABEL_REF ) return 2 ; if ( GET_CODE ( addr ) != SYMBOL_REF ) return 4 ; if ( ! SMALL_INT ( offset ) ) return 2 ; } case SYMBOL_REF : return SYMBOL_REF_FLAG ( addr ) ? 1 : 2 ; case PLUS : { rtx plus0 = XEXP ( addr , 0 ) ; rtx plus1 = XEXP ( addr , 1 ) ; if ( GET_CODE ( plus0 ) != REG && GET_CODE ( plus1 ) == REG ) plus0 = XEXP ( addr , 1 ) , plus1 = XEXP ( addr , 0 ) ; if ( GET_CODE ( plus0 ) != REG ) break ; switch ( GET_CODE ( plus1 ) ) { case CONST_INT : return SMALL_INT ( plus1 ) ? 1 : 2 ; case CONST : case SYMBOL_REF : case LABEL_REF : case HIGH : case LO_SUM : return iq2000_address_cost ( plus1 , mode , as , speed ) + 1 ; default : break ; } } default : break ; } return 4 ; } </s>

Provide the costs of an addressing mode that contains ADDR .


<s> static rtx iq2000_add_large_offset_to_sp ( HOST_WIDE_INT offset ) { rtx reg = gen_rtx_REG ( Pmode , IQ2000_TEMP2_REGNUM ) ; rtx offset_rtx = GEN_INT ( offset ) ; emit_move_insn ( reg , offset_rtx ) ; emit_insn ( gen_addsi3 ( reg , reg , stack_pointer_rtx ) ) ; return reg ; } </s>

Emit instructions to load the value ( SP + OFFSET ) into IQ2000_TEMP2_REGNUM and return an rtl expression for the register . Write the assembly instructions directly to FILE if it is not null , otherwise emit them as rtl . This function is a subroutine of save_restore_insns . It is used when OFFSET is too large to add in a single instruction .


<s> int iq2000_adjust_insn_length ( rtx_insn * insn , int length ) { if ( simplejump_p ( insn ) || ( ( JUMP_P ( insn ) || CALL_P ( insn ) ) ) ) length += 4 ; return length ; } </s>

Return the length of INSN . LENGTH is the initial length computed by attributes in the machine-description file .


<s> static void iq2000_annotate_frame_insn ( rtx_insn * insn , rtx dwarf_pattern ) { RTX_FRAME_RELATED_P ( insn ) = 1 ; REG_NOTES ( insn ) = alloc_EXPR_LIST ( REG_FRAME_RELATED_EXPR , dwarf_pattern , REG_NOTES ( insn ) ) ; } </s>

Make INSN frame related and note that it performs the frame-related operation DWARF_PATTERN .


Worker for TARGET_ASM_TRAMPOLINE_TEMPLATE .


<s> bool iq2000_can_eliminate ( const int from , const int to ) { return ( from == RETURN_ADDRESS_POINTER_REGNUM && ( ! leaf_function_p ( ) || ( to == GP_REG_FIRST + 31 && leaf_function_p ( ) ) ) ) || ( from != RETURN_ADDRESS_POINTER_REGNUM && ( to == HARD_FRAME_POINTER_REGNUM || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed ) ) ) ; } </s>

We can always eliminate to the frame pointer . We can eliminate to the stack pointer unless a frame pointer is needed .


<s> int iq2000_can_use_return_insn ( void ) { if ( ! reload_completed ) return 0 ; if ( df_regs_ever_live_p ( 31 ) || profile_flag ) return 0 ; if ( cfun -> machine -> initialized ) return cfun -> machine -> total_size == 0 ; return compute_frame_size ( get_frame_size ( ) ) == 0 ; } </s>

Return nonzero if this function is known to have a null epilogue . This allows the optimizer to omit jumps to jumps if no stack was created .


<s> int iq2000_check_split ( rtx address , machine_mode mode ) { if ( GET_MODE_SIZE ( mode ) > ( unsigned ) UNITS_PER_WORD ) return 0 ; if ( ( GET_CODE ( address ) == SYMBOL_REF ) || ( GET_CODE ( address ) == CONST && GET_CODE ( XEXP ( XEXP ( address , 0 ) , 0 ) ) == SYMBOL_REF ) || GET_CODE ( address ) == LABEL_REF ) return 1 ; return 0 ; } </s>

Return nonzero if we split the address into high and low parts .


<s> static HOST_WIDE_INT iq2000_constant_alignment ( const_tree exp , HOST_WIDE_INT align ) { if ( TREE_CODE ( exp ) == STRING_CST || TREE_CODE ( exp ) == CONSTRUCTOR ) return MAX ( align , BITS_PER_WORD ) ; return align ; } </s>


Determine whether a memory reference takes one ( based off of the GP pointer ) , two ( normal ) , or three ( label + reg ) instructions , and bump the appropriate counter for -mstats .


<s> HOST_WIDE_INT iq2000_debugger_offset ( rtx addr , HOST_WIDE_INT offset ) { rtx offset2 = const0_rtx ; rtx reg = eliminate_constant_term ( addr , & offset2 ) ; if ( offset == 0 ) offset = INTVAL ( offset2 ) ; if ( reg == stack_pointer_rtx || reg == frame_pointer_rtx || reg == hard_frame_pointer_rtx ) { HOST_WIDE_INT frame_size = ( ! cfun -> machine -> initialized ) ? compute_frame_size ( get_frame_size ( ) ) : cfun -> machine -> total_size ; offset = offset - frame_size ; } return offset ; } </s>

The arg pointer ( which is eliminated ) points to the virtual frame pointer , while the frame pointer ( which may be eliminated ) points to the stack pointer after the initial adjustments .


<s> static void iq2000_emit_frame_related_store ( rtx mem , rtx reg , HOST_WIDE_INT offset ) { rtx dwarf_address = plus_constant ( Pmode , stack_pointer_rtx , offset ) ; rtx dwarf_mem = gen_rtx_MEM ( GET_MODE ( reg ) , dwarf_address ) ; iq2000_annotate_frame_insn ( emit_move_insn ( mem , reg ) , gen_rtx_SET ( dwarf_mem , reg ) ) ; } </s>

Emit a move instruction that stores REG in MEM . Make the instruction frame related and note that it stores REG at ( SP + OFFSET ) .


<s> void iq2000_expand_epilogue ( void ) { HOST_WIDE_INT tsize = cfun -> machine -> total_size ; rtx tsize_rtx = GEN_INT ( tsize ) ; rtx tmp_rtx = ( rtx ) 0 ; if ( iq2000_can_use_return_insn ( ) ) { emit_jump_insn ( gen_return ( ) ) ; return ; } if ( tsize > 32767 ) { tmp_rtx = gen_rtx_REG ( Pmode , IQ2000_TEMP1_REGNUM ) ; emit_move_insn ( tmp_rtx , tsize_rtx ) ; tsize_rtx = tmp_rtx ; } if ( tsize > 0 ) { if ( frame_pointer_needed ) { emit_insn ( gen_blockage ( ) ) ; emit_insn ( gen_movsi ( stack_pointer_rtx , hard_frame_pointer_rtx ) ) ; } save_restore_insns ( 0 ) ; if ( crtl -> calls_eh_return ) { rtx eh_ofs = EH_RETURN_STACKADJ_RTX ; emit_insn ( gen_addsi3 ( eh_ofs , eh_ofs , tsize_rtx ) ) ; tsize_rtx = eh_ofs ; } emit_insn ( gen_blockage ( ) ) ; if ( tsize != 0 || crtl -> calls_eh_return ) { emit_insn ( gen_addsi3 ( stack_pointer_rtx , stack_pointer_rtx , tsize_rtx ) ) ; } } if ( crtl -> calls_eh_return ) { emit_move_insn ( gen_rtx_REG ( Pmode , HARD_FRAME_POINTER_REGNUM ) , stack_pointer_rtx ) ; emit_use ( gen_rtx_REG ( Pmode , HARD_FRAME_POINTER_REGNUM ) ) ; emit_jump_insn ( gen_eh_return_internal ( ) ) ; } else emit_jump_insn ( gen_return_internal ( gen_rtx_REG ( Pmode , GP_REG_FIRST + 31 ) ) ) ; } </s>

Expand the epilogue into a bunch of separate insns .


<s> const char * iq2000_fill_delay_slot ( const char * ret , enum delay_type type , rtx operands [ ] , rtx_insn * cur_insn ) { rtx set_reg ; machine_mode mode ; rtx_insn * next_insn = cur_insn ? NEXT_INSN ( cur_insn ) : NULL ; int num_nops ; if ( type == DELAY_LOAD || type == DELAY_FCMP ) num_nops = 1 ; else num_nops = 0 ; next_insn = NEXT_INSN ( cur_insn ) ; while ( next_insn != 0 && ( NOTE_P ( next_insn ) || LABEL_P ( next_insn ) ) ) next_insn = NEXT_INSN ( next_insn ) ; dslots_load_total += num_nops ; if ( TARGET_DEBUG_C_MODE || type == DELAY_NONE || operands == 0 || cur_insn == 0 || next_insn == 0 || LABEL_P ( next_insn ) || ( set_reg = operands [ 0 ] ) == 0 ) { dslots_number_nops = 0 ; iq2000_load_reg = 0 ; iq2000_load_reg2 = 0 ; iq2000_load_reg3 = 0 ; iq2000_load_reg4 = 0 ; return ret ; } set_reg = operands [ 0 ] ; if ( set_reg == 0 ) return ret ; while ( GET_CODE ( set_reg ) == SUBREG ) set_reg = SUBREG_REG ( set_reg ) ; mode = GET_MODE ( set_reg ) ; dslots_number_nops = num_nops ; iq2000_load_reg = set_reg ; if ( GET_MODE_SIZE ( mode ) > ( unsigned ) ( UNITS_PER_WORD ) ) iq2000_load_reg2 = gen_rtx_REG ( SImode , REGNO ( set_reg ) + 1 ) ; else iq2000_load_reg2 = 0 ; return ret ; } </s>

Returns an operand string for the given instruction 's delay slot , after updating filled delay slot statistics . We assume that operands [ 0 ] is the target register that is set . In order to check the next insn , most of this functionality is moved to FINAL_PRESCAN_INSN , and we just set the global variables that it needs .


"function_adv({gp reg found = %d, arg # = %2d, words = %2d}, %4s, "

Advance the argument of type TYPE and mode MODE to the next argument position in CUM .


<s> static pad_direction iq2000_function_arg_padding ( machine_mode mode , const_tree type ) { return ( ! BYTES_BIG_ENDIAN ? PAD_UPWARD : ( ( mode == BLKmode ? ( type && TREE_CODE ( TYPE_SIZE ( type ) ) == INTEGER_CST && int_size_in_bytes ( type ) < ( PARM_BOUNDARY / BITS_PER_UNIT ) ) : ( GET_MODE_BITSIZE ( mode ) < PARM_BOUNDARY && GET_MODE_CLASS ( mode ) == MODE_INT ) ) ? PAD_DOWNWARD : PAD_UPWARD ) ) ; } </s>


<s> static rtx iq2000_function_value ( const_tree valtype , const_tree fn_decl_or_type , bool outgoing ATTRIBUTE_UNUSED ) { int reg = GP_RETURN ; machine_mode mode = TYPE_MODE ( valtype ) ; int unsignedp = TYPE_UNSIGNED ( valtype ) ; const_tree func = fn_decl_or_type ; if ( fn_decl_or_type && ! DECL_P ( fn_decl_or_type ) ) fn_decl_or_type = NULL ; mode = promote_function_mode ( valtype , mode , & unsignedp , func , 1 ) ; return gen_rtx_REG ( mode , reg ) ; } </s>

Return register to use for a function return value with VALTYPE for function FUNC .


<s> bool iq2000_function_value_regno_p ( const unsigned int regno ) { return ( regno == GP_RETURN ) ; } </s>

Worker function for FUNCTION_VALUE_REGNO_P . On the IQ2000 , R2 and R3 are the only register thus used .


<s> static bool iq2000_hard_regno_mode_ok ( unsigned int regno , machine_mode mode ) { return ( REGNO_REG_CLASS ( regno ) == GR_REGS ? ( regno & 1 ) == 0 || GET_MODE_SIZE ( mode ) <= 4 : ( regno & 1 ) == 0 || GET_MODE_SIZE ( mode ) == 4 ) ; } </s>


<s> int iq2000_initial_elimination_offset ( int from , int to ATTRIBUTE_UNUSED ) { int offset ; compute_frame_size ( get_frame_size ( ) ) ; if ( ( from ) == FRAME_POINTER_REGNUM ) ( offset ) = 0 ; else if ( ( from ) == ARG_POINTER_REGNUM ) ( offset ) = ( cfun -> machine -> total_size ) ; else if ( ( from ) == RETURN_ADDRESS_POINTER_REGNUM ) { if ( leaf_function_p ( ) ) ( offset ) = 0 ; else ( offset ) = cfun -> machine -> gp_sp_offset + ( ( UNITS_PER_WORD - ( POINTER_SIZE / BITS_PER_UNIT ) ) * ( BYTES_BIG_ENDIAN != 0 ) ) ; } else gcc_unreachable ( ) ; return offset ; } </s>

Implement INITIAL_ELIMINATION_OFFSET . FROM is either the frame pointer , argument pointer , or return address pointer . TO is either the stack pointer or hard frame pointer .


<s> static struct machine_function * iq2000_init_machine_status ( void ) { return ggc_cleared_alloc < machine_function > ( ) ; } </s>

Allocate a chunk of memory for per-function machine-dependent data .


"Not a machine_mode mode, legitimate address\n"

Return a nonzero value if XINSN is a legitimate address for a memory operand of the indicated MODE . STRICT is nonzero if this function is called during reload .


<s>
rtx
iq2000_legitimize_address
(
rtx
xinsn
,
rtx
old_x
ATTRIBUTE_UNUSED
,
machine_mode
mode
)
{
if
(
TARGET_DEBUG_B_MODE
)
{
GO_PRINTF
(
"\n========== LEGITIMIZE_ADDRESS\n"
)
;
GO_DEBUG_RTX
(
xinsn
)
;
}
if
(
iq2000_check_split
(
xinsn
,
mode
)
)
{
return
gen_rtx_LO_SUM
(
Pmode
,
copy_to_mode_reg
(
Pmode
,
gen_rtx_HIGH
(
Pmode
,
xinsn
)
)
,
xinsn
)
;
}
if
(
GET_CODE
(
xinsn
)
==
PLUS
)
{
rtx
xplus0
=
XEXP
(
xinsn
,
0
)
;
rtx
xplus1
=
XEXP
(
xinsn
,
1
)
;
enum
rtx_code
code0
=
GET_CODE
(
xplus0
)
;
enum
rtx_code
code1
=
GET_CODE
(
xplus1
)
;
if
(
code0
!=
REG
&&
code1
==
REG
)
{
xplus0
=
XEXP
(
xinsn
,
1
)
;
xplus1
=
XEXP
(
xinsn
,
0
)
;
code0
=
GET_CODE
(
xplus0
)
;
code1
=
GET_CODE
(
xplus1
)
;
}
if
(
code0
==
REG
&&
REG_MODE_OK_FOR_BASE_P
(
xplus0
,
mode
)
&&
code1
==
CONST_INT
&&
!
SMALL_INT
(
xplus1
)
)
{
rtx
int_reg
=
gen_reg_rtx
(
Pmode
)
;
rtx
ptr_reg
=
gen_reg_rtx
(
Pmode
)
;
emit_move_insn
(
int_reg
,
GEN_INT
(
INTVAL
(
xplus1
)
&
~
0x7fff
)
)
;
emit_insn
(
gen_rtx_SET
(
ptr_reg
,
gen_rtx_PLUS
(
Pmode
,
xplus0
,
int_reg
)
)
)
;
return
plus_constant
(
Pmode
,
ptr_reg
,
INTVAL
(
xplus1
)
&
0x7fff
)
;
}
}
if
(
TARGET_DEBUG_B_MODE
)
GO_PRINTF
(
"LEGITIMIZE_ADDRESS could not fix.\n"
)
;
return
xinsn
;
}
</s>

For the IQ2000 , transform : memory ( X + < large int > ) into : Y = < large int > & ~0x7fff ; Z = X + Y memory ( Z + ( < large int > & 0x7fff ) ) ;


<s> static rtx iq2000_libcall_value ( machine_mode mode , const_rtx fun ATTRIBUTE_UNUSED ) { return gen_rtx_REG ( ( ( GET_MODE_CLASS ( mode ) != MODE_INT || GET_MODE_SIZE ( mode ) >= 4 ) ? mode : SImode ) , GP_RETURN ) ; } </s>

Worker function for TARGET_LIBCALL_VALUE .


<s> static void iq2000_option_override ( void ) { target_flags &= ~ MASK_GPOPT ; iq2000_isa = IQ2000_ISA_DEFAULT ; iq2000_print_operand_punct [ '?' ] = 1 ; iq2000_print_operand_punct [ '#' ] = 1 ; iq2000_print_operand_punct [ '&' ] = 1 ; iq2000_print_operand_punct [ '!' ] = 1 ; iq2000_print_operand_punct [ '*' ] = 1 ; iq2000_print_operand_punct [ '@' ] = 1 ; iq2000_print_operand_punct [ '.' ] = 1 ; iq2000_print_operand_punct [ '(' ] = 1 ; iq2000_print_operand_punct [ ')' ] = 1 ; iq2000_print_operand_punct [ '[' ] = 1 ; iq2000_print_operand_punct [ ']' ] = 1 ; iq2000_print_operand_punct [ '<' ] = 1 ; iq2000_print_operand_punct [ '>' ] = 1 ; iq2000_print_operand_punct [ '{' ] = 1 ; iq2000_print_operand_punct [ '}' ] = 1 ; iq2000_print_operand_punct [ '^' ] = 1 ; iq2000_print_operand_punct [ '$' ] = 1 ; iq2000_print_operand_punct [ '+' ] = 1 ; iq2000_print_operand_punct [ '~' ] = 1 ; gpr_mode = SImode ; init_machine_status = iq2000_init_machine_status ; } </s>


<s> char * iq2000_output_conditional_branch ( rtx_insn * insn , rtx * operands , int two_operands_p , int float_p , int inverted_p , int length ) { static char buffer [ 200 ] ; enum rtx_code code = GET_CODE ( operands [ 0 ] ) ; int need_z_p ; const char * op1 = "%z2" ; const char * op2 = ( two_operands_p ? ",%z3" : ",%." ) ; const char * comp = ( float_p ? "%F0" : "%C0" ) ; const char * inverted_comp = ( float_p ? "%W0" : "%N0" ) ; iq2000_branch_likely = ( final_sequence && INSN_ANNULLED_BRANCH_P ( insn ) ) ; if ( ! two_operands_p ) { switch ( code ) { case GTU : code = NE ; break ; case LEU : code = EQ ; break ; case GEU : code = EQ ; op1 = "%." ; break ; case LTU : code = NE ; op1 = "%." ; break ; default : break ; } } need_z_p = ( ! float_p && code != EQ && code != NE ) ; if ( need_z_p ) op2 = "" ; buffer [ 0 ] = '\0' ; switch ( length ) { case 4 : case 8 : if ( float_p ) sprintf ( buffer , "b%s%%?\t%%Z2%%1" , inverted_p ? inverted_comp : comp ) ; else sprintf ( buffer , "b%s%s%%?\t%s%s,%%1" , inverted_p ? inverted_comp : comp , need_z_p ? "z" : "" , op1 , op2 ) ; return buffer ; case 12 : case 16 : { const char * target = ( ( iq2000_branch_likely || length == 16 ) ? ".+16" : ".+12" ) ; char * c ; c = strchr ( buffer , '\0' ) ; if ( float_p ) sprintf ( c , "b%s\t%%Z2%s" , inverted_p ? comp : inverted_comp , target ) ; else sprintf ( c , "b%s%s\t%s%s,%s" , inverted_p ? comp : inverted_comp , need_z_p ? "z" : "" , op1 , op2 , target ) ; strcat ( c , "\n\tnop\n\tj\t%1" ) ; if ( length == 16 ) strcat ( buffer , "\n\tnop" ) ; return buffer ; } default : gcc_unreachable ( ) ; } return 0 ; } </s>

Output assembly instructions to perform a conditional branch . INSN is the branch instruction . OPERANDS [ 0 ] is the condition . OPERANDS [ 1 ] is the target of the branch . OPERANDS [ 2 ] is the target of the first operand to the condition . If TWO_OPERANDS_P is nonzero the comparison takes two operands ; OPERANDS [ 3 ] will be the second operand . If INVERTED_P is nonzero we are to branch if the condition does not hold . If FLOAT_P is nonzero this is a floating-point comparison . LENGTH is the length ( in bytes ) of the sequence we are to generate . That tells us whether to generate a simple conditional branch , or a reversed conditional branch around a ` jr ' instruction .


<s> static bool iq2000_pass_by_reference ( cumulative_args_t cum_v , const function_arg_info & arg ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; int size ; if ( cum && targetm . calls . must_pass_in_stack ( arg ) ) { CUMULATIVE_ARGS temp ; temp = * cum ; if ( iq2000_function_arg ( pack_cumulative_args ( & temp ) , arg ) != 0 ) return 1 ; } if ( arg . type == NULL_TREE || arg . mode == DImode || arg . mode == DFmode ) return 0 ; size = int_size_in_bytes ( arg . type ) ; return size == - 1 || size > UNITS_PER_WORD ; } </s>

Return true when an argument must be passed by reference .


"PRINT_OPERAND_ADDRESS, LO_SUM with #1 not REG."

"PRINT_OPERAND_ADDRESS, invalid insn #2"

"PRINT_OPERAND_ADDRESS, invalid insn #1"

A C compound statement to output to stdio stream STREAM the assembler syntax for an instruction operand that is a memory reference whose address is ADDR . ADDR is an RTL expression .


<s> int iq2000_reg_mode_ok_for_base_p ( rtx reg , machine_mode mode ATTRIBUTE_UNUSED , int strict ) { return ( strict ? REGNO_MODE_OK_FOR_BASE_P ( REGNO ( reg ) , mode ) : GP_REG_OR_PSEUDO_NONSTRICT_P ( REGNO ( reg ) , mode ) ) ; } </s>

Return nonzero if REG is valid for MODE .


<s> static bool iq2000_return_in_memory ( const_tree type , const_tree fntype ATTRIBUTE_UNUSED ) { return ( ( int_size_in_bytes ( type ) > ( 2 * UNITS_PER_WORD ) ) || ( int_size_in_bytes ( type ) == - 1 ) ) ; } </s>

Worker function for TARGET_RETURN_IN_MEMORY .


<s> static section * iq2000_select_rtx_section ( machine_mode mode , rtx x ATTRIBUTE_UNUSED , unsigned HOST_WIDE_INT align ) { return mergeable_constant_section ( mode , align , 0 ) ; } </s>

Choose the section to use for the constant rtx expression X that has mode MODE .


<s> static void iq2000_setup_incoming_varargs ( cumulative_args_t cum_v , const function_arg_info & , int * pretend_size , int no_rtl ) { CUMULATIVE_ARGS * cum = get_cumulative_args ( cum_v ) ; unsigned int iq2000_off = ! cum -> last_arg_fp ; unsigned int iq2000_fp_off = cum -> last_arg_fp ; if ( ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) ) { int iq2000_save_gp_regs = MAX_ARGS_IN_REGISTERS - cum -> arg_words - iq2000_off ; int iq2000_save_fp_regs = ( MAX_ARGS_IN_REGISTERS - cum -> fp_arg_words - iq2000_fp_off ) ; if ( iq2000_save_gp_regs < 0 ) iq2000_save_gp_regs = 0 ; if ( iq2000_save_fp_regs < 0 ) iq2000_save_fp_regs = 0 ; * pretend_size = ( ( iq2000_save_gp_regs * UNITS_PER_WORD ) + ( iq2000_save_fp_regs * UNITS_PER_FPREG ) ) ; if ( ! ( no_rtl ) ) { if ( cum -> arg_words < MAX_ARGS_IN_REGISTERS - iq2000_off ) { rtx ptr , mem ; ptr = plus_constant ( Pmode , virtual_incoming_args_rtx , - ( iq2000_save_gp_regs * UNITS_PER_WORD ) ) ; mem = gen_rtx_MEM ( BLKmode , ptr ) ; move_block_from_reg ( cum -> arg_words + GP_ARG_FIRST + iq2000_off , mem , iq2000_save_gp_regs ) ; } } } } </s>

Worker function for TARGET_SETUP_INCOMING_VARARGS .


<s> static HOST_WIDE_INT iq2000_starting_frame_offset ( void ) { return crtl -> outgoing_args_size ; } </s>


<s> static void iq2000_trampoline_init ( rtx m_tramp , tree fndecl , rtx chain_value ) { rtx fnaddr = XEXP ( DECL_RTL ( fndecl ) , 0 ) ; rtx mem ; emit_block_move ( m_tramp , assemble_trampoline_template ( ) , GEN_INT ( TRAMPOLINE_CODE_SIZE ) , BLOCK_OP_NORMAL ) ; mem = adjust_address ( m_tramp , Pmode , TRAMPOLINE_CODE_SIZE ) ; emit_move_insn ( mem , fnaddr ) ; mem = adjust_address ( m_tramp , Pmode , TRAMPOLINE_CODE_SIZE + GET_MODE_SIZE ( Pmode ) ) ; emit_move_insn ( mem , chain_value ) ; } </s>


<s> static void iq2000_va_start ( tree valist , rtx nextarg ) { int int_arg_words ; int gpr_save_area_size ; int_arg_words = crtl -> args . info . arg_words ; if ( int_arg_words < 8 ) gpr_save_area_size = ( 8 - int_arg_words ) * UNITS_PER_WORD ; else gpr_save_area_size = 0 ; nextarg = plus_constant ( Pmode , nextarg , - gpr_save_area_size ) ; std_expand_builtin_va_start ( valist , nextarg ) ; } </s>


<s> static enum internal_test map_test_to_internal_test ( enum rtx_code test_code ) { enum internal_test test = ITEST_MAX ; switch ( test_code ) { case EQ : test = ITEST_EQ ; break ; case NE : test = ITEST_NE ; break ; case GT : test = ITEST_GT ; break ; case GE : test = ITEST_GE ; break ; case LT : test = ITEST_LT ; break ; case LE : test = ITEST_LE ; break ; case GTU : test = ITEST_GTU ; break ; case GEU : test = ITEST_GEU ; break ; case LTU : test = ITEST_LTU ; break ; case LEU : test = ITEST_LEU ; break ; default : break ; } return test ; } </s>

Make normal rtx_code into something we can index from an array


"%<gp_offset%> (%ld) or %<end_offset%> (%ld) is less than zero"

Save or restore instructions based on whether this is the prologue or epilogue . prologue is 1 for the prologue .