1c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
2c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj/* On amd64, to exercise x87, compile with
3c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    gcc4 -ffast-math -mfpmath=387 -mfancy-math-387
4c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
5c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  gcc4 really does generate all the sin cos tan stuff as
6c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  x87 insns inline.  gcc 3.3 doesn't, which makes the test
7c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  pretty useless, but it should still pass.  To be on the safe
8c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  side we need to link with -lm to handle the gcc 3.3 behaviour.
9c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj*/
10c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
11c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj/* Derived from: */
12c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
13c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj/*
14c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  x86 CPU test
15c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *
16c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  Copyright (c) 2003 Fabrice Bellard
17c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *
18c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  This program is free software; you can redistribute it and/or modify
19c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  it under the terms of the GNU General Public License as published by
20c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  the Free Software Foundation; either version 2 of the License, or
21c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  (at your option) any later version.
22c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *
23c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  This program is distributed in the hope that it will be useful,
24c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  GNU General Public License for more details.
27c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *
28c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  You should have received a copy of the GNU General Public License
29c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  along with this program; if not, write to the Free Software
30c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj */
32c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
33c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
34c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#include <stdlib.h>
35c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#include <stdio.h>
36c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#include <string.h>
37c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#include <inttypes.h>
38c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#include <math.h>
39c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
40c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj/**********************************************/
41c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
42c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fops(double a, double b)
43c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
44c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
45c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
46c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
47c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
48c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    // requires fprem/fprem1 -- not done
49c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    //printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
50c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
51c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f sin(a)=%f\n", a, sin(a));
52c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f cos(a)=%f\n", a, cos(a));
53c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f tan(a)=%f\n", a, tan(a));
54c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f log(a)=%f\n", a, log(a));
55c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f exp(a)=%f\n", a, exp(a));
56c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
57c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    /* just to test some op combining */
58c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
59c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
60c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
61c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
62c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_C    0x0001
63c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_P    0x0004
64c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_A    0x0010
65c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_Z    0x0040
66c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_S    0x0080
67c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define CC_O    0x0800
68c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
69c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
70c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fcmp(double a, double b)
71c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
72c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(%f<%f)=%d\n",
73c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, b, a < b);
74c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(%f<=%f)=%d\n",
75c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, b, a <= b);
76c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(%f==%f)=%d\n",
77c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, b, a == b);
78c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(%f>%f)=%d\n",
79c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, b, a > b);
80c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(%f<=%f)=%d\n",
81c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, b, a >= b);
82c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    {
83c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        unsigned long long int eflags;
84c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        /* test f(u)comi instruction */
85c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm("fcomi %2, %1\n"
86c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            "pushfq\n"
87c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            "popq %0\n"
88c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            : "=r" (eflags)
89c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            : "t" (a), "u" (b));
90c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("fcomi(%f %f)=%08llx\n", a, b, eflags & (CC_Z | CC_P | CC_C));
91c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    }
92c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
93c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
94c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fcvt(double a)
95c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
96c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    float fa;
97c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    long double la;
98c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int16_t fpuc;
99c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int i;
100c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int64_t lla;
101c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int ia;
102c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int16_t wa;
103c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double ra;
104c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
105c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    fa = a;
106c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    la = a;
107c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(float)%e = %e\n", a, fa);
108c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("(long double)%f = %Lf\n", a, la);
109dde7b5980607ef557f23136f8ac1d2592ac79addflorian    printf("a=%016llx\n", *(long long *)&a);
110dde7b5980607ef557f23136f8ac1d2592ac79addflorian    printf("la=%016llx %04x\n", *(long long *)&la,
111c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           *(unsigned short *)((char *)(&la) + 8));
112c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
113c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    /* test all roundings */
114c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm volatile ("fstcw %0" : "=m" (fpuc));
115c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<4;i++) {
116c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj      int16_t tmp = (fpuc & ~0x0c00) | (i << 10);
117c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fldcw %0" : : "m" (tmp));
118c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        wa=0;//asm volatile ("fist %0" : "=m" (wa) : "t" (a));
119c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj	asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
120c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
121c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
122c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fldcw %0" : : "m" (fpuc));
123c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("(short)a = %d\n", wa);
124c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("(int)a = %d\n", ia);
125c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("(int64_t)a = %lld\n", (long long int)lla);
126c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("rint(a) = %f\n", ra);
127c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    }
128c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
129c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
130c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define TEST(N) \
131c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm("fld" #N : "=t" (a)); \
132c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("fld" #N "= %f\n", a);
133c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
134c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fconst(void)
135c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
136c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double a;
137c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(1);
138c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(l2t);
139c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(l2e);
140c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(pi);
141c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(lg2);
142c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(ln2);
143c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST(z);
144c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
145c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
146c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fbcd(double a)
147c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
148c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    unsigned short bcd[5];
149c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double b;
150c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
151c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
152c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
153c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
154c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
155c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
156c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
157c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define TEST_ENV(env, save, restore)\
158c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{\
159c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    memset((env), 0xaa, sizeof(*(env)));\
160c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<5;i++)\
161c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fldl %0" : : "m" (dtab[i]));\
162c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm(save " %0\n" : : "m" (*(env)));\
163c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm(restore " %0\n": : "m" (*(env)));\
164c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<5;i++)\
165c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
166c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<5;i++)\
167c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        printf("res[%d]=%f\n", i, rtab[i]);\
168c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
169c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           (env)->fpuc,\
170c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           (env)->fpus & 0xff00,\
171c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           (env)->fptag);\
172c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
173c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
174c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fenv(void)
175c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
176c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    struct __attribute__((packed)) {
177c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fpuc;
178c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t dummy1;
179c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fpus;
180c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t dummy2;
181c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fptag;
182c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t dummy3;
183c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint32_t ignored[4];
184c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        long double fpregs[8];
185c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    } float_env32;
186c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    struct __attribute__((packed)) {
187c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fpuc;
188c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fpus;
189c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t fptag;
190c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        uint16_t ignored[4];
191c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        long double fpregs[8];
192c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    } float_env16;
193c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double dtab[8];
194c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double rtab[8];
195c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    int i;
196c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
197c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<8;i++)
198c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        dtab[i] = i + 1;
199c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
200c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
201c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
202c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_ENV(&float_env32, "fnstenv", "fldenv");
203c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_ENV(&float_env32, "fnsave", "frstor");
204c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
205c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    /* test for ffree */
206c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i=0;i<5;i++)
207c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        asm volatile ("fldl %0" : : "m" (dtab[i]));
208c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm volatile("ffree %st(2)");
209c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
210c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm volatile ("fninit");
211c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("fptag=%04x\n", float_env32.fptag);
212c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
213c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
214c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
215c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj#define TEST_FCMOV(a, b, eflags, CC)\
216c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{\
217c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double res;\
218c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    asm("pushq %3\n"\
219c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        "popfq\n"\
220c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        "fcmov" CC " %2, %0\n"\
221c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        : "=t" (res)\
222c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        : "0" (a), "u" (b), "g" ((long long int)eflags));\
223c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    printf("fcmov%s eflags=0x%04llx-> %f\n", \
224c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj           CC, (long long int)eflags, res);\
225c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
226c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
227c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_fcmov(void)
228c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
229c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    double a, b;
230c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    long long int eflags, i;
231c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
232c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    a = 1.0;
233c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    b = 2.0;
234c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    for(i = 0; i < 4; i++) {
235c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        eflags = 0;
236c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        if (i & 1)
237c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            eflags |= CC_C;
238c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        if (i & 2)
239c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj            eflags |= CC_Z;
240c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "b");
241c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "e");
242c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "be");
243c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "nb");
244c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "ne");
245c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj        TEST_FCMOV(a, b, eflags, "nbe");
246c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    }
247c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_FCMOV(a, b, 0, "u");
248c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_FCMOV(a, b, CC_P, "u");
249c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_FCMOV(a, b, 0, "nu");
250c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    TEST_FCMOV(a, b, CC_P, "nu");
251c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
252c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
253c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjvoid test_floats(void)
254c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
255c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fops(2, 3);
256c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fops(1.4, -5);
257c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcmp(2, -1);
258c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcmp(2, 2);
259c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcmp(2, 3);
260c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(0.5);
261c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(-0.5);
262c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(1.0/7.0);
263c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(-1.0/9.0);
264c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(32768);
265c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fcvt(-1e20);
266c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj    test_fconst();
267c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
268c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj
269c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardjint main ( void )
270c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj{
271c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  test_floats();
272c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj  return 0;
273c7e8c749773701d3ff8d090d48c785b6a6465bd6sewardj}
274