Commit 4d1135e486fcdd3b00caf524f01af7f0d56a0af7
1 parent
5147f5aa
i386 emulator test
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@11 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
325 additions
and
0 deletions
tests/Makefile
0 โ 100644
1 | +CC=gcc | |
2 | +CFLAGS=-Wall -O2 -g | |
3 | +LDFLAGS= | |
4 | + | |
5 | +TESTS=hello test1 test2 sha1 test-i386 | |
6 | +GEMU=../gemu | |
7 | + | |
8 | +all: $(TESTS) | |
9 | + | |
10 | +hello: hello.c | |
11 | + $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< | |
12 | + | |
13 | +test1: test1.c | |
14 | + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< | |
15 | + | |
16 | +test2: test2.c | |
17 | + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< | |
18 | + | |
19 | +# i386 emulation test (dump various opcodes) */ | |
20 | +test-i386: test-i386.c test-i386.h | |
21 | + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< | |
22 | + | |
23 | +test: test-i386 | |
24 | + ./test-i386 > test-i386.ref | |
25 | + $(GEMU) test-i386 > test-i386.out | |
26 | + @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi | |
27 | + | |
28 | +# speed test | |
29 | +sha1: sha1.c | |
30 | + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< | |
31 | + | |
32 | +speed: sha1 | |
33 | + time ./sha1 | |
34 | + time $(GEMU) sha1 | |
35 | + | |
36 | +# interpreter test | |
37 | +interp: interp.c interploop.c | |
38 | + $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -o $@ $^ | ... | ... |
tests/hello.c
0 โ 100644
1 | +#include <asm/unistd.h> | |
2 | + | |
3 | +extern inline volatile void exit(int status) | |
4 | +{ | |
5 | + int __res; | |
6 | + __asm__ volatile ("movl %%ecx,%%ebx\n"\ | |
7 | + "int $0x80" \ | |
8 | + : "=a" (__res) : "0" (__NR_exit),"c" ((long)(status))); | |
9 | +} | |
10 | + | |
11 | +extern inline int write(int fd, const char * buf, int len) | |
12 | +{ | |
13 | + int status; | |
14 | + __asm__ volatile ("pushl %%ebx\n"\ | |
15 | + "movl %%esi,%%ebx\n"\ | |
16 | + "int $0x80\n" \ | |
17 | + "popl %%ebx\n"\ | |
18 | + : "=a" (status) \ | |
19 | + : "0" (__NR_write),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len))); | |
20 | +} | |
21 | + | |
22 | +void _startup(void) | |
23 | +{ | |
24 | + write(1, "Hello World\n", 12); | |
25 | + exit(0); | |
26 | +} | ... | ... |
tests/test-i386.c
0 โ 100644
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 | +/* XXX: currently no A flag */ | |
18 | +#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) | |
19 | + | |
20 | +#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) | |
21 | + | |
22 | +static void *call_start __init_call = NULL; | |
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 | +/* lea test (modrm support) */ | |
71 | +#define TEST_LEA(STR)\ | |
72 | +{\ | |
73 | + asm("leal " STR ", %0"\ | |
74 | + : "=r" (res)\ | |
75 | + : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ | |
76 | + printf("lea %s = %08x\n", STR, res);\ | |
77 | +} | |
78 | + | |
79 | +#define TEST_LEA16(STR)\ | |
80 | +{\ | |
81 | + asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ | |
82 | + : "=wq" (res)\ | |
83 | + : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ | |
84 | + printf("lea %s = %08x\n", STR, res);\ | |
85 | +} | |
86 | + | |
87 | + | |
88 | +void test_lea(void) | |
89 | +{ | |
90 | + int eax, ebx, ecx, edx, esi, edi, res; | |
91 | + eax = 0x0001; | |
92 | + ebx = 0x0002; | |
93 | + ecx = 0x0004; | |
94 | + edx = 0x0008; | |
95 | + esi = 0x0010; | |
96 | + edi = 0x0020; | |
97 | + | |
98 | + TEST_LEA("0x4000"); | |
99 | + | |
100 | + TEST_LEA("(%%eax)"); | |
101 | + TEST_LEA("(%%ebx)"); | |
102 | + TEST_LEA("(%%ecx)"); | |
103 | + TEST_LEA("(%%edx)"); | |
104 | + TEST_LEA("(%%esi)"); | |
105 | + TEST_LEA("(%%edi)"); | |
106 | + | |
107 | + TEST_LEA("0x40(%%eax)"); | |
108 | + TEST_LEA("0x40(%%ebx)"); | |
109 | + TEST_LEA("0x40(%%ecx)"); | |
110 | + TEST_LEA("0x40(%%edx)"); | |
111 | + TEST_LEA("0x40(%%esi)"); | |
112 | + TEST_LEA("0x40(%%edi)"); | |
113 | + | |
114 | + TEST_LEA("0x4000(%%eax)"); | |
115 | + TEST_LEA("0x4000(%%ebx)"); | |
116 | + TEST_LEA("0x4000(%%ecx)"); | |
117 | + TEST_LEA("0x4000(%%edx)"); | |
118 | + TEST_LEA("0x4000(%%esi)"); | |
119 | + TEST_LEA("0x4000(%%edi)"); | |
120 | + | |
121 | + TEST_LEA("(%%eax, %%ecx)"); | |
122 | + TEST_LEA("(%%ebx, %%edx)"); | |
123 | + TEST_LEA("(%%ecx, %%ecx)"); | |
124 | + TEST_LEA("(%%edx, %%ecx)"); | |
125 | + TEST_LEA("(%%esi, %%ecx)"); | |
126 | + TEST_LEA("(%%edi, %%ecx)"); | |
127 | + | |
128 | + TEST_LEA("0x40(%%eax, %%ecx)"); | |
129 | + TEST_LEA("0x4000(%%ebx, %%edx)"); | |
130 | + | |
131 | + TEST_LEA("(%%ecx, %%ecx, 2)"); | |
132 | + TEST_LEA("(%%edx, %%ecx, 4)"); | |
133 | + TEST_LEA("(%%esi, %%ecx, 8)"); | |
134 | + | |
135 | + TEST_LEA("(,%%eax, 2)"); | |
136 | + TEST_LEA("(,%%ebx, 4)"); | |
137 | + TEST_LEA("(,%%ecx, 8)"); | |
138 | + | |
139 | + TEST_LEA("0x40(,%%eax, 2)"); | |
140 | + TEST_LEA("0x40(,%%ebx, 4)"); | |
141 | + TEST_LEA("0x40(,%%ecx, 8)"); | |
142 | + | |
143 | + | |
144 | + TEST_LEA("-10(%%ecx, %%ecx, 2)"); | |
145 | + TEST_LEA("-10(%%edx, %%ecx, 4)"); | |
146 | + TEST_LEA("-10(%%esi, %%ecx, 8)"); | |
147 | + | |
148 | + TEST_LEA("0x4000(%%ecx, %%ecx, 2)"); | |
149 | + TEST_LEA("0x4000(%%edx, %%ecx, 4)"); | |
150 | + TEST_LEA("0x4000(%%esi, %%ecx, 8)"); | |
151 | + | |
152 | + /* limited 16 bit addressing test */ | |
153 | + TEST_LEA16("0x4000"); | |
154 | + TEST_LEA16("(%%bx)"); | |
155 | + TEST_LEA16("(%%si)"); | |
156 | + TEST_LEA16("(%%di)"); | |
157 | + TEST_LEA16("0x40(%%bx)"); | |
158 | + TEST_LEA16("0x40(%%si)"); | |
159 | + TEST_LEA16("0x40(%%di)"); | |
160 | + TEST_LEA16("0x4000(%%bx)"); | |
161 | + TEST_LEA16("0x4000(%%si)"); | |
162 | + TEST_LEA16("(%%bx,%%si)"); | |
163 | + TEST_LEA16("(%%bx,%%di)"); | |
164 | + TEST_LEA16("0x40(%%bx,%%si)"); | |
165 | + TEST_LEA16("0x40(%%bx,%%di)"); | |
166 | + TEST_LEA16("0x4000(%%bx,%%si)"); | |
167 | + TEST_LEA16("0x4000(%%bx,%%di)"); | |
168 | +} | |
169 | + | |
170 | +#define TEST_JCC(JCC, v1, v2)\ | |
171 | +{\ | |
172 | + asm("movl $1, %0\n\t"\ | |
173 | + "cmpl %2, %1\n\t"\ | |
174 | + JCC " 1f\n\t"\ | |
175 | + "movl $0, %0\n\t"\ | |
176 | + "1:\n\t"\ | |
177 | + : "=r" (res)\ | |
178 | + : "r" (v1), "r" (v2));\ | |
179 | + printf("%-10s %d\n", JCC, res);\ | |
180 | +} | |
181 | + | |
182 | +/* various jump tests */ | |
183 | +void test_jcc(void) | |
184 | +{ | |
185 | + int res; | |
186 | + | |
187 | + TEST_JCC("jne", 1, 1); | |
188 | + TEST_JCC("jne", 1, 0); | |
189 | + | |
190 | + TEST_JCC("je", 1, 1); | |
191 | + TEST_JCC("je", 1, 0); | |
192 | + | |
193 | + TEST_JCC("jl", 1, 1); | |
194 | + TEST_JCC("jl", 1, 0); | |
195 | + TEST_JCC("jl", 1, -1); | |
196 | + | |
197 | + TEST_JCC("jle", 1, 1); | |
198 | + TEST_JCC("jle", 1, 0); | |
199 | + TEST_JCC("jle", 1, -1); | |
200 | + | |
201 | + TEST_JCC("jge", 1, 1); | |
202 | + TEST_JCC("jge", 1, 0); | |
203 | + TEST_JCC("jge", -1, 1); | |
204 | + | |
205 | + TEST_JCC("jg", 1, 1); | |
206 | + TEST_JCC("jg", 1, 0); | |
207 | + TEST_JCC("jg", 1, -1); | |
208 | + | |
209 | + TEST_JCC("jb", 1, 1); | |
210 | + TEST_JCC("jb", 1, 0); | |
211 | + TEST_JCC("jb", 1, -1); | |
212 | + | |
213 | + TEST_JCC("jbe", 1, 1); | |
214 | + TEST_JCC("jbe", 1, 0); | |
215 | + TEST_JCC("jbe", 1, -1); | |
216 | + | |
217 | + TEST_JCC("jae", 1, 1); | |
218 | + TEST_JCC("jae", 1, 0); | |
219 | + TEST_JCC("jae", 1, -1); | |
220 | + | |
221 | + TEST_JCC("ja", 1, 1); | |
222 | + TEST_JCC("ja", 1, 0); | |
223 | + TEST_JCC("ja", 1, -1); | |
224 | + | |
225 | + | |
226 | + TEST_JCC("jp", 1, 1); | |
227 | + TEST_JCC("jp", 1, 0); | |
228 | + | |
229 | + TEST_JCC("jnp", 1, 1); | |
230 | + TEST_JCC("jnp", 1, 0); | |
231 | + | |
232 | + TEST_JCC("jo", 0x7fffffff, 0); | |
233 | + TEST_JCC("jo", 0x7fffffff, -1); | |
234 | + | |
235 | + TEST_JCC("jno", 0x7fffffff, 0); | |
236 | + TEST_JCC("jno", 0x7fffffff, -1); | |
237 | + | |
238 | + TEST_JCC("js", 0, 1); | |
239 | + TEST_JCC("js", 0, -1); | |
240 | + TEST_JCC("js", 0, 0); | |
241 | + | |
242 | + TEST_JCC("jns", 0, 1); | |
243 | + TEST_JCC("jns", 0, -1); | |
244 | + TEST_JCC("jns", 0, 0); | |
245 | +} | |
246 | + | |
247 | +static void *call_end __init_call = NULL; | |
248 | + | |
249 | +int main(int argc, char **argv) | |
250 | +{ | |
251 | + void **ptr; | |
252 | + void (*func)(void); | |
253 | + ptr = &call_start + 1; | |
254 | + while (*ptr != NULL) { | |
255 | + func = *ptr++; | |
256 | + func(); | |
257 | + } | |
258 | + test_lea(); | |
259 | + test_jcc(); | |
260 | + return 0; | |
261 | +} | ... | ... |