This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]