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