xref: /qemu/tests/tcg/i386/test-i386.c (revision 4d1135e486fcdd3b00caf524f01af7f0d56a0af7)
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <math.h>
4 
5 #define xglue(x, y) x ## y
6 #define glue(x, y) xglue(x, y)
7 #define stringify(s)	tostring(s)
8 #define tostring(s)	#s
9 
10 #define CC_C   	0x0001
11 #define CC_P 	0x0004
12 #define CC_A	0x0010
13 #define CC_Z	0x0040
14 #define CC_S    0x0080
15 #define CC_O    0x0800
16 
17 /* XXX: currently no A flag */
18 #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
19 
20 #define __init_call	__attribute__ ((unused,__section__ (".initcall.init")))
21 
22 static void *call_start __init_call = NULL;
23 
24 #define OP add
25 #include "test-i386.h"
26 
27 #define OP sub
28 #include "test-i386.h"
29 
30 #define OP xor
31 #include "test-i386.h"
32 
33 #define OP and
34 #include "test-i386.h"
35 
36 #define OP or
37 #include "test-i386.h"
38 
39 #define OP cmp
40 #include "test-i386.h"
41 
42 #define OP adc
43 #define OP_CC
44 #include "test-i386.h"
45 
46 #define OP sbb
47 #define OP_CC
48 #include "test-i386.h"
49 
50 #define OP inc
51 #define OP_CC
52 #define OP1
53 #include "test-i386.h"
54 
55 #define OP dec
56 #define OP_CC
57 #define OP1
58 #include "test-i386.h"
59 
60 #define OP neg
61 #define OP_CC
62 #define OP1
63 #include "test-i386.h"
64 
65 #define OP not
66 #define OP_CC
67 #define OP1
68 #include "test-i386.h"
69 
70 /* lea test (modrm support) */
71 #define TEST_LEA(STR)\
72 {\
73     asm("leal " STR ", %0"\
74         : "=r" (res)\
75         : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
76     printf("lea %s = %08x\n", STR, res);\
77 }
78 
79 #define TEST_LEA16(STR)\
80 {\
81     asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
82         : "=wq" (res)\
83         : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
84     printf("lea %s = %08x\n", STR, res);\
85 }
86 
87 
88 void test_lea(void)
89 {
90     int eax, ebx, ecx, edx, esi, edi, res;
91     eax = 0x0001;
92     ebx = 0x0002;
93     ecx = 0x0004;
94     edx = 0x0008;
95     esi = 0x0010;
96     edi = 0x0020;
97 
98     TEST_LEA("0x4000");
99 
100     TEST_LEA("(%%eax)");
101     TEST_LEA("(%%ebx)");
102     TEST_LEA("(%%ecx)");
103     TEST_LEA("(%%edx)");
104     TEST_LEA("(%%esi)");
105     TEST_LEA("(%%edi)");
106 
107     TEST_LEA("0x40(%%eax)");
108     TEST_LEA("0x40(%%ebx)");
109     TEST_LEA("0x40(%%ecx)");
110     TEST_LEA("0x40(%%edx)");
111     TEST_LEA("0x40(%%esi)");
112     TEST_LEA("0x40(%%edi)");
113 
114     TEST_LEA("0x4000(%%eax)");
115     TEST_LEA("0x4000(%%ebx)");
116     TEST_LEA("0x4000(%%ecx)");
117     TEST_LEA("0x4000(%%edx)");
118     TEST_LEA("0x4000(%%esi)");
119     TEST_LEA("0x4000(%%edi)");
120 
121     TEST_LEA("(%%eax, %%ecx)");
122     TEST_LEA("(%%ebx, %%edx)");
123     TEST_LEA("(%%ecx, %%ecx)");
124     TEST_LEA("(%%edx, %%ecx)");
125     TEST_LEA("(%%esi, %%ecx)");
126     TEST_LEA("(%%edi, %%ecx)");
127 
128     TEST_LEA("0x40(%%eax, %%ecx)");
129     TEST_LEA("0x4000(%%ebx, %%edx)");
130 
131     TEST_LEA("(%%ecx, %%ecx, 2)");
132     TEST_LEA("(%%edx, %%ecx, 4)");
133     TEST_LEA("(%%esi, %%ecx, 8)");
134 
135     TEST_LEA("(,%%eax, 2)");
136     TEST_LEA("(,%%ebx, 4)");
137     TEST_LEA("(,%%ecx, 8)");
138 
139     TEST_LEA("0x40(,%%eax, 2)");
140     TEST_LEA("0x40(,%%ebx, 4)");
141     TEST_LEA("0x40(,%%ecx, 8)");
142 
143 
144     TEST_LEA("-10(%%ecx, %%ecx, 2)");
145     TEST_LEA("-10(%%edx, %%ecx, 4)");
146     TEST_LEA("-10(%%esi, %%ecx, 8)");
147 
148     TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
149     TEST_LEA("0x4000(%%edx, %%ecx, 4)");
150     TEST_LEA("0x4000(%%esi, %%ecx, 8)");
151 
152     /* limited 16 bit addressing test */
153     TEST_LEA16("0x4000");
154     TEST_LEA16("(%%bx)");
155     TEST_LEA16("(%%si)");
156     TEST_LEA16("(%%di)");
157     TEST_LEA16("0x40(%%bx)");
158     TEST_LEA16("0x40(%%si)");
159     TEST_LEA16("0x40(%%di)");
160     TEST_LEA16("0x4000(%%bx)");
161     TEST_LEA16("0x4000(%%si)");
162     TEST_LEA16("(%%bx,%%si)");
163     TEST_LEA16("(%%bx,%%di)");
164     TEST_LEA16("0x40(%%bx,%%si)");
165     TEST_LEA16("0x40(%%bx,%%di)");
166     TEST_LEA16("0x4000(%%bx,%%si)");
167     TEST_LEA16("0x4000(%%bx,%%di)");
168 }
169 
170 #define TEST_JCC(JCC, v1, v2)\
171 {\
172     asm("movl $1, %0\n\t"\
173         "cmpl %2, %1\n\t"\
174         JCC " 1f\n\t"\
175         "movl $0, %0\n\t"\
176         "1:\n\t"\
177         : "=r" (res)\
178         : "r" (v1), "r" (v2));\
179     printf("%-10s %d\n", JCC, res);\
180 }
181 
182 /* various jump tests */
183 void test_jcc(void)
184 {
185     int res;
186 
187     TEST_JCC("jne", 1, 1);
188     TEST_JCC("jne", 1, 0);
189 
190     TEST_JCC("je", 1, 1);
191     TEST_JCC("je", 1, 0);
192 
193     TEST_JCC("jl", 1, 1);
194     TEST_JCC("jl", 1, 0);
195     TEST_JCC("jl", 1, -1);
196 
197     TEST_JCC("jle", 1, 1);
198     TEST_JCC("jle", 1, 0);
199     TEST_JCC("jle", 1, -1);
200 
201     TEST_JCC("jge", 1, 1);
202     TEST_JCC("jge", 1, 0);
203     TEST_JCC("jge", -1, 1);
204 
205     TEST_JCC("jg", 1, 1);
206     TEST_JCC("jg", 1, 0);
207     TEST_JCC("jg", 1, -1);
208 
209     TEST_JCC("jb", 1, 1);
210     TEST_JCC("jb", 1, 0);
211     TEST_JCC("jb", 1, -1);
212 
213     TEST_JCC("jbe", 1, 1);
214     TEST_JCC("jbe", 1, 0);
215     TEST_JCC("jbe", 1, -1);
216 
217     TEST_JCC("jae", 1, 1);
218     TEST_JCC("jae", 1, 0);
219     TEST_JCC("jae", 1, -1);
220 
221     TEST_JCC("ja", 1, 1);
222     TEST_JCC("ja", 1, 0);
223     TEST_JCC("ja", 1, -1);
224 
225 
226     TEST_JCC("jp", 1, 1);
227     TEST_JCC("jp", 1, 0);
228 
229     TEST_JCC("jnp", 1, 1);
230     TEST_JCC("jnp", 1, 0);
231 
232     TEST_JCC("jo", 0x7fffffff, 0);
233     TEST_JCC("jo", 0x7fffffff, -1);
234 
235     TEST_JCC("jno", 0x7fffffff, 0);
236     TEST_JCC("jno", 0x7fffffff, -1);
237 
238     TEST_JCC("js", 0, 1);
239     TEST_JCC("js", 0, -1);
240     TEST_JCC("js", 0, 0);
241 
242     TEST_JCC("jns", 0, 1);
243     TEST_JCC("jns", 0, -1);
244     TEST_JCC("jns", 0, 0);
245 }
246 
247 static void *call_end __init_call = NULL;
248 
249 int main(int argc, char **argv)
250 {
251     void **ptr;
252     void (*func)(void);
253     ptr = &call_start + 1;
254     while (*ptr != NULL) {
255         func = *ptr++;
256         func();
257     }
258     test_lea();
259     test_jcc();
260     return 0;
261 }
262