From 1508cc4663c41afdcaf9df3499b24f6537afe818 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Wed, 9 Nov 2005 09:34:21 +0000 Subject: [PATCH] Add ms2 support Add ms2 support * config/ms1/ms1.md (UNSPEC_BLOCKAGE, UNSPEC_EI, UNSPEC_DI): New constants. (call,load,store): New insn types. (mem_access, branch_access): Adjust reservation conditions. (define_delay): Adjust condition. (decrement_and_branch_until_zero): Allow for ms2. Set branch type. (*decrement_and_rbanch_until_zero_no_clobber): Allow for ms2. (*movqi_internal,*movsi_internal,*movsf_internal): Use load,store insn type. (call_internal, call_value_internal, return_internal, return_interrupt_internal, eh_return_internal, indirect_jump, tablejump): Set call insn type. (blockage, ei, di): Use appropriate unspec const. * config/ms1/ms1.c (ms1_flag_delayed_branch): New. (ms1_get_attr_type): Adjust to give load & store types. (ms1_final_prescan_insn): Adjust for new insn types. Don't look backwards past a barrier. (ms1_override_options): Accept ms2 arch. Copy and reset delayed branch scheduling. (struct branch_info, struct label_info): New. (ms1_labels): New. (ms1_add_branches, ms1_check_delay_slot, ms1_reorg_hazard): New. (ms1_machine_reorg): New. (TARGET_MACHINE_DEPENDENT_REORG): Override. * config/ms1/crtn.asm: Add nop for ms2 JAL hazard. * config/ms1/ms1.h (processor_type): Add PROCESSOR_MS2. (ASM_SPEC, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Add ms2. (TARGET_MS2): New. From-SVN: r106680 --- gcc/ChangeLog | 33 ++++ gcc/config/ms1/crtn.asm | 2 + gcc/config/ms1/ms1.c | 390 ++++++++++++++++++++++++++++++++++++---- gcc/config/ms1/ms1.h | 18 +- gcc/config/ms1/ms1.md | 55 +++--- 5 files changed, 440 insertions(+), 58 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9836318d76e..32c9206a6835 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,36 @@ +2005-11-09 Nathan Sidwell + + Add ms2 support + * config/ms1/ms1.md (UNSPEC_BLOCKAGE, UNSPEC_EI, UNSPEC_DI): New + constants. + (call,load,store): New insn types. + (mem_access, branch_access): Adjust reservation conditions. + (define_delay): Adjust condition. + (decrement_and_branch_until_zero): Allow for ms2. Set branch + type. + (*decrement_and_rbanch_until_zero_no_clobber): Allow for ms2. + (*movqi_internal,*movsi_internal,*movsf_internal): Use load,store + insn type. + (call_internal, call_value_internal, return_internal, + return_interrupt_internal, eh_return_internal, indirect_jump, + tablejump): Set call insn type. + (blockage, ei, di): Use appropriate unspec const. + * config/ms1/ms1.c (ms1_flag_delayed_branch): New. + (ms1_get_attr_type): Adjust to give load & store types. + (ms1_final_prescan_insn): Adjust for new insn types. Don't look + backwards past a barrier. + (ms1_override_options): Accept ms2 arch. Copy and reset delayed + branch scheduling. + (struct branch_info, struct label_info): New. + (ms1_labels): New. + (ms1_add_branches, ms1_check_delay_slot, ms1_reorg_hazard): New. + (ms1_machine_reorg): New. + (TARGET_MACHINE_DEPENDENT_REORG): Override. + * config/ms1/crtn.asm: Add nop for ms2 JAL hazard. + * config/ms1/ms1.h (processor_type): Add PROCESSOR_MS2. + (ASM_SPEC, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): Add ms2. + (TARGET_MS2): New. + 2005-11-09 Per Bothner Uros Bizjak diff --git a/gcc/config/ms1/crtn.asm b/gcc/config/ms1/crtn.asm index 1fa42ac56a41..5fbe7ece9695 100644 --- a/gcc/config/ms1/crtn.asm +++ b/gcc/config/ms1/crtn.asm @@ -42,6 +42,7 @@ .align 4 ldw r14, sp, #0 addi sp, sp, #4 + nop jal r0, r14 or r0, r0, r0 @@ -50,5 +51,6 @@ ldw r14, sp, #0 addi sp, sp, #4 + nop jal r0, r14 or r0, r0, r0 diff --git a/gcc/config/ms1/ms1.c b/gcc/config/ms1/ms1.c index 25ba78ec40b5..19f02a1c7469 100644 --- a/gcc/config/ms1/ms1.c +++ b/gcc/config/ms1/ms1.c @@ -84,6 +84,8 @@ struct ms1_frame_info zero_frame_info; /* ms1 doesn't have unsigned compares need a library call for this. */ struct rtx_def * ms1_ucmpsi3_libcall; +static int ms1_flag_delayed_branch; + static rtx ms1_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED, @@ -125,13 +127,6 @@ ms1_asm_output_opcode (FILE *f ATTRIBUTE_UNUSED, const char *ptr) return ptr; } -/* Return TRUE if INSN is a memory load. */ -static bool -ms1_memory_load (rtx insn) -{ - return ((GET_CODE (insn) == SET) && (GET_CODE (XEXP (insn,1)) == MEM)); -} - /* Given an insn, return whether it's a memory operation or a branch operation, otherwise return TYPE_ARITH. */ static enum attr_type @@ -139,18 +134,24 @@ ms1_get_attr_type (rtx complete_insn) { rtx insn = PATTERN (complete_insn); - if ((GET_CODE (insn) == SET) - && ((GET_CODE (XEXP (insn, 0)) == MEM) - || (GET_CODE (XEXP (insn, 1)) == MEM))) - return TYPE_MEM; - - else if (((GET_CODE (insn) == SET) && (XEXP (insn, 0) == pc_rtx)) - || (GET_CODE (complete_insn) == JUMP_INSN) - || (GET_CODE (complete_insn) == CALL_INSN)) + if (JUMP_P (complete_insn)) + return TYPE_BRANCH; + if (CALL_P (complete_insn)) return TYPE_BRANCH; - else + if (GET_CODE (insn) != SET) return TYPE_ARITH; + + if (SET_DEST (insn) == pc_rtx) + return TYPE_BRANCH; + + if (GET_CODE (SET_DEST (insn)) == MEM) + return TYPE_STORE; + + if (GET_CODE (SET_SRC (insn)) == MEM) + return TYPE_LOAD; + + return TYPE_ARITH; } /* A helper routine for insn_dependent_p called through note_stores. */ @@ -212,35 +213,48 @@ ms1_final_prescan_insn (rtx insn, int noperands ATTRIBUTE_UNUSED) { rtx prev_i; + enum attr_type prev_attr; ms1_nops_required = 0; ms1_nop_reasons = ""; + /* ms2 constraints are dealt with in reorg. */ + if (ms1_cpu == PROCESSOR_MS2) + return; + /* Only worry about real instructions. */ if (! INSN_P (insn)) return; /* Find the previous real instructions. */ - prev_i = PREV_INSN (insn); - while (prev_i != NULL + for (prev_i = PREV_INSN (insn); + prev_i != NULL && (! INSN_P (prev_i) || GET_CODE (PATTERN (prev_i)) == USE - || GET_CODE (PATTERN (prev_i)) == CLOBBER)) - prev_i = PREV_INSN (prev_i); - + || GET_CODE (PATTERN (prev_i)) == CLOBBER); + prev_i = PREV_INSN (prev_i)) + { + /* If we meet a barrier, there is no flow through here. */ + if (BARRIER_P (prev_i)) + return; + } + /* If there isn't one then there is nothing that we need do. */ if (prev_i == NULL || ! INSN_P (prev_i)) return; + prev_attr = ms1_get_attr_type (prev_i); + /* Delayed branch slots already taken care of by delay branch scheduling. */ - if (ms1_get_attr_type (prev_i) == TYPE_BRANCH) + if (prev_attr == TYPE_BRANCH) return; switch (ms1_get_attr_type (insn)) { - case TYPE_MEM: + case TYPE_LOAD: + case TYPE_STORE: /* Avoid consecutive memory operation. */ - if (ms1_get_attr_type (prev_i) == TYPE_MEM + if ((prev_attr == TYPE_LOAD || prev_attr == TYPE_STORE) && ms1_cpu == PROCESSOR_MS1_64_001) { ms1_nops_required = 1; @@ -252,7 +266,7 @@ ms1_final_prescan_insn (rtx insn, case TYPE_COMPLEX: /* One cycle of delay is required between load and the dependent arithmetic instruction. */ - if (ms1_memory_load (PATTERN (prev_i)) + if (prev_attr == TYPE_LOAD && insn_true_dependent_p (prev_i, insn)) { ms1_nops_required = 1; @@ -263,7 +277,7 @@ ms1_final_prescan_insn (rtx insn, case TYPE_BRANCH: if (insn_dependent_p (prev_i, insn)) { - if (ms1_get_attr_type (prev_i) == TYPE_ARITH + if (prev_attr == TYPE_ARITH && ms1_cpu == PROCESSOR_MS1_64_001) { /* One cycle of delay between arith @@ -271,7 +285,7 @@ ms1_final_prescan_insn (rtx insn, ms1_nops_required = 1; ms1_nop_reasons = "arith->branch dependency delay"; } - else if (ms1_memory_load (PATTERN (prev_i))) + else if (prev_attr == TYPE_LOAD) { /* Two cycles of delay are required between load and dependent branch. */ @@ -790,10 +804,9 @@ ms1_override_options (void) else if (!strcasecmp (ms1_cpu_string, "MS1-16-002")) ms1_cpu = PROCESSOR_MS1_16_002; else if (!strcasecmp (ms1_cpu_string, "MS1-16-003")) - { - ms1_cpu = PROCESSOR_MS1_16_003; - target_flags |= MASK_MUL; - } + ms1_cpu = PROCESSOR_MS1_16_003; + else if (!strcasecmp (ms1_cpu_string, "MS2")) + ms1_cpu = PROCESSOR_MS2; else error ("bad value (%s) for -march= switch", ms1_cpu_string); } @@ -806,6 +819,10 @@ ms1_override_options (void) flag_gcse = 0; } + /* We do delayed branch filling in machine dependent reorg */ + ms1_flag_delayed_branch = flag_delayed_branch; + flag_delayed_branch = 0; + init_machine_status = ms1_init_machine_status; } @@ -1631,6 +1648,315 @@ ms1_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type) || TREE_ADDRESSABLE (type)))); } + +/* Structures to hold branch information during reorg. */ +typedef struct branch_info +{ + rtx insn; /* The branch insn. */ + + struct branch_info *next; +} branch_info; + +typedef struct label_info +{ + rtx label; /* The label. */ + branch_info *branches; /* branches to this label. */ + struct label_info *next; +} label_info; + +/* Chain of labels found in current function, used during reorg. */ +static label_info *ms1_labels; + +/* If *X is a label, add INSN to the list of branches for that + label. */ + +static int +ms1_add_branches (rtx *x, void *insn) +{ + if (GET_CODE (*x) == LABEL_REF) + { + branch_info *branch = xmalloc (sizeof (*branch)); + rtx label = XEXP (*x, 0); + label_info *info; + + for (info = ms1_labels; info; info = info->next) + if (info->label == label) + break; + + if (!info) + { + info = xmalloc (sizeof (*info)); + info->next = ms1_labels; + ms1_labels = info; + + info->label = label; + info->branches = NULL; + } + + branch->next = info->branches; + info->branches = branch; + branch->insn = insn; + } + return 0; +} + +/* If BRANCH has a filled delay slot, check if INSN is dependent upon + it. If so, undo the delay slot fill. Returns the next insn, if + we patch out the branch. Returns the branch insn, if we cannot + patch out the branch (due to anti-dependency in the delay slot). + In that case, the caller must insert nops at the branch target. */ + +static rtx +ms1_check_delay_slot (rtx branch, rtx insn) +{ + rtx slot; + rtx tmp; + rtx p; + rtx jmp; + + gcc_assert (GET_CODE (PATTERN (branch)) == SEQUENCE); + if (INSN_DELETED_P (branch)) + return NULL_RTX; + slot = XVECEXP (PATTERN (branch), 0, 1); + + tmp = PATTERN (insn); + note_stores (PATTERN (slot), insn_dependent_p_1, &tmp); + if (tmp) + /* Not dependent. */ + return NULL_RTX; + + /* Undo the delay slot. */ + jmp = XVECEXP (PATTERN (branch), 0, 0); + + tmp = PATTERN (jmp); + note_stores (PATTERN (slot), insn_dependent_p_1, &tmp); + if (!tmp) + /* Anti dependent. */ + return branch; + + p = PREV_INSN (branch); + NEXT_INSN (p) = slot; + PREV_INSN (slot) = p; + NEXT_INSN (slot) = jmp; + PREV_INSN (jmp) = slot; + NEXT_INSN (jmp) = branch; + PREV_INSN (branch) = jmp; + XVECEXP (PATTERN (branch), 0, 0) = NULL_RTX; + XVECEXP (PATTERN (branch), 0, 1) = NULL_RTX; + delete_insn (branch); + return jmp; +} + +/* Insert nops to satisfy pipeline constraints. We only deal with ms2 + constraints here. Earlier CPUs are dealt with by inserting nops with + final_prescan (but that can lead to inferior code, and is + impractical with ms2's JAL hazard). + + ms2 dynamic constraints + 1) a load and a following use must be separated by one insn + 2) an insn and a following dependent call must be separated by two insns + + only arith insns are placed in delay slots so #1 cannot happen with + a load in a delay slot. #2 can happen with an arith insn in the + delay slot. */ + +static void +ms1_reorg_hazard (void) +{ + rtx insn, next; + + /* Find all the branches */ + for (insn = get_insns (); + insn; + insn = NEXT_INSN (insn)) + { + rtx jmp; + + if (!INSN_P (insn)) + continue; + + jmp = PATTERN (insn); + + if (GET_CODE (jmp) != SEQUENCE) + /* If it's not got a filled delay slot, then it can't + conflict. */ + continue; + + jmp = XVECEXP (jmp, 0, 0); + + if (recog_memoized (jmp) == CODE_FOR_tablejump) + for (jmp = XEXP (XEXP (XVECEXP (PATTERN (jmp), 0, 1), 0), 0); + !JUMP_TABLE_DATA_P (jmp); + jmp = NEXT_INSN (jmp)) + continue; + + for_each_rtx (&PATTERN (jmp), ms1_add_branches, insn); + } + + /* Now scan for dependencies. */ + for (insn = get_insns (); + insn && !INSN_P (insn); + insn = NEXT_INSN (insn)) + continue; + + for (; + insn; + insn = next) + { + rtx jmp, tmp; + enum attr_type attr; + + gcc_assert (INSN_P (insn) && !INSN_DELETED_P (insn)); + for (next = NEXT_INSN (insn); + next && !INSN_P (next); + next = NEXT_INSN (next)) + continue; + + jmp = insn; + if (GET_CODE (PATTERN (insn)) == SEQUENCE) + jmp = XVECEXP (PATTERN (insn), 0, 0); + + attr = recog_memoized (jmp) >= 0 ? get_attr_type (jmp) : TYPE_UNKNOWN; + + if (next && attr == TYPE_LOAD) + { + /* A load. See if NEXT is dependent, and if so insert a + nop. */ + + tmp = PATTERN (next); + if (GET_CODE (tmp) == SEQUENCE) + tmp = PATTERN (XVECEXP (tmp, 0, 0)); + note_stores (PATTERN (insn), insn_dependent_p_1, &tmp); + if (!tmp) + emit_insn_after (gen_nop (), insn); + } + + if (attr == TYPE_CALL) + { + /* A call. Make sure we're not dependent on either of the + previous two dynamic instructions. */ + int nops = 0; + int count; + rtx prev = insn; + rtx rescan = NULL_RTX; + + for (count = 2; count && !nops;) + { + int type; + + prev = PREV_INSN (prev); + if (!prev) + { + /* If we reach the start of the function, we must + presume the caller set the address in the delay + slot of the call instruction. */ + nops = count; + break; + } + + if (BARRIER_P (prev)) + break; + if (LABEL_P (prev)) + { + /* Look at branches to this label. */ + label_info *label; + branch_info *branch; + + for (label = ms1_labels; + label; + label = label->next) + if (label->label == prev) + { + for (branch = label->branches; + branch; + branch = branch->next) + { + tmp = ms1_check_delay_slot (branch->insn, jmp); + + if (tmp == branch->insn) + { + nops = count; + break; + } + + if (tmp && branch->insn == next) + rescan = tmp; + } + break; + } + continue; + } + if (!INSN_P (prev)) + continue; + + if (GET_CODE (PATTERN (prev)) == SEQUENCE) + { + /* Look at the delay slot. */ + tmp = ms1_check_delay_slot (prev, jmp); + if (tmp == prev) + nops = count; + break; + } + + type = (INSN_CODE (prev) >= 0 ? get_attr_type (prev) + : TYPE_COMPLEX); + if (type == TYPE_CALL || type == TYPE_BRANCH) + break; + + if (type == TYPE_LOAD + || type == TYPE_ARITH + || type == TYPE_COMPLEX) + { + tmp = PATTERN (jmp); + note_stores (PATTERN (prev), insn_dependent_p_1, &tmp); + if (!tmp) + { + nops = count; + break; + } + } + count -= INSN_CODE (prev) >= 0; + } + + if (rescan) + for (next = NEXT_INSN (rescan); + next && !INSN_P (next); + next = NEXT_INSN (next)) + continue; + while (nops--) + emit_insn_before (gen_nop (), insn); + } + } + + /* Free the data structures. */ + while (ms1_labels) + { + label_info *label = ms1_labels; + branch_info *branch, *next; + + ms1_labels = label->next; + for (branch = label->branches; branch; branch = next) + { + next = branch->next; + free (branch); + } + free (label); + } +} + +/* Fixup the looping instructions, do delayed branch scheduling, fixup + scheduling hazards. */ + +static void +ms1_machine_reorg (void) +{ + if (ms1_flag_delayed_branch) + dbr_schedule (get_insns (), dump_file); + + if (ms1_cpu == PROCESSOR_MS2) + ms1_reorg_hazard (); +} + /* Initialize the GCC target structure. */ const struct attribute_spec ms1_attribute_table[]; @@ -1646,6 +1972,8 @@ const struct attribute_spec ms1_attribute_table[]; #define TARGET_MUST_PASS_IN_STACK ms1_pass_in_stack #undef TARGET_ARG_PARTIAL_BYTES #define TARGET_ARG_PARTIAL_BYTES ms1_arg_partial_bytes +#undef TARGET_MACHINE_DEPENDENT_REORG +#define TARGET_MACHINE_DEPENDENT_REORG ms1_machine_reorg struct gcc_target targetm = TARGET_INITIALIZER; diff --git a/gcc/config/ms1/ms1.h b/gcc/config/ms1/ms1.h index cf24671a5965..aa01831ade4f 100644 --- a/gcc/config/ms1/ms1.h +++ b/gcc/config/ms1/ms1.h @@ -25,7 +25,8 @@ enum processor_type { PROCESSOR_MS1_64_001, PROCESSOR_MS1_16_002, - PROCESSOR_MS1_16_003 + PROCESSOR_MS1_16_003, + PROCESSOR_MS2 }; enum epilogue_type @@ -40,7 +41,7 @@ extern enum processor_type ms1_cpu; /* A C string constant that tells the GCC driver program options to pass to the assembler. */ #undef ASM_SPEC -#define ASM_SPEC "%{march=ms1-16-002: -march=ms1-16-002} %{march=ms1-16-003: -march=ms1-16-003} %{!march=*: -march=ms1-16-002}" +#define ASM_SPEC "%{march=ms1-16-002: -march=ms1-16-002} %{march=ms1-16-003: -march=ms1-16-003} %{march=ms2: -march=ms2} %{!march=*: -march=ms1-16-002}" /* A string to pass to at the end of the command given to the linker. */ #undef LIB_SPEC @@ -51,7 +52,9 @@ march=MS1-64-001:-T 64-001.ld%s; \ march=ms1-16-002:-T 16-002.ld%s; \ march=MS1-16-002:-T 16-002.ld%s; \ march=ms1-16-003:-T 16-003.ld%s; \ -march=MS1-16-003:-T 16-003.ld%s}" +march=MS1-16-003:-T 16-003.ld%s; \ +march=ms2:-T ms2.ld%s; \ +march=MS2:-T ms2.ld%s}" /* A string to pass at the very beginning of the command given to the linker. */ @@ -62,7 +65,9 @@ march=MS1-64-001:%{!mno-crt0:crt0-64-001.o%s} startup-64-001.o%s; \ march=ms1-16-002:%{!mno-crt0:crt0-16-002.o%s} startup-16-002.o%s; \ march=MS1-16-002:%{!mno-crt0:crt0-16-002.o%s} startup-16-002.o%s; \ march=ms1-16-003:%{!mno-crt0:crt0-16-003.o%s} startup-16-003.o%s; \ -march=MS1-16-003:%{!mno-crt0:crt0-16-003.o%s} startup-16-003.o%s} \ +march=MS1-16-003:%{!mno-crt0:crt0-16-003.o%s} startup-16-003.o%s; \ +march=ms2:%{!mno-crt0:crt0-ms2.o%s} startup-ms2.o%s; \ +march=MS2:%{!mno-crt0:crt0-ms2.o%s} startup-ms2.o%s} \ crti.o%s crtbegin.o%s" /* A string to pass at the end of the command given to the linker. */ @@ -73,7 +78,9 @@ march=MS1-64-001:exit-64-001.o%s; \ march=ms1-16-002:exit-16-002.o%s; \ march=MS1-16-002:exit-16-002.o%s; \ march=ms1-16-003:exit-16-003.o%s; \ -march=MS1-16-003:exit-16-003.o%s} \ +march=MS1-16-003:exit-16-003.o%s; \ +march=ms2:exit-ms2.o%s; \ +march=MS2:exit-ms2.o%s} \ crtend.o%s crtn.o%s" /* Run-time target specifications. */ @@ -89,6 +96,7 @@ march=MS1-16-003:exit-16-003.o%s} \ #define TARGET_MS1_64_001 (ms1_cpu == PROCESSOR_MS1_64_001) #define TARGET_MS1_16_002 (ms1_cpu == PROCESSOR_MS1_16_002) #define TARGET_MS1_16_003 (ms1_cpu == PROCESSOR_MS1_16_003) +#define TARGET_MS2 (ms1_cpu == PROCESSOR_MS2) #define TARGET_VERSION fprintf (stderr, " (ms1)"); diff --git a/gcc/config/ms1/ms1.md b/gcc/config/ms1/ms1.md index b96dfc07d600..1d5ff5266f36 100644 --- a/gcc/config/ms1/ms1.md +++ b/gcc/config/ms1/ms1.md @@ -19,8 +19,16 @@ ;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA ;; 02110-1301, USA. +;; UNSPECs +(define_constants + [ + (UNSPEC_BLOCKAGE 0) + (UNSPEC_EI 1) + (UNSPEC_DI 2) + ]) + ;; Attributes -(define_attr "type" "branch,mem,io,arith,complex,unknown" +(define_attr "type" "branch,call,load,store,io,arith,complex,unknown" (const_string "unknown") ) ;; If the attribute takes numeric values, no `enum' type will be defined and @@ -36,7 +44,7 @@ (define_cpu_unit "branch_unit" "other") (define_insn_reservation "mem_access" 2 - (eq_attr "type" "mem") + (ior (eq_attr "type" "load") (eq_attr "type" "store")) "decode_unit+memory_unit*2") (define_insn_reservation "io_access" 2 @@ -44,7 +52,8 @@ "decode_unit+memory_unit*2") (define_insn_reservation "branch_access" 2 - (eq_attr "type" "branch") + (ior (eq_attr "type" "branch") + (eq_attr "type" "call")) "decode_unit+branch_unit*2") (define_insn_reservation "arith_access" 1 @@ -64,7 +73,8 @@ ;; the destination of the branch. Thus, only type that will be acceptable ;; (safe) is the arith type. -(define_delay (eq_attr "type" "branch") +(define_delay (ior (eq_attr "type" "branch") + (eq_attr "type" "call")) [(eq_attr "type" "arith") (nil) (nil)]) @@ -79,7 +89,7 @@ (plus:SI (match_dup 0) (const_int -1))) (clobber (match_scratch:SI 2 "=X,r"))] - "TARGET_MS1_16_003" + "TARGET_MS1_16_003 || TARGET_MS2" "@ dbnz\t%0, %l1%# #" @@ -98,9 +108,10 @@ (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] - "TARGET_MS1_16_003" + "TARGET_MS1_16_003 || TARGET_MS2" "dbnz\t%0, %l1%#" - [(set_attr "length" "4")] + [(set_attr "length" "4") + (set_attr "type" "branch")] ) ;; Split the above to handle the case where operand 0 is in memory @@ -116,7 +127,7 @@ (plus:SI (match_dup 0) (const_int -1))) (clobber (match_scratch:SI 2 ""))] - "TARGET_MS1_16_003" + "TARGET_MS1_16_003 || TARGET_MS2" [(set (match_dup 2) (match_dup 0)) (set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) (set (match_dup 0) (match_dup 2)) @@ -143,7 +154,7 @@ (label_ref (match_operand 2 "" "")) (pc))) ] - "TARGET_MS1_16_003" + "TARGET_MS1_16_003 || TARGET_MS2" [(parallel [(set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) @@ -308,7 +319,7 @@ stb %1, %0 addi %0, r0, %1" [(set_attr "length" "4,4,4,4") - (set_attr "type" "arith,mem,mem,arith")]) + (set_attr "type" "arith,load,store,arith")]) (define_insn "*movqi_internal_nobyte" [(set (match_operand:QI 0 "register_operand" "=r,r") @@ -566,7 +577,7 @@ nori %0, r0, %N1 ldui %0, %H1\;addui %0, %0, %L1" [(set_attr "length" "4,4,4,4,4,4,4,8") - (set_attr "type" "arith,mem,mem,arith,arith,arith,arith,complex")] + (set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")] ) ;; Floating Point Moves @@ -641,7 +652,7 @@ ldw %0, %1 stw %1, %0" [(set_attr "length" "4,4,4") - (set_attr "type" "arith,mem,mem")] + (set_attr "type" "arith,load,store")] ) (define_expand "movdf" @@ -1269,7 +1280,7 @@ "" "jal r14, %0%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) (define_expand "call_value" [(parallel [(set (match_operand 0 "register_operand" "") @@ -1292,7 +1303,7 @@ "" "jal r14, %1%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) ;; Subroutine return (define_insn "return_internal" @@ -1302,7 +1313,7 @@ "" "jal r0, r14%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) ;; Interrupt return (define_insn "return_interrupt_internal" @@ -1312,7 +1323,7 @@ "" "reti r15%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) ;; Subroutine return (define_insn "eh_return_internal" @@ -1324,7 +1335,7 @@ "" "jal r0, r11%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) ;; Normal unconditional jump @@ -1341,7 +1352,7 @@ "" "jal r0,%0%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) (define_insn "tablejump" [(set (pc) (match_operand:SI 0 "register_operand" "r")) @@ -1349,7 +1360,7 @@ "" "jal r0, %0%#" [(set_attr "length" "4") - (set_attr "type" "branch")]) + (set_attr "type" "call")]) (define_expand "prologue" @@ -1412,7 +1423,7 @@ ;; Pseudo instruction that prevents the scheduler from moving code above this ;; point. (define_insn "blockage" - [(unspec_volatile [(const_int 0)] 0)] + [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)] "" "" [(set_attr "length" "0")]) @@ -1442,14 +1453,14 @@ ;; Enable interrupts template (define_insn "ei" - [(unspec_volatile [(const_int 0)] 1)] + [(unspec_volatile [(const_int 0)] UNSPEC_EI)] "" "ei" [(set_attr "length" "4")]) ;; Enable interrupts template (define_insn "di" - [(unspec_volatile [(const_int 0)] 2)] + [(unspec_volatile [(const_int 0)] UNSPEC_DI)] "" "di" [(set_attr "length" "4")])