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