diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-20 08:41:32 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-11-20 08:41:32 +0000 |
commit | 03248b193e6bac947221d44cc4dff913183cb5ae (patch) | |
tree | e2c9a37069b356f4cb760951f499abdac631e293 /gcc/config/mips | |
parent | d7cbb3ef81425f9adec25287428049a99320c479 (diff) | |
download | gcc-03248b193e6bac947221d44cc4dff913183cb5ae.tar.gz |
2008-11-20 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk r142033
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@142036 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mips')
-rw-r--r-- | gcc/config/mips/loongson.md | 20 | ||||
-rw-r--r-- | gcc/config/mips/loongson2ef.md | 9 | ||||
-rw-r--r-- | gcc/config/mips/mips-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 161 | ||||
-rw-r--r-- | gcc/config/mips/mips.h | 48 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 153 | ||||
-rw-r--r-- | gcc/config/mips/mips.opt | 4 | ||||
-rw-r--r-- | gcc/config/mips/sde.h | 2 | ||||
-rw-r--r-- | gcc/config/mips/sync.md | 86 | ||||
-rw-r--r-- | gcc/config/mips/t-isa3264 | 10 | ||||
-rw-r--r-- | gcc/config/mips/t-sde | 12 | ||||
-rw-r--r-- | gcc/config/mips/t-sdemtk | 4 |
12 files changed, 323 insertions, 187 deletions
diff --git a/gcc/config/mips/loongson.md b/gcc/config/mips/loongson.md index 98b5113fbb5..8cdb5f466e9 100644 --- a/gcc/config/mips/loongson.md +++ b/gcc/config/mips/loongson.md @@ -473,3 +473,23 @@ "TARGET_HARD_FLOAT && TARGET_LOONGSON_VECTORS" "punpckl<V_stretch_half_suffix>\t%0,%1,%2" [(set_attr "type" "fdiv")]) + +;; Integer division and modulus. + +(define_insn "<u>div<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_div:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF" + { return mips_output_division ("<d>div<u>.g\t%0,%1,%2", operands); } + [(set_attr "type" "idiv3") + (set_attr "mode" "<MODE>")]) + +(define_insn "<u>mod<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (any_mod:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF" + { return mips_output_division ("<d>mod<u>.g\t%0,%1,%2", operands); } + [(set_attr "type" "idiv3") + (set_attr "mode" "<MODE>")]) diff --git a/gcc/config/mips/loongson2ef.md b/gcc/config/mips/loongson2ef.md index 8d294822102..df3de33f809 100644 --- a/gcc/config/mips/loongson2ef.md +++ b/gcc/config/mips/loongson2ef.md @@ -160,14 +160,14 @@ ;; Reservation for integer multiplication instructions. (define_insn_reservation "ls2_imult" 5 (and (eq_attr "cpu" "loongson_2e,loongson_2f") - (eq_attr "type" "imul,imul3")) + (eq_attr "type" "imul,imul3nc")) "ls2_alu2,ls2_alu2_core") ;; Reservation for integer division / remainder instructions. ;; These instructions use the SRT algorithm and hence take 2-38 cycles. (define_insn_reservation "ls2_idiv" 20 (and (eq_attr "cpu" "loongson_2e,loongson_2f") - (eq_attr "type" "idiv")) + (eq_attr "type" "idiv,idiv3")) "ls2_alu2,ls2_alu2_core*18") ;; Reservation for memory load instructions. @@ -176,6 +176,11 @@ (eq_attr "type" "load,fpload,mfc,mtc")) "ls2_mem") +(define_insn_reservation "ls2_prefetch" 0 + (and (eq_attr "cpu" "loongson_2e,loongson_2f") + (eq_attr "type" "prefetch,prefetchx")) + "ls2_mem") + ;; Reservation for memory store instructions. ;; With stores we assume they don't alias with dependent loads. ;; Therefore we set the latency to zero. diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index 9403945a4f3..3fa67c982ea 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -300,6 +300,7 @@ extern const char *mips_output_load_label (void); extern const char *mips_output_conditional_branch (rtx, rtx *, const char *, const char *); extern const char *mips_output_order_conditional_branch (rtx, rtx *, bool); +extern const char *mips_output_sync_loop (const char *); extern const char *mips_output_division (const char *, rtx *); extern unsigned int mips_hard_regno_nregs (int, enum machine_mode); extern bool mips_linked_madd_p (rtx, rtx); diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index fa78c8bf270..c868b10a107 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -292,7 +292,8 @@ struct machine_function GTY(()) { /* The current frame information, calculated by mips_compute_frame_info. */ struct mips_frame_info frame; - /* The register to use as the function's global pointer. */ + /* The register to use as the function's global pointer, or INVALID_REGNUM + if the function doesn't need one. */ unsigned int global_pointer; /* True if mips_adjust_insn_length should ignore an instruction's @@ -5331,7 +5332,7 @@ mips_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, { /* [1] Emit code for: off &= -rsize. */ t = build2 (BIT_AND_EXPR, TREE_TYPE (off), off, - build_int_cst (NULL_TREE, -rsize)); + build_int_cst (TREE_TYPE (off), -rsize)); gimplify_assign (off, t, pre_p); } osize = rsize; @@ -6909,6 +6910,7 @@ mips_print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context, '#' Print a nop if in a ".set noreorder" block. '/' Like '#', but do nothing within a delayed-branch sequence. '?' Print "l" if mips_branch_likely is true + '~' Print a nop if mips_branch_likely is true '.' Print the name of the register with a hard-wired zero (zero or $0). '@' Print the name of the assembler temporary register (at or $1). '^' Print the name of the pic call-through register (t9 or $25). @@ -6983,6 +6985,11 @@ mips_print_operand_punctuation (FILE *file, int ch) putc ('l', file); break; + case '~': + if (mips_branch_likely) + fputs ("\n\tnop", file); + break; + case '.': fputs (reg_names[GP_REG_FIRST + 0], file); break; @@ -7026,7 +7033,7 @@ mips_init_print_operand_punct (void) { const char *p; - for (p = "()[]<>*#/?.@^+$|-"; *p; p++) + for (p = "()[]<>*#/?~.@^+$|-"; *p; p++) mips_print_operand_punct[(unsigned char) *p] = true; } @@ -8352,8 +8359,8 @@ mips16_cfun_returns_in_fpr_p (void) } /* Return the register that should be used as the global pointer - within this function. Return 0 if the function doesn't need - a global pointer. */ + within this function. Return INVALID_REGNUM if the function + doesn't need a global pointer. */ static unsigned int mips_global_pointer (void) @@ -8388,7 +8395,7 @@ mips_global_pointer (void) -call_nonpic code, no new uses will be introduced during or after reload. */ if (TARGET_ABICALLS_PIC0) - return 0; + return INVALID_REGNUM; /* We need to handle the following implicit gp references: @@ -8410,7 +8417,7 @@ mips_global_pointer (void) external libgcc routine. */ if (!crtl->uses_const_pool && !mips16_cfun_returns_in_fpr_p ()) - return 0; + return INVALID_REGNUM; } /* We need a global pointer, but perhaps we can use a call-clobbered @@ -8426,48 +8433,85 @@ mips_global_pointer (void) return GLOBAL_POINTER_REGNUM; } -/* Return true if the current function must save register REGNO. */ +/* Return true if the current function should treat register REGNO + as call-saved. */ static bool -mips_save_reg_p (unsigned int regno) +mips_cfun_call_saved_reg_p (unsigned int regno) +{ + /* call_insns preserve $28 unless they explicitly say otherwise, + so call_really_used_regs[] treats $28 as call-saved. However, + we want the ABI property rather than the default call_insn + property here. */ + return (regno == GLOBAL_POINTER_REGNUM + ? TARGET_CALL_SAVED_GP + : !call_really_used_regs[regno]); +} + +/* Return true if the function body might clobber register REGNO. + We know that REGNO is call-saved. */ + +static bool +mips_cfun_might_clobber_call_saved_reg_p (unsigned int regno) { - /* We need to save $gp if TARGET_CALL_SAVED_GP and if we have not - chosen a call-clobbered substitute. */ - if (TARGET_CALL_SAVED_GP - && regno == GLOBAL_POINTER_REGNUM - && cfun->machine->global_pointer == regno) + /* Some functions should be treated as clobbering all call-saved + registers. */ + if (crtl->saves_all_registers) return true; - /* Check call-saved registers. */ - if ((crtl->saves_all_registers || df_regs_ever_live_p (regno)) - && !call_really_used_regs[regno]) + /* DF handles cases where a register is explicitly referenced in + the rtl. Incoming values are passed in call-clobbered registers, + so we can assume that any live call-saved register is set within + the function. */ + if (df_regs_ever_live_p (regno)) return true; - /* Save both registers in an FPR pair if either one is used. This is - needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd - register to be used without the even register. */ - if (FP_REG_P (regno) - && MAX_FPRS_PER_FMT == 2 - && df_regs_ever_live_p (regno + 1) - && !call_really_used_regs[regno + 1]) + /* Check for registers that are clobbered by FUNCTION_PROFILER. + These clobbers are not explicit in the rtl. */ + if (crtl->profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno)) + return true; + + /* If we're using a call-saved global pointer, the function's + prologue will need to set it up. */ + if (cfun->machine->global_pointer == regno) return true; - /* We need to save the old frame pointer before setting up a new one. */ + /* The function's prologue will need to set the frame pointer if + frame_pointer_needed. */ if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed) return true; - /* Check for registers that must be saved for FUNCTION_PROFILER. */ - if (crtl->profile && MIPS_SAVE_REG_FOR_PROFILING_P (regno)) + /* If a MIPS16 function returns a value in FPRs, its epilogue + will need to call an external libgcc routine. This yet-to-be + generated call_insn will clobber $31. */ + if (regno == GP_REG_FIRST + 31 && mips16_cfun_returns_in_fpr_p ()) return true; - /* We need to save the incoming return address if it is ever clobbered - within the function, if __builtin_eh_return is being used to set a - different return address, or if a stub is being used to return a - value in FPRs. */ - if (regno == GP_REG_FIRST + 31 - && (df_regs_ever_live_p (regno) - || crtl->calls_eh_return - || mips16_cfun_returns_in_fpr_p ())) + return false; +} + +/* Return true if the current function must save register REGNO. */ + +static bool +mips_save_reg_p (unsigned int regno) +{ + if (mips_cfun_call_saved_reg_p (regno)) + { + if (mips_cfun_might_clobber_call_saved_reg_p (regno)) + return true; + + /* Save both registers in an FPR pair if either one is used. This is + needed for the case when MIN_FPRS_PER_FMT == 1, which allows the odd + register to be used without the even register. */ + if (FP_REG_P (regno) + && MAX_FPRS_PER_FMT == 2 + && mips_cfun_might_clobber_call_saved_reg_p (regno + 1)) + return true; + } + + /* We need to save the incoming return address if __builtin_eh_return + is being used to set a different return address. */ + if (regno == GP_REG_FIRST + 31 && crtl->calls_eh_return) return true; return false; @@ -8653,7 +8697,7 @@ mips_compute_frame_info (void) enum mips_loadgp_style mips_current_loadgp_style (void) { - if (!TARGET_USE_GOT || cfun->machine->global_pointer == 0) + if (!TARGET_USE_GOT || cfun->machine->global_pointer == INVALID_REGNUM) return LOADGP_NONE; if (TARGET_RTP_PIC) @@ -8803,7 +8847,7 @@ mips_restore_gp (rtx temp) { gcc_assert (TARGET_ABICALLS && TARGET_OLDABI); - if (cfun->machine->global_pointer == 0) + if (cfun->machine->global_pointer == INVALID_REGNUM) return; if (TARGET_MIPS16) @@ -8880,7 +8924,7 @@ static void mips_output_cplocal (void) { if (!TARGET_EXPLICIT_RELOCS - && cfun->machine->global_pointer > 0 + && cfun->machine->global_pointer != INVALID_REGNUM && cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM) output_asm_insn (".cplocal %+", 0); } @@ -9116,7 +9160,7 @@ mips_expand_prologue (void) unsigned int nargs; rtx insn; - if (cfun->machine->global_pointer > 0) + if (cfun->machine->global_pointer != INVALID_REGNUM) SET_REGNO (pic_offset_table_rtx, cfun->machine->global_pointer); frame = &cfun->machine->frame; @@ -9234,7 +9278,7 @@ mips_expand_prologue (void) /* Initialize the $gp save slot. */ if (frame->cprestore_size > 0 - && cfun->machine->global_pointer != 0) + && cfun->machine->global_pointer != INVALID_REGNUM) { if (TARGET_MIPS16) mips_emit_move (mips_cprestore_slot (MIPS_PROLOGUE_TEMP (Pmode)), @@ -9842,8 +9886,12 @@ mips_ira_cover_classes (void) }; /* Don't allow the register allocators to use LO and HI in MIPS16 mode, - which has no MTLO or MTHI instructions. */ - return TARGET_MIPS16 ? no_acc_classes : acc_classes; + which has no MTLO or MTHI instructions. Also, using GR_AND_ACC_REGS + as a cover class only works well when we keep per-register costs. + Using it when not optimizing can cause us to think accumulators + have the same cost as GPRs in cases where GPRs are actually much + cheaper. */ + return TARGET_MIPS16 || !optimize ? no_acc_classes : acc_classes; } /* Return the register class required for a secondary register when @@ -10250,6 +10298,17 @@ mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p) return mips_output_conditional_branch (insn, operands, branch[1], branch[0]); } +/* Return the assembly code for __sync_*() loop LOOP. The loop should support + both normal and likely branches, using %? and %~ where appropriate. */ + +const char * +mips_output_sync_loop (const char *loop) +{ + /* Use branch-likely instructions to work around the LL/SC R10000 errata. */ + mips_branch_likely = TARGET_FIX_R10000; + return loop; +} + /* Return the assembly code for DIV or DDIV instruction DIVISION, which has the operands given by OPERANDS. Add in a divide-by-zero check if needed. @@ -13971,6 +14030,24 @@ mips_override_options (void) && mips_matching_cpu_name_p (mips_arch_info->name, "r4400")) target_flags |= MASK_FIX_R4400; + /* Default to working around R10000 errata only if the processor + was selected explicitly. */ + if ((target_flags_explicit & MASK_FIX_R10000) == 0 + && mips_matching_cpu_name_p (mips_arch_info->name, "r10000")) + target_flags |= MASK_FIX_R10000; + + /* Make sure that branch-likely instructions available when using + -mfix-r10000. The instructions are not available if either: + + 1. -mno-branch-likely was passed. + 2. The selected ISA does not support branch-likely and + the command line does not include -mbranch-likely. */ + if (TARGET_FIX_R10000 + && ((target_flags_explicit & MASK_BRANCHLIKELY) == 0 + ? !ISA_HAS_BRANCHLIKELY + : !TARGET_BRANCHLIKELY)) + sorry ("%qs requires branch-likely instructions", "-mfix-r10000"); + /* Save base state of options. */ mips_base_target_flags = target_flags; mips_base_delayed_branch = flag_delayed_branch; diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index bf2e0d0fae7..562c0533379 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -699,7 +699,8 @@ enum mips_code_readable_setting { %{march=mips1|march=r2000|march=r3000|march=r3900:-mips1} \ %{march=mips2|march=r6000:-mips2} \ %{march=mips3|march=r4*|march=vr4*|march=orion|march=loongson2*:-mips3} \ - %{march=mips4|march=r8000|march=vr5*|march=rm7000|march=rm9000:-mips4} \ + %{march=mips4|march=r8000|march=vr5*|march=rm7000|march=rm9000 \ + |march=r10000|march=r12000|march=r14000|march=r16000:-mips4} \ %{march=mips32|march=4kc|march=4km|march=4kp|march=4ksc:-mips32} \ %{march=mips32r2|march=m4k|march=4ke*|march=4ksd|march=24k* \ |march=34k*|march=74k*: -mips32r2} \ @@ -919,6 +920,7 @@ enum mips_code_readable_setting { /* ISA has data prefetch instructions. This controls use of 'pref'. */ #define ISA_HAS_PREFETCH ((ISA_MIPS4 \ + || TARGET_LOONGSON_2EF \ || ISA_MIPS32 \ || ISA_MIPS32R2 \ || ISA_MIPS64 \ @@ -1923,8 +1925,16 @@ enum reg_class call-saved ones. (IRA expects this.) */ #define REG_ALLOC_ORDER \ -{ /* Call-clobbered GPRs. */ \ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ +{ /* Accumulator registers. When GPRs and accumulators have equal \ + cost, we generally prefer to use accumulators. For example, \ + a division of multiplication result is better allocated to LO, \ + so that we put the MFLO at the point of use instead of at the \ + point of definition. It's also needed if we're to take advantage \ + of the extra accumulators available with -mdspr2. In some cases, \ + it can also help to reduce register pressure. */ \ + 64, 65,176,177,178,179,180,181, \ + /* Call-clobbered GPRs. */ \ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ 24, 25, 31, \ /* The global pointer. This is call-clobbered for o32 and o64 \ abicalls, call-saved for n32 and n64 abicalls, and a program \ @@ -1934,7 +1944,7 @@ enum reg_class /* Call-saved GPRs. */ \ 16, 17, 18, 19, 20, 21, 22, 23, 30, \ /* GPRs that can never be exposed to the register allocator. */ \ - 0, 26, 27, 29, \ + 0, 26, 27, 29, \ /* Call-clobbered FPRs. */ \ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ 48, 49, 50, 51, \ @@ -1947,14 +1957,14 @@ enum reg_class 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, \ /* None of the remaining classes have defined call-saved \ registers. */ \ - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \ + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, \ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \ 96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111, \ 112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, \ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, \ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, \ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, \ - 176,177,178,179,180,181,182,183,184,185,186,187 \ + 182,183,184,185,186,187 \ } /* ORDER_REGS_FOR_LOCAL_ALLOC is a macro which permits reg_alloc_order @@ -3089,7 +3099,7 @@ while (0) "\tbne\t%0,%z2,2f\n" \ "\t" OP "\t%@,%3\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)\n" \ "2:\n" @@ -3114,7 +3124,7 @@ while (0) "\tand\t%@,%0,%3\n" \ OPS \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)\n" \ "2:\n" @@ -3134,7 +3144,7 @@ while (0) "1:\tll" SUFFIX "\t%@,%0\n" \ "\t" INSN "\t%@,%@,%1\n" \ "\tsc" SUFFIX "\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3159,7 +3169,7 @@ while (0) "\tand\t%4,%4,%1\n" \ "\tor\t%@,%@,%4\n" \ "\tsc\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3192,7 +3202,7 @@ while (0) "\tand\t%5,%5,%2\n" \ "\tor\t%@,%@,%5\n" \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3222,7 +3232,7 @@ while (0) "\tand\t%0,%0,%2\n" \ "\tor\t%@,%@,%0\n" \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3242,7 +3252,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3259,7 +3269,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b%~\n" \ "\t" INSN "\t%0,%0,%2\n" \ "\tsync%-%]%>%)" @@ -3276,7 +3286,7 @@ while (0) "\tnor\t%@,%@,%.\n" \ "\t" INSN "\t%@,%@,%1\n" \ "\tsc" SUFFIX "\t%@,%0\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3295,7 +3305,7 @@ while (0) "\tnor\t%@,%0,%.\n" \ "\t" INSN "\t%@,%@,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3314,7 +3324,7 @@ while (0) "\tnor\t%0,%0,%.\n" \ "\t" INSN "\t%@,%0,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b%~\n" \ "\t" INSN "\t%0,%0,%2\n" \ "\tsync%-%]%>%)" @@ -3332,7 +3342,7 @@ while (0) "1:\tll" SUFFIX "\t%0,%1\n" \ "\t" OP "\t%@,%2\n" \ "\tsc" SUFFIX "\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" @@ -3356,7 +3366,7 @@ while (0) "\tand\t%@,%0,%3\n" \ OPS \ "\tsc\t%@,%1\n" \ - "\tbeq\t%@,%.,1b\n" \ + "\tbeq%?\t%@,%.,1b\n" \ "\tnop\n" \ "\tsync%-%]%>%)" diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 3f56feb2ee9..22fcc8875cb 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -351,8 +351,10 @@ ;; trap trap if instructions ;; imul integer multiply 2 operands ;; imul3 integer multiply 3 operands +;; imul3nc integer multiply 3 operands without clobbering HI/LO ;; imadd integer multiply-add -;; idiv integer divide +;; idiv integer divide 2 operands +;; idiv3 integer divide 3 operands ;; move integer register move ({,D}ADD{,U} with rt = 0) ;; fmove floating point register move ;; fadd floating point add/subtract @@ -376,9 +378,9 @@ (define_attr "type" "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore, prefetch,prefetchx,condmove,mtc,mfc,mthilo,mfhilo,const,arith,logical, - shift,slt,signext,clz,pop,trap,imul,imul3,imadd,idiv,move,fmove,fadd,fmul, - fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1, - frsqrt2,multi,nop,ghost" + shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move, + fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt, + frsqrt,frsqrt1,frsqrt2,multi,nop,ghost" (cond [(eq_attr "jal" "!unset") (const_string "call") (eq_attr "got" "load") (const_string "load") @@ -553,7 +555,7 @@ (ne (symbol_ref "TARGET_FIX_VR4120") (const_int 0)))) (const_int 8) - (eq_attr "type" "idiv") + (eq_attr "type" "idiv,idiv3") (symbol_ref "mips_idiv_insns () * 4") ] (const_int 4))) @@ -787,6 +789,10 @@ ;; from the same template. (define_code_iterator any_div [div udiv]) +;; This code iterator allows unsigned and signed modulus to be generated +;; from the same template. +(define_code_iterator any_mod [mod umod]) + ;; This code iterator allows all native floating-point comparisons to be ;; generated from the same template. (define_code_iterator fcond [unordered uneq unlt unle eq lt le]) @@ -809,6 +815,7 @@ ;; "u" when doing an unsigned operation. (define_code_attr u [(sign_extend "") (zero_extend "u") (div "") (udiv "u") + (mod "") (umod "u") (gt "") (gtu "u") (ge "") (geu "u") (lt "") (ltu "u") @@ -1357,7 +1364,10 @@ (match_operand:GPR 2 "register_operand")))] "" { - if (ISA_HAS_<D>MUL3) + if (TARGET_LOONGSON_2EF) + emit_insn (gen_mul<mode>3_mul3_ls2ef (operands[0], operands[1], + operands[2])); + else if (ISA_HAS_<D>MUL3) emit_insn (gen_mul<mode>3_mul3 (operands[0], operands[1], operands[2])); else if (TARGET_FIX_R4000) emit_insn (gen_mul<mode>3_r4000 (operands[0], operands[1], operands[2])); @@ -1367,6 +1377,15 @@ DONE; }) +(define_insn "mul<mode>3_mul3_ls2ef" + [(set (match_operand:GPR 0 "register_operand" "=d") + (mult:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:GPR 2 "register_operand" "d")))] + "TARGET_LOONGSON_2EF" + "<d>multu.g\t%0,%1,%2" + [(set_attr "type" "imul3nc") + (set_attr "mode" "<MODE>")]) + (define_insn "mul<mode>3_mul3" [(set (match_operand:GPR 0 "register_operand" "=d,l") (mult:GPR (match_operand:GPR 1 "register_operand" "d,d") @@ -1455,34 +1474,50 @@ ;; Multiply-accumulate patterns -;; For processors that can copy the output to a general register: -;; -;; The all-d alternative is needed because the combiner will find this -;; pattern and then register alloc/reload will move registers around to -;; make them fit, and we don't want to trigger unnecessary loads to LO. -;; -;; The last alternative should be made slightly less desirable, but adding -;; "?" to the constraint is too strong, and causes values to be loaded into -;; LO even when that's more costly. For now, using "*d" mostly does the -;; trick. +;; This pattern is first matched by combine, which tries to use the +;; pattern wherever it can. We don't know until later whether it +;; is actually profitable to use MADD over a "MUL; ADDIU" sequence, +;; so we need to keep both options open. +;; +;; The second alternative has a "?" marker because it is generally +;; one instruction more costly than the first alternative. This "?" +;; marker is enough to convey the relative costs to the register +;; allocator. +;; +;; However, reload counts reloads of operands 4 and 5 in the same way as +;; reloads of the other operands, even though operands 4 and 5 need no +;; copy instructions. Reload therefore thinks that the second alternative +;; is two reloads more costly than the first. We add "*?*?" to the first +;; alternative as a counterweight. (define_insn "*mul_acc_si" - [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") + (match_operand:SI 2 "register_operand" "d,d")) + (match_operand:SI 3 "register_operand" "0,d"))) + (clobber (match_scratch:SI 4 "=X,l")) + (clobber (match_scratch:SI 5 "=X,&d"))] + "GENERATE_MADD_MSUB && !TARGET_MIPS16" + "@ + madd\t%1,%2 + #" + [(set_attr "type" "imadd") + (set_attr "mode" "SI") + (set_attr "length" "4,8")]) + +;; The same idea applies here. The middle alternative needs one less +;; clobber than the final alternative, so we add "*?" as a counterweight. +(define_insn "*mul_acc_si_r3900" + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d*?,d?") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d,d") (match_operand:SI 2 "register_operand" "d,d,d")) - (match_operand:SI 3 "register_operand" "0,l,*d"))) + (match_operand:SI 3 "register_operand" "0,l,d"))) (clobber (match_scratch:SI 4 "=X,3,l")) (clobber (match_scratch:SI 5 "=X,X,&d"))] - "(TARGET_MIPS3900 - || GENERATE_MADD_MSUB) - && !TARGET_MIPS16" -{ - static const char *const madd[] = { "madd\t%1,%2", "madd\t%0,%1,%2" }; - if (which_alternative == 2) - return "#"; - if (GENERATE_MADD_MSUB && which_alternative != 0) - return "#"; - return madd[which_alternative]; -} + "TARGET_MIPS3900 && !TARGET_MIPS16" + "@ + madd\t%1,%2 + madd\t%0,%1,%2 + #" [(set_attr "type" "imadd") (set_attr "mode" "SI") (set_attr "length" "4,4,8")]) @@ -1503,23 +1538,6 @@ (set (match_dup 0) (plus:SI (match_dup 5) (match_dup 3)))] "") -;; Split *mul_acc_si if the destination accumulator value is in a GPR -;; and the source accumulator value is in LO. -(define_split - [(set (match_operand:SI 0 "d_operand") - (plus:SI (mult:SI (match_operand:SI 1 "d_operand") - (match_operand:SI 2 "d_operand")) - (match_operand:SI 3 "lo_operand"))) - (clobber (match_dup 3)) - (clobber (scratch:SI))] - "reload_completed" - [(parallel [(set (match_dup 3) - (plus:SI (mult:SI (match_dup 1) (match_dup 2)) - (match_dup 3))) - (clobber (scratch:SI)) - (clobber (scratch:SI))]) - (set (match_dup 0) (match_dup 3))]) - (define_insn "*macc" [(set (match_operand:SI 0 "register_operand" "=l,d") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") @@ -1699,21 +1717,21 @@ operands[2], operands[0]); }) +;; See the comment above *mul_add_si for details. (define_insn "*mul_sub_si" - [(set (match_operand:SI 0 "register_operand" "=l,*d,*d") - (minus:SI (match_operand:SI 1 "register_operand" "0,l,*d") - (mult:SI (match_operand:SI 2 "register_operand" "d,d,d") - (match_operand:SI 3 "register_operand" "d,d,d")))) - (clobber (match_scratch:SI 4 "=X,1,l")) - (clobber (match_scratch:SI 5 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=l*?*?,d?") + (minus:SI (match_operand:SI 1 "register_operand" "0,d") + (mult:SI (match_operand:SI 2 "register_operand" "d,d") + (match_operand:SI 3 "register_operand" "d,d")))) + (clobber (match_scratch:SI 4 "=X,l")) + (clobber (match_scratch:SI 5 "=X,&d"))] "GENERATE_MADD_MSUB" "@ msub\t%2,%3 - # #" [(set_attr "type" "imadd") (set_attr "mode" "SI") - (set_attr "length" "4,8,8")]) + (set_attr "length" "4,8")]) ;; Split *mul_sub_si if both the source and destination accumulator ;; values are GPRs. @@ -1731,24 +1749,6 @@ (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 5)))] "") -;; Split *mul_acc_si if the destination accumulator value is in a GPR -;; and the source accumulator value is in LO. -(define_split - [(set (match_operand:SI 0 "d_operand") - (minus:SI (match_operand:SI 1 "lo_operand") - (mult:SI (match_operand:SI 2 "d_operand") - (match_operand:SI 3 "d_operand")))) - (clobber (match_dup 1)) - (clobber (scratch:SI))] - "reload_completed" - [(parallel [(set (match_dup 1) - (minus:SI (match_dup 1) - (mult:SI (match_dup 2) (match_dup 3)))) - (clobber (scratch:SI)) - (clobber (scratch:SI))]) - (set (match_dup 0) (match_dup 1))] - "") - (define_insn "*muls" [(set (match_operand:SI 0 "register_operand" "=l,d") (neg:SI (mult:SI (match_operand:SI 1 "register_operand" "d,d") @@ -4508,7 +4508,7 @@ rtx low = mips_subword (operands[1], 0); rtx high = mips_subword (operands[1], 1); emit_insn (gen_load_low<mode> (operands[0], low)); - if (ISA_HAS_MXHC1) + if (ISA_HAS_MXHC1 && reg_or_0_operand (high, <HALFMODE>mode)) emit_insn (gen_mthc1<mode> (operands[0], high, operands[0])); else emit_insn (gen_load_high<mode> (operands[0], high, operands[0])); @@ -4518,7 +4518,7 @@ rtx low = mips_subword (operands[0], 0); rtx high = mips_subword (operands[0], 1); emit_insn (gen_store_word<mode> (low, operands[1], const0_rtx)); - if (ISA_HAS_MXHC1) + if (ISA_HAS_MXHC1 && register_operand (high, <HALFMODE>mode)) emit_insn (gen_mfhc1<mode> (high, operands[1])); else emit_insn (gen_store_word<mode> (high, operands[1], const1_rtx)); @@ -4573,7 +4573,7 @@ ;; value in the low word. (define_insn "mthc1<mode>" [(set (match_operand:SPLITF 0 "register_operand" "=f") - (unspec:SPLITF [(match_operand:<HALFMODE> 1 "general_operand" "dJ") + (unspec:SPLITF [(match_operand:<HALFMODE> 1 "reg_or_0_operand" "dJ") (match_operand:SPLITF 2 "register_operand" "0")] UNSPEC_MTHC1))] "TARGET_HARD_FLOAT && ISA_HAS_MXHC1" @@ -6128,6 +6128,9 @@ (match_operand 2 "const_int_operand" "n"))] "ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS" { + if (TARGET_LOONGSON_2EF) + /* Loongson 2[ef] use load to $0 to perform prefetching. */ + return "ld\t$0,%a0"; operands[1] = mips_prefetch_cookie (operands[1], operands[2]); return "pref\t%1,%a0"; } diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt index f192f0b52b8..c7e78ff5d13 100644 --- a/gcc/config/mips/mips.opt +++ b/gcc/config/mips/mips.opt @@ -112,6 +112,10 @@ mfix-r4400 Target Report Mask(FIX_R4400) Work around certain R4400 errata +mfix-r10000 +Target Report Mask(FIX_R10000) +Work around certain R10000 errata + mfix-sb1 Target Report Var(TARGET_FIX_SB1) Work around errata for early SB-1 revision 2 cores diff --git a/gcc/config/mips/sde.h b/gcc/config/mips/sde.h index f80b6f71b08..ee8b20b0996 100644 --- a/gcc/config/mips/sde.h +++ b/gcc/config/mips/sde.h @@ -66,7 +66,7 @@ along with GCC; see the file COPYING3. If not see #undef LINK_SPEC #define LINK_SPEC "\ %(endian_spec) \ -%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32} %{mips32r2} %{mips64} \ +%{G*} %{mips1} %{mips2} %{mips3} %{mips4} %{mips32*} %{mips64*} \ %{bestGnum} \ %{shared} %{non_shared} %{call_shared} \ %{mabi=n32:-melf32%{EB:b}%{EL:l}tsmipn32} \ diff --git a/gcc/config/mips/sync.md b/gcc/config/mips/sync.md index 0052f46dc9f..286ca369214 100644 --- a/gcc/config/mips/sync.md +++ b/gcc/config/mips/sync.md @@ -43,9 +43,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_COMPARE_AND_SWAP ("<d>", "li"); + return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("<d>", "li")); else - return MIPS_COMPARE_AND_SWAP ("<d>", "move"); + return mips_output_sync_loop (MIPS_COMPARE_AND_SWAP ("<d>", "move")); } [(set_attr "length" "32")]) @@ -76,9 +76,11 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP); + return (mips_output_sync_loop + (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_NONZERO_OP))); else - return MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP); + return (mips_output_sync_loop + (MIPS_COMPARE_AND_SWAP_12 (MIPS_COMPARE_AND_SWAP_12_ZERO_OP))); } [(set_attr "length" "40,36")]) @@ -91,9 +93,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OP ("<d>", "<d>addiu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>addiu")); else - return MIPS_SYNC_OP ("<d>", "<d>addu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>addu")); } [(set_attr "length" "28")]) @@ -124,7 +126,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP); + return (mips_output_sync_loop + (MIPS_SYNC_OP_12 ("<insn>", MIPS_SYNC_OP_12_NOT_NOP))); } [(set_attr "length" "40")]) @@ -160,8 +163,9 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP, - MIPS_SYNC_OLD_OP_12_NOT_NOP_REG); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP_12 ("<insn>", MIPS_SYNC_OLD_OP_12_NOT_NOP, + MIPS_SYNC_OLD_OP_12_NOT_NOP_REG))); } [(set_attr "length" "40")]) @@ -202,7 +206,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP_12 ("<insn>", MIPS_SYNC_NEW_OP_12_NOT_NOP))); } [(set_attr "length" "40")]) @@ -233,7 +238,8 @@ (clobber (match_scratch:SI 4 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT); + return (mips_output_sync_loop + (MIPS_SYNC_OP_12 ("and", MIPS_SYNC_OP_12_NOT_NOT))); } [(set_attr "length" "44")]) @@ -267,8 +273,9 @@ (clobber (match_scratch:SI 5 "=&d"))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT, - MIPS_SYNC_OLD_OP_12_NOT_NOT_REG); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP_12 ("and", MIPS_SYNC_OLD_OP_12_NOT_NOT, + MIPS_SYNC_OLD_OP_12_NOT_NOT_REG))); } [(set_attr "length" "44")]) @@ -307,7 +314,8 @@ (match_dup 4)] UNSPEC_SYNC_NEW_OP_12))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP_12 ("and", MIPS_SYNC_NEW_OP_12_NOT_NOT))); } [(set_attr "length" "40")]) @@ -319,7 +327,7 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_OP ("<d>", "<d>subu"); + return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<d>subu")); } [(set_attr "length" "28")]) @@ -334,9 +342,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>addiu")); else - return MIPS_SYNC_OLD_OP ("<d>", "<d>addu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>addu")); } [(set_attr "length" "28")]) @@ -350,7 +358,7 @@ UNSPEC_SYNC_OLD_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_OLD_OP ("<d>", "<d>subu"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<d>subu")); } [(set_attr "length" "28")]) @@ -365,9 +373,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>addiu")); else - return MIPS_SYNC_NEW_OP ("<d>", "<d>addu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>addu")); } [(set_attr "length" "28")]) @@ -381,7 +389,7 @@ UNSPEC_SYNC_NEW_OP))] "GENERATE_LL_SC" { - return MIPS_SYNC_NEW_OP ("<d>", "<d>subu"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<d>subu")); } [(set_attr "length" "28")]) @@ -394,9 +402,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OP ("<d>", "<immediate_insn>"); + return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<immediate_insn>")); else - return MIPS_SYNC_OP ("<d>", "<insn>"); + return mips_output_sync_loop (MIPS_SYNC_OP ("<d>", "<insn>")); } [(set_attr "length" "28")]) @@ -411,9 +419,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>"); + return (mips_output_sync_loop + (MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>"))); else - return MIPS_SYNC_OLD_OP ("<d>", "<insn>"); + return mips_output_sync_loop (MIPS_SYNC_OLD_OP ("<d>", "<insn>")); } [(set_attr "length" "28")]) @@ -428,9 +437,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>"); + return (mips_output_sync_loop + (MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>"))); else - return MIPS_SYNC_NEW_OP ("<d>", "<insn>"); + return mips_output_sync_loop (MIPS_SYNC_NEW_OP ("<d>", "<insn>")); } [(set_attr "length" "28")]) @@ -441,9 +451,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NAND ("<d>", "andi"); + return mips_output_sync_loop (MIPS_SYNC_NAND ("<d>", "andi")); else - return MIPS_SYNC_NAND ("<d>", "and"); + return mips_output_sync_loop (MIPS_SYNC_NAND ("<d>", "and")); } [(set_attr "length" "32")]) @@ -456,9 +466,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_OLD_NAND ("<d>", "andi"); + return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("<d>", "andi")); else - return MIPS_SYNC_OLD_NAND ("<d>", "and"); + return mips_output_sync_loop (MIPS_SYNC_OLD_NAND ("<d>", "and")); } [(set_attr "length" "32")]) @@ -471,9 +481,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_NEW_NAND ("<d>", "andi"); + return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("<d>", "andi")); else - return MIPS_SYNC_NEW_NAND ("<d>", "and"); + return mips_output_sync_loop (MIPS_SYNC_NEW_NAND ("<d>", "and")); } [(set_attr "length" "32")]) @@ -486,9 +496,9 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_EXCHANGE ("<d>", "li"); + return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("<d>", "li")); else - return MIPS_SYNC_EXCHANGE ("<d>", "move"); + return mips_output_sync_loop (MIPS_SYNC_EXCHANGE ("<d>", "move")); } [(set_attr "length" "24")]) @@ -516,8 +526,10 @@ "GENERATE_LL_SC" { if (which_alternative == 0) - return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP); + return (mips_output_sync_loop + (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_NONZERO_OP))); else - return MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP); + return (mips_output_sync_loop + (MIPS_SYNC_EXCHANGE_12 (MIPS_SYNC_EXCHANGE_12_ZERO_OP))); } [(set_attr "length" "28,24")]) diff --git a/gcc/config/mips/t-isa3264 b/gcc/config/mips/t-isa3264 index cec7e5e64b5..ef2de4e8675 100644 --- a/gcc/config/mips/t-isa3264 +++ b/gcc/config/mips/t-isa3264 @@ -17,13 +17,13 @@ TARGET_LIBGCC2_CFLAGS = -G 0 # Build the libraries for both hard and soft floating point ifneq ($(filter MIPS_ABI_DEFAULT=ABI_EABI,$(tm_defines)),) -MULTILIB_OPTIONS = msoft-float EL/EB mips32/mips32r2/mips64 -MULTILIB_DIRNAMES = soft-float el eb mips32 mips32r2 mips64 +MULTILIB_OPTIONS = msoft-float EL/EB mips32/mips32r2/mips64/mips64r2 +MULTILIB_DIRNAMES = soft-float el eb mips32 mips32r2 mips64 mips64r2 else -MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips64 -MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips64 +MULTILIB_OPTIONS = msoft-float/mfp64 EL/EB mips32/mips32r2/mips64/mips64r2 +MULTILIB_DIRNAMES = soft-float fp64 el eb mips32 mips32r2 mips64 mips64r2 ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),) -MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 +MULTILIB_EXCLUSIONS = mips32/mfp64 mips64/mfp64 mips64r2/mfp64 else MULTILIB_EXCLUSIONS = !mips32r2/mfp64 endif diff --git a/gcc/config/mips/t-sde b/gcc/config/mips/t-sde index a6d4290750f..64180d9ecf1 100644 --- a/gcc/config/mips/t-sde +++ b/gcc/config/mips/t-sde @@ -10,19 +10,23 @@ $(T)crtn.o: $(srcdir)/config/mips/crtn.asm $(GCC_PASSES) $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/mips/crtn.asm -MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mfp64 mcode-readable=no -MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof f64 spram +MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64/mips64r2 mips16 msoft-float/mfp64 mcode-readable=no +MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips64r2 mips16 sof f64 spram MULTILIB_MATCHES = EL=mel EB=meb # The -mfp64 option is only valid in conjunction with -mips32r2. ifneq ($(filter MIPS_ISA_DEFAULT=33,$(tm_defines)),) -MULTILIB_EXCLUSIONS := mips32/mfp64 mips64/mfp64 +MULTILIB_EXCLUSIONS := mips32/mfp64 mips64/mfp64 mips64r2/mfp64 else MULTILIB_EXCLUSIONS := !mips32r2/mfp64 endif # Don't build 64-bit MIPS16 multilibs. -MULTILIB_EXCLUSIONS += mips16/mips64 +ifneq ($(filter MIPS_ISA_DEFAULT=6%,$(tm_defines)),) +MULTILIB_EXCLUSIONS += !mips32/!mips32r2/mips16 +else +MULTILIB_EXCLUSIONS += mips64/mips16 mips64r2/mips16 +endif EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crti.o crtn.o diff --git a/gcc/config/mips/t-sdemtk b/gcc/config/mips/t-sdemtk index 5169dee53b3..1135015f665 100644 --- a/gcc/config/mips/t-sdemtk +++ b/gcc/config/mips/t-sdemtk @@ -1,8 +1,8 @@ # Override newlib settings in t-sde and set up for building # against SDE header files and libraries. -MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64 mips16 msoft-float/mno-float/mfp64 -MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips16 sof nof f64 +MULTILIB_OPTIONS = EL/EB mips32/mips32r2/mips64/mips64r2 mips16 msoft-float/mno-float/mfp64 +MULTILIB_DIRNAMES = el eb mips32 mips32r2 mips64 mips64r2 mips16 sof nof f64 # Remove stdarg.h and stddef.h from USER_H. USER_H = $(srcdir)/ginclude/float.h \ |