diff options
Diffstat (limited to 'gcc/config/mips/mips.c')
-rw-r--r-- | gcc/config/mips/mips.c | 78 |
1 files changed, 53 insertions, 25 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index ff72e28a35c..d3fd7097f57 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -2163,7 +2163,7 @@ static bool mips16_unextended_reference_p (enum machine_mode mode, rtx base, unsigned HOST_WIDE_INT offset) { - if (offset % GET_MODE_SIZE (mode) == 0) + if (mode != BLKmode && offset % GET_MODE_SIZE (mode) == 0) { if (GET_MODE_SIZE (mode) == 4 && base == stack_pointer_rtx) return offset < 256U * GET_MODE_SIZE (mode); @@ -2398,7 +2398,7 @@ mips_force_unary (enum machine_mode mode, enum rtx_code code, rtx op0) /* Emit an instruction of the form (set TARGET (CODE OP0 OP1)). */ -static void +void mips_emit_binary (enum rtx_code code, rtx target, rtx op0, rtx op1) { emit_insn (gen_rtx_SET (VOIDmode, target, @@ -3777,6 +3777,16 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, return false; case ZERO_EXTEND: + if (outer_code == SET + && ISA_HAS_BADDU + && (GET_CODE (XEXP (x, 0)) == TRUNCATE + || GET_CODE (XEXP (x, 0)) == SUBREG) + && GET_MODE (XEXP (x, 0)) == QImode + && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS) + { + *total = set_src_cost (XEXP (XEXP (x, 0), 0), speed); + return true; + } *total = mips_zero_extend_cost (mode, XEXP (x, 0)); return false; @@ -11218,9 +11228,13 @@ mips_init_libfuncs (void) } /* The MIPS16 ISA does not have an encoding for "sync", so we rely - on an external non-MIPS16 routine to implement __sync_synchronize. */ + on an external non-MIPS16 routine to implement __sync_synchronize. + Similarly for the rest of the ll/sc libfuncs. */ if (TARGET_MIPS16) - synchronize_libfunc = init_one_libfunc ("__sync_synchronize"); + { + synchronize_libfunc = init_one_libfunc ("__sync_synchronize"); + init_sync_libfuncs (UNITS_PER_WORD); + } } /* Build up a multi-insn sequence that loads label TARGET into $AT. */ @@ -15246,6 +15260,11 @@ mips_set_mips16_mode (int mips16_p) /* MIPS16 has no BAL instruction. */ target_flags &= ~MASK_RELAX_PIC_CALLS; + /* The R4000 errata don't apply to any known MIPS16 cores. + It's simpler to make the R4000 fixes and MIPS16 mode + mutually exclusive. */ + target_flags &= ~MASK_FIX_R4000; + if (flag_pic && !TARGET_OLDABI) sorry ("MIPS16 PIC for ABIs other than o32 and o64"); @@ -15831,38 +15850,33 @@ mips_conditional_register_usage (void) global_regs[CCDSP_PO_REGNUM] = 1; global_regs[CCDSP_SC_REGNUM] = 1; } - else - { - int regno; + else + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) DSP_ACC_REGS]); - for (regno = DSP_ACC_REG_FIRST; regno <= DSP_ACC_REG_LAST; regno++) - fixed_regs[regno] = call_used_regs[regno] = 1; - } if (!TARGET_HARD_FLOAT) { - int regno; - - for (regno = FP_REG_FIRST; regno <= FP_REG_LAST; regno++) - fixed_regs[regno] = call_used_regs[regno] = 1; - for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++) - fixed_regs[regno] = call_used_regs[regno] = 1; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) FP_REGS]); + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) ST_REGS]); } - else if (! ISA_HAS_8CC) + else if (!ISA_HAS_8CC) { - int regno; - /* We only have a single condition-code register. We implement this by fixing all the condition-code registers and generating RTL that refers directly to ST_REG_FIRST. */ - for (regno = ST_REG_FIRST; regno <= ST_REG_LAST; regno++) - fixed_regs[regno] = call_used_regs[regno] = 1; + AND_COMPL_HARD_REG_SET (accessible_reg_set, + reg_class_contents[(int) ST_REGS]); + SET_HARD_REG_BIT (accessible_reg_set, FPSW_REGNUM); + fixed_regs[FPSW_REGNUM] = call_used_regs[FPSW_REGNUM] = 1; } - /* In MIPS16 mode, we permit the $t temporary registers to be used - for reload. We prohibit the unused $s registers, since they - are call-saved, and saving them via a MIPS16 register would - probably waste more time than just reloading the value. */ if (TARGET_MIPS16) { + /* In MIPS16 mode, we permit the $t temporary registers to be used + for reload. We prohibit the unused $s registers, since they + are call-saved, and saving them via a MIPS16 register would + probably waste more time than just reloading the value. */ fixed_regs[18] = call_used_regs[18] = 1; fixed_regs[19] = call_used_regs[19] = 1; fixed_regs[20] = call_used_regs[20] = 1; @@ -15872,6 +15886,12 @@ mips_conditional_register_usage (void) fixed_regs[26] = call_used_regs[26] = 1; fixed_regs[27] = call_used_regs[27] = 1; fixed_regs[30] = call_used_regs[30] = 1; + + /* Do not allow HI and LO to be treated as register operands. + There are no MTHI or MTLO instructions (or any real need + for them) and one-way registers cannot easily be reloaded. */ + AND_COMPL_HARD_REG_SET (operand_reg_set, + reg_class_contents[(int) MD_REGS]); } /* $f20-$f23 are call-clobbered for n64. */ if (mips_abi == ABI_64) @@ -16057,12 +16077,20 @@ mips_mulsidi3_gen_fn (enum rtx_code ext_code) case we still expand mulsidi3 for DMUL. */ if (ISA_HAS_DMUL3) return signed_p ? gen_mulsidi3_64bit_dmul : NULL; + if (TARGET_MIPS16) + return (signed_p + ? gen_mulsidi3_64bit_mips16 + : gen_umulsidi3_64bit_mips16); if (TARGET_FIX_R4000) return NULL; return signed_p ? gen_mulsidi3_64bit : gen_umulsidi3_64bit; } else { + if (TARGET_MIPS16) + return (signed_p + ? gen_mulsidi3_32bit_mips16 + : gen_umulsidi3_32bit_mips16); if (TARGET_FIX_R4000 && !ISA_HAS_DSP) return signed_p ? gen_mulsidi3_32bit_r4000 : gen_umulsidi3_32bit_r4000; return signed_p ? gen_mulsidi3_32bit : gen_umulsidi3_32bit; |