diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 76e3fc11303..accf42b8630 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2003-07-14 Richard Sandiford + + * config/mips/mips.c (mips_expand_prologue): Use a single insn to + allocate 32768 bytes of stack. Use addition rather than subtraction + when a single insn is enough. + * config/mips/mips.md: Remove insns and splitters for subtracting + constants. + (subsi3): Only accept register operands. + (subsi3_internal): Likewise. Use for TARGET_MIPS16 as well. + (subdi3_internal_3, subsi3_internal_2): Likewise. + (casesi): Use expand_binop to subtract the lower bound. + 2003-07-14 Richard Sandiford * config/mips/mips.c (mips_in_small_data_p): Don't handle diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index bb52f5ccd91..5e069b789a1 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -7424,27 +7424,24 @@ mips_expand_prologue () { rtx tsize_rtx = GEN_INT (tsize); - /* If we are doing svr4-abi, sp move is done by - function_prologue. In mips16 mode with a large frame, we - save the registers before adjusting the stack. */ - if (!TARGET_MIPS16 || tsize <= 32767) + /* In mips16 mode with a large frame, we save the registers before + adjusting the stack. */ + if (!TARGET_MIPS16 || tsize <= 32768) { - rtx adjustment_rtx; - - if (tsize > 32767) + if (tsize > 32768) { + rtx adjustment_rtx; + adjustment_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM); emit_move_insn (adjustment_rtx, tsize_rtx); + emit_insn (gen_sub3_insn (stack_pointer_rtx, + stack_pointer_rtx, + adjustment_rtx)); } else - adjustment_rtx = tsize_rtx; - - if (Pmode == DImode) - emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, - adjustment_rtx)); - else - emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, - adjustment_rtx)); + emit_insn (gen_add3_insn (stack_pointer_rtx, + stack_pointer_rtx, + GEN_INT (-tsize))); mips_set_frame_expr (gen_rtx_SET (VOIDmode, stack_pointer_rtx, @@ -7460,7 +7457,7 @@ mips_expand_prologue () emit_insn (gen_cprestore (GEN_INT (current_function_outgoing_args_size))); - if (TARGET_MIPS16 && tsize > 32767) + if (TARGET_MIPS16 && tsize > 32768) { rtx reg_rtx; @@ -7470,14 +7467,9 @@ mips_expand_prologue () reg_rtx = gen_rtx (REG, Pmode, 3); emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); emit_move_insn (reg_rtx, tsize_rtx); - if (Pmode == DImode) - emit_insn (gen_subdi3 (hard_frame_pointer_rtx, - hard_frame_pointer_rtx, - reg_rtx)); - else - emit_insn (gen_subsi3 (hard_frame_pointer_rtx, - hard_frame_pointer_rtx, - reg_rtx)); + emit_insn (gen_sub3_insn (hard_frame_pointer_rtx, + hard_frame_pointer_rtx, + reg_rtx)); emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); } diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md index 0be11733250..d30f4690e2f 100644 --- a/gcc/config/mips/mips.md +++ b/gcc/config/mips/mips.md @@ -1250,153 +1250,21 @@ (set_attr "mode" "SF")]) (define_expand "subsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI")))] + [(set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "register_operand" "")))] "" - " -{ - if (GET_CODE (operands[2]) == CONST_INT - && (INTVAL (operands[2]) == -32768 - || (TARGET_MIPS16 - && INTVAL (operands[2]) == -0x4000))) - operands[2] = force_reg (SImode, operands[2]); -}") + "") (define_insn "subsi3_internal" [(set (match_operand:SI 0 "register_operand" "=d") - (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI")))] - "!TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" + (minus:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d")))] + "" "subu\\t%0,%z1,%2" [(set_attr "type" "arith") (set_attr "mode" "SI")]) -;; For the mips16, we need to recognize stack pointer subtractions -;; explicitly, since we don't have a constraint for $sp. These insns -;; will be generated by the save_restore_insns functions. - -(define_insn "" - [(set (reg:SI 29) - (minus:SI (reg:SI 29) - (match_operand:SI 0 "small_int" "I")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "addu\\t%$,%$,%n0" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "") - (const_int 4) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d") - (minus:SI (reg:SI 29) - (match_operand:SI 1 "small_int" "I")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "addu\\t%0,%$,%n1" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set (attr "length") (if_then_else (match_operand:VOID 1 "m16_nuimm8_4" "") - (const_int 4) - (const_int 8)))]) - - -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (minus:SI (match_operand:SI 1 "register_operand" "0,d,d") - (match_operand:SI 2 "arith_operand" "I,O,d")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT - || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"subu\\t%0,%2\"; - return \"subu\\t%0,%1,%2\"; -}" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set_attr_alternative "length" - [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") - (const_int 4) - (const_int 8)) - (const_int 4)])]) - -;; On the mips16, we can sometimes split a subtract of a constant -;; which is a 4 byte instruction into two adds which are both 2 byte -;; instructions. There are two cases: one where we are setting a -;; register to a register minus a constant, and one where we are -;; simply subtracting a constant from a register. - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_dup 0) - (match_operand:SI 1 "const_int_operand" "")))] - "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE - && GET_CODE (operands[0]) == REG - && M16_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == CONST_INT - && ((INTVAL (operands[1]) > 0x80 - && INTVAL (operands[1]) <= 0x80 + 0x80) - || (INTVAL (operands[1]) < - 0x7f - && INTVAL (operands[1]) >= - 0x7f - 0x7f))" - [(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 1))) - (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 2)))] - " -{ - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (val >= 0) - { - operands[1] = GEN_INT (0x80); - operands[2] = GEN_INT (val - 0x80); - } - else - { - operands[1] = GEN_INT (- 0x7f); - operands[2] = GEN_INT (val + 0x7f); - } -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 1 "register_operand" "") - (match_operand:SI 2 "const_int_operand" "")))] - "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE - && GET_CODE (operands[0]) == REG - && M16_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG - && M16_REG_P (REGNO (operands[1])) - && REGNO (operands[0]) != REGNO (operands[1]) - && GET_CODE (operands[2]) == CONST_INT - && ((INTVAL (operands[2]) > 0x8 - && INTVAL (operands[2]) <= 0x8 + 0x80) - || (INTVAL (operands[2]) < - 0x7 - && INTVAL (operands[2]) >= - 0x7 - 0x7f))" - [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:SI (match_dup 0) (match_dup 3)))] - " -{ - HOST_WIDE_INT val = INTVAL (operands[2]); - - if (val >= 0) - { - operands[2] = GEN_INT (0x8); - operands[3] = GEN_INT (val - 0x8); - } - else - { - operands[2] = GEN_INT (- 0x7); - operands[3] = GEN_INT (val + 0x7); - } -}") - (define_expand "subdi3" [(parallel [(set (match_operand:DI 0 "register_operand" "=d") (minus:DI (match_operand:DI 1 "register_operand" "d") @@ -1482,247 +1350,24 @@ (match_dup 3)))] "") -(define_insn "subdi3_internal_2" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (minus:DI (match_operand:DI 1 "register_operand" "d,d,d") - (match_operand:DI 2 "small_int" "P,J,N"))) - (clobber (match_operand:SI 3 "register_operand" "=d,d,d"))] - "!TARGET_64BIT && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 - && INTVAL (operands[2]) != -32768" - "@ - sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,%3 - move\\t%L0,%L1\;move\\t%M0,%M1 - sltu\\t%3,%L1,%2\;subu\\t%L0,%L1,%2\;subu\\t%M0,%M1,1\;subu\\t%M0,%M0,%3" - [(set_attr "type" "darith") - (set_attr "mode" "DI") - (set_attr "length" "12,8,16")]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "small_int" ""))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "reload_completed && !WORDS_BIG_ENDIAN && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && INTVAL (operands[2]) > 0" - - [(set (match_dup 3) - (ltu:SI (subreg:SI (match_dup 1) 0) - (match_dup 2))) - - (set (subreg:SI (match_dup 0) 0) - (minus:SI (subreg:SI (match_dup 1) 0) - (match_dup 2))) - - (set (subreg:SI (match_dup 0) 4) - (minus:SI (subreg:SI (match_dup 1) 4) - (match_dup 3)))] - "") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "small_int" ""))) - (clobber (match_operand:SI 3 "register_operand" ""))] - "reload_completed && WORDS_BIG_ENDIAN && !TARGET_64BIT - && !TARGET_DEBUG_D_MODE && !TARGET_DEBUG_G_MODE && !TARGET_MIPS16 - && GET_CODE (operands[0]) == REG && GP_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG && GP_REG_P (REGNO (operands[1])) - && INTVAL (operands[2]) > 0" - - [(set (match_dup 3) - (ltu:SI (subreg:SI (match_dup 1) 4) - (match_dup 2))) - - (set (subreg:SI (match_dup 0) 4) - (minus:SI (subreg:SI (match_dup 1) 4) - (match_dup 2))) - - (set (subreg:SI (match_dup 0) 0) - (minus:SI (subreg:SI (match_dup 1) 0) - (match_dup 3)))] - "") - (define_insn "subdi3_internal_3" [(set (match_operand:DI 0 "register_operand" "=d") - (minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ") - (match_operand:DI 2 "arith_operand" "dI")))] - "TARGET_64BIT && !TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "* -{ - return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - ? \"daddu\\t%0,%z1,%n2\" - : \"dsubu\\t%0,%z1,%2\"; -}" + (minus:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] + "TARGET_64BIT" + "dsubu\\t%0,%1,%2" [(set_attr "type" "darith") (set_attr "mode" "DI")]) -;; For the mips16, we need to recognize stack pointer subtractions -;; explicitly, since we don't have a constraint for $sp. These insns -;; will be generated by the save_restore_insns functions. - -(define_insn "" - [(set (reg:DI 29) - (minus:DI (reg:DI 29) - (match_operand:DI 0 "small_int" "I")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "daddu\\t%$,%$,%n0" - [(set_attr "type" "arith") - (set_attr "mode" "DI") - (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nsimm8_8" "") - (const_int 4) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d") - (minus:DI (reg:DI 29) - (match_operand:DI 1 "small_int" "I")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "daddu\\t%0,%$,%n1" - [(set_attr "type" "arith") - (set_attr "mode" "DI") - (set (attr "length") (if_then_else (match_operand:VOID 0 "m16_nuimm5_4" "") - (const_int 4) - (const_int 8)))]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (minus:DI (match_operand:DI 1 "register_operand" "0,d,d") - (match_operand:DI 2 "arith_operand" "I,O,d")))] - "TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT - || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"dsubu\\t%0,%2\"; - return \"dsubu\\t%0,%1,%2\"; -}" - [(set_attr "type" "arith") - (set_attr "mode" "DI") - (set_attr_alternative "length" - [(if_then_else (match_operand:VOID 2 "m16_nsimm5_1" "") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") - (const_int 4) - (const_int 8)) - (const_int 4)])]) - -;; On the mips16, we can sometimes split an add of a constant which is -;; a 4 byte instruction into two adds which are both 2 byte -;; instructions. There are two cases: one where we are adding a -;; constant plus a register to another register, and one where we are -;; simply adding a constant to a register. - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_dup 0) - (match_operand:DI 1 "const_int_operand" "")))] - "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE - && GET_CODE (operands[0]) == REG - && M16_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == CONST_INT - && ((INTVAL (operands[1]) > 0x10 - && INTVAL (operands[1]) <= 0x10 + 0x10) - || (INTVAL (operands[1]) < - 0xf - && INTVAL (operands[1]) >= - 0xf - 0xf))" - [(set (match_dup 0) (minus:DI (match_dup 0) (match_dup 1))) - (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 2)))] - " -{ - HOST_WIDE_INT val = INTVAL (operands[1]); - - if (val >= 0) - { - operands[1] = GEN_INT (0xf); - operands[2] = GEN_INT (val - 0xf); - } - else - { - operands[1] = GEN_INT (- 0x10); - operands[2] = GEN_INT (val + 0x10); - } -}") - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "const_int_operand" "")))] - "TARGET_MIPS16 && TARGET_64BIT && reload_completed && !TARGET_DEBUG_D_MODE - && GET_CODE (operands[0]) == REG - && M16_REG_P (REGNO (operands[0])) - && GET_CODE (operands[1]) == REG - && M16_REG_P (REGNO (operands[1])) - && REGNO (operands[0]) != REGNO (operands[1]) - && GET_CODE (operands[2]) == CONST_INT - && ((INTVAL (operands[2]) > 0x8 - && INTVAL (operands[2]) <= 0x8 + 0x10) - || (INTVAL (operands[2]) < - 0x7 - && INTVAL (operands[2]) >= - 0x7 - 0xf))" - [(set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2))) - (set (match_dup 0) (minus:DI (match_dup 0) (match_dup 3)))] - " -{ - HOST_WIDE_INT val = INTVAL (operands[2]); - - if (val >= 0) - { - operands[2] = GEN_INT (0x8); - operands[3] = GEN_INT (val - 0x8); - } - else - { - operands[2] = GEN_INT (- 0x7); - operands[3] = GEN_INT (val + 0x7); - } -}") - (define_insn "subsi3_internal_2" [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ") - (match_operand:SI 2 "arith_operand" "dI"))))] - "TARGET_64BIT && !TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)" - "* -{ - return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) - ? \"addu\\t%0,%z1,%n2\" - : \"subu\\t%0,%z1,%2\"; -}" + (sign_extend:DI + (minus:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "register_operand" "d"))))] + "TARGET_64BIT" + "subu\t%0,%1,%2" [(set_attr "type" "arith") (set_attr "mode" "DI")]) - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (sign_extend:DI (minus:SI (match_operand:SI 1 "register_operand" "0,d,d") - (match_operand:SI 2 "arith_operand" "I,O,d"))))] - "TARGET_64BIT && TARGET_MIPS16 - && (GET_CODE (operands[2]) != CONST_INT - || (INTVAL (operands[2]) != -32768 && INTVAL (operands[2]) != -0x4000))" - "* -{ - if (REGNO (operands[0]) == REGNO (operands[1])) - return \"subu\\t%0,%2\"; - return \"subu\\t%0,%1,%2\"; -}" - [(set_attr "type" "arith") - (set_attr "mode" "SI") - (set_attr_alternative "length" - [(if_then_else (match_operand:VOID 2 "m16_nsimm8_1" "") - (const_int 4) - (const_int 8)) - (if_then_else (match_operand:VOID 2 "m16_nsimm4_1" "") - (const_int 4) - (const_int 8)) - (const_int 4)])]) - - ;; ;; .................... @@ -8540,8 +8185,8 @@ move\\t%0,%z4\\n\\ (define_expand "casesi" [(set (match_dup 5) - (minus:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "arith_operand" "dI"))) + (minus:SI (match_operand:SI 0 "register_operand" "") + (match_operand:SI 1 "const_int_operand" ""))) (set (cc0) (compare:CC (match_dup 5) (match_operand:SI 2 "arith_operand" ""))) @@ -8562,19 +8207,20 @@ move\\t%0,%z4\\n\\ { if (operands[0]) { - rtx reg = gen_reg_rtx (SImode); + rtx index; /* If the index is too large, go to the default label. */ - emit_insn (gen_subsi3 (reg, operands[0], operands[1])); - emit_insn (gen_cmpsi (reg, operands[2])); + index = expand_binop (SImode, sub_optab, operands[0], + operands[1], 0, 0, OPTAB_WIDEN); + emit_insn (gen_cmpsi (index, operands[2])); emit_insn (gen_bgtu (operands[4])); /* Do the PIC jump. */ if (Pmode != DImode) - emit_jump_insn (gen_casesi_internal (reg, operands[3], + emit_jump_insn (gen_casesi_internal (index, operands[3], gen_reg_rtx (SImode))); else - emit_jump_insn (gen_casesi_internal_di (reg, operands[3], + emit_jump_insn (gen_casesi_internal_di (index, operands[3], gen_reg_rtx (DImode))); DONE;