\f
;; 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" "")
{
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