File: bug132918.c

package info (click to toggle)
valgrind 1%3A3.6.0~svn11254%2Bnmu1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 36,460 kB
  • ctags: 39,734
  • sloc: ansic: 339,440; sh: 15,713; xml: 15,183; cpp: 6,982; asm: 6,630; perl: 5,105; makefile: 3,576; exp: 678; haskell: 250
file content (55 lines) | stat: -rw-r--r-- 1,131 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

#include <stdio.h>
#include <math.h>

typedef unsigned long long int ULong;

typedef
   struct { double d; int i; } Res;

static void do_fprem ( Res* res, double x, double y )
{
  ULong c3210;
  double f64;
  double xx = x;
  double yy = y;
  __asm__ __volatile__(
     "finit\n\t"
     "fldl    %2\n\t"
     "fldl    %3\n\t"
     "fprem\n\t"
     "fstpl   %1\n\t"
     "movq    %%rax,%%r15\n\t"
     "xorq    %%rax,%%rax\n\t"
     "fnstsw  %%ax\n\t"
     "movq    %%rax,%0\n\t"
     "movq    %%r15,%%rax"
     : /*out*/ "=r" (c3210)
     : /*in*/  "m" (f64), "m" (xx), "m" (yy)
     : /*trash*/ "r15", "rax", "%st", "%st(1)", "cc"
   );
  res->d = f64;
  res->i = (int)(c3210 & 0x4700); /* mask for C3,2,1,0 */
}

static void show ( char* s, Res* res )
{
  printf("%s -> 0x%04x %f\n", s, (int)res->i, (double)res->d);
}

int main ( void )
{
  Res r;
  int i;
  double theta;
 
  do_fprem(&r, 10.1, 200.2); show("xx1", &r);
  do_fprem(&r, 20.3, 1.44);  show("xx2", &r);

  for (i = 0; i < 20; i++) {
    theta = (2.0 * 3.14159) / 10.0 * (double)i;
    do_fprem(&r, 12.3*sin(theta), cos(theta)); show("xx", &r);
  }

  return 0;
}