From dbe3df294330ee9d910328cece3578589daf0972 Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Thu, 19 Oct 1995 19:27:43 -0400 Subject: [PATCH] (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 --- gcc/config/rs6000/rs6000.md | 137 +++++++++++++++++------------------- 1 file changed, 64 insertions(+), 73 deletions(-) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 55c0273cc68..7851358e081 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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 -- 2.30.2