summaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-20 08:41:32 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2008-11-20 08:41:32 +0000
commit03248b193e6bac947221d44cc4dff913183cb5ae (patch)
treee2c9a37069b356f4cb760951f499abdac631e293 /gcc/config/mips
parentd7cbb3ef81425f9adec25287428049a99320c479 (diff)
downloadgcc-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.md20
-rw-r--r--gcc/config/mips/loongson2ef.md9
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c161
-rw-r--r--gcc/config/mips/mips.h48
-rw-r--r--gcc/config/mips/mips.md153
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/config/mips/sde.h2
-rw-r--r--gcc/config/mips/sync.md86
-rw-r--r--gcc/config/mips/t-isa326410
-rw-r--r--gcc/config/mips/t-sde12
-rw-r--r--gcc/config/mips/t-sdemtk4
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 \