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