]> Git Repo - qemu.git/blame - tests/test-i386.c
direct chaining for PowerPC and i386
[qemu.git] / tests / test-i386.c
CommitLineData
3a27ad0b 1#define _GNU_SOURCE
4d1135e4
FB
2#include <stdlib.h>
3#include <stdio.h>
6dbad63e 4#include <inttypes.h>
4d1135e4 5#include <math.h>
3a27ad0b
FB
6#include <signal.h>
7#include <setjmp.h>
8#include <sys/ucontext.h>
9#include <sys/mman.h>
10#include <asm/vm86.h>
4d1135e4 11
5dd9488c
FB
12#define TEST_CMOV 0
13
4d1135e4
FB
14#define xglue(x, y) x ## y
15#define glue(x, y) xglue(x, y)
16#define stringify(s) tostring(s)
17#define tostring(s) #s
18
19#define CC_C 0x0001
20#define CC_P 0x0004
21#define CC_A 0x0010
22#define CC_Z 0x0040
23#define CC_S 0x0080
24#define CC_O 0x0800
25
4d1135e4
FB
26#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
27
28static void *call_start __init_call = NULL;
29
4b74fe1f
FB
30#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
31
4d1135e4
FB
32#define OP add
33#include "test-i386.h"
34
35#define OP sub
36#include "test-i386.h"
37
38#define OP xor
39#include "test-i386.h"
40
41#define OP and
42#include "test-i386.h"
43
44#define OP or
45#include "test-i386.h"
46
47#define OP cmp
48#include "test-i386.h"
49
50#define OP adc
51#define OP_CC
52#include "test-i386.h"
53
54#define OP sbb
55#define OP_CC
56#include "test-i386.h"
57
58#define OP inc
59#define OP_CC
60#define OP1
61#include "test-i386.h"
62
63#define OP dec
64#define OP_CC
65#define OP1
66#include "test-i386.h"
67
68#define OP neg
69#define OP_CC
70#define OP1
71#include "test-i386.h"
72
73#define OP not
74#define OP_CC
75#define OP1
76#include "test-i386.h"
77
4b74fe1f
FB
78#undef CC_MASK
79#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
80
379ca80d
FB
81#define OP shl
82#include "test-i386-shift.h"
83
84#define OP shr
85#include "test-i386-shift.h"
86
87#define OP sar
88#include "test-i386-shift.h"
89
90#define OP rol
91#include "test-i386-shift.h"
92
93#define OP ror
94#include "test-i386-shift.h"
95
96#define OP rcr
97#define OP_CC
98#include "test-i386-shift.h"
99
100#define OP rcl
101#define OP_CC
102#include "test-i386-shift.h"
103
d57c4e01
FB
104#define OP shld
105#define OP_SHIFTD
106#define OP_NOBYTE
107#include "test-i386-shift.h"
108
109#define OP shrd
110#define OP_SHIFTD
111#define OP_NOBYTE
112#include "test-i386-shift.h"
113
114/* XXX: should be more precise ? */
115#undef CC_MASK
116#define CC_MASK (CC_C)
117
118#define OP bt
119#define OP_NOBYTE
120#include "test-i386-shift.h"
121
122#define OP bts
123#define OP_NOBYTE
124#include "test-i386-shift.h"
125
126#define OP btr
127#define OP_NOBYTE
128#include "test-i386-shift.h"
129
130#define OP btc
131#define OP_NOBYTE
132#include "test-i386-shift.h"
379ca80d 133
4d1135e4
FB
134/* lea test (modrm support) */
135#define TEST_LEA(STR)\
136{\
137 asm("leal " STR ", %0"\
138 : "=r" (res)\
139 : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
140 printf("lea %s = %08x\n", STR, res);\
141}
142
143#define TEST_LEA16(STR)\
144{\
145 asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
146 : "=wq" (res)\
147 : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
148 printf("lea %s = %08x\n", STR, res);\
149}
150
151
152void test_lea(void)
153{
154 int eax, ebx, ecx, edx, esi, edi, res;
155 eax = 0x0001;
156 ebx = 0x0002;
157 ecx = 0x0004;
158 edx = 0x0008;
159 esi = 0x0010;
160 edi = 0x0020;
161
162 TEST_LEA("0x4000");
163
164 TEST_LEA("(%%eax)");
165 TEST_LEA("(%%ebx)");
166 TEST_LEA("(%%ecx)");
167 TEST_LEA("(%%edx)");
168 TEST_LEA("(%%esi)");
169 TEST_LEA("(%%edi)");
170
171 TEST_LEA("0x40(%%eax)");
172 TEST_LEA("0x40(%%ebx)");
173 TEST_LEA("0x40(%%ecx)");
174 TEST_LEA("0x40(%%edx)");
175 TEST_LEA("0x40(%%esi)");
176 TEST_LEA("0x40(%%edi)");
177
178 TEST_LEA("0x4000(%%eax)");
179 TEST_LEA("0x4000(%%ebx)");
180 TEST_LEA("0x4000(%%ecx)");
181 TEST_LEA("0x4000(%%edx)");
182 TEST_LEA("0x4000(%%esi)");
183 TEST_LEA("0x4000(%%edi)");
184
185 TEST_LEA("(%%eax, %%ecx)");
186 TEST_LEA("(%%ebx, %%edx)");
187 TEST_LEA("(%%ecx, %%ecx)");
188 TEST_LEA("(%%edx, %%ecx)");
189 TEST_LEA("(%%esi, %%ecx)");
190 TEST_LEA("(%%edi, %%ecx)");
191
192 TEST_LEA("0x40(%%eax, %%ecx)");
193 TEST_LEA("0x4000(%%ebx, %%edx)");
194
195 TEST_LEA("(%%ecx, %%ecx, 2)");
196 TEST_LEA("(%%edx, %%ecx, 4)");
197 TEST_LEA("(%%esi, %%ecx, 8)");
198
199 TEST_LEA("(,%%eax, 2)");
200 TEST_LEA("(,%%ebx, 4)");
201 TEST_LEA("(,%%ecx, 8)");
202
203 TEST_LEA("0x40(,%%eax, 2)");
204 TEST_LEA("0x40(,%%ebx, 4)");
205 TEST_LEA("0x40(,%%ecx, 8)");
206
207
208 TEST_LEA("-10(%%ecx, %%ecx, 2)");
209 TEST_LEA("-10(%%edx, %%ecx, 4)");
210 TEST_LEA("-10(%%esi, %%ecx, 8)");
211
212 TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
213 TEST_LEA("0x4000(%%edx, %%ecx, 4)");
214 TEST_LEA("0x4000(%%esi, %%ecx, 8)");
215
216 /* limited 16 bit addressing test */
217 TEST_LEA16("0x4000");
218 TEST_LEA16("(%%bx)");
219 TEST_LEA16("(%%si)");
220 TEST_LEA16("(%%di)");
221 TEST_LEA16("0x40(%%bx)");
222 TEST_LEA16("0x40(%%si)");
223 TEST_LEA16("0x40(%%di)");
224 TEST_LEA16("0x4000(%%bx)");
225 TEST_LEA16("0x4000(%%si)");
226 TEST_LEA16("(%%bx,%%si)");
227 TEST_LEA16("(%%bx,%%di)");
228 TEST_LEA16("0x40(%%bx,%%si)");
229 TEST_LEA16("0x40(%%bx,%%di)");
230 TEST_LEA16("0x4000(%%bx,%%si)");
231 TEST_LEA16("0x4000(%%bx,%%di)");
232}
233
234#define TEST_JCC(JCC, v1, v2)\
235{\
5dd9488c 236 int res;\
4d1135e4
FB
237 asm("movl $1, %0\n\t"\
238 "cmpl %2, %1\n\t"\
5dd9488c 239 "j" JCC " 1f\n\t"\
4d1135e4
FB
240 "movl $0, %0\n\t"\
241 "1:\n\t"\
242 : "=r" (res)\
243 : "r" (v1), "r" (v2));\
5dd9488c
FB
244 printf("%-10s %d\n", "j" JCC, res);\
245\
246 asm("movl $0, %0\n\t"\
247 "cmpl %2, %1\n\t"\
248 "set" JCC " %b0\n\t"\
249 : "=r" (res)\
250 : "r" (v1), "r" (v2));\
251 printf("%-10s %d\n", "set" JCC, res);\
252 if (TEST_CMOV) {\
253 asm("movl $0x12345678, %0\n\t"\
254 "cmpl %2, %1\n\t"\
255 "cmov" JCC "l %3, %0\n\t"\
256 : "=r" (res)\
257 : "r" (v1), "r" (v2), "m" (1));\
258 printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\
259 asm("movl $0x12345678, %0\n\t"\
260 "cmpl %2, %1\n\t"\
261 "cmov" JCC "w %w3, %w0\n\t"\
262 : "=r" (res)\
263 : "r" (v1), "r" (v2), "r" (1));\
264 printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\
265 } \
4d1135e4
FB
266}
267
268/* various jump tests */
269void test_jcc(void)
270{
5dd9488c
FB
271 TEST_JCC("ne", 1, 1);
272 TEST_JCC("ne", 1, 0);
4d1135e4 273
5dd9488c
FB
274 TEST_JCC("e", 1, 1);
275 TEST_JCC("e", 1, 0);
4d1135e4 276
5dd9488c
FB
277 TEST_JCC("l", 1, 1);
278 TEST_JCC("l", 1, 0);
279 TEST_JCC("l", 1, -1);
4d1135e4 280
5dd9488c
FB
281 TEST_JCC("le", 1, 1);
282 TEST_JCC("le", 1, 0);
283 TEST_JCC("le", 1, -1);
4d1135e4 284
5dd9488c
FB
285 TEST_JCC("ge", 1, 1);
286 TEST_JCC("ge", 1, 0);
287 TEST_JCC("ge", -1, 1);
4d1135e4 288
5dd9488c
FB
289 TEST_JCC("g", 1, 1);
290 TEST_JCC("g", 1, 0);
291 TEST_JCC("g", 1, -1);
4d1135e4 292
5dd9488c
FB
293 TEST_JCC("b", 1, 1);
294 TEST_JCC("b", 1, 0);
295 TEST_JCC("b", 1, -1);
4d1135e4 296
5dd9488c
FB
297 TEST_JCC("be", 1, 1);
298 TEST_JCC("be", 1, 0);
299 TEST_JCC("be", 1, -1);
4d1135e4 300
5dd9488c
FB
301 TEST_JCC("ae", 1, 1);
302 TEST_JCC("ae", 1, 0);
303 TEST_JCC("ae", 1, -1);
4d1135e4 304
5dd9488c
FB
305 TEST_JCC("a", 1, 1);
306 TEST_JCC("a", 1, 0);
307 TEST_JCC("a", 1, -1);
4d1135e4
FB
308
309
5dd9488c
FB
310 TEST_JCC("p", 1, 1);
311 TEST_JCC("p", 1, 0);
4d1135e4 312
5dd9488c
FB
313 TEST_JCC("np", 1, 1);
314 TEST_JCC("np", 1, 0);
4d1135e4 315
5dd9488c
FB
316 TEST_JCC("o", 0x7fffffff, 0);
317 TEST_JCC("o", 0x7fffffff, -1);
4d1135e4 318
5dd9488c
FB
319 TEST_JCC("no", 0x7fffffff, 0);
320 TEST_JCC("no", 0x7fffffff, -1);
4d1135e4 321
5dd9488c
FB
322 TEST_JCC("s", 0, 1);
323 TEST_JCC("s", 0, -1);
324 TEST_JCC("s", 0, 0);
4d1135e4 325
5dd9488c
FB
326 TEST_JCC("ns", 0, 1);
327 TEST_JCC("ns", 0, -1);
328 TEST_JCC("ns", 0, 0);
4d1135e4
FB
329}
330
4b74fe1f
FB
331#undef CC_MASK
332#define CC_MASK (CC_O | CC_C)
333
334#define OP mul
335#include "test-i386-muldiv.h"
336
337#define OP imul
338#include "test-i386-muldiv.h"
339
340#undef CC_MASK
341#define CC_MASK (0)
342
343#define OP div
344#include "test-i386-muldiv.h"
345
346#define OP idiv
347#include "test-i386-muldiv.h"
348
349void test_imulw2(int op0, int op1)
350{
351 int res, s1, s0, flags;
352 s0 = op0;
353 s1 = op1;
354 res = s0;
355 flags = 0;
356 asm ("push %4\n\t"
357 "popf\n\t"
358 "imulw %w2, %w0\n\t"
359 "pushf\n\t"
360 "popl %1\n\t"
361 : "=q" (res), "=g" (flags)
362 : "q" (s1), "0" (res), "1" (flags));
363 printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
364 "imulw", s0, s1, res, flags & CC_MASK);
365}
366
367void test_imull2(int op0, int op1)
368{
369 int res, s1, s0, flags;
370 s0 = op0;
371 s1 = op1;
372 res = s0;
373 flags = 0;
374 asm ("push %4\n\t"
375 "popf\n\t"
376 "imull %2, %0\n\t"
377 "pushf\n\t"
378 "popl %1\n\t"
379 : "=q" (res), "=g" (flags)
380 : "q" (s1), "0" (res), "1" (flags));
381 printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
382 "imull", s0, s1, res, flags & CC_MASK);
383}
384
385void test_mul(void)
386{
387 test_imulb(0x1234561d, 4);
388 test_imulb(3, -4);
389 test_imulb(0x80, 0x80);
390 test_imulb(0x10, 0x10);
391
392 test_imulw(0, 0x1234001d, 45);
393 test_imulw(0, 23, -45);
394 test_imulw(0, 0x8000, 0x8000);
395 test_imulw(0, 0x100, 0x100);
396
397 test_imull(0, 0x1234001d, 45);
398 test_imull(0, 23, -45);
399 test_imull(0, 0x80000000, 0x80000000);
400 test_imull(0, 0x10000, 0x10000);
401
402 test_mulb(0x1234561d, 4);
403 test_mulb(3, -4);
404 test_mulb(0x80, 0x80);
405 test_mulb(0x10, 0x10);
406
407 test_mulw(0, 0x1234001d, 45);
408 test_mulw(0, 23, -45);
409 test_mulw(0, 0x8000, 0x8000);
410 test_mulw(0, 0x100, 0x100);
411
412 test_mull(0, 0x1234001d, 45);
413 test_mull(0, 23, -45);
414 test_mull(0, 0x80000000, 0x80000000);
415 test_mull(0, 0x10000, 0x10000);
416
417 test_imulw2(0x1234001d, 45);
418 test_imulw2(23, -45);
419 test_imulw2(0x8000, 0x8000);
420 test_imulw2(0x100, 0x100);
421
422 test_imull2(0x1234001d, 45);
423 test_imull2(23, -45);
424 test_imull2(0x80000000, 0x80000000);
425 test_imull2(0x10000, 0x10000);
426
427 test_idivb(0x12341678, 0x127e);
428 test_idivb(0x43210123, -5);
429 test_idivb(0x12340004, -1);
430
431 test_idivw(0, 0x12345678, 12347);
432 test_idivw(0, -23223, -45);
433 test_idivw(0, 0x12348000, -1);
434 test_idivw(0x12343, 0x12345678, 0x81238567);
435
436 test_idivl(0, 0x12345678, 12347);
437 test_idivl(0, -233223, -45);
438 test_idivl(0, 0x80000000, -1);
439 test_idivl(0x12343, 0x12345678, 0x81234567);
440
441 test_divb(0x12341678, 0x127e);
442 test_divb(0x43210123, -5);
443 test_divb(0x12340004, -1);
444
445 test_divw(0, 0x12345678, 12347);
446 test_divw(0, -23223, -45);
447 test_divw(0, 0x12348000, -1);
448 test_divw(0x12343, 0x12345678, 0x81238567);
449
450 test_divl(0, 0x12345678, 12347);
451 test_divl(0, -233223, -45);
452 test_divl(0, 0x80000000, -1);
453 test_divl(0x12343, 0x12345678, 0x81234567);
454}
455
9d8e9c09
FB
456#define TEST_BSX(op, size, op0)\
457{\
458 int res, val, resz;\
459 val = op0;\
460 asm("xorl %1, %1 ; " #op " %" size "2, %" size "0 ; setz %b1" \
461 : "=r" (res), "=q" (resz)\
462 : "g" (val));\
463 printf("%-10s A=%08x R=%08x %d\n", #op, val, resz ? 0 : res, resz);\
464}
465
466void test_bsx(void)
467{
468 TEST_BSX(bsrw, "w", 0);
469 TEST_BSX(bsrw, "w", 0x12340128);
470 TEST_BSX(bsrl, "", 0);
471 TEST_BSX(bsrl, "", 0x00340128);
472 TEST_BSX(bsfw, "w", 0);
473 TEST_BSX(bsfw, "w", 0x12340128);
474 TEST_BSX(bsfl, "", 0);
475 TEST_BSX(bsfl, "", 0x00340128);
476}
477
55480af8
FB
478/**********************************************/
479
9d8e9c09
FB
480void test_fops(double a, double b)
481{
482 printf("a=%f b=%f a+b=%f\n", a, b, a + b);
483 printf("a=%f b=%f a-b=%f\n", a, b, a - b);
484 printf("a=%f b=%f a*b=%f\n", a, b, a * b);
485 printf("a=%f b=%f a/b=%f\n", a, b, a / b);
486 printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
487 printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
488 printf("a=%f sin(a)=%f\n", a, sin(a));
489 printf("a=%f cos(a)=%f\n", a, cos(a));
490 printf("a=%f tan(a)=%f\n", a, tan(a));
491 printf("a=%f log(a)=%f\n", a, log(a));
492 printf("a=%f exp(a)=%f\n", a, exp(a));
493 printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
494 /* just to test some op combining */
495 printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
496 printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
497 printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
498
499}
500
501void test_fcmp(double a, double b)
502{
503 printf("(%f<%f)=%d\n",
504 a, b, a < b);
505 printf("(%f<=%f)=%d\n",
506 a, b, a <= b);
507 printf("(%f==%f)=%d\n",
508 a, b, a == b);
509 printf("(%f>%f)=%d\n",
510 a, b, a > b);
511 printf("(%f<=%f)=%d\n",
512 a, b, a >= b);
513}
514
515void test_fcvt(double a)
516{
517 float fa;
518 long double la;
519
520 fa = a;
521 la = a;
522 printf("(float)%f = %f\n", a, fa);
523 printf("(long double)%f = %Lf\n", a, la);
c5e9815d
FB
524 printf("a=%016Lx\n", *(long long *)&a);
525 printf("la=%016Lx %04x\n", *(long long *)&la,
526 *(unsigned short *)((char *)(&la) + 8));
9d8e9c09
FB
527 printf("a=%f floor(a)=%f\n", a, floor(a));
528 printf("a=%f ceil(a)=%f\n", a, ceil(a));
529 printf("a=%f rint(a)=%f\n", a, rint(a));
530}
531
532#define TEST(N) \
533 asm("fld" #N : "=t" (a)); \
534 printf("fld" #N "= %f\n", a);
535
536void test_fconst(void)
537{
538 double a;
539 TEST(1);
540 TEST(l2t);
541 TEST(l2e);
542 TEST(pi);
543 TEST(lg2);
544 TEST(ln2);
545 TEST(z);
546}
547
c5e9815d
FB
548void test_fbcd(double a)
549{
550 unsigned short bcd[5];
551 double b;
552
553 asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
554 asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
555 printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
556 a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
557}
558
9d8e9c09
FB
559void test_floats(void)
560{
561 test_fops(2, 3);
562 test_fops(1.4, -5);
563 test_fcmp(2, -1);
564 test_fcmp(2, 2);
565 test_fcmp(2, 3);
566 test_fcvt(1.0/7.0);
567 test_fcvt(-1.0/9.0);
568 test_fcvt(1e30);
569 test_fconst();
c5e9815d
FB
570 test_fbcd(1234567890123456);
571 test_fbcd(-123451234567890);
9d8e9c09 572}
4b74fe1f 573
55480af8
FB
574/**********************************************/
575
576#define TEST_BCD(op, op0, cc_in, cc_mask)\
577{\
578 int res, flags;\
579 res = op0;\
580 flags = cc_in;\
581 asm ("push %3\n\t"\
582 "popf\n\t"\
583 #op "\n\t"\
584 "pushf\n\t"\
585 "popl %1\n\t"\
586 : "=a" (res), "=g" (flags)\
587 : "0" (res), "1" (flags));\
588 printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
589 #op, op0, res, cc_in, flags & cc_mask);\
590}
591
592void test_bcd(void)
593{
594 TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
595 TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
596 TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
597 TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
598 TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
599 TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
600 TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
601 TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
602 TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
603 TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
604 TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
605 TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
606 TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
607
608 TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
609 TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
610 TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
611 TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
612 TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
613 TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
614 TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
615 TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
616 TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
617 TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
618 TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
619 TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
620 TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
621
622 TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
623 TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
624 TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
625 TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
626 TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
627 TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
628 TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
629 TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
630
631 TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
632 TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
633 TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
634 TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
635 TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
636 TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
637 TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
638 TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
639
640 TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
641 TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
642}
643
e5918247
FB
644#define TEST_XCHG(op, size, opconst)\
645{\
646 int op0, op1;\
647 op0 = 0x12345678;\
648 op1 = 0xfbca7654;\
649 asm(#op " %" size "0, %" size "1" \
650 : "=q" (op0), opconst (op1) \
651 : "0" (op0), "1" (op1));\
652 printf("%-10s A=%08x B=%08x\n",\
653 #op, op0, op1);\
654}
655
656#define TEST_CMPXCHG(op, size, opconst, eax)\
657{\
658 int op0, op1;\
659 op0 = 0x12345678;\
660 op1 = 0xfbca7654;\
661 asm(#op " %" size "0, %" size "1" \
662 : "=q" (op0), opconst (op1) \
663 : "0" (op0), "1" (op1), "a" (eax));\
664 printf("%-10s EAX=%08x A=%08x C=%08x\n",\
665 #op, eax, op0, op1);\
666}
667
668void test_xchg(void)
669{
670 TEST_XCHG(xchgl, "", "=q");
671 TEST_XCHG(xchgw, "w", "=q");
672 TEST_XCHG(xchgb, "b", "=q");
673
674 TEST_XCHG(xchgl, "", "=m");
675 TEST_XCHG(xchgw, "w", "=m");
676 TEST_XCHG(xchgb, "b", "=m");
677
678 TEST_XCHG(xaddl, "", "=q");
679 TEST_XCHG(xaddw, "w", "=q");
680 TEST_XCHG(xaddb, "b", "=q");
681
682 TEST_XCHG(xaddl, "", "=m");
683 TEST_XCHG(xaddw, "w", "=m");
684 TEST_XCHG(xaddb, "b", "=m");
685
686 TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654);
687 TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654);
688 TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654);
689
690 TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc);
691 TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc);
692 TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc);
693
694 TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654);
695 TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654);
696 TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654);
697
698 TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc);
699 TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc);
700 TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc);
701}
702
6dbad63e
FB
703/**********************************************/
704/* segmentation tests */
705
706#include <asm/ldt.h>
707#include <linux/unistd.h>
708
709_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
710
711uint8_t seg_data1[4096];
712uint8_t seg_data2[4096];
713
e5918247 714#define MK_SEL(n) (((n) << 3) | 7)
6dbad63e 715
288426fe
FB
716#define TEST_LR(op, size, seg, mask)\
717{\
718 int res, res2;\
719 res = 0x12345678;\
720 asm (op " %" size "2, %" size "0\n" \
721 "movl $0, %1\n"\
722 "jnz 1f\n"\
723 "movl $1, %1\n"\
724 "1:\n"\
725 : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\
726 printf(op ": Z=%d %08x\n", res2, res & ~(mask));\
727}
728
6dbad63e
FB
729/* NOTE: we use Linux modify_ldt syscall */
730void test_segs(void)
731{
732 struct modify_ldt_ldt_s ldt;
733 long long ldt_table[3];
04369ff2 734 int res, res2;
6dbad63e 735 char tmp;
e1d4294a
FB
736 struct {
737 uint32_t offset;
738 uint16_t seg;
739 } __attribute__((packed)) segoff;
6dbad63e
FB
740
741 ldt.entry_number = 1;
742 ldt.base_addr = (unsigned long)&seg_data1;
743 ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
744 ldt.seg_32bit = 1;
745 ldt.contents = MODIFY_LDT_CONTENTS_DATA;
746 ldt.read_exec_only = 0;
747 ldt.limit_in_pages = 1;
748 ldt.seg_not_present = 0;
749 ldt.useable = 1;
750 modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
751
752 ldt.entry_number = 2;
753 ldt.base_addr = (unsigned long)&seg_data2;
754 ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
755 ldt.seg_32bit = 1;
756 ldt.contents = MODIFY_LDT_CONTENTS_DATA;
757 ldt.read_exec_only = 0;
758 ldt.limit_in_pages = 1;
759 ldt.seg_not_present = 0;
760 ldt.useable = 1;
761 modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
762
763 modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
04369ff2
FB
764#if 0
765 {
766 int i;
767 for(i=0;i<3;i++)
768 printf("%d: %016Lx\n", i, ldt_table[i]);
769 }
770#endif
6dbad63e
FB
771 /* do some tests with fs or gs */
772 asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
773 asm volatile ("movl %0, %%gs" : : "r" (MK_SEL(2)));
774
775 seg_data1[1] = 0xaa;
776 seg_data2[1] = 0x55;
777
778 asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
779 printf("FS[1] = %02x\n", res);
780
781 asm volatile ("gs movzbl 0x1, %0" : "=r" (res));
782 printf("GS[1] = %02x\n", res);
783
784 /* tests with ds/ss (implicit segment case) */
785 tmp = 0xa5;
786 asm volatile ("pushl %%ebp\n\t"
787 "pushl %%ds\n\t"
788 "movl %2, %%ds\n\t"
789 "movl %3, %%ebp\n\t"
790 "movzbl 0x1, %0\n\t"
791 "movzbl (%%ebp), %1\n\t"
792 "popl %%ds\n\t"
793 "popl %%ebp\n\t"
794 : "=r" (res), "=r" (res2)
795 : "r" (MK_SEL(1)), "r" (&tmp));
796 printf("DS[1] = %02x\n", res);
797 printf("SS[tmp] = %02x\n", res2);
e1d4294a
FB
798
799 segoff.seg = MK_SEL(2);
800 segoff.offset = 0xabcdef12;
801 asm volatile("lfs %2, %0\n\t"
802 "movl %%fs, %1\n\t"
803 : "=r" (res), "=g" (res2)
804 : "m" (segoff));
805 printf("FS:reg = %04x:%08x\n", res2, res);
288426fe
FB
806
807 TEST_LR("larw", "w", MK_SEL(2), 0x0100);
808 TEST_LR("larl", "", MK_SEL(2), 0x0100);
809 TEST_LR("lslw", "w", MK_SEL(2), 0);
810 TEST_LR("lsll", "", MK_SEL(2), 0);
811
812 TEST_LR("larw", "w", 0xfff8, 0);
813 TEST_LR("larl", "", 0xfff8, 0);
814 TEST_LR("lslw", "w", 0xfff8, 0);
815 TEST_LR("lsll", "", 0xfff8, 0);
6dbad63e 816}
55480af8 817
e5918247
FB
818/* 16 bit code test */
819extern char code16_start, code16_end;
820extern char code16_func1;
821extern char code16_func2;
822extern char code16_func3;
a300e691 823
e5918247 824void test_code16(void)
1a9353d2 825{
e5918247
FB
826 struct modify_ldt_ldt_s ldt;
827 int res, res2;
a300e691 828
e5918247
FB
829 /* build a code segment */
830 ldt.entry_number = 1;
831 ldt.base_addr = (unsigned long)&code16_start;
832 ldt.limit = &code16_end - &code16_start;
833 ldt.seg_32bit = 0;
834 ldt.contents = MODIFY_LDT_CONTENTS_CODE;
835 ldt.read_exec_only = 0;
836 ldt.limit_in_pages = 0;
837 ldt.seg_not_present = 0;
838 ldt.useable = 1;
839 modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
a300e691 840
e5918247
FB
841 /* call the first function */
842 asm volatile ("lcall %1, %2"
843 : "=a" (res)
844 : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
845 printf("func1() = 0x%08x\n", res);
846 asm volatile ("lcall %2, %3"
847 : "=a" (res), "=c" (res2)
848 : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
849 printf("func2() = 0x%08x spdec=%d\n", res, res2);
850 asm volatile ("lcall %1, %2"
851 : "=a" (res)
852 : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
853 printf("func3() = 0x%08x\n", res);
1a9353d2
FB
854}
855
e1d4294a
FB
856void test_misc(void)
857{
858 char table[256];
859 int res, i;
860
861 for(i=0;i<256;i++) table[i] = 256 - i;
862 res = 0x12345678;
863 asm ("xlat" : "=a" (res) : "b" (table), "0" (res));
864 printf("xlat: EAX=%08x\n", res);
865}
866
867uint8_t str_buffer[4096];
868
869#define TEST_STRING1(OP, size, DF, REP)\
870{\
871 int esi, edi, eax, ecx, eflags;\
872\
873 esi = (long)(str_buffer + sizeof(str_buffer) / 2);\
874 edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\
875 eax = 0x12345678;\
876 ecx = 17;\
877\
878 asm volatile ("pushl $0\n\t"\
879 "popf\n\t"\
880 DF "\n\t"\
881 REP #OP size "\n\t"\
882 "cld\n\t"\
883 "pushf\n\t"\
884 "popl %4\n\t"\
885 : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\
886 : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\
887 printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\
888 REP #OP size, esi, edi, eax, ecx,\
889 eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\
890}
891
892#define TEST_STRING(OP, REP)\
893 TEST_STRING1(OP, "b", "", REP);\
894 TEST_STRING1(OP, "w", "", REP);\
895 TEST_STRING1(OP, "l", "", REP);\
896 TEST_STRING1(OP, "b", "std", REP);\
897 TEST_STRING1(OP, "w", "std", REP);\
898 TEST_STRING1(OP, "l", "std", REP)
899
900void test_string(void)
901{
902 int i;
903 for(i = 0;i < sizeof(str_buffer); i++)
904 str_buffer[i] = i + 0x56;
905 TEST_STRING(stos, "");
906 TEST_STRING(stos, "rep ");
907 TEST_STRING(lods, ""); /* to verify stos */
908 TEST_STRING(lods, "rep ");
909 TEST_STRING(movs, "");
910 TEST_STRING(movs, "rep ");
911 TEST_STRING(lods, ""); /* to verify stos */
912
913 /* XXX: better tests */
914 TEST_STRING(scas, "");
915 TEST_STRING(scas, "repz ");
916 TEST_STRING(scas, "repnz ");
917 TEST_STRING(cmps, "");
918 TEST_STRING(cmps, "repz ");
919 TEST_STRING(cmps, "repnz ");
920}
e5918247 921
3a27ad0b
FB
922/* VM86 test */
923
924static inline void set_bit(uint8_t *a, unsigned int bit)
925{
926 a[bit / 8] |= (1 << (bit % 8));
927}
928
929static inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg)
930{
931 return (uint8_t *)((seg << 4) + (reg & 0xffff));
932}
933
934static inline void pushw(struct vm86_regs *r, int val)
935{
936 r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff);
937 *(uint16_t *)seg_to_linear(r->ss, r->esp) = val;
938}
939
940#undef __syscall_return
941#define __syscall_return(type, res) \
942do { \
943 return (type) (res); \
944} while (0)
945
946_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
947
948extern char vm86_code_start;
949extern char vm86_code_end;
950
951#define VM86_CODE_CS 0x100
952#define VM86_CODE_IP 0x100
953
954void test_vm86(void)
955{
956 struct vm86plus_struct ctx;
957 struct vm86_regs *r;
958 uint8_t *vm86_mem;
959 int seg, ret;
960
961 vm86_mem = mmap((void *)0x00000000, 0x110000,
962 PROT_WRITE | PROT_READ | PROT_EXEC,
963 MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
964 if (vm86_mem == MAP_FAILED) {
965 printf("ERROR: could not map vm86 memory");
966 return;
967 }
968 memset(&ctx, 0, sizeof(ctx));
969
970 /* init basic registers */
971 r = &ctx.regs;
972 r->eip = VM86_CODE_IP;
973 r->esp = 0xfffe;
974 seg = VM86_CODE_CS;
975 r->cs = seg;
976 r->ss = seg;
977 r->ds = seg;
978 r->es = seg;
979 r->fs = seg;
980 r->gs = seg;
981 r->eflags = VIF_MASK;
982
983 /* move code to proper address. We use the same layout as a .com
984 dos program. */
985 memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP,
986 &vm86_code_start, &vm86_code_end - &vm86_code_start);
987
988 /* mark int 0x21 as being emulated */
989 set_bit((uint8_t *)&ctx.int_revectored, 0x21);
990
991 for(;;) {
992 ret = vm86(VM86_ENTER, &ctx);
993 switch(VM86_TYPE(ret)) {
994 case VM86_INTx:
995 {
996 int int_num, ah;
997
998 int_num = VM86_ARG(ret);
999 if (int_num != 0x21)
1000 goto unknown_int;
1001 ah = (r->eax >> 8) & 0xff;
1002 switch(ah) {
1003 case 0x00: /* exit */
1004 goto the_end;
1005 case 0x02: /* write char */
1006 {
1007 uint8_t c = r->edx;
1008 putchar(c);
1009 }
1010 break;
1011 case 0x09: /* write string */
1012 {
1013 uint8_t c, *ptr;
1014 ptr = seg_to_linear(r->ds, r->edx);
1015 for(;;) {
1016 c = *ptr++;
1017 if (c == '$')
1018 break;
1019 putchar(c);
1020 }
1021 r->eax = (r->eax & ~0xff) | '$';
1022 }
1023 break;
1024 case 0xff: /* extension: write hex number in edx */
1025 printf("%08x\n", (int)r->edx);
1026 break;
1027 default:
1028 unknown_int:
1029 printf("unsupported int 0x%02x\n", int_num);
1030 goto the_end;
1031 }
1032 }
1033 break;
1034 case VM86_SIGNAL:
1035 /* a signal came, we just ignore that */
1036 break;
1037 case VM86_STI:
1038 break;
1039 default:
1040 printf("ERROR: unhandled vm86 return code (0x%x)\n", ret);
1041 goto the_end;
1042 }
1043 }
1044 the_end:
1045 printf("VM86 end\n");
1046 munmap(vm86_mem, 0x110000);
1047}
1048
1049/* exception tests */
1050#ifndef REG_EAX
1051#define REG_EAX EAX
1052#define REG_EBX EBX
1053#define REG_ECX ECX
1054#define REG_EDX EDX
1055#define REG_ESI ESI
1056#define REG_EDI EDI
1057#define REG_EBP EBP
1058#define REG_ESP ESP
1059#define REG_EIP EIP
1060#define REG_EFL EFL
1061#define REG_TRAPNO TRAPNO
1062#define REG_ERR ERR
1063#endif
1064
1065jmp_buf jmp_env;
1066int dump_eip;
1067int dump_si_addr;
1068int v1;
1069int tab[2];
1070
1071void sig_handler(int sig, siginfo_t *info, void *puc)
1072{
1073 struct ucontext *uc = puc;
1074
1075 printf("si_signo=%d si_errno=%d si_code=%d",
1076 info->si_signo, info->si_errno, info->si_code);
1077 if (dump_si_addr) {
1078 printf(" si_addr=0x%08lx",
1079 (unsigned long)info->si_addr);
1080 }
1081 printf("\n");
1082
1083 printf("trapno=0x%02x err=0x%08x",
1084 uc->uc_mcontext.gregs[REG_TRAPNO],
1085 uc->uc_mcontext.gregs[REG_ERR]);
1086 if (dump_eip)
1087 printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]);
1088 printf("\n");
1089 longjmp(jmp_env, 1);
1090}
1091
1092void test_exceptions(void)
1093{
1094 struct sigaction act;
1095 volatile int val;
1096
1097 act.sa_sigaction = sig_handler;
1098 sigemptyset(&act.sa_mask);
1099 act.sa_flags = SA_SIGINFO;
1100 sigaction(SIGFPE, &act, NULL);
1101 sigaction(SIGILL, &act, NULL);
1102 sigaction(SIGSEGV, &act, NULL);
1103 sigaction(SIGTRAP, &act, NULL);
1104
1105 /* test division by zero reporting */
1106 dump_eip = 0;
1107 dump_si_addr = 0;
1108 printf("DIVZ exception (currently imprecise):\n");
1109 if (setjmp(jmp_env) == 0) {
1110 /* now divide by zero */
1111 v1 = 0;
1112 v1 = 2 / v1;
1113 }
1114
1115 dump_si_addr = 1;
1116 printf("BOUND exception (currently imprecise):\n");
1117 if (setjmp(jmp_env) == 0) {
1118 /* bound exception */
1119 tab[0] = 1;
1120 tab[1] = 10;
1121 asm volatile ("bound %0, %1" : : "r" (11), "m" (tab));
1122 }
1123
1124 /* test SEGV reporting */
1125 printf("PF exception (currently imprecise):\n");
1126 if (setjmp(jmp_env) == 0) {
1127 /* now store in an invalid address */
1128 *(char *)0x1234 = 1;
1129 }
1130
1131 /* test SEGV reporting */
1132 printf("PF exception (currently imprecise):\n");
1133 if (setjmp(jmp_env) == 0) {
1134 /* read from an invalid address */
1135 v1 = *(char *)0x1234;
1136 }
1137
1138 printf("segment GPF exception (currently imprecise):\n");
1139 if (setjmp(jmp_env) == 0) {
1140 /* load an invalid segment */
1141 asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0));
1142 }
1143
1144 dump_eip = 1;
1145 /* test illegal instruction reporting */
1146 printf("UD2 exception:\n");
1147 if (setjmp(jmp_env) == 0) {
1148 /* now execute an invalid instruction */
1149 asm volatile("ud2");
1150 }
1151
1152 printf("INT exception:\n");
1153 if (setjmp(jmp_env) == 0) {
1154 asm volatile ("int $0xfd");
1155 }
1156
1157 printf("INT3 exception:\n");
1158 if (setjmp(jmp_env) == 0) {
1159 asm volatile ("int3");
1160 }
1161
1162 printf("CLI exception:\n");
1163 if (setjmp(jmp_env) == 0) {
1164 asm volatile ("cli");
1165 }
1166
1167 printf("STI exception:\n");
1168 if (setjmp(jmp_env) == 0) {
1169 asm volatile ("cli");
1170 }
1171
1172 printf("INTO exception:\n");
1173 if (setjmp(jmp_env) == 0) {
1174 /* overflow exception */
1175 asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
1176 }
1177
1178 printf("OUTB exception:\n");
1179 if (setjmp(jmp_env) == 0) {
1180 asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
1181 }
1182
1183 printf("INB exception:\n");
1184 if (setjmp(jmp_env) == 0) {
1185 asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
1186 }
1187
1188 printf("REP OUTSB exception:\n");
1189 if (setjmp(jmp_env) == 0) {
1190 asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
1191 }
1192
1193 printf("REP INSB exception:\n");
1194 if (setjmp(jmp_env) == 0) {
1195 asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
1196 }
1197
1198 printf("HLT exception:\n");
1199 if (setjmp(jmp_env) == 0) {
1200 asm volatile ("hlt");
1201 }
1202
1203 printf("single step exception:\n");
1204 val = 0;
1205 if (setjmp(jmp_env) == 0) {
1206 asm volatile ("pushf\n"
1207 "orl $0x00100, (%%esp)\n"
1208 "popf\n"
1209 "movl $0xabcd, %0\n"
1210 "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory");
1211 }
1212 printf("val=0x%x\n", val);
1213}
1214
1215/* self modifying code test */
1216uint8_t code[] = {
1217 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */
1218 0xc3, /* ret */
1219};
1220
1221void test_self_modifying_code(void)
1222{
1223 int (*func)(void);
1224
1225 func = (void *)code;
1226 printf("self modifying code:\n");
1227 printf("func1 = 0x%x\n", func());
1228 code[1] = 0x2;
1229 printf("func1 = 0x%x\n", func());
1230}
1231
4d1135e4
FB
1232static void *call_end __init_call = NULL;
1233
1234int main(int argc, char **argv)
1235{
1236 void **ptr;
1237 void (*func)(void);
4b74fe1f 1238
4d1135e4
FB
1239 ptr = &call_start + 1;
1240 while (*ptr != NULL) {
1241 func = *ptr++;
1242 func();
1243 }
9d8e9c09 1244 test_bsx();
d57c4e01 1245 test_mul();
4d1135e4 1246 test_jcc();
9d8e9c09 1247 test_floats();
55480af8 1248 test_bcd();
1a9353d2 1249 test_xchg();
e1d4294a
FB
1250 test_string();
1251 test_misc();
6dbad63e
FB
1252 test_lea();
1253 test_segs();
e5918247 1254 test_code16();
3a27ad0b
FB
1255 test_vm86();
1256 test_exceptions();
1257 test_self_modifying_code();
4d1135e4
FB
1258 return 0;
1259}
This page took 0.16253 seconds and 4 git commands to generate.