From b5144086d5b3629755524744084a6d696723efc5 Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Tue, 16 Dec 2003 15:20:51 +0000 Subject: [PATCH] iq2000.h: Formatting. * config/iq2000/iq2000.h: Formatting. (MAX_INT_TYPE_SIZE, MAX_INT_TYPE_SIZE, CONST_COSTS, RTX_COSTS) (ADDRESS_COST, ASM_OUTPUT_INTERNAL_LABEL, ASM_OUTPUT_INTERNAL_LABEL) (IMPLICIT_FIX_EXPR, EASY_DIV_EXPR, SLOW_ZERO_EXTEND): Remove * config/iq2000/iq2000.c: Formatting. (iq2000_rtx_costs): New. From-SVN: r74697 --- gcc/ChangeLog | 9 + gcc/config/iq2000/iq2000-protos.h | 62 ++- gcc/config/iq2000/iq2000.c | 712 ++++++++++++++++++------------ gcc/config/iq2000/iq2000.h | 494 +++++++-------------- 4 files changed, 616 insertions(+), 661 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 67871739ddc..a9a86f312f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-12-16 Stan Cox + + * config/iq2000/iq2000.h: Formatting. + (MAX_INT_TYPE_SIZE, MAX_INT_TYPE_SIZE, CONST_COSTS, RTX_COSTS) + (ADDRESS_COST, ASM_OUTPUT_INTERNAL_LABEL, ASM_OUTPUT_INTERNAL_LABEL) + (IMPLICIT_FIX_EXPR, EASY_DIV_EXPR, SLOW_ZERO_EXTEND): Remove + * config/iq2000/iq2000.c: Formatting. + (iq2000_rtx_costs): New. + 2003-12-16 Richard Earnshaw * arm.md (addsi3_carryin_shift): Add missing register constraints. diff --git a/gcc/config/iq2000/iq2000-protos.h b/gcc/config/iq2000/iq2000-protos.h index 8901fd300b1..2a37f276eb2 100644 --- a/gcc/config/iq2000/iq2000-protos.h +++ b/gcc/config/iq2000/iq2000-protos.h @@ -21,44 +21,40 @@ #ifndef GCC_IQ2000_PROTOS_H #define GCC_IQ2000_PROTOS_H -extern int iq2000_check_split (rtx, enum machine_mode); -extern int iq2000_reg_mode_ok_for_base_p (rtx, enum machine_mode, int); -extern int iq2000_legitimate_address_p (enum machine_mode, rtx, int); -extern const char* iq2000_fill_delay_slot (const char*, enum delay_type, rtx*, rtx); -extern const char *iq2000_move_1word (rtx *, rtx, int); -extern int iq2000_address_cost (rtx); -extern void override_options (void); -extern HOST_WIDE_INT iq2000_debugger_offset (rtx, HOST_WIDE_INT); -extern void final_prescan_insn (rtx, rtx*, int); -extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT); -extern int iq2000_initial_elimination_offset (int, int); -extern void iq2000_expand_prologue (void); -extern void iq2000_expand_epilogue (void); -extern void iq2000_expand_eh_return (rtx); -extern int iq2000_can_use_return_insn (void); -int function_arg_pass_by_reference (CUMULATIVE_ARGS*, enum machine_mode, tree, int); -int iq2000_adjust_insn_length (rtx, int); -char *iq2000_output_conditional_branch (rtx, rtx*, int, int, int, int); -extern void iq2000_init_builtins (void); -extern void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS, int, tree, int*, int); -extern void print_operand_address (FILE*, rtx); -extern void print_operand (FILE*, rtx, int); +extern int iq2000_check_split (rtx, enum machine_mode); +extern int iq2000_reg_mode_ok_for_base_p (rtx, enum machine_mode, int); +extern int iq2000_legitimate_address_p (enum machine_mode, rtx, int); +extern const char * iq2000_fill_delay_slot (const char *, enum delay_type, rtx *, rtx); +extern const char * iq2000_move_1word (rtx *, rtx, int); +extern void override_options (void); +extern HOST_WIDE_INT iq2000_debugger_offset (rtx, HOST_WIDE_INT); +extern void final_prescan_insn (rtx, rtx *, int); +extern HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT); +extern int iq2000_initial_elimination_offset (int, int); +extern void iq2000_expand_prologue (void); +extern void iq2000_expand_epilogue (void); +extern void iq2000_expand_eh_return (rtx); +extern int iq2000_can_use_return_insn (void); +extern int function_arg_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode, tree, int); +extern int iq2000_adjust_insn_length (rtx, int); +extern char * iq2000_output_conditional_branch (rtx, rtx *, int, int, int, int); +extern void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS, int, tree, int*, int); +extern void print_operand_address (FILE *, rtx); +extern void print_operand (FILE *, rtx, int); #ifdef RTX_CODE -extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int*); -extern void gen_conditional_branch (rtx *, enum rtx_code); +extern rtx gen_int_relational (enum rtx_code, rtx, rtx, rtx, int *); +extern void gen_conditional_branch (rtx *, enum rtx_code); #endif #ifdef TREE_CODE -extern void init_cumulative_args (CUMULATIVE_ARGS*, tree, rtx); -extern void function_arg_advance (CUMULATIVE_ARGS*, enum machine_mode, tree, int); -extern struct rtx_def* function_arg (CUMULATIVE_ARGS*, enum machine_mode, tree, int); -extern int function_arg_partial_nregs (CUMULATIVE_ARGS*, enum machine_mode, tree, int); -extern void iq2000_va_start (tree, rtx); -extern rtx iq2000_va_arg (tree, tree); -extern rtx iq2000_function_value (tree, tree); -extern rtx iq2000_expand_builtin (tree, rtx, rtx, - enum machine_mode, int); +extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx); +extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode, tree, int); +extern struct rtx_def * function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int); +extern int function_arg_partial_nregs (CUMULATIVE_ARGS *, enum machine_mode, tree, int); +extern void iq2000_va_start (tree, rtx); +extern rtx iq2000_va_arg (tree, tree); +extern rtx iq2000_function_value (tree, tree); #endif #endif /* ! GCC_IQ2000_PROTOS_H */ diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c index f9a62d28189..d895bb3c88d 100644 --- a/gcc/config/iq2000/iq2000.c +++ b/gcc/config/iq2000/iq2000.c @@ -50,7 +50,8 @@ Boston, MA 02111-1307, USA. */ arrays indexed by the test type, and not worry about the order of EQ, NE, etc. */ -enum internal_test { +enum internal_test + { ITEST_EQ, ITEST_NE, ITEST_GT, @@ -66,114 +67,118 @@ enum internal_test { struct constant; -static void iq2000_count_memory_refs (rtx, int); -static enum internal_test map_test_to_internal_test (enum rtx_code); -static rtx iq2000_add_large_offset_to_sp (HOST_WIDE_INT); -static void iq2000_annotate_frame_insn (rtx, rtx); -static void iq2000_emit_frame_related_store (rtx, rtx, - HOST_WIDE_INT); -static struct machine_function * iq2000_init_machine_status (void); -static void save_restore_insns (int); -static void abort_with_insn (rtx, const char *) - ATTRIBUTE_NORETURN; -static int symbolic_expression_p (rtx); -static enum processor_type iq2000_parse_cpu (const char *); -static void iq2000_select_rtx_section (enum machine_mode, rtx, - unsigned HOST_WIDE_INT); -static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); -static rtx expand_one_builtin (enum insn_code, rtx, tree, enum rtx_code*, - int); /* Structure to be filled in by compute_frame_size with register save masks, and offsets for the current function. */ struct iq2000_frame_info { - long total_size; /* # bytes that the entire frame takes up */ - long var_size; /* # bytes that variables take up */ - long args_size; /* # bytes that outgoing arguments take up */ - long extra_size; /* # bytes of extra gunk */ - int gp_reg_size; /* # bytes needed to store gp regs */ - int fp_reg_size; /* # bytes needed to store fp regs */ - long mask; /* mask of saved gp registers */ - long gp_save_offset; /* offset from vfp to store gp registers */ - long fp_save_offset; /* offset from vfp to store fp registers */ - long gp_sp_offset; /* offset from new sp to store gp registers */ - long fp_sp_offset; /* offset from new sp to store fp registers */ - int initialized; /* != 0 if frame size already calculated */ - int num_gp; /* number of gp registers saved */ -}; - -struct machine_function + long total_size; /* # bytes that the entire frame takes up. */ + long var_size; /* # bytes that variables take up. */ + long args_size; /* # bytes that outgoing arguments take up. */ + long extra_size; /* # bytes of extra gunk. */ + int gp_reg_size; /* # bytes needed to store gp regs. */ + int fp_reg_size; /* # bytes needed to store fp regs. */ + long mask; /* Mask of saved gp registers. */ + long gp_save_offset; /* Offset from vfp to store gp registers. */ + long fp_save_offset; /* Offset from vfp to store fp registers. */ + long gp_sp_offset; /* Offset from new sp to store gp registers. */ + long fp_sp_offset; /* Offset from new sp to store fp registers. */ + int initialized; /* != 0 if frame size already calculated. */ + int num_gp; /* Number of gp registers saved. */ +} iq2000_frame_info; + +struct machine_function GTY(()) { /* Current frame information, calculated by compute_frame_size. */ - struct iq2000_frame_info frame; + long total_size; /* # bytes that the entire frame takes up. */ + long var_size; /* # bytes that variables take up. */ + long args_size; /* # bytes that outgoing arguments take up. */ + long extra_size; /* # bytes of extra gunk. */ + int gp_reg_size; /* # bytes needed to store gp regs. */ + int fp_reg_size; /* # bytes needed to store fp regs. */ + long mask; /* Mask of saved gp registers. */ + long gp_save_offset; /* Offset from vfp to store gp registers. */ + long fp_save_offset; /* Offset from vfp to store fp registers. */ + long gp_sp_offset; /* Offset from new sp to store gp registers. */ + long fp_sp_offset; /* Offset from new sp to store fp registers. */ + int initialized; /* != 0 if frame size already calculated. */ + int num_gp; /* Number of gp registers saved. */ }; /* Global variables for machine-dependent things. */ -/* Count the number of .file directives, so that .loc is up to date. */ -int num_source_filenames = 0; - -/* Files to separate the text and the data output, so that all of the data - can be emitted before the text, which will mean that the assembler will - generate smaller code, based on the global pointer. */ -FILE *asm_out_data_file; -FILE *asm_out_text_file; - -/* The next branch instruction is a branch likely, not branch normal. */ -int iq2000_branch_likely; - -/* Count of delay slots and how many are filled. */ -int dslots_load_total; -int dslots_load_filled; -int dslots_jump_total; -int dslots_jump_filled; - -/* # of nops needed by previous insn */ -int dslots_number_nops; +/* List of all IQ2000 punctuation characters used by print_operand. */ +char iq2000_print_operand_punct[256]; -/* Number of 1/2/3 word references to data items (ie, not jal's). */ -int num_refs[3]; +/* The target cpu for optimization and scheduling. */ +enum processor_type iq2000_tune; -/* registers to check for load delay */ -rtx iq2000_load_reg, iq2000_load_reg2, iq2000_load_reg3, iq2000_load_reg4; +/* Which instruction set architecture to use. */ +int iq2000_isa; /* Cached operands, and operator to compare for use in set/branch/trap on condition codes. */ rtx branch_cmp[2]; -/* what type of branch to use */ +/* What type of branch to use. */ enum cmp_type branch_type; -/* The target cpu for code generation. */ -enum processor_type iq2000_arch; +/* Strings to hold which cpu and instruction set architecture to use. */ +const char * iq2000_cpu_string; /* For -mcpu=. */ +const char * iq2000_arch_string; /* For -march=. */ -/* The target cpu for optimization and scheduling. */ -enum processor_type iq2000_tune; -/* which instruction set architecture to use. */ -int iq2000_isa; +/* Local variables. */ -/* Strings to hold which cpu and instruction set architecture to use. */ -const char *iq2000_cpu_string; /* for -mcpu= */ -const char *iq2000_arch_string; /* for -march= */ +/* The next branch instruction is a branch likely, not branch normal. */ +static int iq2000_branch_likely; + +/* Count of delay slots and how many are filled. */ +static int dslots_load_total; +static int dslots_load_filled; +static int dslots_jump_total; + +/* # of nops needed by previous insn. */ +static int dslots_number_nops; + +/* Number of 1/2/3 word references to data items (ie, not jal's). */ +static int num_refs[3]; + +/* Registers to check for load delay. */ +static rtx iq2000_load_reg; +static rtx iq2000_load_reg2; +static rtx iq2000_load_reg3; +static rtx iq2000_load_reg4; + +/* The target cpu for code generation. */ +static enum processor_type iq2000_arch; /* Mode used for saving/restoring general purpose registers. */ static enum machine_mode gpr_mode; -/* List of all IQ2000 punctuation characters used by print_operand. */ -char iq2000_print_operand_punct[256]; /* Initialize the GCC target structure. */ -#undef TARGET_INIT_BUILTINS -#define TARGET_INIT_BUILTINS iq2000_init_builtins - -#undef TARGET_EXPAND_BUILTIN -#define TARGET_EXPAND_BUILTIN iq2000_expand_builtin - -#undef TARGET_ASM_SELECT_RTX_SECTION -#define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section +static struct machine_function* iq2000_init_machine_status (void); +static void iq2000_select_rtx_section (enum machine_mode, rtx, unsigned HOST_WIDE_INT); +static void iq2000_init_builtins (void); +static rtx iq2000_expand_builtin (tree, rtx, rtx, enum machine_mode, int); +static bool iq2000_rtx_costs (rtx, int, int, int *); +static int iq2000_address_cost (rtx); +static void iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); + +#undef TARGET_INIT_BUILTINS +#define TARGET_INIT_BUILTINS iq2000_init_builtins +#undef TARGET_EXPAND_BUILTIN +#define TARGET_EXPAND_BUILTIN iq2000_expand_builtin +#undef TARGET_ASM_SELECT_RTX_SECTION +#define TARGET_ASM_SELECT_RTX_SECTION iq2000_select_rtx_section +#undef TARGET_RTX_COSTS +#define TARGET_RTX_COSTS iq2000_rtx_costs +#undef TARGET_ADDRESS_COST +#define TARGET_ADDRESS_COST iq2000_address_cost +#undef TARGET_ASM_SELECT_SECTION +#define TARGET_ASM_SELECT_SECTION iq2000_select_section struct gcc_target targetm = TARGET_INITIALIZER; @@ -189,7 +194,7 @@ uns_arith_operand (rtx op, enum machine_mode mode) return register_operand (op, mode); } -/* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */ +/* Return 1 if OP can be used as an operand where a 16 bit integer is needed. */ int arith_operand (rtx op, enum machine_mode mode) @@ -200,7 +205,7 @@ arith_operand (rtx op, enum machine_mode mode) return register_operand (op, mode); } -/* Return 1 if OP is a integer which fits in 16 bits */ +/* Return 1 if OP is a integer which fits in 16 bits. */ int small_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) @@ -221,15 +226,15 @@ large_int (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) value = INTVAL (op); - /* ior reg,$r0,value */ + /* IOR reg,$r0,value. */ if ((value & ~ ((HOST_WIDE_INT) 0x0000ffff)) == 0) return 0; - /* subu reg,$r0,value */ + /* SUBU reg,$r0,value. */ if (((unsigned HOST_WIDE_INT) (value + 32768)) <= 32767) return 0; - /* lui reg,value>>16 */ + /* LUI reg,value >> 16. */ if ((value & 0x0000ffff) == 0) return 0; @@ -268,11 +273,11 @@ simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) { rtx addr, plus0, plus1; - /* Eliminate non-memory operations */ + /* Eliminate non-memory operations. */ if (GET_CODE (op) != MEM) return 0; - /* dword operations really put out 2 instructions, so eliminate them. */ + /* Dword operations really put out 2 instructions, so eliminate them. */ if (GET_MODE_SIZE (GET_MODE (op)) > (unsigned) UNITS_PER_WORD) return 0; @@ -292,12 +297,12 @@ simple_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED) plus1 = XEXP (addr, 1); if (GET_CODE (plus0) == REG && GET_CODE (plus1) == CONST_INT && SMALL_INT (plus1) - && SMALL_INT_UNSIGNED (plus1) /* No negative offsets */) + && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */) return 1; else if (GET_CODE (plus1) == REG && GET_CODE (plus0) == CONST_INT && SMALL_INT (plus0) - && SMALL_INT_UNSIGNED (plus1) /* No negative offsets */) + && SMALL_INT_UNSIGNED (plus1) /* No negative offsets. */) return 1; else @@ -324,7 +329,7 @@ equality_op (rtx op, enum machine_mode mode) return GET_CODE (op) == EQ || GET_CODE (op) == NE; } -/* Return nonzero if the code is a relational operations (EQ, LE, etc.) */ +/* Return nonzero if the code is a relational operations (EQ, LE, etc). */ int cmp_op (rtx op, enum machine_mode mode) @@ -449,8 +454,8 @@ iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict) if (GET_CODE (xinsn) == LO_SUM) { - register rtx xlow0 = XEXP (xinsn, 0); - register rtx xlow1 = XEXP (xinsn, 1); + rtx xlow0 = XEXP (xinsn, 0); + rtx xlow1 = XEXP (xinsn, 1); while (GET_CODE (xlow0) == SUBREG) xlow0 = SUBREG_REG (xlow0); @@ -462,10 +467,10 @@ iq2000_legitimate_address_p (enum machine_mode mode, rtx xinsn, int strict) if (GET_CODE (xinsn) == PLUS) { - register rtx xplus0 = XEXP (xinsn, 0); - register rtx xplus1 = XEXP (xinsn, 1); - register enum rtx_code code0; - register enum rtx_code code1; + rtx xplus0 = XEXP (xinsn, 0); + rtx xplus1 = XEXP (xinsn, 1); + enum rtx_code code0; + enum rtx_code code1; while (GET_CODE (xplus0) == SUBREG) xplus0 = SUBREG_REG (xplus0); @@ -504,10 +509,10 @@ const char * iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[], rtx cur_insn) { - register rtx set_reg; - register enum machine_mode mode; - register rtx next_insn = cur_insn ? NEXT_INSN (cur_insn) : NULL_RTX; - register int num_nops; + 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; @@ -536,6 +541,7 @@ iq2000_fill_delay_slot (const char *ret, enum delay_type type, rtx operands[], iq2000_load_reg2 = 0; iq2000_load_reg3 = 0; iq2000_load_reg4 = 0; + return ret; } @@ -644,7 +650,7 @@ iq2000_count_memory_refs (rtx op, int num) break; case LABEL_REF: - n_words = 2; /* always 2 words */ + n_words = 2; /* Always 2 words. */ break; case CONST: @@ -672,6 +678,16 @@ iq2000_count_memory_refs (rtx op, int num) num_refs[n_words-1] += num; } +/* Abort after printing out a specific insn. */ + +static void +abort_with_insn (rtx insn, const char * reason) +{ + error (reason); + debug_rtx (insn); + abort (); +} + /* Return the appropriate instructions to move one operand to another. */ const char * @@ -904,7 +920,7 @@ iq2000_move_1word (rtx operands[], rtx insn, int unsignedp) /* Provide the costs of an addressing mode that contains ADDR. */ -int +static int iq2000_address_cost (rtx addr) { switch (GET_CODE (addr)) @@ -918,7 +934,8 @@ iq2000_address_cost (rtx addr) case CONST: { rtx offset = const0_rtx; - addr = eliminate_constant_term (XEXP (addr, 0), &offset); + + addr = eliminate_constant_term (XEXP (addr, 0), & offset); if (GET_CODE (addr) == LABEL_REF) return 2; @@ -929,15 +946,15 @@ iq2000_address_cost (rtx addr) return 2; } - /* ... fall through ... */ + /* Fall through. */ case SYMBOL_REF: return SYMBOL_REF_FLAG (addr) ? 1 : 2; case PLUS: { - register rtx plus0 = XEXP (addr, 0); - register rtx plus1 = XEXP (addr, 1); + 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); @@ -994,15 +1011,11 @@ map_test_to_internal_test (enum rtx_code test_code) return test; } -/* Generate the code to compare two integer values. The return value is: +/* Generate the code to do a TEST_CODE comparison on two integer values CMP0 + and CMP1. P_INVERT is NULL or ptr if branch needs to reverse its test. + The return value RESULT is: (reg:SI xx) The pseudo register the comparison is in - 0 No register, generate a simple branch. - - TEST_CODE: relational test (EQ, etc). - RESULT: result to store comp. or 0 if branch. - CMP0: first operand to compare - CMP1: second operand to compare - *P_INVERT: NULL or ptr to hold whether branch needs to reverse its test. */ + 0 No register, generate a simple branch. */ rtx gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1, @@ -1010,18 +1023,18 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1, { struct cmp_info { - enum rtx_code test_code; /* code to use in instruction (LT vs. LTU) */ - int const_low; /* low bound of constant we can accept */ - int const_high; /* high bound of constant we can accept */ - int const_add; /* constant to add (convert LE -> LT) */ - int reverse_regs; /* reverse registers in test */ - int invert_const; /* != 0 if invert value if cmp1 is constant */ - int invert_reg; /* != 0 if invert value if cmp1 is register */ + enum rtx_code test_code; /* Code to use in instruction (LT vs. LTU). */ + int const_low; /* Low bound of constant we can accept. */ + int const_high; /* High bound of constant we can accept. */ + int const_add; /* Constant to add (convert LE -> LT). */ + int reverse_regs; /* Reverse registers in test. */ + int invert_const; /* != 0 if invert value if cmp1 is constant. */ + int invert_reg; /* != 0 if invert value if cmp1 is register. */ int unsignedp; /* != 0 for unsigned comparisons. */ }; - static struct cmp_info info[ (int)ITEST_MAX ] = { - + static struct cmp_info info[ (int)ITEST_MAX ] = + { { XOR, 0, 65535, 0, 0, 0, 0, 0 }, /* EQ */ { XOR, 0, 65535, 0, 0, 1, 1, 0 }, /* NE */ { LT, -32769, 32766, 1, 1, 1, 0, 0 }, /* GT */ @@ -1054,13 +1067,13 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1, if (mode == VOIDmode) mode = GET_MODE (cmp1); - /* Eliminate simple branches */ + /* Eliminate simple branches. */ branch_p = (result == 0); if (branch_p) { if (GET_CODE (cmp0) == REG || GET_CODE (cmp0) == SUBREG) { - /* Comparisons against zero are simple branches */ + /* Comparisons against zero are simple branches. */ if (GET_CODE (cmp1) == CONST_INT && INTVAL (cmp1) == 0) return 0; @@ -1069,7 +1082,7 @@ gen_int_relational (enum rtx_code test_code, rtx result, rtx cmp0, rtx cmp1, return 0; } - /* allocate a pseudo to calculate the value in. */ + /* Allocate a pseudo to calculate the value in. */ result = gen_reg_rtx (mode); } @@ -1205,7 +1218,7 @@ gen_conditional_branch (rtx operands[], enum rtx_code test_code) case CMP_DF: reg = gen_reg_rtx (CCmode); - /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0 */ + /* For cmp0 != cmp1, build cmp0 == cmp1, and test for result == 0. */ emit_insn (gen_rtx_SET (VOIDmode, reg, gen_rtx (test_code == NE ? EQ : test_code, CCmode, cmp0, cmp1))); @@ -1222,7 +1235,6 @@ gen_conditional_branch (rtx operands[], enum rtx_code test_code) } /* Generate the branch. */ - label1 = gen_rtx_LABEL_REF (VOIDmode, operands[0]); label2 = pc_rtx; @@ -1239,19 +1251,20 @@ gen_conditional_branch (rtx operands[], enum rtx_code test_code) label1, label2))); } -/* Initialize CUMULATIVE_ARGS for a function. */ +/* Initialize CUM for a function FNTYPE. */ void init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname ATTRIBUTE_UNUSED) { static CUMULATIVE_ARGS zero_cum; - tree param, next_param; + tree param; + tree next_param; if (TARGET_DEBUG_D_MODE) { fprintf (stderr, - "\ninit_cumulative_args, fntype = 0x%.8lx", (long)fntype); + "\ninit_cumulative_args, fntype = 0x%.8lx", (long) fntype); if (!fntype) fputc ('\n', stderr); @@ -1259,6 +1272,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, else { tree ret_type = TREE_TYPE (fntype); + fprintf (stderr, ", fntype code = %s, ret code = %s\n", tree_code_name[(int)TREE_CODE (fntype)], tree_code_name[(int)TREE_CODE (ret_type)]); @@ -1281,7 +1295,8 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, } } -/* Advance the argument to the next argument position. */ +/* Advance the argument of type TYPE and mode MODE to the next argument + position in CUM. */ void function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, @@ -1320,7 +1335,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, break; case SFmode: - cum->arg_words++; + cum->arg_words ++; if (! cum->gp_reg_found && cum->arg_number <= 2) cum->fp_code += 1 << ((cum->arg_number - 1) * 2); break; @@ -1340,13 +1355,13 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, case HImode: case SImode: cum->gp_reg_found = 1; - cum->arg_words++; + cum->arg_words ++; break; } } -/* Return an RTL expression containing the register for the given mode, - or 0 if the argument is to be passed on the stack. */ +/* Return an RTL expression containing the register for the given mode MODE + and type TYPE in CUM, or 0 if the argument is to be passed on the stack. */ struct rtx_def * function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, @@ -1450,13 +1465,12 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type, /* ??? If this is a packed structure, then the last hunk won't be 64 bits. */ - chunks = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD; if (chunks + *arg_words + bias > (unsigned) MAX_ARGS_IN_REGISTERS) chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias; - /* assign_parms checks the mode of ENTRY_PARM, so we must + /* Assign_parms checks the mode of ENTRY_PARM, so we must use the actual mode here. */ ret = gen_rtx_PARALLEL (mode, rtvec_alloc (chunks)); @@ -1532,21 +1546,20 @@ void iq2000_va_start (tree valist, rtx nextarg) { int int_arg_words; - - /* Find out how many non-float named formals */ + /* Find out how many non-float named formals. */ int gpr_save_area_size; - /* Note UNITS_PER_WORD is 4 bytes */ + /* Note UNITS_PER_WORD is 4 bytes. */ int_arg_words = current_function_args_info.arg_words; + if (int_arg_words < 8 ) - /* Adjust for the prologue's economy measure */ + /* Adjust for the prologue's economy measure. */ gpr_save_area_size = (8 - int_arg_words) * UNITS_PER_WORD; else gpr_save_area_size = 0; /* Everything is in the GPR save area, or in the overflow area which is contiguous with it. */ - - nextarg = plus_constant (nextarg, -gpr_save_area_size); + nextarg = plus_constant (nextarg, - gpr_save_area_size); std_expand_builtin_va_start (valist, nextarg); } @@ -1558,7 +1571,6 @@ iq2000_va_arg (tree valist, tree type) HOST_WIDE_INT size, rsize; rtx addr_rtx; tree t; - int indirect; rtx r, lab_over = NULL_RTX, lab_false; tree f_ovfl, f_gtop, f_ftop, f_goff, f_foff; @@ -1579,8 +1591,8 @@ iq2000_va_arg (tree valist, tree type) { /* Case of all args in a merged stack. No need to check bounds, just advance valist along the stack. */ - tree gpr = valist; + if (! indirect && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD) { @@ -1616,7 +1628,6 @@ iq2000_va_arg (tree valist, tree type) } /* Not a simple merged stack. Need ptrs and indexes left by va_start. */ - f_ovfl = TYPE_FIELDS (va_list_type_node); f_gtop = TREE_CHAIN (f_ovfl); f_ftop = TREE_CHAIN (f_gtop); @@ -1634,26 +1645,25 @@ iq2000_va_arg (tree valist, tree type) if (TREE_CODE (type) == REAL_TYPE) { - /* Emit code to branch if foff == 0. */ r = expand_expr (foff, NULL_RTX, TYPE_MODE (TREE_TYPE (foff)), EXPAND_NORMAL); emit_cmp_and_jump_insns (r, const0_rtx, EQ, const1_rtx, GET_MODE (r), 1, lab_false); - /* Emit code for addr_rtx = ftop - foff */ + /* Emit code for addr_rtx = ftop - foff. */ t = build (MINUS_EXPR, TREE_TYPE (ftop), ftop, foff ); r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); if (r != addr_rtx) emit_move_insn (addr_rtx, r); /* Emit code for foff-=8. - Advances the offset up FPR save area by one double */ + Advances the offset up FPR save area by one double. */ t = build (MINUS_EXPR, TREE_TYPE (foff), foff, build_int_2 (8, 0)); t = build (MODIFY_EXPR, TREE_TYPE (foff), foff, t); expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); - emit_queue(); + emit_queue (); emit_jump (lab_over); emit_barrier (); emit_label (lab_false); @@ -1681,7 +1691,7 @@ iq2000_va_arg (tree valist, tree type) } else { - /* not REAL_TYPE */ + /* Not REAL_TYPE. */ int step_size; if (TREE_CODE (type) == INTEGER_TYPE @@ -1726,7 +1736,7 @@ iq2000_va_arg (tree valist, tree type) emit_barrier (); emit_label (lab_false); - /* Emit code for addr_rtx -> overflow area, postinc by step_size */ + /* Emit code for addr_rtx -> overflow area, postinc by step_size. */ t = build (POSTINCREMENT_EXPR, TREE_TYPE(ovfl), ovfl, size_int (step_size)); r = expand_expr (t, addr_rtx, Pmode, EXPAND_NORMAL); @@ -1751,22 +1761,46 @@ iq2000_va_arg (tree valist, tree type) } } -/* Abort after printing out a specific insn. */ +/* Allocate a chunk of memory for per-function machine-dependent data. */ -static void -abort_with_insn (rtx insn, const char *reason) +static struct machine_function * +iq2000_init_machine_status (void) { - error (reason); - debug_rtx (insn); - abort (); + struct machine_function *f; + + f = ggc_alloc_cleared (sizeof (struct machine_function)); + + return f; } - + +static enum processor_type +iq2000_parse_cpu (const char * cpu_string) +{ + const char *p = cpu_string; + enum processor_type cpu; + + cpu = PROCESSOR_DEFAULT; + switch (p[2]) + { + case '1': + if (!strcmp (p, "iq10")) + cpu = PROCESSOR_IQ10; + break; + case '2': + if (!strcmp (p, "iq2000")) + cpu = PROCESSOR_IQ2000; + break; + } + + return cpu; +} + /* Detect any conflicts in the switches. */ void override_options (void) { - register enum processor_type iq2000_cpu; + enum processor_type iq2000_cpu; target_flags &= ~MASK_GPOPT; @@ -1838,16 +1872,7 @@ override_options (void) gpr_mode = SImode; /* Function to allocate machine-dependent function status. */ - init_machine_status = &iq2000_init_machine_status; -} - -/* Allocate a chunk of memory for per-function machine-dependent data. */ - -static struct machine_function * -iq2000_init_machine_status (void) -{ - return ((struct machine_function *) - ggc_alloc_cleared (sizeof (struct machine_function))); + init_machine_status = iq2000_init_machine_status; } /* The arg pointer (which is eliminated) points to the virtual frame pointer, @@ -1858,7 +1883,7 @@ HOST_WIDE_INT iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset) { rtx offset2 = const0_rtx; - rtx reg = eliminate_constant_term (addr, &offset2); + rtx reg = eliminate_constant_term (addr, & offset2); if (offset == 0) offset = INTVAL (offset2); @@ -1866,9 +1891,9 @@ iq2000_debugger_offset (rtx addr, HOST_WIDE_INT offset) if (reg == stack_pointer_rtx || reg == frame_pointer_rtx || reg == hard_frame_pointer_rtx) { - HOST_WIDE_INT frame_size = (!cfun->machine->frame.initialized) + HOST_WIDE_INT frame_size = (!cfun->machine->initialized) ? compute_frame_size (get_frame_size ()) - : cfun->machine->frame.total_size; + : cfun->machine->total_size; offset = offset - frame_size; } @@ -1898,7 +1923,7 @@ final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, rtx pattern = PATTERN (insn); int length = get_attr_length (insn); - /* Do we need to emit a NOP? */ + /* Do we need to emit a NOP? */ 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)) @@ -1908,7 +1933,7 @@ final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, fputs ("\tnop\n", asm_out_file); else - dslots_load_filled++; + dslots_load_filled ++; while (--dslots_number_nops > 0) fputs ("\tnop\n", asm_out_file); @@ -1919,22 +1944,23 @@ final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, iq2000_load_reg4 = 0; } - if ((GET_CODE (insn) == JUMP_INSN + 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++; + dslots_jump_total ++; } /* Return the bytes needed to compute the frame pointer from the current - stack pointer. + stack pointer where SIZE is the # of var. bytes allocated. IQ2000 stack frames look like: @@ -1982,24 +2008,22 @@ final_prescan_insn (rtx insn, rtx opvec[] ATTRIBUTE_UNUSED, | arguments passed | | in registers, even | low SP->| if not passed. | - memory +-----------------------+ - -*/ + memory +-----------------------+ */ HOST_WIDE_INT compute_frame_size (HOST_WIDE_INT size) { int regno; - HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up */ - HOST_WIDE_INT var_size; /* # bytes that variables take up */ - HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up */ - HOST_WIDE_INT extra_size; /* # extra bytes */ - HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding */ - HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs */ - HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs */ - long mask; /* mask of saved gp registers */ - int fp_inc; /* 1 or 2 depending on the size of fp regs */ - long fp_bits; /* bitmask to use for each fp register */ + HOST_WIDE_INT total_size; /* # bytes that the entire frame takes up. */ + HOST_WIDE_INT var_size; /* # bytes that variables take up. */ + HOST_WIDE_INT args_size; /* # bytes that outgoing arguments take up. */ + HOST_WIDE_INT extra_size; /* # extra bytes. */ + HOST_WIDE_INT gp_reg_rounded; /* # bytes needed to store gp after rounding. */ + HOST_WIDE_INT gp_reg_size; /* # bytes needed to store gp regs. */ + HOST_WIDE_INT fp_reg_size; /* # bytes needed to store fp regs. */ + long mask; /* mask of saved gp registers. */ + int fp_inc; /* 1 or 2 depending on the size of fp regs. */ + long fp_bits; /* bitmask to use for each fp register. */ gp_reg_size = 0; fp_reg_size = 0; @@ -2009,8 +2033,7 @@ compute_frame_size (HOST_WIDE_INT size) args_size = IQ2000_STACK_ALIGN (current_function_outgoing_args_size); /* If a function dynamically allocates the stack and - has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space */ - + has 0 for STACK_DYNAMIC_OFFSET then allocate some stack space. */ if (args_size == 0 && current_function_calls_alloca) args_size = 4 * UNITS_PER_WORD; @@ -2029,11 +2052,12 @@ compute_frame_size (HOST_WIDE_INT size) /* We need to restore these for the handler. */ if (current_function_calls_eh_return) { - int i; + unsigned int i; + for (i = 0; ; ++i) { regno = EH_RETURN_DATA_REGNO (i); - if (regno == (signed int) INVALID_REGNUM) + if (regno == (int) INVALID_REGNUM) break; gp_reg_size += GET_MODE_SIZE (gpr_mode); mask |= 1L << (regno - GP_REG_FIRST); @@ -2054,15 +2078,15 @@ compute_frame_size (HOST_WIDE_INT size) total_size += IQ2000_STACK_ALIGN (current_function_pretend_args_size); /* Save other computed information. */ - cfun->machine->frame.total_size = total_size; - cfun->machine->frame.var_size = var_size; - cfun->machine->frame.args_size = args_size; - cfun->machine->frame.extra_size = extra_size; - cfun->machine->frame.gp_reg_size = gp_reg_size; - cfun->machine->frame.fp_reg_size = fp_reg_size; - cfun->machine->frame.mask = mask; - cfun->machine->frame.initialized = reload_completed; - cfun->machine->frame.num_gp = gp_reg_size / UNITS_PER_WORD; + 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) { @@ -2071,17 +2095,17 @@ compute_frame_size (HOST_WIDE_INT size) offset = (args_size + extra_size + var_size + gp_reg_size - GET_MODE_SIZE (gpr_mode)); - cfun->machine->frame.gp_sp_offset = offset; - cfun->machine->frame.gp_save_offset = offset - total_size; + cfun->machine->gp_sp_offset = offset; + cfun->machine->gp_save_offset = offset - total_size; } else { - cfun->machine->frame.gp_sp_offset = 0; - cfun->machine->frame.gp_save_offset = 0; + cfun->machine->gp_sp_offset = 0; + cfun->machine->gp_save_offset = 0; } - cfun->machine->frame.fp_sp_offset = 0; - cfun->machine->frame.fp_save_offset = 0; + cfun->machine->fp_sp_offset = 0; + cfun->machine->fp_save_offset = 0; /* Ok, we're done. */ return total_size; @@ -2100,15 +2124,15 @@ iq2000_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED) if ((from) == FRAME_POINTER_REGNUM) (offset) = 0; else if ((from) == ARG_POINTER_REGNUM) - (offset) = (cfun->machine->frame.total_size); + (offset) = (cfun->machine->total_size); else if ((from) == RETURN_ADDRESS_POINTER_REGNUM) - { - if (leaf_function_p ()) - (offset) = 0; - else (offset) = cfun->machine->frame.gp_sp_offset - + ((UNITS_PER_WORD - (POINTER_SIZE / BITS_PER_UNIT)) - * (BYTES_BIG_ENDIAN != 0)); - } + { + 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; } @@ -2164,10 +2188,12 @@ iq2000_emit_frame_related_store (rtx mem, rtx reg, HOST_WIDE_INT offset) gen_rtx_SET (GET_MODE (reg), dwarf_mem, reg)); } +/* Emit instructions to save/restore registers, as determined by STORE_P. */ + static void save_restore_insns (int store_p) { - long mask = cfun->machine->frame.mask; + long mask = cfun->machine->mask; int regno; rtx base_reg_rtx; HOST_WIDE_INT base_offset; @@ -2196,9 +2222,9 @@ save_restore_insns (int store_p) the constant created in the prologue/epilogue to adjust the stack frame. */ - gp_offset = cfun->machine->frame.gp_sp_offset; + gp_offset = cfun->machine->gp_sp_offset; end_offset - = gp_offset - (cfun->machine->frame.gp_reg_size + = gp_offset - (cfun->machine->gp_reg_size - GET_MODE_SIZE (gpr_mode)); if (gp_offset < 0 || end_offset < 0) @@ -2212,6 +2238,7 @@ save_restore_insns (int store_p) { int regno; int reg_save_count = 0; + for (regno = GP_REG_LAST; regno >= GP_REG_FIRST; regno--) if (BITSET_P (mask, regno - GP_REG_FIRST)) reg_save_count += 1; base_offset = gp_offset - ((reg_save_count - 1) * 4); @@ -2263,9 +2290,9 @@ iq2000_expand_prologue (void) int store_args_on_stack = (iq2000_can_use_return_insn ()); /* If struct value address is treated as the first argument. */ - if (aggregate_value_p (DECL_RESULT (fndecl)) + if (aggregate_value_p (DECL_RESULT (fndecl), fndecl) && ! current_function_returns_pcc_struct - && struct_value_incoming_rtx == 0) + && targetm.calls.struct_value_rtx (TREE_TYPE (fndecl), 1) == 0) { tree type = build_pointer_type (fntype); tree function_result_decl = build_decl (PARM_DECL, NULL_TREE, type); @@ -2282,7 +2309,6 @@ iq2000_expand_prologue (void) variable arguments. This is only needed if store_args_on_stack is true. */ - INIT_CUMULATIVE_ARGS (args_so_far, fntype, NULL_RTX, 0); regno = GP_ARG_FIRST; @@ -2343,7 +2369,6 @@ iq2000_expand_prologue (void) Function_arg has encoded a PARALLEL rtx, holding a vector of adjustments to be made as the next_arg_reg variable, so we split up the insns, and emit them separately. */ - next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1); if (next_arg_reg != 0 && GET_CODE (next_arg_reg) == PARALLEL) { @@ -2438,7 +2463,7 @@ iq2000_expand_prologue (void) void iq2000_expand_epilogue (void) { - HOST_WIDE_INT tsize = cfun->machine->frame.total_size; + HOST_WIDE_INT tsize = cfun->machine->total_size; rtx tsize_rtx = GEN_INT (tsize); rtx tmp_rtx = (rtx)0; @@ -2499,7 +2524,7 @@ iq2000_expand_epilogue (void) void iq2000_expand_eh_return (rtx address) { - HOST_WIDE_INT gp_offset = cfun->machine->frame.gp_sp_offset; + HOST_WIDE_INT gp_offset = cfun->machine->gp_sp_offset; rtx scratch; scratch = plus_constant (stack_pointer_rtx, gp_offset); @@ -2519,8 +2544,8 @@ iq2000_can_use_return_insn (void) if (regs_ever_live[31] || profile_flag) return 0; - if (cfun->machine->frame.initialized) - return cfun->machine->frame.total_size == 0; + if (cfun->machine->initialized) + return cfun->machine->total_size == 0; return compute_frame_size (get_frame_size ()) == 0; } @@ -2576,7 +2601,6 @@ iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, { /* For embedded applications, always put an object in read-only data if possible, in order to reduce RAM usage. */ - if (((TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) && DECL_INITIAL (decl) @@ -2594,7 +2618,6 @@ iq2000_select_section (tree decl, int reloc ATTRIBUTE_UNUSED, { /* For hosted applications, always put an object in small data if possible, as this gives the best performance. */ - if (((TREE_CODE (decl) == VAR_DECL && TREE_READONLY (decl) && !TREE_SIDE_EFFECTS (decl) && DECL_INITIAL (decl) @@ -2639,13 +2662,13 @@ function_arg_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, /* We must pass by reference if we would be both passing in registers and the stack. This is because any subsequent partial arg would be handled incorrectly in this case. */ - if (cum && MUST_PASS_IN_STACK (mode, type)) { /* Don't pass the actual CUM to FUNCTION_ARG, because we would get double copies of any offsets generated for small structs passed in registers. */ CUMULATIVE_ARGS temp; + temp = *cum; if (FUNCTION_ARG (temp, mode, type, named) != 0) return 1; @@ -2665,10 +2688,10 @@ int iq2000_adjust_insn_length (rtx insn, int length) { /* A unconditional jump has an unfilled delay slot if it is not part - of a sequence. A conditional jump normally has a delay slot */ + of a sequence. A conditional jump normally has a delay slot. */ if (simplejump_p (insn) - || ((GET_CODE (insn) == JUMP_INSN - || GET_CODE (insn) == CALL_INSN))) + || ( (GET_CODE (insn) == JUMP_INSN + || GET_CODE (insn) == CALL_INSN))) length += 4; return length; @@ -2690,13 +2713,13 @@ iq2000_adjust_insn_length (rtx insn, int length) reversed conditional branch around a `jr' instruction. */ char * -iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p, +iq2000_output_conditional_branch (rtx insn, rtx * operands, int two_operands_p, int float_p, int inverted_p, int length) { static char buffer[200]; /* The kind of comparison we are doing. */ enum rtx_code code = GET_CODE (operands[0]); - /* Nonzero if the opcode for the comparison needs a `z' indicating + /* nonzero if the opcode for the comparison needs a `z' indicating that it is a comparison against zero. */ int need_z_p; /* A string to use in the assembly output to represent the first @@ -2711,7 +2734,7 @@ iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p, /* The operand-printing string for the inverted comparison. */ const char *inverted_comp = (float_p ? "%W0" : "%N0"); - /* likely variants of each branch instruction annul the instruction + /* Likely variants of each branch instruction annul the instruction in the delay slot if the branch is not taken. */ iq2000_branch_likely = (final_sequence && INSN_ANNULLED_BRANCH_P (insn)); @@ -2813,7 +2836,7 @@ iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p, char *c; c = strchr (buffer, '\0'); - /* Generate the reversed comparison. This takes four + /* Generate the reversed comparision. This takes four bytes. */ if (float_p) sprintf (c, "b%s\t%%Z2%s", @@ -2843,32 +2866,10 @@ iq2000_output_conditional_branch (rtx insn, rtx *operands, int two_operands_p, return 0; } -static enum processor_type -iq2000_parse_cpu (const char *cpu_string) -{ - const char *p = cpu_string; - enum processor_type cpu; - - cpu = PROCESSOR_DEFAULT; - switch (p[2]) - { - case '1': - if (!strcmp (p, "iq10")) - cpu = PROCESSOR_IQ10; - break; - case '2': - if (!strcmp (p, "iq2000")) - cpu = PROCESSOR_IQ2000; - break; - } - - return cpu; -} - #define def_builtin(NAME, TYPE, CODE) \ builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD, NULL, NULL_TREE) -void +static void iq2000_init_builtins (void) { tree endlink = void_list_node; @@ -2999,7 +3000,7 @@ void_ftype_int_int_int } /* Builtin for ICODE having ARGCOUNT args in ARGLIST where each arg - has an rtx CODE */ + has an rtx CODE. */ static rtx expand_one_builtin (enum insn_code icode, rtx target, tree arglist, @@ -3079,7 +3080,7 @@ expand_one_builtin (enum insn_code icode, rtx target, tree arglist, SUBTARGET may be used as the target for computing one of EXP's operands. IGNORE is nonzero if the value is to be ignored. */ -rtx +static rtx iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, int ignore ATTRIBUTE_UNUSED) @@ -3263,11 +3264,12 @@ iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS cum, int mode ATTRIBUTE_UNUSED, - tree type ATTRIBUTE_UNUSED, int *pretend_size, - int no_rtl) + 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 @@ -3303,11 +3305,10 @@ iq2000_setup_incoming_varargs (CUMULATIVE_ARGS cum, int mode ATTRIBUTE_UNUSED, /* 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. -*/ + reference whose address is ADDR. ADDR is an RTL expression. */ void -print_operand_address (FILE *file, rtx addr) +print_operand_address (FILE * file, rtx addr) { if (!addr) error ("PRINT_OPERAND_ADDRESS, null pointer"); @@ -3324,8 +3325,8 @@ print_operand_address (FILE *file, rtx addr) case LO_SUM: { - register rtx arg0 = XEXP (addr, 0); - register rtx arg1 = XEXP (addr, 1); + rtx arg0 = XEXP (addr, 0); + rtx arg1 = XEXP (addr, 1); if (GET_CODE (arg0) != REG) abort_with_insn (addr, @@ -3339,10 +3340,10 @@ print_operand_address (FILE *file, rtx addr) case PLUS: { - register rtx reg = 0; - register rtx offset = 0; - register rtx arg0 = XEXP (addr, 0); - register rtx arg1 = XEXP (addr, 1); + rtx reg = 0; + rtx offset = 0; + rtx arg0 = XEXP (addr, 0); + rtx arg1 = XEXP (addr, 1); if (GET_CODE (arg0) == REG) { @@ -3388,25 +3389,24 @@ print_operand_address (FILE *file, rtx addr) } } -/* A C compound statement to output to stdio stream STREAM the - assembler syntax for an instruction operand X. X is an RTL - expression. +/* A C compound statement to output to stdio stream FILE the + assembler syntax for an instruction operand OP. - CODE is a value that can be used to specify one of several ways + LETTER is a value that can be used to specify one of several ways of printing the operand. It is used when identical operands - must be printed differently depending on the context. CODE + must be printed differently depending on the context. LETTER comes from the `%' specification that was used to request printing of the operand. If the specification was just `%DIGIT' - then CODE is 0; if the specification was `%LTR DIGIT' then CODE + then LETTER is 0; if the specification was `%LTR DIGIT' then LETTER is the ASCII code for LTR. - If X is a register, this macro should print the register's name. + If OP is a register, this macro should print the register's name. The names can be found in an array `reg_names' whose type is `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'. When the machine description has a specification `%PUNCT' (a `%' followed by a punctuation character), this macro is called with - a null pointer for X and the punctuation character for CODE. + a null pointer for X and the punctuation character for LETTER. The IQ2000 specific codes are: @@ -3438,7 +3438,7 @@ print_operand_address (FILE *file, rtx addr) void print_operand (FILE *file, rtx op, int letter) { - register enum rtx_code code; + enum rtx_code code; if (PRINT_OPERAND_PUNCT_VALID_P (letter)) { @@ -3558,7 +3558,7 @@ print_operand (FILE *file, rtx op, int letter) else if (letter == 'Z') { - register int regnum; + int regnum; if (code != REG) abort (); @@ -3571,7 +3571,7 @@ print_operand (FILE *file, rtx op, int letter) else if (code == REG || code == SUBREG) { - register int regnum; + int regnum; if (code == REG) regnum = REGNO (op); @@ -3635,3 +3635,143 @@ print_operand (FILE *file, rtx op, int letter) else output_addr_const (file, op); } + +static bool +iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total) +{ + enum machine_mode mode = GET_MODE (x); + + switch (code) + { + case MEM: + { + int num_words = (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1; + + if (simple_memory_operand (x, mode)) + return COSTS_N_INSNS (num_words); + + * total = COSTS_N_INSNS (2 * num_words); + break; + } + + case FFS: + * total = COSTS_N_INSNS (6); + break; + + case AND: + case IOR: + case XOR: + case NOT: + * total = COSTS_N_INSNS (mode == DImode ? 2 : 1); + break; + + case ASHIFT: + case ASHIFTRT: + case LSHIFTRT: + if (mode == DImode) + * total = COSTS_N_INSNS ((GET_CODE (XEXP (x, 1)) == CONST_INT) ? 4 : 12); + else + * total = COSTS_N_INSNS (1); + break; + + case ABS: + if (mode == SFmode || mode == DFmode) + * total = COSTS_N_INSNS (1); + else + * total = COSTS_N_INSNS (4); + break; + + case PLUS: + case MINUS: + if (mode == SFmode || mode == DFmode) + * total = COSTS_N_INSNS (6); + else if (mode == DImode) + * total = COSTS_N_INSNS (4); + else + * total = COSTS_N_INSNS (1); + break; + + case NEG: + * total = (mode == DImode) ? 4 : 1; + break; + + case MULT: + if (mode == SFmode) + * total = COSTS_N_INSNS (7); + else if (mode == DFmode) + * total = COSTS_N_INSNS (8); + else + * total = COSTS_N_INSNS (10); + break; + + case DIV: + case MOD: + if (mode == SFmode) + * total = COSTS_N_INSNS (23); + else if (mode == DFmode) + * total = COSTS_N_INSNS (36); + else + * total = COSTS_N_INSNS (69); + break; + + case UDIV: + case UMOD: + * total = COSTS_N_INSNS (69); + break; + + case SIGN_EXTEND: + * total = COSTS_N_INSNS (2); + break; + + case ZERO_EXTEND: + * total = COSTS_N_INSNS (1); + break; + + case CONST_INT: + * total = 0; + break; + + case LABEL_REF: + * total = COSTS_N_INSNS (2); + break; + + case CONST: + { + rtx offset = const0_rtx; + rtx symref = eliminate_constant_term (XEXP (x, 0), & offset); + + if (GET_CODE (symref) == LABEL_REF) + * total = COSTS_N_INSNS (2); + else if (GET_CODE (symref) != SYMBOL_REF) + * total = COSTS_N_INSNS (4); + /* let's be paranoid.... */ + else if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767) + * total = COSTS_N_INSNS (2); + else + * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2); + break; + } + + case SYMBOL_REF: + * total = COSTS_N_INSNS (SYMBOL_REF_FLAG (x) ? 1 : 2); + break; + + case CONST_DOUBLE: + { + rtx high, low; + + split_double (x, & high, & low); + + * total = COSTS_N_INSNS ( (high == CONST0_RTX (GET_MODE (high)) + || low == CONST0_RTX (GET_MODE (low))) + ? 2 : 4); + break; + } + + default: + return false; + } + return true; +} + +#include "gt-iq2000.h" diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h index 6bc18f3b20d..a54856a402b 100644 --- a/gcc/config/iq2000/iq2000.h +++ b/gcc/config/iq2000/iq2000.h @@ -21,7 +21,7 @@ /* Driver configuration. */ -#undef SWITCH_TAKES_ARG +#undef SWITCH_TAKES_ARG #define SWITCH_TAKES_ARG(CHAR) \ (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G') @@ -38,28 +38,26 @@ #define TARGET_CPU_CPP_BUILTINS() \ do \ { \ - builtin_define ("__iq2000__"); \ - builtin_assert ("cpu=iq2000"); \ - builtin_assert ("machine=iq2000"); \ + builtin_define ("__iq2000__"); \ + builtin_assert ("cpu=iq2000"); \ + builtin_assert ("machine=iq2000"); \ } \ while (0) - extern int target_flags; -#define MASK_GPOPT 0x00000008 /* Optimize for global pointer */ -#define MASK_EMBEDDED_DATA 0x00008000 /* Reduce RAM usage, not fast code */ +#define MASK_GPOPT 0x00000008 /* Optimize for global pointer. */ +#define MASK_EMBEDDED_DATA 0x00008000 /* Reduce RAM usage, not fast code. */ #define MASK_UNINIT_CONST_IN_RODATA \ 0x00800000 /* Store uninitialized - consts in rodata */ + consts in rodata. */ /* Macros used in the machine description to test the flags. */ #define TARGET_STATS 0 - /* for embedded systems, optimize for - reduced RAM space instead of for - fastest code. */ +/* For embedded systems, optimize for reduced RAM space instead of for + fastest code. */ #define TARGET_EMBEDDED_DATA (target_flags & MASK_EMBEDDED_DATA) #define TARGET_DEBUG_MODE (target_flags & 0) @@ -134,23 +132,15 @@ extern int target_flags; /* Storage Layout. */ -#define BITS_BIG_ENDIAN 0 - -#define BYTES_BIG_ENDIAN 1 - -#define WORDS_BIG_ENDIAN 1 - -#define LIBGCC2_WORDS_BIG_ENDIAN 1 - -#define BITS_PER_WORD 32 - -#define MAX_BITS_PER_WORD 64 - -#define UNITS_PER_WORD 4 - -#define MIN_UNITS_PER_WORD 4 - -#define POINTER_SIZE 32 +#define BITS_BIG_ENDIAN 0 +#define BYTES_BIG_ENDIAN 1 +#define WORDS_BIG_ENDIAN 1 +#define LIBGCC2_WORDS_BIG_ENDIAN 1 +#define BITS_PER_WORD 32 +#define MAX_BITS_PER_WORD 64 +#define UNITS_PER_WORD 4 +#define MIN_UNITS_PER_WORD 4 +#define POINTER_SIZE 32 /* Define this macro if it is advisable to hold scalars in registers in a wider mode than that declared by the program. In such cases, @@ -177,7 +167,7 @@ extern int target_flags; #define BIGGEST_ALIGNMENT 64 -#undef DATA_ALIGNMENT +#undef DATA_ALIGNMENT #define DATA_ALIGNMENT(TYPE, ALIGN) \ ((((ALIGN) < BITS_PER_WORD) \ && (TREE_CODE (TYPE) == ARRAY_TYPE \ @@ -201,27 +191,16 @@ extern int target_flags; /* Layout of Source Language Data Types. */ -#define INT_TYPE_SIZE 32 - -#define MAX_INT_TYPE_SIZE 32 - -#define SHORT_TYPE_SIZE 16 - -#define LONG_TYPE_SIZE 32 - -#define LONG_LONG_TYPE_SIZE 64 - -#define CHAR_TYPE_SIZE BITS_PER_UNIT - -#define FLOAT_TYPE_SIZE 32 - -#define DOUBLE_TYPE_SIZE 64 - -#define LONG_DOUBLE_TYPE_SIZE 64 - -#define DEFAULT_SIGNED_CHAR 1 - -#define MAX_WCHAR_TYPE_SIZE MAX_INT_TYPE_SIZE +#define INT_TYPE_SIZE 32 +#define SHORT_TYPE_SIZE 16 +#define LONG_TYPE_SIZE 32 +#define LONG_LONG_TYPE_SIZE 64 +#define CHAR_TYPE_SIZE BITS_PER_UNIT +#define FLOAT_TYPE_SIZE 32 +#define DOUBLE_TYPE_SIZE 64 +#define LONG_DOUBLE_TYPE_SIZE 64 +#define DEFAULT_SIGNED_CHAR 1 +#define MAX_WCHAR_TYPE_SIZE 32 /* Register Basics. */ @@ -255,15 +234,15 @@ extern int target_flags; #define HARD_REGNO_NREGS(REGNO, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO_REG_CLASS (REGNO) == GR_REGS) \ - ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \ +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO_REG_CLASS (REGNO) == GR_REGS) \ + ? ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) <= 4 \ : ((REGNO) & 1) == 0 || GET_MODE_SIZE (MODE) == 4) -#define MODES_TIEABLE_P(MODE1, MODE2) \ - ((GET_MODE_CLASS (MODE1) == MODE_FLOAT || \ - GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \ - == (GET_MODE_CLASS (MODE2) == MODE_FLOAT || \ +#define MODES_TIEABLE_P(MODE1, MODE2) \ + ((GET_MODE_CLASS (MODE1) == MODE_FLOAT || \ + GET_MODE_CLASS (MODE1) == MODE_COMPLEX_FLOAT) \ + == (GET_MODE_CLASS (MODE2) == MODE_FLOAT || \ GET_MODE_CLASS (MODE2) == MODE_COMPLEX_FLOAT)) #define AVOID_CCMODE_COPIES @@ -273,28 +252,28 @@ extern int target_flags; enum reg_class { - NO_REGS, /* no registers in set */ - GR_REGS, /* integer registers */ - ALL_REGS, /* all registers */ - LIM_REG_CLASSES /* max value + 1 */ + NO_REGS, /* No registers in set. */ + GR_REGS, /* Integer registers. */ + ALL_REGS, /* All registers. */ + LIM_REG_CLASSES /* Max value + 1. */ }; #define GENERAL_REGS GR_REGS #define N_REG_CLASSES (int) LIM_REG_CLASSES -#define REG_CLASS_NAMES \ -{ \ - "NO_REGS", \ - "GR_REGS", \ - "ALL_REGS" \ +#define REG_CLASS_NAMES \ +{ \ + "NO_REGS", \ + "GR_REGS", \ + "ALL_REGS" \ } -#define REG_CLASS_CONTENTS \ -{ \ - { 0x00000000, 0x00000000 }, /* no registers */ \ - { 0xffffffff, 0x00000000 }, /* integer registers */ \ - { 0xffffffff, 0x00000001 } /* all registers */ \ +#define REG_CLASS_CONTENTS \ +{ \ + { 0x00000000, 0x00000000 }, /* No registers, */ \ + { 0xffffffff, 0x00000000 }, /* Integer registers. */ \ + { 0xffffffff, 0x00000001 } /* All registers. */ \ } #define REGNO_REG_CLASS(REGNO) \ @@ -305,22 +284,22 @@ enum reg_class #define INDEX_REG_CLASS NO_REGS #define REG_CLASS_FROM_LETTER(C) \ - ((C) == 'd' ? GR_REGS : \ - (C) == 'b' ? ALL_REGS : \ - (C) == 'y' ? GR_REGS : \ + ((C) == 'd' ? GR_REGS : \ + (C) == 'b' ? ALL_REGS : \ + (C) == 'y' ? GR_REGS : \ NO_REGS) #define REGNO_OK_FOR_INDEX_P(regno) 0 -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - ((CLASS) != ALL_REGS \ - ? (CLASS) \ - : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ - || GET_MODE_CLASS (GET_MODE (X)) == MODE_COMPLEX_FLOAT) \ - ? (GR_REGS) \ - : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \ - || GET_MODE (X) == VOIDmode) \ - ? (GR_REGS) \ +#define PREFERRED_RELOAD_CLASS(X,CLASS) \ + ((CLASS) != ALL_REGS \ + ? (CLASS) \ + : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ + || GET_MODE_CLASS (GET_MODE (X)) == MODE_COMPLEX_FLOAT) \ + ? (GR_REGS) \ + : ((GET_MODE_CLASS (GET_MODE (X)) == MODE_INT \ + || GET_MODE (X) == VOIDmode) \ + ? (GR_REGS) \ : (CLASS)))) #define SMALL_REGISTER_CLASSES 0 @@ -346,8 +325,7 @@ enum reg_class `N' is used for constants 0xffffnnnn or 0xnnnnffff - `O' is a 5 bit zero-extended integer. -*/ + `O' is a 5 bit zero-extended integer. */ #define CONST_OK_FOR_LETTER_P(VALUE, C) \ ((C) == 'I' ? ((unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000) \ @@ -412,18 +390,12 @@ enum reg_class /* Register That Address the Stack Frame. */ -#define STACK_POINTER_REGNUM (GP_REG_FIRST + 29) - -#define FRAME_POINTER_REGNUM (GP_REG_FIRST + 1) - -#define HARD_FRAME_POINTER_REGNUM \ - (GP_REG_FIRST + 27) - -#define ARG_POINTER_REGNUM GP_REG_FIRST - -#define RETURN_ADDRESS_POINTER_REGNUM RAP_REG_NUM - -#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2) +#define STACK_POINTER_REGNUM (GP_REG_FIRST + 29) +#define FRAME_POINTER_REGNUM (GP_REG_FIRST + 1) +#define HARD_FRAME_POINTER_REGNUM (GP_REG_FIRST + 27) +#define ARG_POINTER_REGNUM GP_REG_FIRST +#define RETURN_ADDRESS_POINTER_REGNUM RAP_REG_NUM +#define STATIC_CHAIN_REGNUM (GP_REG_FIRST + 2) /* Eliminating the Frame Pointer and the Arg Pointer. */ @@ -471,39 +443,40 @@ enum reg_class /* Function Arguments in Registers. */ #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ - function_arg( &CUM, MODE, TYPE, NAMED) + function_arg (& CUM, MODE, TYPE, NAMED) #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ - function_arg_partial_nregs (&CUM, MODE, TYPE, NAMED) + function_arg_partial_nregs (& CUM, MODE, TYPE, NAMED) #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \ - function_arg_pass_by_reference (&CUM, MODE, TYPE, NAMED) + function_arg_pass_by_reference (& CUM, MODE, TYPE, NAMED) #define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \ ((NAMED) && FUNCTION_ARG_PASS_BY_REFERENCE (CUM, MODE, TYPE, NAMED)) #define MAX_ARGS_IN_REGISTERS 8 -typedef struct iq2000_args { - int gp_reg_found; /* whether a gp register was found yet */ - unsigned int arg_number; /* argument number */ - unsigned int arg_words; /* # total words the arguments take */ - unsigned int fp_arg_words; /* # words for FP args (IQ2000_EABI only) */ - int last_arg_fp; /* nonzero if last arg was FP (EABI only) */ - int fp_code; /* Mode of FP arguments */ - unsigned int num_adjusts; /* number of adjustments made */ +typedef struct iq2000_args +{ + int gp_reg_found; /* Whether a gp register was found yet. */ + unsigned int arg_number; /* Argument number. */ + unsigned int arg_words; /* # total words the arguments take. */ + unsigned int fp_arg_words; /* # words for FP args (IQ2000_EABI only). */ + int last_arg_fp; /* Nonzero if last arg was FP (EABI only). */ + int fp_code; /* Mode of FP arguments. */ + unsigned int num_adjusts; /* Number of adjustments made. */ /* Adjustments made to args pass in regs. */ - struct rtx_def *adjust[MAX_ARGS_IN_REGISTERS*2]; + struct rtx_def * adjust[MAX_ARGS_IN_REGISTERS * 2]; } CUMULATIVE_ARGS; /* 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. */ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \ - init_cumulative_args (&CUM, FNTYPE, LIBNAME) \ + init_cumulative_args (& CUM, FNTYPE, LIBNAME) \ #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - function_arg_advance (&CUM, MODE, TYPE, NAMED) + function_arg_advance (& CUM, MODE, TYPE, NAMED) #define FUNCTION_ARG_PADDING(MODE, TYPE) \ (! BYTES_BIG_ENDIAN \ @@ -641,24 +614,24 @@ typedef struct iq2000_args { /* Addressing Modes. */ #define CONSTANT_ADDRESS_P(X) \ - ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + ( (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ || GET_CODE (X) == CONST_INT || GET_CODE (X) == HIGH \ || (GET_CODE (X) == CONST))) #define MAX_REGS_PER_ADDRESS 1 #ifdef REG_OK_STRICT -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ \ - if (iq2000_legitimate_address_p (MODE, X, 1)) \ - goto ADDR; \ -} +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ + { \ + if (iq2000_legitimate_address_p (MODE, X, 1)) \ + goto ADDR; \ + } #else -#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ -{ \ - if (iq2000_legitimate_address_p (MODE, X, 0)) \ - goto ADDR; \ -} +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ + { \ + if (iq2000_legitimate_address_p (MODE, X, 0)) \ + goto ADDR; \ + } #endif #define REG_OK_FOR_INDEX_P(X) 0 @@ -675,7 +648,7 @@ typedef struct iq2000_args { #define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ { \ - register rtx xinsn = (X); \ + rtx xinsn = (X); \ \ if (TARGET_DEBUG_B_MODE) \ { \ @@ -694,10 +667,10 @@ typedef struct iq2000_args { \ if (GET_CODE (xinsn) == PLUS) \ { \ - register rtx xplus0 = XEXP (xinsn, 0); \ - register rtx xplus1 = XEXP (xinsn, 1); \ - register enum rtx_code code0 = GET_CODE (xplus0); \ - register enum rtx_code code1 = GET_CODE (xplus1); \ + 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) \ { \ @@ -736,149 +709,6 @@ typedef struct iq2000_args { /* Describing Relative Costs of Operations. */ -#define CONST_COSTS(X,CODE,OUTER_CODE) \ - case CONST_INT: \ - return 0; \ - \ - case LABEL_REF: \ - return COSTS_N_INSNS (2); \ - \ - case CONST: \ - { \ - rtx offset = const0_rtx; \ - rtx symref = eliminate_constant_term (XEXP (X, 0), &offset); \ - \ - if (GET_CODE (symref) == LABEL_REF) \ - return COSTS_N_INSNS (2); \ - \ - if (GET_CODE (symref) != SYMBOL_REF) \ - return COSTS_N_INSNS (4); \ - \ - /* let's be paranoid.... */ \ - if (INTVAL (offset) < -32768 || INTVAL (offset) > 32767) \ - return COSTS_N_INSNS (2); \ - \ - return COSTS_N_INSNS (SYMBOL_REF_FLAG (symref) ? 1 : 2); \ - } \ - \ - case SYMBOL_REF: \ - return COSTS_N_INSNS (SYMBOL_REF_FLAG (X) ? 1 : 2); \ - \ - case CONST_DOUBLE: \ - { \ - rtx high, low; \ - split_double (X, &high, &low); \ - return COSTS_N_INSNS ((high == CONST0_RTX (GET_MODE (high)) \ - || low == CONST0_RTX (GET_MODE (low))) \ - ? 2 : 4); \ - } - -#define RTX_COSTS(X,CODE,OUTER_CODE) \ - case MEM: \ - { \ - int num_words = (GET_MODE_SIZE (GET_MODE (X)) > UNITS_PER_WORD) ? 2 : 1; \ - if (simple_memory_operand (X, GET_MODE (X))) \ - return COSTS_N_INSNS (num_words); \ - \ - return COSTS_N_INSNS (2*num_words); \ - } \ - \ - case FFS: \ - return COSTS_N_INSNS (6); \ - \ - case NOT: \ - return COSTS_N_INSNS (GET_MODE (X) == DImode && 2); \ - \ - case AND: \ - case IOR: \ - case XOR: \ - if (GET_MODE (X) == DImode) \ - return COSTS_N_INSNS (2); \ - \ - break; \ - \ - case ASHIFT: \ - case ASHIFTRT: \ - case LSHIFTRT: \ - if (GET_MODE (X) == DImode) \ - return COSTS_N_INSNS ((GET_CODE (XEXP (X, 1)) == CONST_INT) ? 4 : 12); \ - \ - break; \ - \ - case ABS: \ - { \ - enum machine_mode xmode = GET_MODE (X); \ - if (xmode == SFmode || xmode == DFmode) \ - return COSTS_N_INSNS (1); \ - \ - return COSTS_N_INSNS (4); \ - } \ - \ - case PLUS: \ - case MINUS: \ - { \ - enum machine_mode xmode = GET_MODE (X); \ - if (xmode == SFmode || xmode == DFmode) \ - { \ - return COSTS_N_INSNS (6); \ - } \ - \ - if (xmode == DImode) \ - return COSTS_N_INSNS (4); \ - \ - break; \ - } \ - \ - case NEG: \ - if (GET_MODE (X) == DImode) \ - return 4; \ - \ - break; \ - \ - case MULT: \ - { \ - enum machine_mode xmode = GET_MODE (X); \ - if (xmode == SFmode) \ - { \ - return COSTS_N_INSNS (7); \ - } \ - \ - if (xmode == DFmode) \ - { \ - return COSTS_N_INSNS (8); \ - } \ - \ - return COSTS_N_INSNS (10); \ - } \ - \ - case DIV: \ - case MOD: \ - { \ - enum machine_mode xmode = GET_MODE (X); \ - if (xmode == SFmode) \ - { \ - return COSTS_N_INSNS (23); \ - } \ - \ - if (xmode == DFmode) \ - { \ - return COSTS_N_INSNS (36); \ - } \ - } \ - /* fall through */ \ - \ - case UDIV: \ - case UMOD: \ - return COSTS_N_INSNS (69); \ - \ - case SIGN_EXTEND: \ - return COSTS_N_INSNS (2); \ - \ - case ZERO_EXTEND: \ - return COSTS_N_INSNS (1); - -#define ADDRESS_COST(ADDR) (REG_P (ADDR) ? 1 : iq2000_address_cost (ADDR)) - #define REGISTER_MOVE_COST(MODE, FROM, TO) 2 #define MEMORY_MOVE_COST(MODE,CLASS,TO_P) \ @@ -899,9 +729,9 @@ typedef struct iq2000_args { /* Dividing the output into sections. */ -#define TEXT_SECTION_ASM_OP "\t.text" /* instructions */ +#define TEXT_SECTION_ASM_OP "\t.text" /* Instructions. */ -#define DATA_SECTION_ASM_OP "\t.data" /* large data */ +#define DATA_SECTION_ASM_OP "\t.data" /* Large data. */ /* The Overall Framework of an Assembler File. */ @@ -915,13 +745,9 @@ typedef struct iq2000_args { /* Output and Generation of Labels. */ -#undef ASM_OUTPUT_INTERNAL_LABEL -#define ASM_OUTPUT_INTERNAL_LABEL(STREAM,PREFIX,NUM) \ - fprintf (STREAM, "%s%s%d:\n", LOCAL_LABEL_PREFIX, PREFIX, NUM) - #undef ASM_GENERATE_INTERNAL_LABEL #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long)(NUM)) + sprintf ((LABEL), "*%s%s%ld", (LOCAL_LABEL_PREFIX), (PREFIX), (long) (NUM)) #define GLOBAL_ASM_OP "\t.globl\t" @@ -989,7 +815,6 @@ typedef struct iq2000_args { #define DBR_OUTPUT_SEQEND(STREAM) \ do \ { \ - dslots_jump_filled++; \ fputs ("\n", STREAM); \ } \ while (0) @@ -1002,11 +827,13 @@ while (0) /* Output of dispatch tables. */ #define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \ -do { \ - fprintf (STREAM, "\t%s\t%sL%d\n", \ - Pmode == DImode ? ".dword" : ".word", \ - LOCAL_LABEL_PREFIX, VALUE); \ -} while (0) + do \ + { \ + fprintf (STREAM, "\t%s\t%sL%d\n", \ + Pmode == DImode ? ".dword" : ".word", \ + LOCAL_LABEL_PREFIX, VALUE); \ + } \ + while (0) #define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \ fprintf (STREAM, "\t%s\t%sL%d\n", \ @@ -1089,19 +916,19 @@ extern char call_used_regs[]; /* Comparison type. */ enum cmp_type { - CMP_SI, /* compare four byte integers */ - CMP_DI, /* compare eight byte integers */ - CMP_SF, /* compare single precision floats */ - CMP_DF, /* compare double precision floats */ - CMP_MAX /* max comparison type */ + CMP_SI, /* Compare four byte integers. */ + CMP_DI, /* Compare eight byte integers. */ + CMP_SF, /* Compare single precision floats. */ + CMP_DF, /* Compare double precision floats. */ + CMP_MAX /* Max comparison type. */ }; /* Types of delay slot. */ enum delay_type { - DELAY_NONE, /* no delay slot */ - DELAY_LOAD, /* load from memory delay */ - DELAY_FCMP /* delay after doing c..{d,s} */ + DELAY_NONE, /* No delay slot. */ + DELAY_LOAD, /* Load from memory delay. */ + DELAY_FCMP /* Delay after doing c..{d,s}. */ }; /* Which processor to schedule for. */ @@ -1114,36 +941,15 @@ enum processor_type }; /* Recast the cpu class to be the cpu attribute. */ -#define iq2000_cpu_attr ((enum attr_cpu)iq2000_tune) - -extern char iq2000_print_operand_punct[]; /* print_operand punctuation chars */ -extern int num_source_filenames; /* current .file # */ -extern int iq2000_branch_likely; /* emit 'l' after br (branch likely) */ -extern struct rtx_def *branch_cmp[2]; /* operands for compare */ -extern enum cmp_type branch_type; /* what type of branch to use */ -extern enum processor_type iq2000_arch; /* which cpu to codegen for */ -extern enum processor_type iq2000_tune; /* which cpu to schedule for */ -extern int iq2000_isa; /* architectural level */ -extern const char *iq2000_cpu_string; /* for -mcpu= */ -extern const char *iq2000_arch_string; /* for -march= */ -extern int dslots_load_total; /* total # load related delay slots */ -extern int dslots_load_filled; /* # filled load delay slots */ -extern int dslots_jump_total; /* total # jump related delay slots */ -extern int dslots_jump_filled; /* # filled jump delay slots */ -extern int dslots_number_nops; /* # of nops needed by previous insn */ -extern int num_refs[3]; /* # 1/2/3 word references */ -extern struct rtx_def *iq2000_load_reg; /* register to check for load delay */ -extern struct rtx_def *iq2000_load_reg2; /* 2nd reg to check for load delay */ -extern struct rtx_def *iq2000_load_reg3; /* 3rd reg to check for load delay */ -extern struct rtx_def *iq2000_load_reg4; /* 4th reg to check for load delay */ +#define iq2000_cpu_attr ((enum attr_cpu) iq2000_tune) /* Functions to change what output section we are using. */ extern void rdata_section (void); extern void sdata_section (void); -extern void sbss_section (void); +extern void sbss_section (void); -#define BITMASK_UPPER16 ((unsigned long)0xffff << 16) /* 0xffff0000 */ -#define BITMASK_LOWER16 ((unsigned long)0xffff) /* 0x0000ffff */ +#define BITMASK_UPPER16 ((unsigned long) 0xffff << 16) /* 0xffff0000 */ +#define BITMASK_LOWER16 ((unsigned long) 0xffff) /* 0x0000ffff */ #define GENERATE_BRANCHLIKELY (ISA_HAS_BRANCHLIKELY) @@ -1262,10 +1068,10 @@ extern void sbss_section (void); #ifndef STACK_ARGS_ADJUST #define STACK_ARGS_ADJUST(SIZE) \ -{ \ - if (SIZE.constant < 4 * UNITS_PER_WORD) \ - SIZE.constant = 4 * UNITS_PER_WORD; \ -} + { \ + if (SIZE.constant < 4 * UNITS_PER_WORD) \ + SIZE.constant = 4 * UNITS_PER_WORD; \ + } #endif @@ -1333,9 +1139,9 @@ extern void sbss_section (void); #endif #if 1 -#define GO_PRINTF(x) fprintf(stderr, (x)) -#define GO_PRINTF2(x,y) fprintf(stderr, (x), (y)) -#define GO_DEBUG_RTX(x) debug_rtx(x) +#define GO_PRINTF(x) fprintf (stderr, (x)) +#define GO_PRINTF2(x,y) fprintf (stderr, (x), (y)) +#define GO_DEBUG_RTX(x) debug_rtx (x) #else #define GO_PRINTF(x) @@ -1343,15 +1149,6 @@ extern void sbss_section (void); #define GO_DEBUG_RTX(x) #endif -/* Specify the tree operation to be used to convert reals to integers. */ -#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR - -/* This is the kind of divide that is easiest to do in the general case. */ -#define EASY_DIV_EXPR TRUNC_DIV_EXPR - -/* Define this if zero-extension is slow (more than one real instruction). */ -#define SLOW_ZERO_EXTEND - /* If defined, modifies the length assigned to instruction INSN as a function of the context in which it is used. LENGTH is an lvalue that contains the initially computed length of the insn and should @@ -1372,7 +1169,7 @@ extern void sbss_section (void); /* How to tell the debugger about changes of source files. */ #ifndef SET_FILE_NUMBER -#define SET_FILE_NUMBER() ++num_source_filenames +#define SET_FILE_NUMBER() ++ num_source_filenames #endif /* This is how to output a note the debugger telling it the line number @@ -1382,28 +1179,41 @@ extern void sbss_section (void); #define LABEL_AFTER_LOC(STREAM) #endif -/* Handle certain cpp directives used in header files on sysV. */ -#define SCCS_DIRECTIVE - /* Default to -G 8 */ #ifndef IQ2000_DEFAULT_GVALUE #define IQ2000_DEFAULT_GVALUE 8 #endif -#define SDATA_SECTION_ASM_OP "\t.sdata" /* small data */ - -/* Given a decl node or constant node, choose the section to output it in - and select that section. */ +#define SDATA_SECTION_ASM_OP "\t.sdata" /* Small data. */ -#undef TARGET_ASM_SELECT_SECTION -#define TARGET_ASM_SELECT_SECTION iq2000_select_section /* See iq2000_expand_prologue's use of loadgp for when this should be true. */ #define DONT_ACCESS_GBLS_AFTER_EPILOGUE 0 +/* List of all IQ2000 punctuation characters used by print_operand. */ +extern char iq2000_print_operand_punct[256]; + +/* The target cpu for optimization and scheduling. */ +extern enum processor_type iq2000_tune; + +/* Which instruction set architecture to use. */ +extern int iq2000_isa; + +/* Cached operands, and operator to compare for use in set/branch/trap + on condition codes. */ +extern rtx branch_cmp[2]; + +/* What type of branch to use. */ +extern enum cmp_type branch_type; + +/* Strings to hold which cpu and instruction set architecture to use. */ +extern const char * iq2000_cpu_string; /* For -mcpu=. */ +extern const char * iq2000_arch_string; /* For -march=. */ + + enum iq2000_builtins { -- 2.30.2