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]

Re: [PATCH] implement rint{,f,l}, floor{,f,l}. ceil{,f,l}, trunc{,f,l}and nearbyint{,f,l} as x87 built-in functions


Richard Henderson wrote:

On Wed, Aug 25, 2004 at 01:44:47PM +0200, Uros Bizjak wrote:


Also, BUILT_IN_RINT{,F,L} can be treated as BUILT_IN_NEARBYINT{,F,L}.



This has nothing at all to do with the exception enable bit in the fpucw.




Bad wording, this part of patch was meant by "... treated as...":

Index: gcc/builtins.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/builtins.c,v
retrieving revision 1.372
diff -u -p -r1.372 builtins.c
--- gcc/builtins.c	15 Aug 2004 15:44:49 -0000	1.372
+++ gcc/builtins.c	25 Aug 2004 10:20:33 -0000
@@ -1741,6 +1741,10 @@ expand_builtin_mathfn (tree exp, rtx tar
    case BUILT_IN_NEARBYINTF:
    case BUILT_IN_NEARBYINTL:
      builtin_optab = nearbyint_optab; break;
+    case BUILT_IN_RINT:
+    case BUILT_IN_RINTF:
+    case BUILT_IN_RINTL:
+      builtin_optab = rint_optab; break;
    default:
      abort ();
    }
@@ -5637,6 +5641,9 @@ expand_builtin (tree exp, rtx target, rt
    case BUILT_IN_NEARBYINT:
    case BUILT_IN_NEARBYINTF:
    case BUILT_IN_NEARBYINTL:
+    case BUILT_IN_RINT:
+    case BUILT_IN_RINTF:
+    case BUILT_IN_RINTL:
      target = expand_builtin_mathfn (exp, target, subtarget);
      if (target)
	return target;


Regarding nearbyint() and rint():


nearbyint() code in libm looks like:
ENTRY(__nearbyint)
       fldl    4(%esp)
       pushl   %eax
       pushl   %ecx
       fnstcw  (%esp)
       movl    (%esp), %eax
       orl     $0x20, %eax
       movl    %eax, 4(%esp)
       fldcw   4(%esp)
       frndint
       fclex
       fldcw   (%esp)
       popl    %ecx
       popl    %eax
       ret
END (__nearbyint)

and rint():
ENTRY(__rint)
       fldl    4(%esp)
       frndint
       ret
END (__rint)

[which is the same as -ffast-math enabled inlined rint() code from mathinlines,h:
__inline_mathopNP (rint, "frndint")]


With my testcase:
double test1 (double a) {
       return rint (a);
}

double test2 (double a) {
       return nearbyint (a);
}

I got following asm code (with -O2 -ffast-math -fomit-frame-pointer):
test1:
       fldl    4(%esp)
       frndint
       ret

test2:
       subl    $4, %esp
       fnstcw  2(%esp)
       fldl    8(%esp)
       movzwl  2(%esp), %eax
       orw     $32, %ax
       movw    %ax, (%esp)
       fldcw   (%esp)
       frndint
       fclex
       fldcw   2(%esp)
       popl    %eax
       ret

IMHO generated code is functionally equal as current libm code. If it is not OK, then also libm should be fixed.

+(define_attr "i387cw" "any,floor,ceil,trunc,exception"
+ (const_string "any"))



This is a good idea, except that it should replace


+enum i387_cw_mode {FP_CW_FLOOR, FP_CW_CEIL, FP_CW_TRUNC,
+ FP_CW_EXCEPTION, FP_CW_UNINITIALIZED, FP_CW_ANY};



this, so that you don't have to translate between them.




Thank you for rewiew this code, I will incorporate your suggestions into next review of patch.

Uros.


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