This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Correct powerpc64 long double -0.0 to double conversion
On Wed, Mar 10, 2004 at 11:18:38AM -0500, David Edelsohn wrote:
> Using your test program, IBM xlc128 prints:
>
> NaN : 7ff80000 00000000 : 00000000 00000000
> +Inf : 7ff00000 00000000 : 00000000 00000000
> 0 : 00000000 00000000 : 00000000 00000000
> -0 : 80000000 00000000 : 00000000 00000000
> -Inf : fff00000 00000000 : 00000000 00000000
Let's start again. We can do without the -0.0 in the low double, and
also simplify long double -> double conversion.
- The PowerPC GCC long double comparison insn, cmptf_internal1 assumes
there is exactly one representation for any long double value, because
we compare the component doubles. This is despite the currect
PowerPC64 Linux ABI (and probably AIX) defining the IBM extended
precision format in a loose manner that would seem to allow more than
one representation for certain finite values.
- Our math functions always produce a correctly rounded high double
(it's hard to see how they could do otherwise, given that the
underlying hardware does so for double operations if rounding mode is
set correctly)
- Therefore, the current gcc code only supports long doubles that have
a correctly rounded high double.
- Therefore, we don't need to add the component doubles when converting
to double, as Richard Sandiford pointed out.
Also a correctly rounded high double means that our actual precision
is 107 bits, not 106. Changing this is orthogonal to the rs6000 back
end change, so I'll leave it to another patch.
* config/rs6000/rs6000.md (trunctfdf2): Just use the high double.
Bootstrap and regression test in progress.
Index: gcc/config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.299
diff -u -p -r1.299 rs6000.md
--- gcc/config/rs6000/rs6000.md 9 Mar 2004 12:10:25 -0000 1.299
+++ gcc/config/rs6000/rs6000.md 11 Mar 2004 11:22:13 -0000
@@ -8269,14 +8269,19 @@
DONE;
})
-(define_insn "trunctfdf2"
+(define_insn_and_split "trunctfdf2"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(float_truncate:DF (match_operand:TF 1 "gpc_reg_operand" "f")))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN)
&& TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128"
- "fadd %0,%1,%L1"
- [(set_attr "type" "fp")
- (set_attr "length" "4")])
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (match_dup 2))]
+ "
+{
+ const int hi_word = FLOAT_WORDS_BIG_ENDIAN ? 0 : GET_MODE_SIZE (DFmode);
+ operands[2] = simplify_gen_subreg (DFmode, operands[1], TFmode, hi_word);
+}")
(define_insn_and_split "trunctfsf2"
[(set (match_operand:SF 0 "gpc_reg_operand" "=f")
--
Alan Modra
IBM OzLabs - Linux Technology Centre