Commit e591824733ec698d92d1f09c2ffb9b86b799d6da
1 parent
04369ff2
added code16 tests
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@37 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
177 additions
and
56 deletions
tests/Makefile
@@ -20,8 +20,9 @@ test2: test2.c | @@ -20,8 +20,9 @@ test2: test2.c | ||
20 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< | 20 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< |
21 | 21 | ||
22 | # i386 emulation test (test various opcodes) */ | 22 | # i386 emulation test (test various opcodes) */ |
23 | -test-i386: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h | ||
24 | - $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $< -lm | 23 | +test-i386: test-i386.c test-i386-code16.S \ |
24 | + test-i386.h test-i386-shift.h test-i386-muldiv.h | ||
25 | + $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ test-i386.c test-i386-code16.S -lm | ||
25 | 26 | ||
26 | test: test-i386 | 27 | test: test-i386 |
27 | ifeq ($(ARCH),i386) | 28 | ifeq ($(ARCH),i386) |
tests/test-i386-code16.S
0 → 100644
1 | + .code16 | ||
2 | + .globl code16_start | ||
3 | + .globl code16_end | ||
4 | + | ||
5 | +CS_SEG = 0xf | ||
6 | + | ||
7 | +code16_start: | ||
8 | + | ||
9 | + .globl code16_func1 | ||
10 | + | ||
11 | + /* basic test */ | ||
12 | +code16_func1 = . - code16_start | ||
13 | + mov $1, %eax | ||
14 | + data32 lret | ||
15 | + | ||
16 | +/* test push/pop in 16 bit mode */ | ||
17 | + .globl code16_func2 | ||
18 | +code16_func2 = . - code16_start | ||
19 | + xor %eax, %eax | ||
20 | + mov $0x12345678, %ebx | ||
21 | + movl %esp, %ecx | ||
22 | + push %bx | ||
23 | + subl %esp, %ecx | ||
24 | + pop %ax | ||
25 | + data32 lret | ||
26 | + | ||
27 | +/* test various jmp opcodes */ | ||
28 | + .globl code16_func3 | ||
29 | +code16_func3 = . - code16_start | ||
30 | + jmp 1f | ||
31 | + nop | ||
32 | +1: | ||
33 | + mov $4, %eax | ||
34 | + mov $0x12345678, %ebx | ||
35 | + xor %bx, %bx | ||
36 | + jz 2f | ||
37 | + add $2, %ax | ||
38 | +2: | ||
39 | + | ||
40 | + call myfunc | ||
41 | + | ||
42 | + lcall $CS_SEG, $(myfunc2 - code16_start) | ||
43 | + | ||
44 | + ljmp $CS_SEG, $(myjmp1 - code16_start) | ||
45 | +myjmp1_next: | ||
46 | + | ||
47 | + cs lcall myfunc2_addr - code16_start | ||
48 | + | ||
49 | + cs ljmp myjmp2_addr - code16_start | ||
50 | +myjmp2_next: | ||
51 | + | ||
52 | + data32 lret | ||
53 | + | ||
54 | +myfunc2_addr: | ||
55 | + .short myfunc2 - code16_start | ||
56 | + .short CS_SEG | ||
57 | + | ||
58 | +myjmp2_addr: | ||
59 | + .short myjmp2 - code16_start | ||
60 | + .short CS_SEG | ||
61 | + | ||
62 | +myjmp1: | ||
63 | + add $8, %ax | ||
64 | + jmp myjmp1_next | ||
65 | + | ||
66 | +myjmp2: | ||
67 | + add $16, %ax | ||
68 | + jmp myjmp2_next | ||
69 | + | ||
70 | +myfunc: | ||
71 | + add $1, %ax | ||
72 | + ret | ||
73 | + | ||
74 | +myfunc2: | ||
75 | + add $4, %ax | ||
76 | + lret | ||
77 | + | ||
78 | + | ||
79 | +code16_end: | ||
80 | + | ||
0 | \ No newline at end of file | 81 | \ No newline at end of file |
tests/test-i386.c
@@ -635,6 +635,65 @@ void test_bcd(void) | @@ -635,6 +635,65 @@ void test_bcd(void) | ||
635 | TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); | 635 | TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); |
636 | } | 636 | } |
637 | 637 | ||
638 | +#define TEST_XCHG(op, size, opconst)\ | ||
639 | +{\ | ||
640 | + int op0, op1;\ | ||
641 | + op0 = 0x12345678;\ | ||
642 | + op1 = 0xfbca7654;\ | ||
643 | + asm(#op " %" size "0, %" size "1" \ | ||
644 | + : "=q" (op0), opconst (op1) \ | ||
645 | + : "0" (op0), "1" (op1));\ | ||
646 | + printf("%-10s A=%08x B=%08x\n",\ | ||
647 | + #op, op0, op1);\ | ||
648 | +} | ||
649 | + | ||
650 | +#define TEST_CMPXCHG(op, size, opconst, eax)\ | ||
651 | +{\ | ||
652 | + int op0, op1;\ | ||
653 | + op0 = 0x12345678;\ | ||
654 | + op1 = 0xfbca7654;\ | ||
655 | + asm(#op " %" size "0, %" size "1" \ | ||
656 | + : "=q" (op0), opconst (op1) \ | ||
657 | + : "0" (op0), "1" (op1), "a" (eax));\ | ||
658 | + printf("%-10s EAX=%08x A=%08x C=%08x\n",\ | ||
659 | + #op, eax, op0, op1);\ | ||
660 | +} | ||
661 | + | ||
662 | +void test_xchg(void) | ||
663 | +{ | ||
664 | + TEST_XCHG(xchgl, "", "=q"); | ||
665 | + TEST_XCHG(xchgw, "w", "=q"); | ||
666 | + TEST_XCHG(xchgb, "b", "=q"); | ||
667 | + | ||
668 | + TEST_XCHG(xchgl, "", "=m"); | ||
669 | + TEST_XCHG(xchgw, "w", "=m"); | ||
670 | + TEST_XCHG(xchgb, "b", "=m"); | ||
671 | + | ||
672 | + TEST_XCHG(xaddl, "", "=q"); | ||
673 | + TEST_XCHG(xaddw, "w", "=q"); | ||
674 | + TEST_XCHG(xaddb, "b", "=q"); | ||
675 | + | ||
676 | + TEST_XCHG(xaddl, "", "=m"); | ||
677 | + TEST_XCHG(xaddw, "w", "=m"); | ||
678 | + TEST_XCHG(xaddb, "b", "=m"); | ||
679 | + | ||
680 | + TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); | ||
681 | + TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); | ||
682 | + TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); | ||
683 | + | ||
684 | + TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); | ||
685 | + TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); | ||
686 | + TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); | ||
687 | + | ||
688 | + TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); | ||
689 | + TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); | ||
690 | + TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); | ||
691 | + | ||
692 | + TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); | ||
693 | + TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); | ||
694 | + TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); | ||
695 | +} | ||
696 | + | ||
638 | /**********************************************/ | 697 | /**********************************************/ |
639 | /* segmentation tests */ | 698 | /* segmentation tests */ |
640 | 699 | ||
@@ -646,7 +705,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) | @@ -646,7 +705,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) | ||
646 | uint8_t seg_data1[4096]; | 705 | uint8_t seg_data1[4096]; |
647 | uint8_t seg_data2[4096]; | 706 | uint8_t seg_data2[4096]; |
648 | 707 | ||
649 | -#define MK_SEL(n) (((n) << 3) | 4) | 708 | +#define MK_SEL(n) (((n) << 3) | 7) |
650 | 709 | ||
651 | /* NOTE: we use Linux modify_ldt syscall */ | 710 | /* NOTE: we use Linux modify_ldt syscall */ |
652 | void test_segs(void) | 711 | void test_segs(void) |
@@ -715,65 +774,45 @@ void test_segs(void) | @@ -715,65 +774,45 @@ void test_segs(void) | ||
715 | printf("SS[tmp] = %02x\n", res2); | 774 | printf("SS[tmp] = %02x\n", res2); |
716 | } | 775 | } |
717 | 776 | ||
718 | -#define TEST_XCHG(op, size, opconst)\ | ||
719 | -{\ | ||
720 | - int op0, op1;\ | ||
721 | - op0 = 0x12345678;\ | ||
722 | - op1 = 0xfbca7654;\ | ||
723 | - asm(#op " %" size "0, %" size "1" \ | ||
724 | - : "=q" (op0), opconst (op1) \ | ||
725 | - : "0" (op0), "1" (op1));\ | ||
726 | - printf("%-10s A=%08x B=%08x\n",\ | ||
727 | - #op, op0, op1);\ | ||
728 | -} | ||
729 | - | ||
730 | -#define TEST_CMPXCHG(op, size, opconst, eax)\ | ||
731 | -{\ | ||
732 | - int op0, op1;\ | ||
733 | - op0 = 0x12345678;\ | ||
734 | - op1 = 0xfbca7654;\ | ||
735 | - asm(#op " %" size "0, %" size "1" \ | ||
736 | - : "=q" (op0), opconst (op1) \ | ||
737 | - : "0" (op0), "1" (op1), "a" (eax));\ | ||
738 | - printf("%-10s EAX=%08x A=%08x C=%08x\n",\ | ||
739 | - #op, eax, op0, op1);\ | ||
740 | -} | 777 | +/* 16 bit code test */ |
778 | +extern char code16_start, code16_end; | ||
779 | +extern char code16_func1; | ||
780 | +extern char code16_func2; | ||
781 | +extern char code16_func3; | ||
741 | 782 | ||
742 | -void test_xchg(void) | 783 | +void test_code16(void) |
743 | { | 784 | { |
744 | - TEST_XCHG(xchgl, "", "=q"); | ||
745 | - TEST_XCHG(xchgw, "w", "=q"); | ||
746 | - TEST_XCHG(xchgb, "b", "=q"); | ||
747 | - | ||
748 | - TEST_XCHG(xchgl, "", "=m"); | ||
749 | - TEST_XCHG(xchgw, "w", "=m"); | ||
750 | - TEST_XCHG(xchgb, "b", "=m"); | ||
751 | - | ||
752 | - TEST_XCHG(xaddl, "", "=q"); | ||
753 | - TEST_XCHG(xaddw, "w", "=q"); | ||
754 | - TEST_XCHG(xaddb, "b", "=q"); | ||
755 | - | ||
756 | - TEST_XCHG(xaddl, "", "=m"); | ||
757 | - TEST_XCHG(xaddw, "w", "=m"); | ||
758 | - TEST_XCHG(xaddb, "b", "=m"); | ||
759 | - | ||
760 | - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); | ||
761 | - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); | ||
762 | - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); | ||
763 | - | ||
764 | - TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); | ||
765 | - TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); | ||
766 | - TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); | 785 | + struct modify_ldt_ldt_s ldt; |
786 | + int res, res2; | ||
767 | 787 | ||
768 | - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); | ||
769 | - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); | ||
770 | - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); | 788 | + /* build a code segment */ |
789 | + ldt.entry_number = 1; | ||
790 | + ldt.base_addr = (unsigned long)&code16_start; | ||
791 | + ldt.limit = &code16_end - &code16_start; | ||
792 | + ldt.seg_32bit = 0; | ||
793 | + ldt.contents = MODIFY_LDT_CONTENTS_CODE; | ||
794 | + ldt.read_exec_only = 0; | ||
795 | + ldt.limit_in_pages = 0; | ||
796 | + ldt.seg_not_present = 0; | ||
797 | + ldt.useable = 1; | ||
798 | + modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ | ||
771 | 799 | ||
772 | - TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); | ||
773 | - TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); | ||
774 | - TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); | 800 | + /* call the first function */ |
801 | + asm volatile ("lcall %1, %2" | ||
802 | + : "=a" (res) | ||
803 | + : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); | ||
804 | + printf("func1() = 0x%08x\n", res); | ||
805 | + asm volatile ("lcall %2, %3" | ||
806 | + : "=a" (res), "=c" (res2) | ||
807 | + : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); | ||
808 | + printf("func2() = 0x%08x spdec=%d\n", res, res2); | ||
809 | + asm volatile ("lcall %1, %2" | ||
810 | + : "=a" (res) | ||
811 | + : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); | ||
812 | + printf("func3() = 0x%08x\n", res); | ||
775 | } | 813 | } |
776 | 814 | ||
815 | + | ||
777 | static void *call_end __init_call = NULL; | 816 | static void *call_end __init_call = NULL; |
778 | 817 | ||
779 | int main(int argc, char **argv) | 818 | int main(int argc, char **argv) |
@@ -794,5 +833,6 @@ int main(int argc, char **argv) | @@ -794,5 +833,6 @@ int main(int argc, char **argv) | ||
794 | test_xchg(); | 833 | test_xchg(); |
795 | test_lea(); | 834 | test_lea(); |
796 | test_segs(); | 835 | test_segs(); |
836 | + test_code16(); | ||
797 | return 0; | 837 | return 0; |
798 | } | 838 | } |