xref: /qemu/tests/tcg/i386/test-i386.c (revision d57c4e01206ebc8b21702c243e7a19638f783b43)
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 #define __init_call	__attribute__ ((unused,__section__ (".initcall.init")))
18 
19 static void *call_start __init_call = NULL;
20 
21 #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
22 
23 #define OP add
24 #include "test-i386.h"
25 
26 #define OP sub
27 #include "test-i386.h"
28 
29 #define OP xor
30 #include "test-i386.h"
31 
32 #define OP and
33 #include "test-i386.h"
34 
35 #define OP or
36 #include "test-i386.h"
37 
38 #define OP cmp
39 #include "test-i386.h"
40 
41 #define OP adc
42 #define OP_CC
43 #include "test-i386.h"
44 
45 #define OP sbb
46 #define OP_CC
47 #include "test-i386.h"
48 
49 #define OP inc
50 #define OP_CC
51 #define OP1
52 #include "test-i386.h"
53 
54 #define OP dec
55 #define OP_CC
56 #define OP1
57 #include "test-i386.h"
58 
59 #define OP neg
60 #define OP_CC
61 #define OP1
62 #include "test-i386.h"
63 
64 #define OP not
65 #define OP_CC
66 #define OP1
67 #include "test-i386.h"
68 
69 #undef CC_MASK
70 #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
71 
72 #define OP shl
73 #include "test-i386-shift.h"
74 
75 #define OP shr
76 #include "test-i386-shift.h"
77 
78 #define OP sar
79 #include "test-i386-shift.h"
80 
81 #define OP rol
82 #include "test-i386-shift.h"
83 
84 #define OP ror
85 #include "test-i386-shift.h"
86 
87 #define OP rcr
88 #define OP_CC
89 #include "test-i386-shift.h"
90 
91 #define OP rcl
92 #define OP_CC
93 #include "test-i386-shift.h"
94 
95 #define OP shld
96 #define OP_SHIFTD
97 #define OP_NOBYTE
98 #include "test-i386-shift.h"
99 
100 #define OP shrd
101 #define OP_SHIFTD
102 #define OP_NOBYTE
103 #include "test-i386-shift.h"
104 
105 /* XXX: should be more precise ? */
106 #undef CC_MASK
107 #define CC_MASK (CC_C)
108 
109 #define OP bt
110 #define OP_NOBYTE
111 #include "test-i386-shift.h"
112 
113 #define OP bts
114 #define OP_NOBYTE
115 #include "test-i386-shift.h"
116 
117 #define OP btr
118 #define OP_NOBYTE
119 #include "test-i386-shift.h"
120 
121 #define OP btc
122 #define OP_NOBYTE
123 #include "test-i386-shift.h"
124 
125 /* lea test (modrm support) */
126 #define TEST_LEA(STR)\
127 {\
128     asm("leal " STR ", %0"\
129         : "=r" (res)\
130         : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
131     printf("lea %s = %08x\n", STR, res);\
132 }
133 
134 #define TEST_LEA16(STR)\
135 {\
136     asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
137         : "=wq" (res)\
138         : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
139     printf("lea %s = %08x\n", STR, res);\
140 }
141 
142 
143 void test_lea(void)
144 {
145     int eax, ebx, ecx, edx, esi, edi, res;
146     eax = 0x0001;
147     ebx = 0x0002;
148     ecx = 0x0004;
149     edx = 0x0008;
150     esi = 0x0010;
151     edi = 0x0020;
152 
153     TEST_LEA("0x4000");
154 
155     TEST_LEA("(%%eax)");
156     TEST_LEA("(%%ebx)");
157     TEST_LEA("(%%ecx)");
158     TEST_LEA("(%%edx)");
159     TEST_LEA("(%%esi)");
160     TEST_LEA("(%%edi)");
161 
162     TEST_LEA("0x40(%%eax)");
163     TEST_LEA("0x40(%%ebx)");
164     TEST_LEA("0x40(%%ecx)");
165     TEST_LEA("0x40(%%edx)");
166     TEST_LEA("0x40(%%esi)");
167     TEST_LEA("0x40(%%edi)");
168 
169     TEST_LEA("0x4000(%%eax)");
170     TEST_LEA("0x4000(%%ebx)");
171     TEST_LEA("0x4000(%%ecx)");
172     TEST_LEA("0x4000(%%edx)");
173     TEST_LEA("0x4000(%%esi)");
174     TEST_LEA("0x4000(%%edi)");
175 
176     TEST_LEA("(%%eax, %%ecx)");
177     TEST_LEA("(%%ebx, %%edx)");
178     TEST_LEA("(%%ecx, %%ecx)");
179     TEST_LEA("(%%edx, %%ecx)");
180     TEST_LEA("(%%esi, %%ecx)");
181     TEST_LEA("(%%edi, %%ecx)");
182 
183     TEST_LEA("0x40(%%eax, %%ecx)");
184     TEST_LEA("0x4000(%%ebx, %%edx)");
185 
186     TEST_LEA("(%%ecx, %%ecx, 2)");
187     TEST_LEA("(%%edx, %%ecx, 4)");
188     TEST_LEA("(%%esi, %%ecx, 8)");
189 
190     TEST_LEA("(,%%eax, 2)");
191     TEST_LEA("(,%%ebx, 4)");
192     TEST_LEA("(,%%ecx, 8)");
193 
194     TEST_LEA("0x40(,%%eax, 2)");
195     TEST_LEA("0x40(,%%ebx, 4)");
196     TEST_LEA("0x40(,%%ecx, 8)");
197 
198 
199     TEST_LEA("-10(%%ecx, %%ecx, 2)");
200     TEST_LEA("-10(%%edx, %%ecx, 4)");
201     TEST_LEA("-10(%%esi, %%ecx, 8)");
202 
203     TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
204     TEST_LEA("0x4000(%%edx, %%ecx, 4)");
205     TEST_LEA("0x4000(%%esi, %%ecx, 8)");
206 
207     /* limited 16 bit addressing test */
208     TEST_LEA16("0x4000");
209     TEST_LEA16("(%%bx)");
210     TEST_LEA16("(%%si)");
211     TEST_LEA16("(%%di)");
212     TEST_LEA16("0x40(%%bx)");
213     TEST_LEA16("0x40(%%si)");
214     TEST_LEA16("0x40(%%di)");
215     TEST_LEA16("0x4000(%%bx)");
216     TEST_LEA16("0x4000(%%si)");
217     TEST_LEA16("(%%bx,%%si)");
218     TEST_LEA16("(%%bx,%%di)");
219     TEST_LEA16("0x40(%%bx,%%si)");
220     TEST_LEA16("0x40(%%bx,%%di)");
221     TEST_LEA16("0x4000(%%bx,%%si)");
222     TEST_LEA16("0x4000(%%bx,%%di)");
223 }
224 
225 #define TEST_JCC(JCC, v1, v2)\
226 {\
227     asm("movl $1, %0\n\t"\
228         "cmpl %2, %1\n\t"\
229         JCC " 1f\n\t"\
230         "movl $0, %0\n\t"\
231         "1:\n\t"\
232         : "=r" (res)\
233         : "r" (v1), "r" (v2));\
234     printf("%-10s %d\n", JCC, res);\
235 }
236 
237 /* various jump tests */
238 void test_jcc(void)
239 {
240     int res;
241 
242     TEST_JCC("jne", 1, 1);
243     TEST_JCC("jne", 1, 0);
244 
245     TEST_JCC("je", 1, 1);
246     TEST_JCC("je", 1, 0);
247 
248     TEST_JCC("jl", 1, 1);
249     TEST_JCC("jl", 1, 0);
250     TEST_JCC("jl", 1, -1);
251 
252     TEST_JCC("jle", 1, 1);
253     TEST_JCC("jle", 1, 0);
254     TEST_JCC("jle", 1, -1);
255 
256     TEST_JCC("jge", 1, 1);
257     TEST_JCC("jge", 1, 0);
258     TEST_JCC("jge", -1, 1);
259 
260     TEST_JCC("jg", 1, 1);
261     TEST_JCC("jg", 1, 0);
262     TEST_JCC("jg", 1, -1);
263 
264     TEST_JCC("jb", 1, 1);
265     TEST_JCC("jb", 1, 0);
266     TEST_JCC("jb", 1, -1);
267 
268     TEST_JCC("jbe", 1, 1);
269     TEST_JCC("jbe", 1, 0);
270     TEST_JCC("jbe", 1, -1);
271 
272     TEST_JCC("jae", 1, 1);
273     TEST_JCC("jae", 1, 0);
274     TEST_JCC("jae", 1, -1);
275 
276     TEST_JCC("ja", 1, 1);
277     TEST_JCC("ja", 1, 0);
278     TEST_JCC("ja", 1, -1);
279 
280 
281     TEST_JCC("jp", 1, 1);
282     TEST_JCC("jp", 1, 0);
283 
284     TEST_JCC("jnp", 1, 1);
285     TEST_JCC("jnp", 1, 0);
286 
287     TEST_JCC("jo", 0x7fffffff, 0);
288     TEST_JCC("jo", 0x7fffffff, -1);
289 
290     TEST_JCC("jno", 0x7fffffff, 0);
291     TEST_JCC("jno", 0x7fffffff, -1);
292 
293     TEST_JCC("js", 0, 1);
294     TEST_JCC("js", 0, -1);
295     TEST_JCC("js", 0, 0);
296 
297     TEST_JCC("jns", 0, 1);
298     TEST_JCC("jns", 0, -1);
299     TEST_JCC("jns", 0, 0);
300 }
301 
302 #undef CC_MASK
303 #define CC_MASK (CC_O | CC_C)
304 
305 #define OP mul
306 #include "test-i386-muldiv.h"
307 
308 #define OP imul
309 #include "test-i386-muldiv.h"
310 
311 #undef CC_MASK
312 #define CC_MASK (0)
313 
314 #define OP div
315 #include "test-i386-muldiv.h"
316 
317 #define OP idiv
318 #include "test-i386-muldiv.h"
319 
320 void test_imulw2(int op0, int op1)
321 {
322     int res, s1, s0, flags;
323     s0 = op0;
324     s1 = op1;
325     res = s0;
326     flags = 0;
327     asm ("push %4\n\t"
328          "popf\n\t"
329          "imulw %w2, %w0\n\t"
330          "pushf\n\t"
331          "popl %1\n\t"
332          : "=q" (res), "=g" (flags)
333          : "q" (s1), "0" (res), "1" (flags));
334     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
335            "imulw", s0, s1, res, flags & CC_MASK);
336 }
337 
338 void test_imull2(int op0, int op1)
339 {
340     int res, s1, s0, flags;
341     s0 = op0;
342     s1 = op1;
343     res = s0;
344     flags = 0;
345     asm ("push %4\n\t"
346          "popf\n\t"
347          "imull %2, %0\n\t"
348          "pushf\n\t"
349          "popl %1\n\t"
350          : "=q" (res), "=g" (flags)
351          : "q" (s1), "0" (res), "1" (flags));
352     printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
353            "imull", s0, s1, res, flags & CC_MASK);
354 }
355 
356 void test_mul(void)
357 {
358     test_imulb(0x1234561d, 4);
359     test_imulb(3, -4);
360     test_imulb(0x80, 0x80);
361     test_imulb(0x10, 0x10);
362 
363     test_imulw(0, 0x1234001d, 45);
364     test_imulw(0, 23, -45);
365     test_imulw(0, 0x8000, 0x8000);
366     test_imulw(0, 0x100, 0x100);
367 
368     test_imull(0, 0x1234001d, 45);
369     test_imull(0, 23, -45);
370     test_imull(0, 0x80000000, 0x80000000);
371     test_imull(0, 0x10000, 0x10000);
372 
373     test_mulb(0x1234561d, 4);
374     test_mulb(3, -4);
375     test_mulb(0x80, 0x80);
376     test_mulb(0x10, 0x10);
377 
378     test_mulw(0, 0x1234001d, 45);
379     test_mulw(0, 23, -45);
380     test_mulw(0, 0x8000, 0x8000);
381     test_mulw(0, 0x100, 0x100);
382 
383     test_mull(0, 0x1234001d, 45);
384     test_mull(0, 23, -45);
385     test_mull(0, 0x80000000, 0x80000000);
386     test_mull(0, 0x10000, 0x10000);
387 
388     test_imulw2(0x1234001d, 45);
389     test_imulw2(23, -45);
390     test_imulw2(0x8000, 0x8000);
391     test_imulw2(0x100, 0x100);
392 
393     test_imull2(0x1234001d, 45);
394     test_imull2(23, -45);
395     test_imull2(0x80000000, 0x80000000);
396     test_imull2(0x10000, 0x10000);
397 
398     test_idivb(0x12341678, 0x127e);
399     test_idivb(0x43210123, -5);
400     test_idivb(0x12340004, -1);
401 
402     test_idivw(0, 0x12345678, 12347);
403     test_idivw(0, -23223, -45);
404     test_idivw(0, 0x12348000, -1);
405     test_idivw(0x12343, 0x12345678, 0x81238567);
406 
407     test_idivl(0, 0x12345678, 12347);
408     test_idivl(0, -233223, -45);
409     test_idivl(0, 0x80000000, -1);
410     test_idivl(0x12343, 0x12345678, 0x81234567);
411 
412     test_divb(0x12341678, 0x127e);
413     test_divb(0x43210123, -5);
414     test_divb(0x12340004, -1);
415 
416     test_divw(0, 0x12345678, 12347);
417     test_divw(0, -23223, -45);
418     test_divw(0, 0x12348000, -1);
419     test_divw(0x12343, 0x12345678, 0x81238567);
420 
421     test_divl(0, 0x12345678, 12347);
422     test_divl(0, -233223, -45);
423     test_divl(0, 0x80000000, -1);
424     test_divl(0x12343, 0x12345678, 0x81234567);
425 }
426 
427 
428 static void *call_end __init_call = NULL;
429 
430 int main(int argc, char **argv)
431 {
432     void **ptr;
433     void (*func)(void);
434 
435     ptr = &call_start + 1;
436     while (*ptr != NULL) {
437         func = *ptr++;
438         func();
439     }
440     test_mul();
441     test_jcc();
442     test_lea();
443     return 0;
444 }
445