&& INTVAL (operands[2]) < 16
&& magic_milli[INTVAL (operands[2])])
{
+ rtx ret = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
+
emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
emit
(gen_rtx
gen_rtx_CLOBBER (VOIDmode, operands[3]),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 26)),
gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 25)),
- gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 31)))));
+ gen_rtx_CLOBBER (VOIDmode, ret))));
emit_move_insn (operands[0], gen_rtx_REG (SImode, 29));
return 1;
}
Millicode calls always expect their arguments in the integer argument
registers, and always return their result in %r29 (ret1). They
- are expected to clobber their arguments, %r1, %r29, and %r31 and
- nothing else.
-
- By considering this effects delayed reorg reorg can put insns
- which set the argument registers into the delay slot of the millicode
- call -- thus they act more like traditional CALL_INSNs.
+ are expected to clobber their arguments, %r1, %r29, and the return
+ pointer which is %r31 on 32-bit and %r2 on 64-bit, and nothing else.
+
+ This function tells reorg that the references to arguments and
+ millicode calls do not appear to happen until after the millicode call.
+ This allows reorg to put insns which set the argument registers into the
+ delay slot of the millicode call -- thus they act more like traditional
+ CALL_INSNs.
+
+ Note we can not consider side effects of the insn to be delayed because
+ the branch and link insn will clobber the return pointer. If we happened
+ to use the return pointer in the delay slot of the call, then we lose.
get_attr_type will try to recognize the given insn, so make sure to
filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
(clobber (match_dup 3))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 4))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
+ operands[4] = gen_rtx_REG (SImode, TARGET_64BIT ? 2 : 31);
if (TARGET_PA_11 && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
{
rtx scratch = gen_reg_rtx (DImode);
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"* return output_mul_insn (0, insn);"
[(set_attr "type" "milli")
(set (attr "length")
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "* return output_mul_insn (0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (match_operand:DI 1 "register_operand" "")
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
operands[3] = gen_reg_rtx (SImode);
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
DONE;
}")
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_div_insn (operands, 0, insn);"
[(set_attr "type" "milli")
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29)
+ (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+ (clobber (match_operand:SI 1 "register_operand" "=a"))
+ (clobber (match_operand:SI 2 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_div_insn (operands, 0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "udivsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
operands[3] = gen_reg_rtx (SImode);
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
DONE;
}")
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_div_insn (operands, 1, insn);"
[(set_attr "type" "milli")
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29)
+ (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
+ (clobber (match_operand:SI 1 "register_operand" "=a"))
+ (clobber (match_operand:SI 2 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_div_insn (operands, 1, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "modsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
operands[3] = gen_reg_rtx (SImode);
}")
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_mod_insn (0, insn);"
[(set_attr "type" "milli")
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (match_operand:SI 1 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_mod_insn (0, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
(define_expand "umodsi3"
[(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
(set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
(clobber (match_dup 4))
(clobber (reg:SI 26))
(clobber (reg:SI 25))
- (clobber (reg:SI 31))])
+ (clobber (match_dup 5))])
(set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
""
"
{
- operands[4] = gen_reg_rtx (SImode);
if (TARGET_64BIT)
- operands[4] = gen_rtx_REG (SImode, 2);
+ {
+ operands[5] = gen_rtx_REG (SImode, 2);
+ operands[4] = operands[5];
+ }
+ else
+ {
+ operands[5] = gen_rtx_REG (SImode, 31);
+ operands[4] = gen_reg_rtx (SImode);
+ }
operands[3] = gen_reg_rtx (SImode);
}")
(clobber (reg:SI 26))
(clobber (reg:SI 25))
(clobber (reg:SI 31))]
- ""
+ "!TARGET_64BIT"
"*
return output_mod_insn (1, insn);"
[(set_attr "type" "milli")
;; Out of reach, can use ble
(const_int 12)))])
+(define_insn ""
+ [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
+ (clobber (match_operand:SI 0 "register_operand" "=a"))
+ (clobber (match_operand:SI 1 "register_operand" "=&r"))
+ (clobber (reg:SI 26))
+ (clobber (reg:SI 25))
+ (clobber (reg:SI 2))]
+ "TARGET_64BIT"
+ "*
+ return output_mod_insn (1, insn);"
+ [(set_attr "type" "milli")
+ (set (attr "length") (const_int 4))])
+
;;- and instructions
;; We define DImode `and` so with DImode `not` we can get
;; DImode `andn`. Other combinations are possible.