diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-10-19 19:27:43 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-10-19 19:27:43 -0400 |
commit | dbe3df294330ee9d910328cece3578589daf0972 (patch) | |
tree | cd35e9bb7a71f20da8ae0753e5130c513329a8c7 /gcc/config/rs6000 | |
parent | 39b751ce5a6d74289963d38d1cbe6f0e3b65ea11 (diff) | |
download | gcc-dbe3df294330ee9d910328cece3578589daf0972.zip gcc-dbe3df294330ee9d910328cece3578589daf0972.tar.gz gcc-dbe3df294330ee9d910328cece3578589daf0972.tar.bz2 |
(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
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 137 |
1 files changed, 64 insertions, 73 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 55c0273..7851358 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 |