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 |
} |