1 
2 #include <stdio.h>
3 #include <math.h>
4 
5 typedef unsigned long long int ULong;
6 
7 typedef
8    struct { double d; int i; } Res;
9 
do_fprem(Res * res,double x,double y)10 static void do_fprem ( Res* res, double x, double y )
11 {
12   ULong c3210;
13   double f64;
14   double xx = x;
15   double yy = y;
16   __asm__ __volatile__(
17      "finit\n\t"
18      "fldl    %2\n\t"
19      "fldl    %3\n\t"
20      "fprem\n\t"
21      "fstpl   %1\n\t"
22      "movq    %%rax,%%r15\n\t"
23      "xorq    %%rax,%%rax\n\t"
24      "fnstsw  %%ax\n\t"
25      "movq    %%rax,%0\n\t"
26      "movq    %%r15,%%rax"
27      : /*out*/ "=r" (c3210)
28      : /*in*/  "m" (f64), "m" (xx), "m" (yy)
29      : /*trash*/ "r15", "rax", "%st", "%st(1)", "cc"
30    );
31   res->d = f64;
32   res->i = (int)(c3210 & 0x4700); /* mask for C3,2,1,0 */
33 }
34 
show(char * s,Res * res)35 static void show ( char* s, Res* res )
36 {
37   printf("%s -> 0x%04x %f\n", s, (int)res->i, (double)res->d);
38 }
39 
main(void)40 int main ( void )
41 {
42   Res r;
43   int i;
44   double theta;
45 
46   do_fprem(&r, 10.1, 200.2); show("xx1", &r);
47   do_fprem(&r, 20.3, 1.44);  show("xx2", &r);
48 
49   for (i = 0; i < 20; i++) {
50     theta = (2.0 * 3.14159) / 10.0 * (double)i;
51     do_fprem(&r, 12.3*sin(theta), cos(theta)); show("xx", &r);
52   }
53 
54   return 0;
55 }
56