1 2#include <stdio.h> 3#include <math.h> 4 5typedef unsigned long long int ULong; 6 7typedef 8 struct { double d; int i; } Res; 9 10static 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 35static void show ( char* s, Res* res ) 36{ 37 printf("%s -> 0x%04x %f\n", s, (int)res->i, (double)res->d); 38} 39 40int 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