constraints.md (kl): Delete.
gcc/ * config/mips/constraints.md (kl): Delete. * config/mips/mips.md (divmod<mode>4, udivmod<mode>4): Turn into define expands, using... (divmod<mode>4_mips16, udivmod<mode>4_mips16): ...these new instructions for MIPS16. (*divmod<mode>4, *udivmod<mode>4): New patterns, taken from the non-MIPS16 version of the old divmod<mode>4 and udivmod<mode>4. From-SVN: r207079
This commit is contained in:
parent
3abe9053ba
commit
317a951fc7
@ -1,3 +1,13 @@
|
||||
2014-01-25 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* config/mips/constraints.md (kl): Delete.
|
||||
* config/mips/mips.md (divmod<mode>4, udivmod<mode>4): Turn into
|
||||
define expands, using...
|
||||
(divmod<mode>4_mips16, udivmod<mode>4_mips16): ...these new
|
||||
instructions for MIPS16.
|
||||
(*divmod<mode>4, *udivmod<mode>4): New patterns, taken from the
|
||||
non-MIPS16 version of the old divmod<mode>4 and udivmod<mode>4.
|
||||
|
||||
2014-01-25 Walter Lee <walt@tilera.com>
|
||||
|
||||
* config/tilepro/tilepro.md (ctzdi2): Use register_operand
|
||||
|
@ -92,12 +92,6 @@
|
||||
;; but the DSP version allows any accumulator target.
|
||||
(define_register_constraint "ka" "ISA_HAS_DSP_MULT ? ACC_REGS : MD_REGS")
|
||||
|
||||
;; The register class to use for an allocatable division result.
|
||||
;; MIPS16 uses M16_REGS because LO is fixed.
|
||||
(define_register_constraint "kl"
|
||||
"TARGET_MIPS16 ? M16_REGS : TARGET_BIG_ENDIAN ? MD1_REG : MD0_REG"
|
||||
"@internal")
|
||||
|
||||
(define_constraint "kf"
|
||||
"@internal"
|
||||
(match_operand 0 "force_to_mem_operand"))
|
||||
|
@ -2559,56 +2559,129 @@
|
||||
|
||||
;; VR4120 errata MD(A1): signed division instructions do not work correctly
|
||||
;; with negative operands. We use special libgcc functions instead.
|
||||
;;
|
||||
(define_expand "divmod<mode>4"
|
||||
[(parallel
|
||||
[(set (match_operand:GPR 0 "register_operand")
|
||||
(div:GPR (match_operand:GPR 1 "register_operand")
|
||||
(match_operand:GPR 2 "register_operand")))
|
||||
(set (match_operand:GPR 3 "register_operand")
|
||||
(mod:GPR (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
|
||||
{
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
|
||||
emit_insn (gen_divmod<mode>4_mips16 (operands[0], operands[1],
|
||||
operands[2], operands[3], lo));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn_and_split "*divmod<mode>4"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=l")
|
||||
(div:GPR (match_operand:GPR 1 "register_operand" "d")
|
||||
(match_operand:GPR 2 "register_operand" "d")))
|
||||
(set (match_operand:GPR 3 "register_operand" "=d")
|
||||
(mod:GPR (match_dup 1)
|
||||
(match_dup 2)))]
|
||||
"ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && !TARGET_MIPS16"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "idiv")
|
||||
(set_attr "mode" "<MODE>")
|
||||
(set_attr "insn_count" "2")])
|
||||
|
||||
;; Expand generates divmod instructions for individual division and modulus
|
||||
;; operations. We then rely on CSE to reuse earlier divmods where possible.
|
||||
;; This means that, when generating MIPS16 code, it is better not to expose
|
||||
;; the fixed LO register until after CSE has finished. However, it's still
|
||||
;; better to split before register allocation, so that we don't allocate
|
||||
;; one of the scarce MIPS16 registers to an unused result.
|
||||
(define_insn_and_split "divmod<mode>4"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=kl")
|
||||
(define_insn_and_split "divmod<mode>4_mips16"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d")
|
||||
(div:GPR (match_operand:GPR 1 "register_operand" "d")
|
||||
(match_operand:GPR 2 "register_operand" "d")))
|
||||
(set (match_operand:GPR 3 "register_operand" "=d")
|
||||
(mod:GPR (match_dup 1)
|
||||
(match_dup 2)))]
|
||||
"ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
|
||||
(match_dup 2)))
|
||||
(clobber (match_operand:GPR 4 "lo_operand" "=l"))]
|
||||
"ISA_HAS_<D>DIV && !TARGET_FIX_VR4120 && TARGET_MIPS16"
|
||||
"#"
|
||||
"&& ((TARGET_MIPS16 && cse_not_expected) || reload_completed)"
|
||||
"&& cse_not_expected"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_divmod<mode>4_split (operands[3], operands[1], operands[2]));
|
||||
if (TARGET_MIPS16)
|
||||
emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, LO_REGNUM));
|
||||
emit_move_insn (operands[0], operands[4]);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "idiv")
|
||||
(set_attr "mode" "<MODE>")
|
||||
;; Worst case for MIPS16.
|
||||
(set_attr "insn_count" "3")])
|
||||
|
||||
;; See the comment above "divmod<mode>4" for the MIPS16 handling.
|
||||
(define_insn_and_split "udivmod<mode>4"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=kl")
|
||||
(define_expand "udivmod<mode>4"
|
||||
[(parallel
|
||||
[(set (match_operand:GPR 0 "register_operand")
|
||||
(udiv:GPR (match_operand:GPR 1 "register_operand")
|
||||
(match_operand:GPR 2 "register_operand")))
|
||||
(set (match_operand:GPR 3 "register_operand")
|
||||
(umod:GPR (match_dup 1)
|
||||
(match_dup 2)))])]
|
||||
"ISA_HAS_<D>DIV && !TARGET_FIX_VR4120"
|
||||
{
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
rtx lo = gen_rtx_REG (<MODE>mode, LO_REGNUM);
|
||||
emit_insn (gen_udivmod<mode>4_mips16 (operands[0], operands[1],
|
||||
operands[2], operands[3], lo));
|
||||
DONE;
|
||||
}
|
||||
})
|
||||
|
||||
(define_insn_and_split "*udivmod<mode>4"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=l")
|
||||
(udiv:GPR (match_operand:GPR 1 "register_operand" "d")
|
||||
(match_operand:GPR 2 "register_operand" "d")))
|
||||
(set (match_operand:GPR 3 "register_operand" "=d")
|
||||
(umod:GPR (match_dup 1)
|
||||
(match_dup 2)))]
|
||||
"ISA_HAS_<D>DIV"
|
||||
"ISA_HAS_<D>DIV && !TARGET_MIPS16"
|
||||
"#"
|
||||
"(TARGET_MIPS16 && cse_not_expected) || reload_completed"
|
||||
"reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
|
||||
if (TARGET_MIPS16)
|
||||
emit_move_insn (operands[0], gen_rtx_REG (<MODE>mode, LO_REGNUM));
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "idiv")
|
||||
(set_attr "mode" "<MODE>")
|
||||
;; Worst case for MIPS16.
|
||||
(set_attr "insn_count" "2")])
|
||||
|
||||
;; See the comment above "divmod<mode>4_mips16" for the split timing.
|
||||
(define_insn_and_split "udivmod<mode>4_mips16"
|
||||
[(set (match_operand:GPR 0 "register_operand" "=d")
|
||||
(udiv:GPR (match_operand:GPR 1 "register_operand" "d")
|
||||
(match_operand:GPR 2 "register_operand" "d")))
|
||||
(set (match_operand:GPR 3 "register_operand" "=d")
|
||||
(umod:GPR (match_dup 1)
|
||||
(match_dup 2)))
|
||||
(clobber (match_operand:GPR 4 "lo_operand" "=l"))]
|
||||
"ISA_HAS_<D>DIV && TARGET_MIPS16"
|
||||
"#"
|
||||
"cse_not_expected"
|
||||
[(const_int 0)]
|
||||
{
|
||||
emit_insn (gen_udivmod<mode>4_split (operands[3], operands[1], operands[2]));
|
||||
emit_move_insn (operands[0], operands[4]);
|
||||
DONE;
|
||||
}
|
||||
[(set_attr "type" "idiv")
|
||||
(set_attr "mode" "<MODE>")
|
||||
(set_attr "insn_count" "3")])
|
||||
|
||||
(define_expand "<u>divmod<mode>4_split"
|
||||
|
Loading…
Reference in New Issue
Block a user