OSDN Git Service

* arm/vfp.md (negsf2_vfp): Add alternative using integer registers.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 May 2005 08:05:11 +0000 (08:05 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 May 2005 08:05:11 +0000 (08:05 +0000)
(negdf2_vfp): Likewise.  Convert to define_insn_and_split and split
the alternatives using integer registers into the appropriate
primitives.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@99607 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/vfp.md

index b3f576d..fd59b35 100644 (file)
@@ -1,3 +1,10 @@
+2005-05-12  Richard Earnshaw  <richard.earnshaw@arm.com>
+
+       * arm/vfp.md (negsf2_vfp): Add alternative using integer registers.
+       (negdf2_vfp): Likewise.  Convert to define_insn_and_split and split
+       the alternatives using integer registers into the appropriate
+       primitives.
+
 2005-05-11 Kenneth Zadeck <zadeck@naturalbridge.com>
 
        * bitmap.c (bitmap_elmt_to_freelist, bitmap_element_allocate,
index b67163b..c6ace73 100644 (file)
 )
 
 (define_insn "*negsf2_vfp"
-  [(set (match_operand:SF        0 "s_register_operand" "+w")
-       (neg:SF (match_operand:SF 1 "s_register_operand" "w")))]
+  [(set (match_operand:SF        0 "s_register_operand" "=w,?r")
+       (neg:SF (match_operand:SF 1 "s_register_operand" "w,r")))]
   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
-  "fnegs%?\\t%0, %1"
+  "@
+   fnegs%?\\t%0, %1
+   eor%?\\t%0, %1, #-2147483648"
   [(set_attr "predicable" "yes")
    (set_attr "type" "ffarith")]
 )
 
-(define_insn "*negdf2_vfp"
-  [(set (match_operand:DF        0 "s_register_operand" "+w")
-       (neg:DF (match_operand:DF 1 "s_register_operand" "w")))]
+(define_insn_and_split "*negdf2_vfp"
+  [(set (match_operand:DF        0 "s_register_operand" "=w,?r,?r")
+       (neg:DF (match_operand:DF 1 "s_register_operand" "w,0,r")))]
   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
-  "fnegd%?\\t%P0, %P1"
+  "@
+   fnegd%?\\t%P0, %P1
+   #
+   #"
+  "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP && reload_completed
+   && arm_general_register_operand (operands[0], DFmode)"
+  [(set (match_dup 0) (match_dup 1))]
+  "
+  if (REGNO (operands[0]) == REGNO (operands[1]))
+    {
+      operands[0] = gen_highpart (SImode, operands[0]);
+      operands[1] = gen_rtx_XOR (SImode, operands[0], GEN_INT (0x80000000));
+    }
+  else
+    {
+      rtx in_hi, in_lo, out_hi, out_lo;
+
+      in_hi = gen_rtx_XOR (SImode, gen_highpart (SImode, operands[1]),
+                          GEN_INT (0x80000000));
+      in_lo = gen_lowpart (SImode, operands[1]);
+      out_hi = gen_highpart (SImode, operands[0]);
+      out_lo = gen_lowpart (SImode, operands[0]);
+
+      if (REGNO (in_lo) == REGNO (out_hi))
+        {
+          emit_insn (gen_rtx_SET (SImode, out_lo, in_lo));
+         operands[0] = out_hi;
+          operands[1] = in_hi;
+        }
+      else
+        {
+          emit_insn (gen_rtx_SET (SImode, out_hi, in_hi));
+         operands[0] = out_lo;
+          operands[1] = in_lo;
+        }
+    }
+  "
   [(set_attr "predicable" "yes")
+   (set_attr "length" "4,4,8")
    (set_attr "type" "ffarith")]
 )