mips.c (mips_expand_prologue): Use a single insn to allocate 32768 bytes of stack.
* 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. From-SVN: r69357
This commit is contained in:
parent
3485245e16
commit
121d69e69a
|
@ -1,3 +1,15 @@
|
||||||
|
2003-07-14 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
|
* 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 <rsandifo@redhat.com>
|
2003-07-14 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
* config/mips/mips.c (mips_in_small_data_p): Don't handle
|
* config/mips/mips.c (mips_in_small_data_p): Don't handle
|
||||||
|
|
|
@ -7424,27 +7424,24 @@ mips_expand_prologue ()
|
||||||
{
|
{
|
||||||
rtx tsize_rtx = GEN_INT (tsize);
|
rtx tsize_rtx = GEN_INT (tsize);
|
||||||
|
|
||||||
/* If we are doing svr4-abi, sp move is done by
|
/* In mips16 mode with a large frame, we save the registers before
|
||||||
function_prologue. In mips16 mode with a large frame, we
|
adjusting the stack. */
|
||||||
save the registers before adjusting the stack. */
|
if (!TARGET_MIPS16 || tsize <= 32768)
|
||||||
if (!TARGET_MIPS16 || tsize <= 32767)
|
|
||||||
{
|
{
|
||||||
rtx adjustment_rtx;
|
if (tsize > 32768)
|
||||||
|
|
||||||
if (tsize > 32767)
|
|
||||||
{
|
{
|
||||||
|
rtx adjustment_rtx;
|
||||||
|
|
||||||
adjustment_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
|
adjustment_rtx = gen_rtx (REG, Pmode, MIPS_TEMP1_REGNUM);
|
||||||
emit_move_insn (adjustment_rtx, tsize_rtx);
|
emit_move_insn (adjustment_rtx, tsize_rtx);
|
||||||
|
emit_insn (gen_sub3_insn (stack_pointer_rtx,
|
||||||
|
stack_pointer_rtx,
|
||||||
|
adjustment_rtx));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
adjustment_rtx = tsize_rtx;
|
emit_insn (gen_add3_insn (stack_pointer_rtx,
|
||||||
|
stack_pointer_rtx,
|
||||||
if (Pmode == DImode)
|
GEN_INT (-tsize)));
|
||||||
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));
|
|
||||||
|
|
||||||
mips_set_frame_expr
|
mips_set_frame_expr
|
||||||
(gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
(gen_rtx_SET (VOIDmode, stack_pointer_rtx,
|
||||||
|
@ -7460,7 +7457,7 @@ mips_expand_prologue ()
|
||||||
emit_insn (gen_cprestore
|
emit_insn (gen_cprestore
|
||||||
(GEN_INT (current_function_outgoing_args_size)));
|
(GEN_INT (current_function_outgoing_args_size)));
|
||||||
|
|
||||||
if (TARGET_MIPS16 && tsize > 32767)
|
if (TARGET_MIPS16 && tsize > 32768)
|
||||||
{
|
{
|
||||||
rtx reg_rtx;
|
rtx reg_rtx;
|
||||||
|
|
||||||
|
@ -7470,14 +7467,9 @@ mips_expand_prologue ()
|
||||||
reg_rtx = gen_rtx (REG, Pmode, 3);
|
reg_rtx = gen_rtx (REG, Pmode, 3);
|
||||||
emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
|
||||||
emit_move_insn (reg_rtx, tsize_rtx);
|
emit_move_insn (reg_rtx, tsize_rtx);
|
||||||
if (Pmode == DImode)
|
emit_insn (gen_sub3_insn (hard_frame_pointer_rtx,
|
||||||
emit_insn (gen_subdi3 (hard_frame_pointer_rtx,
|
hard_frame_pointer_rtx,
|
||||||
hard_frame_pointer_rtx,
|
reg_rtx));
|
||||||
reg_rtx));
|
|
||||||
else
|
|
||||||
emit_insn (gen_subsi3 (hard_frame_pointer_rtx,
|
|
||||||
hard_frame_pointer_rtx,
|
|
||||||
reg_rtx));
|
|
||||||
emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
|
emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1250,153 +1250,21 @@
|
||||||
(set_attr "mode" "SF")])
|
(set_attr "mode" "SF")])
|
||||||
|
|
||||||
(define_expand "subsi3"
|
(define_expand "subsi3"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
[(set (match_operand:SI 0 "register_operand" "")
|
||||||
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
|
(minus:SI (match_operand:SI 1 "register_operand" "")
|
||||||
(match_operand:SI 2 "arith_operand" "dI")))]
|
(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"
|
(define_insn "subsi3_internal"
|
||||||
[(set (match_operand:SI 0 "register_operand" "=d")
|
[(set (match_operand:SI 0 "register_operand" "=d")
|
||||||
(minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
|
(minus:SI (match_operand:SI 1 "register_operand" "d")
|
||||||
(match_operand:SI 2 "arith_operand" "dI")))]
|
(match_operand:SI 2 "register_operand" "d")))]
|
||||||
"!TARGET_MIPS16
|
""
|
||||||
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
|
|
||||||
"subu\\t%0,%z1,%2"
|
"subu\\t%0,%z1,%2"
|
||||||
[(set_attr "type" "arith")
|
[(set_attr "type" "arith")
|
||||||
(set_attr "mode" "SI")])
|
(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"
|
(define_expand "subdi3"
|
||||||
[(parallel [(set (match_operand:DI 0 "register_operand" "=d")
|
[(parallel [(set (match_operand:DI 0 "register_operand" "=d")
|
||||||
(minus:DI (match_operand:DI 1 "register_operand" "d")
|
(minus:DI (match_operand:DI 1 "register_operand" "d")
|
||||||
|
@ -1482,247 +1350,24 @@
|
||||||
(match_dup 3)))]
|
(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"
|
(define_insn "subdi3_internal_3"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=d")
|
[(set (match_operand:DI 0 "register_operand" "=d")
|
||||||
(minus:DI (match_operand:DI 1 "reg_or_0_operand" "dJ")
|
(minus:DI (match_operand:DI 1 "register_operand" "d")
|
||||||
(match_operand:DI 2 "arith_operand" "dI")))]
|
(match_operand:DI 2 "register_operand" "d")))]
|
||||||
"TARGET_64BIT && !TARGET_MIPS16
|
"TARGET_64BIT"
|
||||||
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
|
"dsubu\\t%0,%1,%2"
|
||||||
"*
|
|
||||||
{
|
|
||||||
return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
|
|
||||||
? \"daddu\\t%0,%z1,%n2\"
|
|
||||||
: \"dsubu\\t%0,%z1,%2\";
|
|
||||||
}"
|
|
||||||
[(set_attr "type" "darith")
|
[(set_attr "type" "darith")
|
||||||
(set_attr "mode" "DI")])
|
(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"
|
(define_insn "subsi3_internal_2"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=d")
|
[(set (match_operand:DI 0 "register_operand" "=d")
|
||||||
(sign_extend:DI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "dJ")
|
(sign_extend:DI
|
||||||
(match_operand:SI 2 "arith_operand" "dI"))))]
|
(minus:SI (match_operand:SI 1 "register_operand" "d")
|
||||||
"TARGET_64BIT && !TARGET_MIPS16
|
(match_operand:SI 2 "register_operand" "d"))))]
|
||||||
&& (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) != -32768)"
|
"TARGET_64BIT"
|
||||||
"*
|
"subu\t%0,%1,%2"
|
||||||
{
|
|
||||||
return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
|
|
||||||
? \"addu\\t%0,%z1,%n2\"
|
|
||||||
: \"subu\\t%0,%z1,%2\";
|
|
||||||
}"
|
|
||||||
[(set_attr "type" "arith")
|
[(set_attr "type" "arith")
|
||||||
(set_attr "mode" "DI")])
|
(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"
|
(define_expand "casesi"
|
||||||
[(set (match_dup 5)
|
[(set (match_dup 5)
|
||||||
(minus:SI (match_operand:SI 0 "register_operand" "d")
|
(minus:SI (match_operand:SI 0 "register_operand" "")
|
||||||
(match_operand:SI 1 "arith_operand" "dI")))
|
(match_operand:SI 1 "const_int_operand" "")))
|
||||||
(set (cc0)
|
(set (cc0)
|
||||||
(compare:CC (match_dup 5)
|
(compare:CC (match_dup 5)
|
||||||
(match_operand:SI 2 "arith_operand" "")))
|
(match_operand:SI 2 "arith_operand" "")))
|
||||||
|
@ -8562,19 +8207,20 @@ move\\t%0,%z4\\n\\
|
||||||
{
|
{
|
||||||
if (operands[0])
|
if (operands[0])
|
||||||
{
|
{
|
||||||
rtx reg = gen_reg_rtx (SImode);
|
rtx index;
|
||||||
|
|
||||||
/* If the index is too large, go to the default label. */
|
/* If the index is too large, go to the default label. */
|
||||||
emit_insn (gen_subsi3 (reg, operands[0], operands[1]));
|
index = expand_binop (SImode, sub_optab, operands[0],
|
||||||
emit_insn (gen_cmpsi (reg, operands[2]));
|
operands[1], 0, 0, OPTAB_WIDEN);
|
||||||
|
emit_insn (gen_cmpsi (index, operands[2]));
|
||||||
emit_insn (gen_bgtu (operands[4]));
|
emit_insn (gen_bgtu (operands[4]));
|
||||||
|
|
||||||
/* Do the PIC jump. */
|
/* Do the PIC jump. */
|
||||||
if (Pmode != DImode)
|
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)));
|
gen_reg_rtx (SImode)));
|
||||||
else
|
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)));
|
gen_reg_rtx (DImode)));
|
||||||
|
|
||||||
DONE;
|
DONE;
|
||||||
|
|
Loading…
Reference in New Issue