added code16 tests
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@37 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
04369ff2f5
commit
e591824733
@ -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)
|
||||
|
80
tests/test-i386-code16.S
Normal file
80
tests/test-i386-code16.S
Normal 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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user