Statistics
| Branch: | Revision:

root / tests / test-i386.c @ 1a9353d2

History | View | Annotate | Download (18.2 kB)

1
#include <stdlib.h>
2
#include <stdio.h>
3
#include <inttypes.h>
4
#include <math.h>
5

    
6
#define xglue(x, y) x ## y
7
#define glue(x, y) xglue(x, y)
8
#define stringify(s)        tostring(s)
9
#define tostring(s)        #s
10

    
11
#define CC_C           0x0001
12
#define CC_P         0x0004
13
#define CC_A        0x0010
14
#define CC_Z        0x0040
15
#define CC_S    0x0080
16
#define CC_O    0x0800
17

    
18
#define __init_call        __attribute__ ((unused,__section__ (".initcall.init")))
19

    
20
static void *call_start __init_call = NULL;
21

    
22
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)
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
#undef CC_MASK
71
#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O)
72

    
73
#define OP shl
74
#include "test-i386-shift.h"
75

    
76
#define OP shr
77
#include "test-i386-shift.h"
78

    
79
#define OP sar
80
#include "test-i386-shift.h"
81

    
82
#define OP rol
83
#include "test-i386-shift.h"
84

    
85
#define OP ror
86
#include "test-i386-shift.h"
87

    
88
#define OP rcr
89
#define OP_CC
90
#include "test-i386-shift.h"
91

    
92
#define OP rcl
93
#define OP_CC
94
#include "test-i386-shift.h"
95

    
96
#define OP shld
97
#define OP_SHIFTD
98
#define OP_NOBYTE
99
#include "test-i386-shift.h"
100

    
101
#define OP shrd
102
#define OP_SHIFTD
103
#define OP_NOBYTE
104
#include "test-i386-shift.h"
105

    
106
/* XXX: should be more precise ? */
107
#undef CC_MASK
108
#define CC_MASK (CC_C)
109

    
110
#define OP bt
111
#define OP_NOBYTE
112
#include "test-i386-shift.h"
113

    
114
#define OP bts
115
#define OP_NOBYTE
116
#include "test-i386-shift.h"
117

    
118
#define OP btr
119
#define OP_NOBYTE
120
#include "test-i386-shift.h"
121

    
122
#define OP btc
123
#define OP_NOBYTE
124
#include "test-i386-shift.h"
125

    
126
/* lea test (modrm support) */
127
#define TEST_LEA(STR)\
128
{\
129
    asm("leal " STR ", %0"\
130
        : "=r" (res)\
131
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
132
    printf("lea %s = %08x\n", STR, res);\
133
}
134

    
135
#define TEST_LEA16(STR)\
136
{\
137
    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
138
        : "=wq" (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

    
144
void test_lea(void)
145
{
146
    int eax, ebx, ecx, edx, esi, edi, res;
147
    eax = 0x0001;
148
    ebx = 0x0002;
149
    ecx = 0x0004;
150
    edx = 0x0008;
151
    esi = 0x0010;
152
    edi = 0x0020;
153

    
154
    TEST_LEA("0x4000");
155

    
156
    TEST_LEA("(%%eax)");
157
    TEST_LEA("(%%ebx)");
158
    TEST_LEA("(%%ecx)");
159
    TEST_LEA("(%%edx)");
160
    TEST_LEA("(%%esi)");
161
    TEST_LEA("(%%edi)");
162

    
163
    TEST_LEA("0x40(%%eax)");
164
    TEST_LEA("0x40(%%ebx)");
165
    TEST_LEA("0x40(%%ecx)");
166
    TEST_LEA("0x40(%%edx)");
167
    TEST_LEA("0x40(%%esi)");
168
    TEST_LEA("0x40(%%edi)");
169

    
170
    TEST_LEA("0x4000(%%eax)");
171
    TEST_LEA("0x4000(%%ebx)");
172
    TEST_LEA("0x4000(%%ecx)");
173
    TEST_LEA("0x4000(%%edx)");
174
    TEST_LEA("0x4000(%%esi)");
175
    TEST_LEA("0x4000(%%edi)");
176

    
177
    TEST_LEA("(%%eax, %%ecx)");
178
    TEST_LEA("(%%ebx, %%edx)");
179
    TEST_LEA("(%%ecx, %%ecx)");
180
    TEST_LEA("(%%edx, %%ecx)");
181
    TEST_LEA("(%%esi, %%ecx)");
182
    TEST_LEA("(%%edi, %%ecx)");
183

    
184
    TEST_LEA("0x40(%%eax, %%ecx)");
185
    TEST_LEA("0x4000(%%ebx, %%edx)");
186

    
187
    TEST_LEA("(%%ecx, %%ecx, 2)");
188
    TEST_LEA("(%%edx, %%ecx, 4)");
189
    TEST_LEA("(%%esi, %%ecx, 8)");
190

    
191
    TEST_LEA("(,%%eax, 2)");
192
    TEST_LEA("(,%%ebx, 4)");
193
    TEST_LEA("(,%%ecx, 8)");
194

    
195
    TEST_LEA("0x40(,%%eax, 2)");
196
    TEST_LEA("0x40(,%%ebx, 4)");
197
    TEST_LEA("0x40(,%%ecx, 8)");
198

    
199

    
200
    TEST_LEA("-10(%%ecx, %%ecx, 2)");
201
    TEST_LEA("-10(%%edx, %%ecx, 4)");
202
    TEST_LEA("-10(%%esi, %%ecx, 8)");
203

    
204
    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
205
    TEST_LEA("0x4000(%%edx, %%ecx, 4)");
206
    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
207

    
208
    /* limited 16 bit addressing test */
209
    TEST_LEA16("0x4000");
210
    TEST_LEA16("(%%bx)");
211
    TEST_LEA16("(%%si)");
212
    TEST_LEA16("(%%di)");
213
    TEST_LEA16("0x40(%%bx)");
214
    TEST_LEA16("0x40(%%si)");
215
    TEST_LEA16("0x40(%%di)");
216
    TEST_LEA16("0x4000(%%bx)");
217
    TEST_LEA16("0x4000(%%si)");
218
    TEST_LEA16("(%%bx,%%si)");
219
    TEST_LEA16("(%%bx,%%di)");
220
    TEST_LEA16("0x40(%%bx,%%si)");
221
    TEST_LEA16("0x40(%%bx,%%di)");
222
    TEST_LEA16("0x4000(%%bx,%%si)");
223
    TEST_LEA16("0x4000(%%bx,%%di)");
224
}
225

    
226
#define TEST_JCC(JCC, v1, v2)\
227
{\
228
    asm("movl $1, %0\n\t"\
229
        "cmpl %2, %1\n\t"\
230
        JCC " 1f\n\t"\
231
        "movl $0, %0\n\t"\
232
        "1:\n\t"\
233
        : "=r" (res)\
234
        : "r" (v1), "r" (v2));\
235
    printf("%-10s %d\n", JCC, res);\
236
}
237

    
238
/* various jump tests */
239
void test_jcc(void)
240
{
241
    int res;
242

    
243
    TEST_JCC("jne", 1, 1);
244
    TEST_JCC("jne", 1, 0);
245

    
246
    TEST_JCC("je", 1, 1);
247
    TEST_JCC("je", 1, 0);
248

    
249
    TEST_JCC("jl", 1, 1);
250
    TEST_JCC("jl", 1, 0);
251
    TEST_JCC("jl", 1, -1);
252

    
253
    TEST_JCC("jle", 1, 1);
254
    TEST_JCC("jle", 1, 0);
255
    TEST_JCC("jle", 1, -1);
256

    
257
    TEST_JCC("jge", 1, 1);
258
    TEST_JCC("jge", 1, 0);
259
    TEST_JCC("jge", -1, 1);
260

    
261
    TEST_JCC("jg", 1, 1);
262
    TEST_JCC("jg", 1, 0);
263
    TEST_JCC("jg", 1, -1);
264

    
265
    TEST_JCC("jb", 1, 1);
266
    TEST_JCC("jb", 1, 0);
267
    TEST_JCC("jb", 1, -1);
268

    
269
    TEST_JCC("jbe", 1, 1);
270
    TEST_JCC("jbe", 1, 0);
271
    TEST_JCC("jbe", 1, -1);
272

    
273
    TEST_JCC("jae", 1, 1);
274
    TEST_JCC("jae", 1, 0);
275
    TEST_JCC("jae", 1, -1);
276

    
277
    TEST_JCC("ja", 1, 1);
278
    TEST_JCC("ja", 1, 0);
279
    TEST_JCC("ja", 1, -1);
280

    
281

    
282
    TEST_JCC("jp", 1, 1);
283
    TEST_JCC("jp", 1, 0);
284

    
285
    TEST_JCC("jnp", 1, 1);
286
    TEST_JCC("jnp", 1, 0);
287

    
288
    TEST_JCC("jo", 0x7fffffff, 0);
289
    TEST_JCC("jo", 0x7fffffff, -1);
290

    
291
    TEST_JCC("jno", 0x7fffffff, 0);
292
    TEST_JCC("jno", 0x7fffffff, -1);
293

    
294
    TEST_JCC("js", 0, 1);
295
    TEST_JCC("js", 0, -1);
296
    TEST_JCC("js", 0, 0);
297

    
298
    TEST_JCC("jns", 0, 1);
299
    TEST_JCC("jns", 0, -1);
300
    TEST_JCC("jns", 0, 0);
301
}
302

    
303
#undef CC_MASK
304
#define CC_MASK (CC_O | CC_C)
305

    
306
#define OP mul
307
#include "test-i386-muldiv.h"
308

    
309
#define OP imul
310
#include "test-i386-muldiv.h"
311

    
312
#undef CC_MASK
313
#define CC_MASK (0)
314

    
315
#define OP div
316
#include "test-i386-muldiv.h"
317

    
318
#define OP idiv
319
#include "test-i386-muldiv.h"
320

    
321
void test_imulw2(int op0, int op1) 
322
{
323
    int res, s1, s0, flags;
324
    s0 = op0;
325
    s1 = op1;
326
    res = s0;
327
    flags = 0;
328
    asm ("push %4\n\t"
329
         "popf\n\t"
330
         "imulw %w2, %w0\n\t" 
331
         "pushf\n\t"
332
         "popl %1\n\t"
333
         : "=q" (res), "=g" (flags)
334
         : "q" (s1), "0" (res), "1" (flags));
335
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
336
           "imulw", s0, s1, res, flags & CC_MASK);
337
}
338

    
339
void test_imull2(int op0, int op1) 
340
{
341
    int res, s1, s0, flags;
342
    s0 = op0;
343
    s1 = op1;
344
    res = s0;
345
    flags = 0;
346
    asm ("push %4\n\t"
347
         "popf\n\t"
348
         "imull %2, %0\n\t" 
349
         "pushf\n\t"
350
         "popl %1\n\t"
351
         : "=q" (res), "=g" (flags)
352
         : "q" (s1), "0" (res), "1" (flags));
353
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
354
           "imull", s0, s1, res, flags & CC_MASK);
355
}
356

    
357
void test_mul(void)
358
{
359
    test_imulb(0x1234561d, 4);
360
    test_imulb(3, -4);
361
    test_imulb(0x80, 0x80);
362
    test_imulb(0x10, 0x10);
363

    
364
    test_imulw(0, 0x1234001d, 45);
365
    test_imulw(0, 23, -45);
366
    test_imulw(0, 0x8000, 0x8000);
367
    test_imulw(0, 0x100, 0x100);
368

    
369
    test_imull(0, 0x1234001d, 45);
370
    test_imull(0, 23, -45);
371
    test_imull(0, 0x80000000, 0x80000000);
372
    test_imull(0, 0x10000, 0x10000);
373

    
374
    test_mulb(0x1234561d, 4);
375
    test_mulb(3, -4);
376
    test_mulb(0x80, 0x80);
377
    test_mulb(0x10, 0x10);
378

    
379
    test_mulw(0, 0x1234001d, 45);
380
    test_mulw(0, 23, -45);
381
    test_mulw(0, 0x8000, 0x8000);
382
    test_mulw(0, 0x100, 0x100);
383

    
384
    test_mull(0, 0x1234001d, 45);
385
    test_mull(0, 23, -45);
386
    test_mull(0, 0x80000000, 0x80000000);
387
    test_mull(0, 0x10000, 0x10000);
388

    
389
    test_imulw2(0x1234001d, 45);
390
    test_imulw2(23, -45);
391
    test_imulw2(0x8000, 0x8000);
392
    test_imulw2(0x100, 0x100);
393

    
394
    test_imull2(0x1234001d, 45);
395
    test_imull2(23, -45);
396
    test_imull2(0x80000000, 0x80000000);
397
    test_imull2(0x10000, 0x10000);
398

    
399
    test_idivb(0x12341678, 0x127e);
400
    test_idivb(0x43210123, -5);
401
    test_idivb(0x12340004, -1);
402

    
403
    test_idivw(0, 0x12345678, 12347);
404
    test_idivw(0, -23223, -45);
405
    test_idivw(0, 0x12348000, -1);
406
    test_idivw(0x12343, 0x12345678, 0x81238567);
407

    
408
    test_idivl(0, 0x12345678, 12347);
409
    test_idivl(0, -233223, -45);
410
    test_idivl(0, 0x80000000, -1);
411
    test_idivl(0x12343, 0x12345678, 0x81234567);
412

    
413
    test_divb(0x12341678, 0x127e);
414
    test_divb(0x43210123, -5);
415
    test_divb(0x12340004, -1);
416

    
417
    test_divw(0, 0x12345678, 12347);
418
    test_divw(0, -23223, -45);
419
    test_divw(0, 0x12348000, -1);
420
    test_divw(0x12343, 0x12345678, 0x81238567);
421

    
422
    test_divl(0, 0x12345678, 12347);
423
    test_divl(0, -233223, -45);
424
    test_divl(0, 0x80000000, -1);
425
    test_divl(0x12343, 0x12345678, 0x81234567);
426
}
427

    
428
#define TEST_BSX(op, size, op0)\
429
{\
430
    int res, val, resz;\
431
    val = op0;\
432
    asm("xorl %1, %1 ; " #op " %" size "2, %" size "0 ; setz %b1" \
433
        : "=r" (res), "=q" (resz)\
434
        : "g" (val));\
435
    printf("%-10s A=%08x R=%08x %d\n", #op, val, resz ? 0 : res, resz);\
436
}
437

    
438
void test_bsx(void)
439
{
440
    TEST_BSX(bsrw, "w", 0);
441
    TEST_BSX(bsrw, "w", 0x12340128);
442
    TEST_BSX(bsrl, "", 0);
443
    TEST_BSX(bsrl, "", 0x00340128);
444
    TEST_BSX(bsfw, "w", 0);
445
    TEST_BSX(bsfw, "w", 0x12340128);
446
    TEST_BSX(bsfl, "", 0);
447
    TEST_BSX(bsfl, "", 0x00340128);
448
}
449

    
450
/**********************************************/
451

    
452
void test_fops(double a, double b)
453
{
454
    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
455
    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
456
    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
457
    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
458
    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
459
    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
460
    printf("a=%f sin(a)=%f\n", a, sin(a));
461
    printf("a=%f cos(a)=%f\n", a, cos(a));
462
    printf("a=%f tan(a)=%f\n", a, tan(a));
463
    printf("a=%f log(a)=%f\n", a, log(a));
464
    printf("a=%f exp(a)=%f\n", a, exp(a));
465
    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
466
    /* just to test some op combining */
467
    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
468
    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
469
    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
470

    
471
}
472

    
473
void test_fcmp(double a, double b)
474
{
475
    printf("(%f<%f)=%d\n",
476
           a, b, a < b);
477
    printf("(%f<=%f)=%d\n",
478
           a, b, a <= b);
479
    printf("(%f==%f)=%d\n",
480
           a, b, a == b);
481
    printf("(%f>%f)=%d\n",
482
           a, b, a > b);
483
    printf("(%f<=%f)=%d\n",
484
           a, b, a >= b);
485
}
486

    
487
void test_fcvt(double a)
488
{
489
    float fa;
490
    long double la;
491

    
492
    fa = a;
493
    la = a;
494
    printf("(float)%f = %f\n", a, fa);
495
    printf("(long double)%f = %Lf\n", a, la);
496
    printf("a=%016Lx\n", *(long long *)&a);
497
    printf("la=%016Lx %04x\n", *(long long *)&la, 
498
           *(unsigned short *)((char *)(&la) + 8));
499
    printf("a=%f floor(a)=%f\n", a, floor(a));
500
    printf("a=%f ceil(a)=%f\n", a, ceil(a));
501
    printf("a=%f rint(a)=%f\n", a, rint(a));
502
}
503

    
504
#define TEST(N) \
505
    asm("fld" #N : "=t" (a)); \
506
    printf("fld" #N "= %f\n", a);
507

    
508
void test_fconst(void)
509
{
510
    double a;
511
    TEST(1);
512
    TEST(l2t);
513
    TEST(l2e);
514
    TEST(pi);
515
    TEST(lg2);
516
    TEST(ln2);
517
    TEST(z);
518
}
519

    
520
void test_fbcd(double a)
521
{
522
    unsigned short bcd[5];
523
    double b;
524

    
525
    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
526
    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
527
    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", 
528
           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
529
}
530

    
531
void test_floats(void)
532
{
533
    test_fops(2, 3);
534
    test_fops(1.4, -5);
535
    test_fcmp(2, -1);
536
    test_fcmp(2, 2);
537
    test_fcmp(2, 3);
538
    test_fcvt(1.0/7.0);
539
    test_fcvt(-1.0/9.0);
540
    test_fcvt(1e30);
541
    test_fconst();
542
    test_fbcd(1234567890123456);
543
    test_fbcd(-123451234567890);
544
}
545

    
546
/**********************************************/
547

    
548
#define TEST_BCD(op, op0, cc_in, cc_mask)\
549
{\
550
    int res, flags;\
551
    res = op0;\
552
    flags = cc_in;\
553
    asm ("push %3\n\t"\
554
         "popf\n\t"\
555
         #op "\n\t"\
556
         "pushf\n\t"\
557
         "popl %1\n\t"\
558
        : "=a" (res), "=g" (flags)\
559
        : "0" (res), "1" (flags));\
560
    printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\
561
           #op, op0, res, cc_in, flags & cc_mask);\
562
}
563

    
564
void test_bcd(void)
565
{
566
    TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
567
    TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
568
    TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
569
    TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
570
    TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
571
    TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
572
    TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
573
    TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
574
    TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
575
    TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
576
    TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
577
    TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
578
    TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
579

    
580
    TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
581
    TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
582
    TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
583
    TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
584
    TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
585
    TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
586
    TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
587
    TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
588
    TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A));
589
    TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
590
    TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A));
591
    TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
592
    TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A));
593

    
594
    TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A));
595
    TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A));
596
    TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A));
597
    TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A));
598
    TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A));
599
    TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A));
600
    TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A));
601
    TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A));
602
    
603
    TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A));
604
    TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A));
605
    TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A));
606
    TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A));
607
    TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A));
608
    TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A));
609
    TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A));
610
    TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A));
611

    
612
    TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
613
    TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));
614
}
615

    
616
/**********************************************/
617
/* segmentation tests */
618

    
619
#include <asm/ldt.h>
620
#include <linux/unistd.h>
621

    
622
_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
623

    
624
uint8_t seg_data1[4096];
625
uint8_t seg_data2[4096];
626

    
627
#define MK_SEL(n) (((n) << 3) | 4)
628

    
629
/* NOTE: we use Linux modify_ldt syscall */
630
void test_segs(void)
631
{
632
    struct modify_ldt_ldt_s ldt;
633
    long long ldt_table[3];
634
    int i, res, res2;
635
    char tmp;
636

    
637
    ldt.entry_number = 1;
638
    ldt.base_addr = (unsigned long)&seg_data1;
639
    ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12;
640
    ldt.seg_32bit = 1;
641
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
642
    ldt.read_exec_only = 0;
643
    ldt.limit_in_pages = 1;
644
    ldt.seg_not_present = 0;
645
    ldt.useable = 1;
646
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
647

    
648
    ldt.entry_number = 2;
649
    ldt.base_addr = (unsigned long)&seg_data2;
650
    ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12;
651
    ldt.seg_32bit = 1;
652
    ldt.contents = MODIFY_LDT_CONTENTS_DATA;
653
    ldt.read_exec_only = 0;
654
    ldt.limit_in_pages = 1;
655
    ldt.seg_not_present = 0;
656
    ldt.useable = 1;
657
    modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
658

    
659
    modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
660
    for(i=0;i<3;i++)
661
        printf("%d: %016Lx\n", i, ldt_table[i]);
662

    
663
    /* do some tests with fs or gs */
664
    asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
665
    asm volatile ("movl %0, %%gs" : : "r" (MK_SEL(2)));
666

    
667
    seg_data1[1] = 0xaa;
668
    seg_data2[1] = 0x55;
669

    
670
    asm volatile ("fs movzbl 0x1, %0" : "=r" (res));
671
    printf("FS[1] = %02x\n", res);
672

    
673
    asm volatile ("gs movzbl 0x1, %0" : "=r" (res));
674
    printf("GS[1] = %02x\n", res);
675

    
676
    /* tests with ds/ss (implicit segment case) */
677
    tmp = 0xa5;
678
    asm volatile ("pushl %%ebp\n\t"
679
                  "pushl %%ds\n\t"
680
                  "movl %2, %%ds\n\t"
681
                  "movl %3, %%ebp\n\t"
682
                  "movzbl 0x1, %0\n\t"
683
                  "movzbl (%%ebp), %1\n\t"
684
                  "popl %%ds\n\t"
685
                  "popl %%ebp\n\t"
686
                  : "=r" (res), "=r" (res2)
687
                  : "r" (MK_SEL(1)), "r" (&tmp));
688
    printf("DS[1] = %02x\n", res);
689
    printf("SS[tmp] = %02x\n", res2);
690
}
691

    
692
#define TEST_XCHG(op, size, opconst)\
693
{\
694
    int op0, op1;\
695
    op0 = 0x12345678;\
696
    op1 = 0xfbca7654;\
697
    asm(#op " %" size "0, %" size "1" \
698
        : "=q" (op0), opconst (op1) \
699
        : "0" (op0), "1" (op1));\
700
    printf("%-10s A=%08x B=%08x\n",\
701
           #op, op0, op1);\
702
}
703

    
704
void test_xchg(void)
705
{
706
    TEST_XCHG(xchgl, "", "=q");
707
    TEST_XCHG(xchgw, "w", "=q");
708
    TEST_XCHG(xchgb, "b", "=q");
709

    
710
    TEST_XCHG(xchgl, "", "=m");
711
    TEST_XCHG(xchgw, "w", "=m");
712
    TEST_XCHG(xchgb, "b", "=m");
713

    
714
    TEST_XCHG(xaddl, "", "=q");
715
    TEST_XCHG(xaddw, "w", "=q");
716
    TEST_XCHG(xaddb, "b", "=q");
717

    
718
    TEST_XCHG(xaddl, "", "=m");
719
    TEST_XCHG(xaddw, "w", "=m");
720
    TEST_XCHG(xaddb, "b", "=m");
721
}
722

    
723
static void *call_end __init_call = NULL;
724

    
725
int main(int argc, char **argv)
726
{
727
    void **ptr;
728
    void (*func)(void);
729

    
730
    ptr = &call_start + 1;
731
    while (*ptr != NULL) {
732
        func = *ptr++;
733
        func();
734
    }
735
    test_bsx();
736
    test_mul();
737
    test_jcc();
738
    test_floats();
739
    test_bcd();
740
    test_xchg();
741
    test_lea();
742
    test_segs();
743
    return 0;
744
}