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 | 20 | $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< |
21 | 21 | |
22 | 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 | 27 | test: test-i386 |
27 | 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 | 81 | \ No newline at end of file | ... | ... |
tests/test-i386.c
... | ... | @@ -635,6 +635,65 @@ void test_bcd(void) |
635 | 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 | 698 | /* segmentation tests */ |
640 | 699 | |
... | ... | @@ -646,7 +705,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) |
646 | 705 | uint8_t seg_data1[4096]; |
647 | 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 | 710 | /* NOTE: we use Linux modify_ldt syscall */ |
652 | 711 | void test_segs(void) |
... | ... | @@ -715,65 +774,45 @@ void test_segs(void) |
715 | 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 | 816 | static void *call_end __init_call = NULL; |
778 | 817 | |
779 | 818 | int main(int argc, char **argv) |
... | ... | @@ -794,5 +833,6 @@ int main(int argc, char **argv) |
794 | 833 | test_xchg(); |
795 | 834 | test_lea(); |
796 | 835 | test_segs(); |
836 | + test_code16(); | |
797 | 837 | return 0; |
798 | 838 | } | ... | ... |