From 32ad6a47f78997e7cb032cea8c45ad09d57a5b7a Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Mon, 9 Jun 2003 07:10:47 +0000 Subject: [PATCH] mips-protos.h (mips_output_division): Declare. * config/mips/mips-protos.h (mips_output_division): Declare. * config/mips/mips.h (MASK_CHECK_RANGE_DIV): Remove. (MASK_BRANCHLIKELY): Use MASK_CHECK_RANGE_DIV's old number. (TARGET_NO_CHECK_ZERO_DIV, TARGET_CHECK_RANGE_DIV): Remove. (TARGET_CHECK_ZERO_DIV): New macro. (TARGET_SWITCHES): Remove -mcheck-range-div & -mno-check-range-div. * config/mips/mips.c (mips_output_division): New function. * config/mips/mips.md (length): Take TARGET_CHECK_ZERO_DIV into account when calculating the default length of a division. (divmodsi4, divmoddi4, udivmodsi4, udivmoddi4): Turn into define_insns. Enable regardless of optimization level. Use mips_output_division. (divmodsi4_internal, divmoddi4_internal, udivmodsi4_internal, udivmoddi4_internal, div_trap, div_trap_normal, div_trap_mips16, divsi3, divsi3_internal, divdi3, divdi3_internal, modsi3, modsi3_internal, moddi3, moddi3_internal, udivsi3, udivsi3_internal, udivdi3, udivdi3_internal, umodsi3, umodsi3_internal, umoddi3, umoddi3_internal): Remove. From-SVN: r67655 --- gcc/ChangeLog | 20 ++ gcc/config/mips/mips-protos.h | 1 + gcc/config/mips/mips.c | 22 ++ gcc/config/mips/mips.h | 13 +- gcc/config/mips/mips.md | 517 ++-------------------------------- 5 files changed, 64 insertions(+), 509 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5811a449d9c..452a23243ee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2003-06-09 Richard Sandiford + + * config/mips/mips-protos.h (mips_output_division): Declare. + * config/mips/mips.h (MASK_CHECK_RANGE_DIV): Remove. + (MASK_BRANCHLIKELY): Use MASK_CHECK_RANGE_DIV's old number. + (TARGET_NO_CHECK_ZERO_DIV, TARGET_CHECK_RANGE_DIV): Remove. + (TARGET_CHECK_ZERO_DIV): New macro. + (TARGET_SWITCHES): Remove -mcheck-range-div & -mno-check-range-div. + * config/mips/mips.c (mips_output_division): New function. + * config/mips/mips.md (length): Take TARGET_CHECK_ZERO_DIV into + account when calculating the default length of a division. + (divmodsi4, divmoddi4, udivmodsi4, udivmoddi4): Turn into define_insns. + Enable regardless of optimization level. Use mips_output_division. + (divmodsi4_internal, divmoddi4_internal, udivmodsi4_internal, + udivmoddi4_internal, div_trap, div_trap_normal, div_trap_mips16, + divsi3, divsi3_internal, divdi3, divdi3_internal, modsi3, + modsi3_internal, moddi3, moddi3_internal, udivsi3, udivsi3_internal, + udivdi3, udivdi3_internal, umodsi3, umodsi3_internal, umoddi3, + umoddi3_internal): Remove. + 2003-06-09 Richard Sandiford * config/mips/mips.c (mips_reg_names): Change hilo entry to "". diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h index a08cf008dd0..a9480d39840 100644 --- a/gcc/config/mips/mips-protos.h +++ b/gcc/config/mips/mips-protos.h @@ -110,6 +110,7 @@ extern const char *mips_output_load_label PARAMS ((void)); extern const char *mips_output_conditional_branch PARAMS ((rtx, rtx *, int, int, int, int)); +extern const char *mips_output_division PARAMS ((const char *, rtx *)); extern int mips_adjust_insn_length PARAMS ((rtx, int)); extern enum reg_class mips_secondary_reload_class PARAMS ((enum reg_class, enum machine_mode, diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 605f3aef3d9..2604d49a02a 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -10217,6 +10217,28 @@ mips_output_conditional_branch (insn, return 0; } +/* Used to output div or ddiv instruction DIVISION, which has the + operands given by OPERANDS. If we need a divide-by-zero check, + output the instruction and return an asm string that traps if + operand 2 is zero. Otherwise just return DIVISION itself. */ + +const char * +mips_output_division (division, operands) + const char *division; + rtx *operands; +{ + if (TARGET_CHECK_ZERO_DIV) + { + output_asm_insn (division, operands); + + if (TARGET_MIPS16) + return "bnez\t%2,1f\n\tbreak\t7\n1:"; + else + return "bne\t%2,%.,1f\n\t%#break\t7\n1:"; + } + return division; +} + /* Return true if GIVEN is the same as CANONICAL, or if it is CANONICAL with a final "000" replaced by "k". Ignore case. diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 865603d50c5..b40abc8245d 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -201,15 +201,13 @@ extern void sbss_section PARAMS ((void)); #define MASK_MIPS16 0x00100000 /* Generate mips16 code */ #define MASK_NO_CHECK_ZERO_DIV \ 0x00200000 /* divide by zero checking */ -#define MASK_CHECK_RANGE_DIV \ - 0x00400000 /* divide result range checking */ +#define MASK_BRANCHLIKELY 0x00400000 /* Generate Branch Likely + instructions. */ #define MASK_UNINIT_CONST_IN_RODATA \ 0x00800000 /* Store uninitialized consts in rodata */ #define MASK_NO_FUSED_MADD 0x01000000 /* Don't generate floating point multiply-add operations. */ -#define MASK_BRANCHLIKELY 0x02000000 /* Generate Branch Likely - instructions. */ /* Debug switches, not documented */ #define MASK_DEBUG 0 /* unused */ @@ -294,8 +292,7 @@ extern void sbss_section PARAMS ((void)); #define TARGET_4300_MUL_FIX (target_flags & MASK_4300_MUL_FIX) -#define TARGET_NO_CHECK_ZERO_DIV (target_flags & MASK_NO_CHECK_ZERO_DIV) -#define TARGET_CHECK_RANGE_DIV (target_flags & MASK_CHECK_RANGE_DIV) +#define TARGET_CHECK_ZERO_DIV (!(target_flags & MASK_NO_CHECK_ZERO_DIV)) #define TARGET_BRANCHLIKELY (target_flags & MASK_BRANCHLIKELY) @@ -624,10 +621,6 @@ extern void sbss_section PARAMS ((void)); N_("Trap on integer divide by zero")}, \ {"no-check-zero-division", MASK_NO_CHECK_ZERO_DIV, \ N_("Don't trap on integer divide by zero")}, \ - {"check-range-division",MASK_CHECK_RANGE_DIV, \ - N_("Trap on integer divide overflow")}, \ - {"no-check-range-division",-MASK_CHECK_RANGE_DIV, \ - N_("Don't trap on integer divide overflow")}, \ { "branch-likely", MASK_BRANCHLIKELY, \ N_("Use Branch Likely instructions, overriding default for arch")}, \ { "no-branch-likely", -MASK_BRANCHLIKELY, \ diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 10a3da04e10..85e9b2d1700 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -174,6 +174,11 @@ (and (eq_attr "extended_mips16" "yes") (ne (symbol_ref "TARGET_MIPS16") (const_int 0))) (const_int 8) + (and (eq_attr "type" "idiv") + (ne (symbol_ref "TARGET_CHECK_ZERO_DIV") (const_int 0))) + (cond [(ne (symbol_ref "TARGET_MIPS16") (const_int 0)) + (const_int 12)] + (const_int 16)) ] (const_int 4))) ;; Attribute describing the processor. This attribute must match exactly @@ -2833,539 +2838,53 @@ [(set_attr "type" "fdiv") (set_attr "mode" "SF")]) -;; If optimizing, prefer the divmod functions over separate div and -;; mod functions, since this will allow using one instruction for both -;; the quotient and remainder. At present, the divmod is not moved out -;; of loops if it is constant within the loop, so allow -mdebugc to -;; use the old method of doing things. - -;; 64 is the multiply/divide hi register -;; 65 is the multiply/divide lo register - -;; ??? We can't accept constants here, because the MIPS assembler will replace -;; a divide by power of 2 with a shift, and then the remainder is no longer -;; available. - -(define_expand "divmodsi4" - [(set (match_operand:SI 0 "register_operand" "") - (div:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (match_operand:SI 3 "register_operand" "") - (mod:SI (match_dup 1) - (match_dup 2)))] - "optimize" - " -{ - emit_insn (gen_divmodsi4_internal (operands[0], operands[1], operands[2], - operands[3])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, - GEN_INT - (trunc_int_for_mode - (BITMASK_HIGH, SImode))), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "divmodsi4_internal" +(define_insn "divmodsi4" [(set (match_operand:SI 0 "register_operand" "=l") (div:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (set (match_operand:SI 3 "register_operand" "=h") (mod:SI (match_dup 1) (match_dup 2)))] - "optimize" - "div\\t$0,%1,%2" + "" + { return mips_output_division ("div\\t$0,%1,%2", operands); } [(set_attr "type" "idiv") (set_attr "mode" "SI")]) -(define_expand "divmoddi4" - [(set (match_operand:DI 0 "register_operand" "") - (div:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (match_operand:DI 3 "register_operand" "") - (mod:DI (match_dup 1) - (match_dup 2)))] - "TARGET_64BIT && optimize" - " -{ - emit_insn (gen_divmoddi4_internal (operands[0], operands[1], operands[2], - operands[3])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, - GEN_INT (BITMASK_HIGH)), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "divmoddi4_internal" +(define_insn "divmoddi4" [(set (match_operand:DI 0 "register_operand" "=l") (div:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=h") (mod:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT && optimize" - "ddiv\\t$0,%1,%2" + "TARGET_64BIT" + { return mips_output_division ("ddiv\\t$0,%1,%2", operands); } [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_expand "udivmodsi4" - [(set (match_operand:SI 0 "register_operand" "") - (udiv:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" ""))) - (set (match_operand:SI 3 "register_operand" "") - (umod:SI (match_dup 1) - (match_dup 2)))] - "optimize" - " -{ - emit_insn (gen_udivmodsi4_internal (operands[0], operands[1], operands[2], - operands[3])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") + (set_attr "mode" "DI")]) -(define_insn "udivmodsi4_internal" +(define_insn "udivmodsi4" [(set (match_operand:SI 0 "register_operand" "=l") (udiv:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "register_operand" "d"))) (set (match_operand:SI 3 "register_operand" "=h") (umod:SI (match_dup 1) (match_dup 2)))] - "optimize" - "divu\\t$0,%1,%2" + "" + { return mips_output_division ("divu\\t$0,%1,%2", operands); } [(set_attr "type" "idiv") (set_attr "mode" "SI")]) -(define_expand "udivmoddi4" - [(set (match_operand:DI 0 "register_operand" "") - (udiv:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" ""))) - (set (match_operand:DI 3 "register_operand" "") - (umod:DI (match_dup 1) - (match_dup 2)))] - "TARGET_64BIT && optimize" - " -{ - emit_insn (gen_udivmoddi4_internal (operands[0], operands[1], operands[2], - operands[3])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") - -(define_insn "udivmoddi4_internal" +(define_insn "udivmoddi4" [(set (match_operand:DI 0 "register_operand" "=l") (udiv:DI (match_operand:DI 1 "register_operand" "d") (match_operand:DI 2 "register_operand" "d"))) (set (match_operand:DI 3 "register_operand" "=h") (umod:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT && optimize" - "ddivu\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -;; Division trap - -(define_expand "div_trap" - [(trap_if (eq (match_operand 0 "register_operand" "d") - (match_operand 1 "true_reg_or_0_operand" "dJ")) - (match_operand 2 "immediate_operand" ""))] - "" - " -{ - if (TARGET_MIPS16) - emit_insn (gen_div_trap_mips16 (operands[0],operands[1],operands[2])); - else - emit_insn (gen_div_trap_normal (operands[0],operands[1],operands[2])); - DONE; -}") - -(define_insn "div_trap_normal" - [(trap_if (eq (match_operand 0 "register_operand" "d,d") - (match_operand 1 "true_reg_or_0_operand" "d,J")) - (match_operand 2 "immediate_operand" ""))] - "!TARGET_MIPS16" - "* -{ - rtx link; - int have_dep_anti = 0; - - /* For divmod if one division is not needed then we don't need an extra - divide by zero trap, which is anti dependent on previous trap */ - for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) - - if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link) - && GET_CODE (XEXP (link, 0)) == INSN - && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF - && which_alternative == 1) - have_dep_anti = 1; - if (! have_dep_anti) - { - if (GENERATE_BRANCHLIKELY) - { - if (which_alternative == 1) - return \"%(beql\\t%0,$0,1f\\n\\tbreak\\t%2\\n%~1:%)\"; - else - return \"%(beql\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\"; - } - else - { - if (which_alternative == 1) - return \"%(bne\\t%0,$0,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\"; - else - return \"%(bne\\t%0,%1,1f\\n\\tnop\\n\\tbreak\\t%2\\n%~1:%)\"; - } - } - return \"\"; -}" - [(set_attr "type" "unknown") - (set_attr "length" "12")]) - - -;; The mips16 bne insns is a macro which uses reg 24 as an intermediate. - -(define_insn "div_trap_mips16" - [(trap_if (eq (match_operand 0 "register_operand" "d,d") - (match_operand 1 "true_reg_or_0_operand" "d,J")) - (match_operand 2 "immediate_operand" "")) - (clobber (reg:SI 24))] - "TARGET_MIPS16" - "* -{ - rtx link; - int have_dep_anti = 0; - - /* For divmod if one division is not needed then we don't need an extra - divide by zero trap, which is anti dependent on previous trap */ - for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) - - if ((int) REG_DEP_ANTI == (int) REG_NOTE_KIND (link) - && GET_CODE (XEXP (link, 0)) == INSN - && GET_CODE (PATTERN (XEXP (link, 0))) == TRAP_IF - && which_alternative == 1) - have_dep_anti = 1; - if (! have_dep_anti) - { - /* No branch delay slots on mips16. */ - if (which_alternative == 1) - return \"%(bnez\\t%0,1f\\n\\tbreak\\t%2\\n%~1:%)\"; - else - return \"%(bne\\t%0,%1,1f\\n\\tbreak\\t%2\\n%~1:%)\"; - } - return \"\"; -}" - [(set_attr "type" "unknown") - (set_attr "length" "12")]) - -(define_expand "divsi3" - [(set (match_operand:SI 0 "register_operand" "") - (div:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "!optimize" - " -{ - emit_insn (gen_divsi3_internal (operands[0], operands[1], operands[2])); - - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, - GEN_INT - (trunc_int_for_mode - (BITMASK_HIGH, SImode))), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "divsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=l") - (div:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=h"))] - "!optimize" - "div\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_expand "divdi3" - [(set (match_operand:DI 0 "register_operand" "") - (div:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT && !optimize" - " -{ - emit_insn (gen_divdi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, - GEN_INT (BITMASK_HIGH)), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "divdi3_internal" - [(set (match_operand:DI 0 "register_operand" "=l") - (div:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=h"))] - "TARGET_64BIT && !optimize" - "ddiv\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "DI")]) - -(define_expand "modsi3" - [(set (match_operand:SI 0 "register_operand" "") - (mod:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "!optimize" - " -{ - emit_insn (gen_modsi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (SImode, - GEN_INT - (trunc_int_for_mode - (BITMASK_HIGH, SImode))), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "modsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=h") - (mod:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=l"))] - "!optimize" - "div\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_expand "moddi3" - [(set (match_operand:DI 0 "register_operand" "") - (mod:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT && !optimize" - " -{ - emit_insn (gen_moddi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - if (TARGET_CHECK_RANGE_DIV) - { - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, GEN_INT (-1)), - GEN_INT (0x6))); - emit_insn (gen_div_trap (operands[2], - copy_to_mode_reg (DImode, - GEN_INT (BITMASK_HIGH)), - GEN_INT (0x6))); - } - - DONE; -}") - -(define_insn "moddi3_internal" - [(set (match_operand:DI 0 "register_operand" "=h") - (mod:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=l"))] - "TARGET_64BIT && !optimize" - "ddiv\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "DI")]) - -(define_expand "udivsi3" - [(set (match_operand:SI 0 "register_operand" "") - (udiv:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "!optimize" - " -{ - emit_insn (gen_udivsi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") - -(define_insn "udivsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=l") - (udiv:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=h"))] - "!optimize" - "divu\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_expand "udivdi3" - [(set (match_operand:DI 0 "register_operand" "") - (udiv:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT && !optimize" - " -{ - emit_insn (gen_udivdi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") - -(define_insn "udivdi3_internal" - [(set (match_operand:DI 0 "register_operand" "=l") - (udiv:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=h"))] - "TARGET_64BIT && !optimize" - "ddivu\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "DI")]) - -(define_expand "umodsi3" - [(set (match_operand:SI 0 "register_operand" "") - (umod:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "register_operand" "")))] - "!optimize" - " -{ - emit_insn (gen_umodsi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") - -(define_insn "umodsi3_internal" - [(set (match_operand:SI 0 "register_operand" "=h") - (umod:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=l"))] - "!optimize" - "divu\\t$0,%1,%2" - [(set_attr "type" "idiv") - (set_attr "mode" "SI")]) - -(define_expand "umoddi3" - [(set (match_operand:DI 0 "register_operand" "") - (umod:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "register_operand" "")))] - "TARGET_64BIT && !optimize" - " -{ - emit_insn (gen_umoddi3_internal (operands[0], operands[1], operands[2])); - if (!TARGET_NO_CHECK_ZERO_DIV) - { - emit_insn (gen_div_trap (operands[2], - GEN_INT (0), - GEN_INT (0x7))); - } - - DONE; -}") - -(define_insn "umoddi3_internal" - [(set (match_operand:DI 0 "register_operand" "=h") - (umod:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "d"))) - (clobber (match_scratch:SI 3 "=l"))] - "TARGET_64BIT && !optimize" - "ddivu\\t$0,%1,%2" + "TARGET_64BIT" + { return mips_output_division ("ddivu\\t$0,%1,%2", operands); } [(set_attr "type" "idiv") (set_attr "mode" "DI")]) - ;; ;; .................... ;; -- 2.30.2