]> gcc.gnu.org Git - gcc.git/commitdiff
(float{,uns}sidf2): Rewrite to break the conversion process into several general...
authorRichard Kenner <kenner@gcc.gnu.org>
Thu, 19 Oct 1995 23:27:43 +0000 (19:27 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Thu, 19 Oct 1995 23:27:43 +0000 (19:27 -0400)
(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

index 55c0273cc6886e81e5159d6a6f5d0ed86a2a0946..7851358e081c956653c6948223d3e3d2fa3998e4 100644 (file)
 \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
This page took 0.088919 seconds and 5 git commands to generate.