Statistics
| Branch: | Revision:

root / tests / test-i386.c @ 4b74fe1f

History | View | Annotate | Download (8.5 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

    
96
/* lea test (modrm support) */
97
#define TEST_LEA(STR)\
98
{\
99
    asm("leal " STR ", %0"\
100
        : "=r" (res)\
101
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
102
    printf("lea %s = %08x\n", STR, res);\
103
}
104

    
105
#define TEST_LEA16(STR)\
106
{\
107
    asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\
108
        : "=wq" (res)\
109
        : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\
110
    printf("lea %s = %08x\n", STR, res);\
111
}
112

    
113

    
114
void test_lea(void)
115
{
116
    int eax, ebx, ecx, edx, esi, edi, res;
117
    eax = 0x0001;
118
    ebx = 0x0002;
119
    ecx = 0x0004;
120
    edx = 0x0008;
121
    esi = 0x0010;
122
    edi = 0x0020;
123

    
124
    TEST_LEA("0x4000");
125

    
126
    TEST_LEA("(%%eax)");
127
    TEST_LEA("(%%ebx)");
128
    TEST_LEA("(%%ecx)");
129
    TEST_LEA("(%%edx)");
130
    TEST_LEA("(%%esi)");
131
    TEST_LEA("(%%edi)");
132

    
133
    TEST_LEA("0x40(%%eax)");
134
    TEST_LEA("0x40(%%ebx)");
135
    TEST_LEA("0x40(%%ecx)");
136
    TEST_LEA("0x40(%%edx)");
137
    TEST_LEA("0x40(%%esi)");
138
    TEST_LEA("0x40(%%edi)");
139

    
140
    TEST_LEA("0x4000(%%eax)");
141
    TEST_LEA("0x4000(%%ebx)");
142
    TEST_LEA("0x4000(%%ecx)");
143
    TEST_LEA("0x4000(%%edx)");
144
    TEST_LEA("0x4000(%%esi)");
145
    TEST_LEA("0x4000(%%edi)");
146

    
147
    TEST_LEA("(%%eax, %%ecx)");
148
    TEST_LEA("(%%ebx, %%edx)");
149
    TEST_LEA("(%%ecx, %%ecx)");
150
    TEST_LEA("(%%edx, %%ecx)");
151
    TEST_LEA("(%%esi, %%ecx)");
152
    TEST_LEA("(%%edi, %%ecx)");
153

    
154
    TEST_LEA("0x40(%%eax, %%ecx)");
155
    TEST_LEA("0x4000(%%ebx, %%edx)");
156

    
157
    TEST_LEA("(%%ecx, %%ecx, 2)");
158
    TEST_LEA("(%%edx, %%ecx, 4)");
159
    TEST_LEA("(%%esi, %%ecx, 8)");
160

    
161
    TEST_LEA("(,%%eax, 2)");
162
    TEST_LEA("(,%%ebx, 4)");
163
    TEST_LEA("(,%%ecx, 8)");
164

    
165
    TEST_LEA("0x40(,%%eax, 2)");
166
    TEST_LEA("0x40(,%%ebx, 4)");
167
    TEST_LEA("0x40(,%%ecx, 8)");
168

    
169

    
170
    TEST_LEA("-10(%%ecx, %%ecx, 2)");
171
    TEST_LEA("-10(%%edx, %%ecx, 4)");
172
    TEST_LEA("-10(%%esi, %%ecx, 8)");
173

    
174
    TEST_LEA("0x4000(%%ecx, %%ecx, 2)");
175
    TEST_LEA("0x4000(%%edx, %%ecx, 4)");
176
    TEST_LEA("0x4000(%%esi, %%ecx, 8)");
177

    
178
    /* limited 16 bit addressing test */
179
    TEST_LEA16("0x4000");
180
    TEST_LEA16("(%%bx)");
181
    TEST_LEA16("(%%si)");
182
    TEST_LEA16("(%%di)");
183
    TEST_LEA16("0x40(%%bx)");
184
    TEST_LEA16("0x40(%%si)");
185
    TEST_LEA16("0x40(%%di)");
186
    TEST_LEA16("0x4000(%%bx)");
187
    TEST_LEA16("0x4000(%%si)");
188
    TEST_LEA16("(%%bx,%%si)");
189
    TEST_LEA16("(%%bx,%%di)");
190
    TEST_LEA16("0x40(%%bx,%%si)");
191
    TEST_LEA16("0x40(%%bx,%%di)");
192
    TEST_LEA16("0x4000(%%bx,%%si)");
193
    TEST_LEA16("0x4000(%%bx,%%di)");
194
}
195

    
196
#define TEST_JCC(JCC, v1, v2)\
197
{\
198
    asm("movl $1, %0\n\t"\
199
        "cmpl %2, %1\n\t"\
200
        JCC " 1f\n\t"\
201
        "movl $0, %0\n\t"\
202
        "1:\n\t"\
203
        : "=r" (res)\
204
        : "r" (v1), "r" (v2));\
205
    printf("%-10s %d\n", JCC, res);\
206
}
207

    
208
/* various jump tests */
209
void test_jcc(void)
210
{
211
    int res;
212

    
213
    TEST_JCC("jne", 1, 1);
214
    TEST_JCC("jne", 1, 0);
215

    
216
    TEST_JCC("je", 1, 1);
217
    TEST_JCC("je", 1, 0);
218

    
219
    TEST_JCC("jl", 1, 1);
220
    TEST_JCC("jl", 1, 0);
221
    TEST_JCC("jl", 1, -1);
222

    
223
    TEST_JCC("jle", 1, 1);
224
    TEST_JCC("jle", 1, 0);
225
    TEST_JCC("jle", 1, -1);
226

    
227
    TEST_JCC("jge", 1, 1);
228
    TEST_JCC("jge", 1, 0);
229
    TEST_JCC("jge", -1, 1);
230

    
231
    TEST_JCC("jg", 1, 1);
232
    TEST_JCC("jg", 1, 0);
233
    TEST_JCC("jg", 1, -1);
234

    
235
    TEST_JCC("jb", 1, 1);
236
    TEST_JCC("jb", 1, 0);
237
    TEST_JCC("jb", 1, -1);
238

    
239
    TEST_JCC("jbe", 1, 1);
240
    TEST_JCC("jbe", 1, 0);
241
    TEST_JCC("jbe", 1, -1);
242

    
243
    TEST_JCC("jae", 1, 1);
244
    TEST_JCC("jae", 1, 0);
245
    TEST_JCC("jae", 1, -1);
246

    
247
    TEST_JCC("ja", 1, 1);
248
    TEST_JCC("ja", 1, 0);
249
    TEST_JCC("ja", 1, -1);
250

    
251

    
252
    TEST_JCC("jp", 1, 1);
253
    TEST_JCC("jp", 1, 0);
254

    
255
    TEST_JCC("jnp", 1, 1);
256
    TEST_JCC("jnp", 1, 0);
257

    
258
    TEST_JCC("jo", 0x7fffffff, 0);
259
    TEST_JCC("jo", 0x7fffffff, -1);
260

    
261
    TEST_JCC("jno", 0x7fffffff, 0);
262
    TEST_JCC("jno", 0x7fffffff, -1);
263

    
264
    TEST_JCC("js", 0, 1);
265
    TEST_JCC("js", 0, -1);
266
    TEST_JCC("js", 0, 0);
267

    
268
    TEST_JCC("jns", 0, 1);
269
    TEST_JCC("jns", 0, -1);
270
    TEST_JCC("jns", 0, 0);
271
}
272

    
273
#undef CC_MASK
274
#define CC_MASK (CC_O | CC_C)
275

    
276
#define OP mul
277
#include "test-i386-muldiv.h"
278

    
279
#define OP imul
280
#include "test-i386-muldiv.h"
281

    
282
#undef CC_MASK
283
#define CC_MASK (0)
284

    
285
#define OP div
286
#include "test-i386-muldiv.h"
287

    
288
#define OP idiv
289
#include "test-i386-muldiv.h"
290

    
291
void test_imulw2(int op0, int op1) 
292
{
293
    int res, s1, s0, flags;
294
    s0 = op0;
295
    s1 = op1;
296
    res = s0;
297
    flags = 0;
298
    asm ("push %4\n\t"
299
         "popf\n\t"
300
         "imulw %w2, %w0\n\t" 
301
         "pushf\n\t"
302
         "popl %1\n\t"
303
         : "=q" (res), "=g" (flags)
304
         : "q" (s1), "0" (res), "1" (flags));
305
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
306
           "imulw", s0, s1, res, flags & CC_MASK);
307
}
308

    
309
void test_imull2(int op0, int op1) 
310
{
311
    int res, s1, s0, flags;
312
    s0 = op0;
313
    s1 = op1;
314
    res = s0;
315
    flags = 0;
316
    asm ("push %4\n\t"
317
         "popf\n\t"
318
         "imull %2, %0\n\t" 
319
         "pushf\n\t"
320
         "popl %1\n\t"
321
         : "=q" (res), "=g" (flags)
322
         : "q" (s1), "0" (res), "1" (flags));
323
    printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",
324
           "imull", s0, s1, res, flags & CC_MASK);
325
}
326

    
327
void test_mul(void)
328
{
329
    test_imulb(0x1234561d, 4);
330
    test_imulb(3, -4);
331
    test_imulb(0x80, 0x80);
332
    test_imulb(0x10, 0x10);
333

    
334
    test_imulw(0, 0x1234001d, 45);
335
    test_imulw(0, 23, -45);
336
    test_imulw(0, 0x8000, 0x8000);
337
    test_imulw(0, 0x100, 0x100);
338

    
339
    test_imull(0, 0x1234001d, 45);
340
    test_imull(0, 23, -45);
341
    test_imull(0, 0x80000000, 0x80000000);
342
    test_imull(0, 0x10000, 0x10000);
343

    
344
    test_mulb(0x1234561d, 4);
345
    test_mulb(3, -4);
346
    test_mulb(0x80, 0x80);
347
    test_mulb(0x10, 0x10);
348

    
349
    test_mulw(0, 0x1234001d, 45);
350
    test_mulw(0, 23, -45);
351
    test_mulw(0, 0x8000, 0x8000);
352
    test_mulw(0, 0x100, 0x100);
353

    
354
    test_mull(0, 0x1234001d, 45);
355
    test_mull(0, 23, -45);
356
    test_mull(0, 0x80000000, 0x80000000);
357
    test_mull(0, 0x10000, 0x10000);
358

    
359
    test_imulw2(0x1234001d, 45);
360
    test_imulw2(23, -45);
361
    test_imulw2(0x8000, 0x8000);
362
    test_imulw2(0x100, 0x100);
363

    
364
    test_imull2(0x1234001d, 45);
365
    test_imull2(23, -45);
366
    test_imull2(0x80000000, 0x80000000);
367
    test_imull2(0x10000, 0x10000);
368

    
369
    test_idivb(0x12341678, 0x127e);
370
    test_idivb(0x43210123, -5);
371
    test_idivb(0x12340004, -1);
372

    
373
    test_idivw(0, 0x12345678, 12347);
374
    test_idivw(0, -23223, -45);
375
    test_idivw(0, 0x12348000, -1);
376
    test_idivw(0x12343, 0x12345678, 0x81238567);
377

    
378
    test_idivl(0, 0x12345678, 12347);
379
    test_idivl(0, -233223, -45);
380
    test_idivl(0, 0x80000000, -1);
381
    test_idivl(0x12343, 0x12345678, 0x81234567);
382

    
383
    test_divb(0x12341678, 0x127e);
384
    test_divb(0x43210123, -5);
385
    test_divb(0x12340004, -1);
386

    
387
    test_divw(0, 0x12345678, 12347);
388
    test_divw(0, -23223, -45);
389
    test_divw(0, 0x12348000, -1);
390
    test_divw(0x12343, 0x12345678, 0x81238567);
391

    
392
    test_divl(0, 0x12345678, 12347);
393
    test_divl(0, -233223, -45);
394
    test_divl(0, 0x80000000, -1);
395
    test_divl(0x12343, 0x12345678, 0x81234567);
396
}
397

    
398

    
399
static void *call_end __init_call = NULL;
400

    
401
int main(int argc, char **argv)
402
{
403
    void **ptr;
404
    void (*func)(void);
405

    
406
    test_mul();
407
#if 0
408
    ptr = &call_start + 1;
409
    while (*ptr != NULL) {
410
        func = *ptr++;
411
        func();
412
    }
413
    test_jcc();
414
    test_lea();
415
#endif
416
    return 0;
417
}