Commit dbe3df29 by Richard Kenner

(float{,uns}sidf2): Rewrite to break the conversion process into several general insns.

(float{,uns}sidf2): Rewrite to break the conversion process into several
general insns.
(move_to_float): New insns to move 2 integer regs into a float
register through memory, taking endianess into account.  Make sure
that the floating temporary is a valid address.  Use one temporary for
all floats converted.
(fix_truncdfsi2): Take endianess into account.

From-SVN: r10480
parent 39b751ce
......@@ -3324,98 +3324,88 @@
;; Conversions to and from floating-point.
(define_expand "floatsidf2"
[(set (match_dup 2)
(plus:DI (zero_extend:DI
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_dup 3)))
(match_dup 4)))
(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (subreg:DF (match_dup 2) 0)
(match_dup 5)))]
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"
{
operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_rtx (CONST_INT, VOIDmode, 0x80000000);
operands[4] = rs6000_immed_double_const (0, 0x43300000, DImode);
operands[5] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
if (operands[0])
{ /* prevent unused warning messages */
rtx high = force_reg (SImode, GEN_INT (0x43300000));
rtx low = gen_reg_rtx (SImode);
rtx df = gen_reg_rtx (DFmode);
rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
emit_insn (gen_xorsi3 (low, operands[1], GEN_INT (0x80000000)));
emit_insn (gen_move_to_float (df, low, high));
emit_insn (gen_subdf3 (operands[0], df, adjust));
DONE;
}
}")
(define_expand "floatunssidf2"
[(set (match_dup 2)
(plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(match_dup 3)))
(set (match_operand:DF 0 "gpc_reg_operand" "")
(minus:DF (subreg:DF (match_dup 2) 0)
(match_dup 4)))]
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"
{
operands[2] = gen_reg_rtx (DImode);
operands[3] = rs6000_immed_double_const (0, 0x43300000, DImode);
operands[4] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
if (operands[0])
{ /* prevent unused warning messages */
rtx high = force_reg (SImode, GEN_INT (0x43300000));
rtx df = gen_reg_rtx (DFmode);
rtx adjust = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
emit_insn (gen_move_to_float (df, operands[1], high));
emit_insn (gen_subdf3 (operands[0], df, adjust));
DONE;
}
}")
;; For the above two cases, we always split.
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "")
(plus:DI (zero_extend:DI
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "logical_operand" "")))
(match_operand:DI 3 "low_32_bit_operand" "")))]
"reload_completed"
[(set (match_dup 6) (xor:SI (match_dup 1) (match_dup 2)))
(set (match_dup 4) (match_dup 5))]
(define_expand "move_to_float"
[(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
(unspec [(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")] 2))
(clobber (match_dup 3))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"
{ operands[4] = operand_subword (operands[0], 0, 0, DImode);
operands[5] = operand_subword (operands[3], 0, 0, DImode);
operands[6] = operand_subword (operands[0], 1, 0, DImode);
}")
{
if (float_conv_temp == NULL_RTX)
{
float_conv_temp = assign_stack_local (DFmode, 8, 0);
if (!offsettable_mem_operand (float_conv_temp, DFmode))
XEXP (float_conv_temp, 0) = copy_addr_to_reg (XEXP (float_conv_temp, 0));
}
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(plus:DI (zero_extend:DI
(xor:SI (match_operand:SI 1 "gpc_reg_operand" "%r")
(match_operand:SI 2 "logical_operand" "rKJ")))
(match_operand:DI 3 "low_32_bit_operand" "n")))]
""
"#"
[(set_attr "length" "8")])
operands[3] = float_conv_temp;
}")
(define_split
[(set (match_operand:DI 0 "gpc_reg_operand" "=")
(plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" ""))
(match_operand:DI 2 "low_32_bit_operand" "")))]
[(set (match_operand:DF 0 "gpc_reg_operand" "")
(unspec [(match_operand:SI 1 "gpc_reg_operand" "")
(match_operand:SI 2 "gpc_reg_operand" "")] 2))
(clobber (match_operand:DF 3 "offsettable_mem_operand" ""))]
"reload_completed"
[(set (match_dup 3) (match_dup 4))
(set (match_dup 5) (match_dup 1))]
[(set (match_dup 4) (match_dup 1))
(set (match_dup 5) (match_dup 2))
(set (match_dup 0) (match_dup 3))]
"
{ operands[3] = operand_subword (operands[0], 0, 0, DImode);
operands[4] = operand_subword (operands[2], 0, 0, DImode);
operands[5] = operand_subword (operands[0], 1, 0, DImode);
if (rtx_equal_p (operands[1], operands[5]))
{
emit_move_insn (operands[3], operands[4]);
DONE;
}
if (rtx_equal_p (operands[1], operands[3]))
{
rtx temp;
{
int little = (WORDS_BIG_ENDIAN == 0);
operands[4] = operand_subword (operands[3], 1 - little, 0, DFmode);
operands[5] = operand_subword (operands[3], little, 0, DFmode);
temp = operands[3]; operands[3] = operands[5]; operands[5] = temp;
temp = operands[4]; operands[4] = operands[1]; operands[1] = temp;
}
MEM_IN_STRUCT_P (operands[4]) = 1;
MEM_IN_STRUCT_P (operands[5]) = 1;
}")
(define_insn ""
[(set (match_operand:DI 0 "gpc_reg_operand" "=r")
(plus:DI (zero_extend:DI (match_operand:SI 1 "gpc_reg_operand" "r"))
(match_operand:DI 2 "low_32_bit_operand" "n")))]
""
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec [(match_operand:SI 1 "gpc_reg_operand" "r")
(match_operand:SI 2 "gpc_reg_operand" "r")] 2))
(clobber (match_operand:DF 3 "offsettable_mem_operand" "=o"))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"#"
[(set_attr "length" "8")])
[(set_attr "length" "12")])
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "gpc_reg_operand" "")
......@@ -3425,13 +3415,14 @@
{
if (TARGET_POWER2 || TARGET_POWERPC)
{
rtx stack_slot = assign_stack_temp (DImode, 8, 0),
temp = gen_reg_rtx (DImode);
int endian = (WORDS_BIG_ENDIAN == 0);
rtx stack_slot = assign_stack_temp (DImode, 8, 0);
rtx temp = gen_reg_rtx (DImode);
emit_insn (gen_fpcvtsi (temp, operands[1]));
emit_move_insn (stack_slot, temp);
emit_move_insn (operands[0],
operand_subword (stack_slot, 1, 0, DImode));
operand_subword (stack_slot, 1 - endian, 0, DImode));
DONE;
}
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment