Commit a5973fbff16ec5f58b648929beb885da3f6e2373
1 parent
26a5f13b
more tests
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4601 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
88 additions
and
18 deletions
tests/test-i386-shift.h
tests/test-i386.c
| ... | ... | @@ -30,19 +30,19 @@ |
| 30 | 30 | #include <sys/mman.h> |
| 31 | 31 | |
| 32 | 32 | #if !defined(__x86_64__) |
| 33 | -#define TEST_VM86 | |
| 33 | +//#define TEST_VM86 | |
| 34 | 34 | #define TEST_SEGS |
| 35 | 35 | #endif |
| 36 | 36 | //#define LINUX_VM86_IOPL_FIX |
| 37 | 37 | //#define TEST_P4_FLAGS |
| 38 | -#if defined(__x86_64__) | |
| 38 | +#ifdef __SSE__ | |
| 39 | 39 | #define TEST_SSE |
| 40 | 40 | #define TEST_CMOV 1 |
| 41 | 41 | #define TEST_FCOMI 1 |
| 42 | 42 | #else |
| 43 | -//#define TEST_SSE | |
| 44 | -#define TEST_CMOV 0 | |
| 45 | -#define TEST_FCOMI 0 | |
| 43 | +#undef TEST_SSE | |
| 44 | +#define TEST_CMOV 1 | |
| 45 | +#define TEST_FCOMI 1 | |
| 46 | 46 | #endif |
| 47 | 47 | |
| 48 | 48 | #if defined(__x86_64__) |
| ... | ... | @@ -457,6 +457,49 @@ void test_jcc(void) |
| 457 | 457 | TEST_JCC("ns", 0, 0); |
| 458 | 458 | } |
| 459 | 459 | |
| 460 | +#define TEST_LOOP(insn) \ | |
| 461 | +{\ | |
| 462 | + for(i = 0; i < sizeof(ecx_vals) / sizeof(long); i++) {\ | |
| 463 | + ecx = ecx_vals[i];\ | |
| 464 | + for(zf = 0; zf < 2; zf++) {\ | |
| 465 | + asm("test %2, %2\n\t"\ | |
| 466 | + "movl $1, %0\n\t"\ | |
| 467 | + insn " 1f\n\t" \ | |
| 468 | + "movl $0, %0\n\t"\ | |
| 469 | + "1:\n\t"\ | |
| 470 | + : "=a" (res)\ | |
| 471 | + : "c" (ecx), "b" (!zf)); \ | |
| 472 | + printf("%-10s ECX=" FMTLX " ZF=%ld r=%d\n", insn, ecx, zf, res); \ | |
| 473 | + }\ | |
| 474 | + }\ | |
| 475 | +} | |
| 476 | + | |
| 477 | +void test_loop(void) | |
| 478 | +{ | |
| 479 | + long ecx, zf; | |
| 480 | + const long ecx_vals[] = { | |
| 481 | + 0, | |
| 482 | + 1, | |
| 483 | + 0x10000, | |
| 484 | + 0x10001, | |
| 485 | +#if defined(__x86_64__) | |
| 486 | + 0x100000000L, | |
| 487 | + 0x100000001L, | |
| 488 | +#endif | |
| 489 | + }; | |
| 490 | + int i, res; | |
| 491 | + | |
| 492 | + TEST_LOOP("jcxz"); | |
| 493 | + TEST_LOOP("loopw"); | |
| 494 | + TEST_LOOP("loopzw"); | |
| 495 | + TEST_LOOP("loopnzw"); | |
| 496 | + | |
| 497 | + TEST_LOOP("jecxz"); | |
| 498 | + TEST_LOOP("loopl"); | |
| 499 | + TEST_LOOP("loopzl"); | |
| 500 | + TEST_LOOP("loopnzl"); | |
| 501 | +} | |
| 502 | + | |
| 460 | 503 | #undef CC_MASK |
| 461 | 504 | #ifdef TEST_P4_FLAGS |
| 462 | 505 | #define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) |
| ... | ... | @@ -1150,22 +1193,25 @@ void test_xchg(void) |
| 1150 | 1193 | |
| 1151 | 1194 | { |
| 1152 | 1195 | uint64_t op0, op1, op2; |
| 1196 | + long eax, edx; | |
| 1153 | 1197 | long i, eflags; |
| 1154 | 1198 | |
| 1155 | 1199 | for(i = 0; i < 2; i++) { |
| 1156 | 1200 | op0 = 0x123456789abcdLL; |
| 1201 | + eax = i2l(op0 & 0xffffffff); | |
| 1202 | + edx = i2l(op0 >> 32); | |
| 1157 | 1203 | if (i == 0) |
| 1158 | 1204 | op1 = 0xfbca765423456LL; |
| 1159 | 1205 | else |
| 1160 | 1206 | op1 = op0; |
| 1161 | 1207 | op2 = 0x6532432432434LL; |
| 1162 | - asm("cmpxchg8b %1\n" | |
| 1208 | + asm("cmpxchg8b %2\n" | |
| 1163 | 1209 | "pushf\n" |
| 1164 | - "pop %2\n" | |
| 1165 | - : "=A" (op0), "=m" (op1), "=g" (eflags) | |
| 1166 | - : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); | |
| 1167 | - printf("cmpxchg8b: op0=" FMT64X " op1=" FMT64X " CC=%02lx\n", | |
| 1168 | - op0, op1, eflags & CC_Z); | |
| 1210 | + "pop %3\n" | |
| 1211 | + : "=a" (eax), "=d" (edx), "=m" (op1), "=g" (eflags) | |
| 1212 | + : "0" (eax), "1" (edx), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); | |
| 1213 | + printf("cmpxchg8b: eax=" FMTLX " edx=" FMTLX " op1=" FMT64X " CC=%02lx\n", | |
| 1214 | + eax, edx, op1, eflags & CC_Z); | |
| 1169 | 1215 | } |
| 1170 | 1216 | } |
| 1171 | 1217 | } |
| ... | ... | @@ -1196,16 +1242,32 @@ uint8_t seg_data2[4096]; |
| 1196 | 1242 | #define TEST_LR(op, size, seg, mask)\ |
| 1197 | 1243 | {\ |
| 1198 | 1244 | int res, res2;\ |
| 1245 | + uint16_t mseg = seg;\ | |
| 1199 | 1246 | res = 0x12345678;\ |
| 1200 | 1247 | asm (op " %" size "2, %" size "0\n" \ |
| 1201 | 1248 | "movl $0, %1\n"\ |
| 1202 | 1249 | "jnz 1f\n"\ |
| 1203 | 1250 | "movl $1, %1\n"\ |
| 1204 | 1251 | "1:\n"\ |
| 1205 | - : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\ | |
| 1252 | + : "=r" (res), "=r" (res2) : "m" (mseg), "0" (res));\ | |
| 1206 | 1253 | printf(op ": Z=%d %08x\n", res2, res & ~(mask));\ |
| 1207 | 1254 | } |
| 1208 | 1255 | |
| 1256 | +#define TEST_ARPL(op, size, op1, op2)\ | |
| 1257 | +{\ | |
| 1258 | + long a, b, c; \ | |
| 1259 | + a = (op1); \ | |
| 1260 | + b = (op2); \ | |
| 1261 | + asm volatile(op " %" size "3, %" size "0\n"\ | |
| 1262 | + "movl $0,%1\n"\ | |
| 1263 | + "jnz 1f\n"\ | |
| 1264 | + "movl $1,%1\n"\ | |
| 1265 | + "1:\n"\ | |
| 1266 | + : "=r" (a), "=r" (c) : "0" (a), "r" (b)); \ | |
| 1267 | + printf(op size " A=" FMTLX " B=" FMTLX " R=" FMTLX " z=%ld\n",\ | |
| 1268 | + (long)(op1), (long)(op2), a, c);\ | |
| 1269 | +} | |
| 1270 | + | |
| 1209 | 1271 | /* NOTE: we use Linux modify_ldt syscall */ |
| 1210 | 1272 | void test_segs(void) |
| 1211 | 1273 | { |
| ... | ... | @@ -1297,6 +1359,10 @@ void test_segs(void) |
| 1297 | 1359 | TEST_LR("larl", "", 0xfff8, 0); |
| 1298 | 1360 | TEST_LR("lslw", "w", 0xfff8, 0); |
| 1299 | 1361 | TEST_LR("lsll", "", 0xfff8, 0); |
| 1362 | + | |
| 1363 | + TEST_ARPL("arpl", "w", 0x12345678 | 3, 0x762123c | 1); | |
| 1364 | + TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 3); | |
| 1365 | + TEST_ARPL("arpl", "w", 0x12345678 | 1, 0x762123c | 1); | |
| 1300 | 1366 | } |
| 1301 | 1367 | |
| 1302 | 1368 | /* 16 bit code test */ |
| ... | ... | @@ -1931,7 +1997,8 @@ uint8_t code[] = { |
| 1931 | 1997 | 0xc3, /* ret */ |
| 1932 | 1998 | }; |
| 1933 | 1999 | |
| 1934 | -asm("smc_code2:\n" | |
| 2000 | +asm(".section \".data\"\n" | |
| 2001 | + "smc_code2:\n" | |
| 1935 | 2002 | "movl 4(%esp), %eax\n" |
| 1936 | 2003 | "movl %eax, smc_patch_addr2 + 1\n" |
| 1937 | 2004 | "nop\n" |
| ... | ... | @@ -1944,14 +2011,15 @@ asm("smc_code2:\n" |
| 1944 | 2011 | "nop\n" |
| 1945 | 2012 | "smc_patch_addr2:\n" |
| 1946 | 2013 | "movl $1, %eax\n" |
| 1947 | - "ret\n"); | |
| 2014 | + "ret\n" | |
| 2015 | + ".previous\n" | |
| 2016 | + ); | |
| 1948 | 2017 | |
| 1949 | 2018 | typedef int FuncType(void); |
| 1950 | 2019 | extern int smc_code2(int); |
| 1951 | 2020 | void test_self_modifying_code(void) |
| 1952 | 2021 | { |
| 1953 | 2022 | int i; |
| 1954 | - | |
| 1955 | 2023 | printf("self modifying code:\n"); |
| 1956 | 2024 | printf("func1 = 0x%x\n", ((FuncType *)code)()); |
| 1957 | 2025 | for(i = 2; i <= 4; i++) { |
| ... | ... | @@ -2211,7 +2279,8 @@ void test_sse_comi(double a1, double b1) |
| 2211 | 2279 | #define CVT_OP_XMM2MMX(op)\ |
| 2212 | 2280 | {\ |
| 2213 | 2281 | asm volatile (#op " %1, %0" : "=y" (r.q[0]) : "x" (a.dq) \ |
| 2214 | - : "%xmm0");\ | |
| 2282 | + : "%xmm0"); \ | |
| 2283 | + asm volatile("emms\n"); \ | |
| 2215 | 2284 | printf("%-9s: a=" FMT64X "" FMT64X " r=" FMT64X "\n",\ |
| 2216 | 2285 | #op,\ |
| 2217 | 2286 | a.q[1], a.q[0],\ |
| ... | ... | @@ -2221,6 +2290,7 @@ void test_sse_comi(double a1, double b1) |
| 2221 | 2290 | #define CVT_OP_MMX2XMM(op)\ |
| 2222 | 2291 | {\ |
| 2223 | 2292 | asm volatile (#op " %1, %0" : "=x" (r.dq) : "y" (a.q[0]));\ |
| 2293 | + asm volatile("emms\n"); \ | |
| 2224 | 2294 | printf("%-9s: a=" FMT64X " r=" FMT64X "" FMT64X "\n",\ |
| 2225 | 2295 | #op,\ |
| 2226 | 2296 | a.q[0],\ |
| ... | ... | @@ -2657,6 +2727,7 @@ int main(int argc, char **argv) |
| 2657 | 2727 | test_bsx(); |
| 2658 | 2728 | test_mul(); |
| 2659 | 2729 | test_jcc(); |
| 2730 | + test_loop(); | |
| 2660 | 2731 | test_floats(); |
| 2661 | 2732 | #if !defined(__x86_64__) |
| 2662 | 2733 | test_bcd(); | ... | ... |