diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2014-01-25 20:16:14 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2014-01-25 20:16:14 +0000 |
commit | 317a951fc75f1afb5e4fc25810722cf9044da7ed (patch) | |
tree | 61e1e082d8cd475a243a3d27fe8660aefe81dfd5 /gcc/config | |
parent | 3abe9053ba83798e124f9efe9996e42a7d07a4e8 (diff) | |
download | gcc-317a951fc75f1afb5e4fc25810722cf9044da7ed.zip gcc-317a951fc75f1afb5e4fc25810722cf9044da7ed.tar.gz gcc-317a951fc75f1afb5e4fc25810722cf9044da7ed.tar.bz2 |
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
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/mips/constraints.md | 6 | ||||
-rw-r--r-- | gcc/config/mips/mips.md | 107 |
2 files changed, 90 insertions, 23 deletions
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md index 196b3e1..49e4895 100644 --- a/gcc/config/mips/constraints.md +++ b/gcc/config/mips/constraints.md @@ -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")) diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index fb47a89..4f64360 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -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" |