aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2005-05-12 08:05:11 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2005-05-12 08:05:11 +0000
commit81632f116801171be7f659a169b0a12e858f06ca (patch)
treec16aedd0a9a53b39a2e83371d5a14bfa37594fcc
parent5db1c53105295810821c3019874388f778782247 (diff)
downloadgcc-81632f116801171be7f659a169b0a12e858f06ca.zip
gcc-81632f116801171be7f659a169b0a12e858f06ca.tar.gz
gcc-81632f116801171be7f659a169b0a12e858f06ca.tar.bz2
vfp.md (negsf2_vfp): Add alternative using integer registers.
* 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. From-SVN: r99607
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/vfp.md53
2 files changed, 53 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b3f576d..fd59b35 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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,
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index b67163b..c6ace73 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -298,20 +298,59 @@
)
(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")]
)