added code16 tests

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@37 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-03-22 15:20:50 +00:00
parent 04369ff2f5
commit e591824733
3 changed files with 177 additions and 56 deletions

View File

@ -20,8 +20,9 @@ test2: test2.c
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
# i386 emulation test (test various opcodes) */ # i386 emulation test (test various opcodes) */
test-i386: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h test-i386: test-i386.c test-i386-code16.S \
$(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $< -lm 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 test: test-i386
ifeq ($(ARCH),i386) ifeq ($(ARCH),i386)

80
tests/test-i386-code16.S Normal file
View File

@ -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:

View File

@ -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)); 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 */ /* 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_data1[4096];
uint8_t seg_data2[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 */ /* NOTE: we use Linux modify_ldt syscall */
void test_segs(void) void test_segs(void)
@ -715,65 +774,45 @@ void test_segs(void)
printf("SS[tmp] = %02x\n", res2); printf("SS[tmp] = %02x\n", res2);
} }
#define TEST_XCHG(op, size, opconst)\ /* 16 bit code test */
{\ extern char code16_start, code16_end;
int op0, op1;\ extern char code16_func1;
op0 = 0x12345678;\ extern char code16_func2;
op1 = 0xfbca7654;\ extern char code16_func3;
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)\ void test_code16(void)
{\
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"); struct modify_ldt_ldt_s ldt;
TEST_XCHG(xchgw, "w", "=q"); int res, res2;
TEST_XCHG(xchgb, "b", "=q");
TEST_XCHG(xchgl, "", "=m"); /* build a code segment */
TEST_XCHG(xchgw, "w", "=m"); ldt.entry_number = 1;
TEST_XCHG(xchgb, "b", "=m"); 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"); /* call the first function */
TEST_XCHG(xaddw, "w", "=q"); asm volatile ("lcall %1, %2"
TEST_XCHG(xaddb, "b", "=q"); : "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc");
TEST_XCHG(xaddl, "", "=m"); printf("func1() = 0x%08x\n", res);
TEST_XCHG(xaddw, "w", "=m"); asm volatile ("lcall %2, %3"
TEST_XCHG(xaddb, "b", "=m"); : "=a" (res), "=c" (res2)
: "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc");
TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); printf("func2() = 0x%08x spdec=%d\n", res, res2);
TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); asm volatile ("lcall %1, %2"
TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); : "=a" (res)
: "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc");
TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); printf("func3() = 0x%08x\n", res);
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);
} }
static void *call_end __init_call = NULL; static void *call_end __init_call = NULL;
int main(int argc, char **argv) int main(int argc, char **argv)
@ -794,5 +833,6 @@ int main(int argc, char **argv)
test_xchg(); test_xchg();
test_lea(); test_lea();
test_segs(); test_segs();
test_code16();
return 0; return 0;
} }