From e591824733ec698d92d1f09c2ffb9b86b799d6da Mon Sep 17 00:00:00 2001 From: bellard Date: Sat, 22 Mar 2003 15:20:50 +0000 Subject: [PATCH] added code16 tests git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@37 c046a42c-6fe2-441c-8c8c-71466251a162 --- tests/Makefile | 5 +- tests/test-i386-code16.S | 80 +++++++++++++++++++++ tests/test-i386.c | 148 +++++++++++++++++++++++++-------------- 3 files changed, 177 insertions(+), 56 deletions(-) create mode 100644 tests/test-i386-code16.S diff --git a/tests/Makefile b/tests/Makefile index 72b559dfd5..3cc205d5b2 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -20,8 +20,9 @@ test2: test2.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< # i386 emulation test (test various opcodes) */ -test-i386: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h - $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $< -lm +test-i386: test-i386.c test-i386-code16.S \ + test-i386.h test-i386-shift.h test-i386-muldiv.h + $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c test-i386-code16.S -lm test: test-i386 ifeq ($(ARCH),i386) diff --git a/tests/test-i386-code16.S b/tests/test-i386-code16.S new file mode 100644 index 0000000000..446f0d7bf1 --- /dev/null +++ b/tests/test-i386-code16.S @@ -0,0 +1,80 @@ + .code16 + .globl code16_start + .globl code16_end + +CS_SEG = 0xf + +code16_start: + + .globl code16_func1 + + /* basic test */ +code16_func1 = . - code16_start + mov $1, %eax + data32 lret + +/* test push/pop in 16 bit mode */ + .globl code16_func2 +code16_func2 = . - code16_start + xor %eax, %eax + mov $0x12345678, %ebx + movl %esp, %ecx + push %bx + subl %esp, %ecx + pop %ax + data32 lret + +/* test various jmp opcodes */ + .globl code16_func3 +code16_func3 = . - code16_start + jmp 1f + nop +1: + mov $4, %eax + mov $0x12345678, %ebx + xor %bx, %bx + jz 2f + add $2, %ax +2: + + call myfunc + + lcall $CS_SEG, $(myfunc2 - code16_start) + + ljmp $CS_SEG, $(myjmp1 - code16_start) +myjmp1_next: + + cs lcall myfunc2_addr - code16_start + + cs ljmp myjmp2_addr - code16_start +myjmp2_next: + + data32 lret + +myfunc2_addr: + .short myfunc2 - code16_start + .short CS_SEG + +myjmp2_addr: + .short myjmp2 - code16_start + .short CS_SEG + +myjmp1: + add $8, %ax + jmp myjmp1_next + +myjmp2: + add $16, %ax + jmp myjmp2_next + +myfunc: + add $1, %ax + ret + +myfunc2: + add $4, %ax + lret + + +code16_end: + \ No newline at end of file diff --git a/tests/test-i386.c b/tests/test-i386.c index f9a5991863..866c769e4b 100644 --- a/tests/test-i386.c +++ b/tests/test-i386.c @@ -635,6 +635,65 @@ void test_bcd(void) TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); } +#define TEST_XCHG(op, size, opconst)\ +{\ + int op0, op1;\ + op0 = 0x12345678;\ + op1 = 0xfbca7654;\ + asm(#op " %" size "0, %" size "1" \ + : "=q" (op0), opconst (op1) \ + : "0" (op0), "1" (op1));\ + printf("%-10s A=%08x B=%08x\n",\ + #op, op0, op1);\ +} + +#define TEST_CMPXCHG(op, size, opconst, eax)\ +{\ + int op0, op1;\ + op0 = 0x12345678;\ + op1 = 0xfbca7654;\ + asm(#op " %" size "0, %" size "1" \ + : "=q" (op0), opconst (op1) \ + : "0" (op0), "1" (op1), "a" (eax));\ + printf("%-10s EAX=%08x A=%08x C=%08x\n",\ + #op, eax, op0, op1);\ +} + +void test_xchg(void) +{ + TEST_XCHG(xchgl, "", "=q"); + TEST_XCHG(xchgw, "w", "=q"); + TEST_XCHG(xchgb, "b", "=q"); + + TEST_XCHG(xchgl, "", "=m"); + TEST_XCHG(xchgw, "w", "=m"); + TEST_XCHG(xchgb, "b", "=m"); + + TEST_XCHG(xaddl, "", "=q"); + TEST_XCHG(xaddw, "w", "=q"); + TEST_XCHG(xaddb, "b", "=q"); + + TEST_XCHG(xaddl, "", "=m"); + TEST_XCHG(xaddw, "w", "=m"); + TEST_XCHG(xaddb, "b", "=m"); + + TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); + TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); + TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); + + TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); + + TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); + TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); + TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); + + TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); + TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); +} + /**********************************************/ /* segmentation tests */ @@ -646,7 +705,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) uint8_t seg_data1[4096]; uint8_t seg_data2[4096]; -#define MK_SEL(n) (((n) << 3) | 4) +#define MK_SEL(n) (((n) << 3) | 7) /* NOTE: we use Linux modify_ldt syscall */ void test_segs(void) @@ -715,65 +774,45 @@ void test_segs(void) printf("SS[tmp] = %02x\n", res2); } -#define TEST_XCHG(op, size, opconst)\ -{\ - int op0, op1;\ - op0 = 0x12345678;\ - op1 = 0xfbca7654;\ - asm(#op " %" size "0, %" size "1" \ - : "=q" (op0), opconst (op1) \ - : "0" (op0), "1" (op1));\ - printf("%-10s A=%08x B=%08x\n",\ - #op, op0, op1);\ -} +/* 16 bit code test */ +extern char code16_start, code16_end; +extern char code16_func1; +extern char code16_func2; +extern char code16_func3; -#define TEST_CMPXCHG(op, size, opconst, eax)\ -{\ - int op0, op1;\ - op0 = 0x12345678;\ - op1 = 0xfbca7654;\ - asm(#op " %" size "0, %" size "1" \ - : "=q" (op0), opconst (op1) \ - : "0" (op0), "1" (op1), "a" (eax));\ - printf("%-10s EAX=%08x A=%08x C=%08x\n",\ - #op, eax, op0, op1);\ -} - -void test_xchg(void) +void test_code16(void) { - TEST_XCHG(xchgl, "", "=q"); - TEST_XCHG(xchgw, "w", "=q"); - TEST_XCHG(xchgb, "b", "=q"); + struct modify_ldt_ldt_s ldt; + int res, res2; - TEST_XCHG(xchgl, "", "=m"); - TEST_XCHG(xchgw, "w", "=m"); - TEST_XCHG(xchgb, "b", "=m"); + /* build a code segment */ + ldt.entry_number = 1; + ldt.base_addr = (unsigned long)&code16_start; + ldt.limit = &code16_end - &code16_start; + ldt.seg_32bit = 0; + ldt.contents = MODIFY_LDT_CONTENTS_CODE; + ldt.read_exec_only = 0; + ldt.limit_in_pages = 0; + ldt.seg_not_present = 0; + ldt.useable = 1; + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ - TEST_XCHG(xaddl, "", "=q"); - TEST_XCHG(xaddw, "w", "=q"); - TEST_XCHG(xaddb, "b", "=q"); - - TEST_XCHG(xaddl, "", "=m"); - TEST_XCHG(xaddw, "w", "=m"); - TEST_XCHG(xaddb, "b", "=m"); - - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); - - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); - - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); - - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); + /* call the first function */ + asm volatile ("lcall %1, %2" + : "=a" (res) + : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); + printf("func1() = 0x%08x\n", res); + asm volatile ("lcall %2, %3" + : "=a" (res), "=c" (res2) + : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); + printf("func2() = 0x%08x spdec=%d\n", res, res2); + asm volatile ("lcall %1, %2" + : "=a" (res) + : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); + printf("func3() = 0x%08x\n", res); } + static void *call_end __init_call = NULL; int main(int argc, char **argv) @@ -794,5 +833,6 @@ int main(int argc, char **argv) test_xchg(); test_lea(); test_segs(); + test_code16(); return 0; }