This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: fix zero floating point negation on PA 1.x
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: fix zero floating point negation on PA 1.x
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Date: Sat, 3 Nov 2001 14:31:23 -0500 (EST)
- Cc: law at redhat dot com
This patch fixes the failure of the ieee/mzero2.c testsuite program on
PA 1.x processors. Using a subtract from zero generates the wrong zero
when negating plus or minus zero. The patched code now does a multiply
by -1. The old behavior can still be obtained with the
unsafe-math-optimizations flag. I have checked that CSE still converts
"-1. * x" to "-x" when this is specified.
Bootstrap checked on hppa1.1-hp-hpux10.20. There was one regression
prior to my previous build (20010327-1.c). However, I don't think it is
related, and I see that it also fails now on i686-ps-linux-gnu.
OK to install?
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2001-11-02 John David Anglin <dave@hiauly1.hia.nrc.ca>
* pa.md (negdf2, negsf2): Use multiplication rather than subtraction
to implement floating negation on processors prior to PA 2.0.
--- pa.md.orig Thu Nov 1 11:39:21 2001
+++ pa.md Fri Nov 2 11:04:41 2001
@@ -4633,10 +4633,29 @@
[(set_attr "type" "fpdivsgl")
(set_attr "length" "4")])
-(define_insn "negdf2"
+;; Processors prior to PA 2.0 don't have a fneg instruction. Fast
+;; negation can be done by subtracting from zero. However, this
+;; violates the IEEE standard when negating plus and minus zero.
+(define_expand "negdf2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (neg:DF (match_operand:DF 1 "register_operand" "")))
+ (use (match_dup 2))])]
+ "! TARGET_SOFT_FLOAT"
+{
+ if (TARGET_PA_20 || flag_unsafe_math_optimizations)
+ emit_insn (gen_negdf2_fast (operands[0], operands[1]));
+ else
+ {
+ operands[2] = force_reg (DFmode, immed_real_const_1 (dconstm1, DFmode));
+ emit_insn (gen_muldf3 (operands[0], operands[1], operands[2]));
+ }
+ DONE;
+})
+
+(define_insn "negdf2_fast"
[(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
+ "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
"*
{
if (TARGET_PA_20)
@@ -4647,10 +4666,26 @@
[(set_attr "type" "fpalu")
(set_attr "length" "4")])
-(define_insn "negsf2"
+(define_expand "negsf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (neg:SF (match_operand:SF 1 "register_operand" "")))
+ (use (match_dup 2))])]
+ "! TARGET_SOFT_FLOAT"
+{
+ if (TARGET_PA_20 || flag_unsafe_math_optimizations)
+ emit_insn (gen_negsf2_fast (operands[0], operands[1]));
+ else
+ {
+ operands[2] = force_reg (SFmode, immed_real_const_1 (dconstm1, SFmode));
+ emit_insn (gen_mulsf3 (operands[0], operands[1], operands[2]));
+ }
+ DONE;
+})
+
+(define_insn "negsf2_fast"
[(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
+ "! TARGET_SOFT_FLOAT && (TARGET_PA_20 || flag_unsafe_math_optimizations)"
"*
{
if (TARGET_PA_20)