Statistics
| Branch: | Revision:

root / tests / test-i386.c @ d57c4e01

History | View | Annotate | Download (9 kB)

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
}