- Timestamp:
- May 25, 2008 11:54:49 PM (17 years ago)
- Location:
- trunk/src/VBox/Disassembler/testcase
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Disassembler/testcase/Makefile.kmk
r9098 r9099 49 49 50 50 # Tests that will be disassembled and re-build from disassembly (list of binaries). 51 ## @todo tstBinMovzx-1.bin: does C7 imply 32-bit reg in 16-bit mode, or what exactly does it do? 51 52 VBOX_DISAS_TESTS_BINARIES := \ 52 $(PATH_SUB_CURRENT)/tstBinMovzx-1.bin 53 # $(PATH_SUB_CURRENT)/tstBin-1.bin \ 53 tstBinMovzx-1.bin 54 ifeq ($(USER),bird) 55 VBOX_DISAS_TESTS_BINARIES += \ 56 tstBin-1.bin \ 57 tstBin-2.bin \ 58 tstBin-3.bin \ 54 59 # $(PATH_BIN)/testcase/tstDisasm-2$(SUFF_EXEC) 60 endif 55 61 56 62 … … 162 168 # Generate the rules for the binary tests. 163 169 define def_vbox_disas_binary_rules 164 $(outbase).asm: $( binary) $$$$(INSTARGET_tstDisasm-2) | $(VBOX_DISAS_TEST_PATH)/170 $(outbase).asm: $(full_binary) $$$$(INSTARGET_tstDisasm-2) | $(VBOX_DISAS_TEST_PATH)/ 165 171 @$$(ECHO) "Generating: $$(@F) from $$(<F)" 166 172 $$(REDIRECT) -E VBOX_LOG_DEST=nofile -o $$@ -- $$(INSTARGET_tstDisasm-2) --style=yasm --cpumode=$(bits) --undef-op=db $$< … … 171 177 172 178 $(outbase).tst: $(outbase).bin 173 @$$(ECHO) "Verifying build: $$(<F) against $(not-dir $( binary))"179 @$$(ECHO) "Verifying build: $$(<F) against $(not-dir $(full_binary))" 174 180 @$$(RM) -f $$@ 175 $$(CMP) -l $( binary) $$<176 @$$(APPEND) $ @ "done"181 $$(CMP) -l $(full_binary) $$< 182 @$$(APPEND) $$@ "done" 177 183 @$$(ECHO) " PASSED: $$(<F) [binary]" 178 184 179 185 $(name).tst:: $(outbase).tst 180 186 VBOX_DISAS_TEST_CLEAN += $(outbase).tst $(outbase).bin $(outbase).asm 187 VBOX_DISAS_TESTS += $(name)-rebuild-$(bits).tst 181 188 endef # def_vbox_disas_binary_rules 182 189 183 190 define def_vbox_disas_binary 184 191 local name := $(notdir $(basename $(binary))) 185 local name := $(notdir $(basename $(binary)))192 local full_binary := $(abspathex $(binary),$(PATH_SUB_CURRENT)) 186 193 local outbase := $(VBOX_DISAS_TEST_PATH)/$(name)-rebuild-$(bits) 187 194 $(eval $(def_vbox_disas_binary_rules)) 188 195 endef # def_vbox_disas_binary 189 196 190 ## @todo 64-bit is problematic because of POP RDI ending up as POP EDI (incorrect default opmode), and the unused REX.X bit when mod != 3.197 ## @todo 64-bit is problematic because of bugs like POP RDI ending up as POP EDI (incorrect default opmode). 191 198 #$(foreach bits, 32 16 64, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary))) 192 199 $(foreach bits, 32 16, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary))) … … 216 223 # The test aliases 217 224 # 218 219 # individual test and per source file (for the editor). 220 $(VBOX_DISAS_TESTS:.tst=.o):: $(VBOX_DISAS_TEST_PATH)/$$(patsubst %.o,%.tst,$$@) 221 $(VBOX_DISAS_TESTS:.tst=.obj):: $$(patsubst %.obj,%.o,$$@) 225 # To run the tstAsmLock-3.asm test: kmk tstAsmLock-3.tst 226 # To run the 64-bit tstAsmLock-3.asm test: kmk tstAsmLock-3-64.tst 227 # 222 228 define def_vbox_test_aliases 223 229 local test_base := $(basename $(test)) 224 230 local test_root := $(patsubst %-16,%,$(patsubst %-32,%,$(patsubst %-64,%,$(test_base)))) 225 $(test_base).o:: $(VBOX_DISAS_TEST_PATH)/$(test) 226 $(test_base).obj:: $(VBOX_DISAS_TEST_PATH)/$(test) 227 $(test_root).o:: $(test_base).o 228 $(test_root).obj:: $(test_base).obj 231 $(test_base).tst:: $(VBOX_DISAS_TEST_PATH)/$(test) 232 $(test_root).tst:: $(test_base).tst 233 $(test_base).o:: $(test_base).tst 234 $(test_base).obj:: $(test_base).tst 235 $(test_root).o:: $(test_root).tst 236 $(test_root).obj:: $(test_root).tst 229 237 endef 230 238 $(foreach test,$(VBOX_DISAS_TESTS),$(evalvalctx def_vbox_test_aliases)) -
trunk/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm
r9098 r9099 8 8 %if TEST_BITS != 64 9 9 movzx ax, [bx+si+8] 10 movzx ax, byte [bx+si+8]11 10 movzx eax, byte [bx+si+8] 12 11 movzx eax, word [bx+si+8] -
trunk/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm
r9098 r9099 19 19 cmp bx, strict byte -1 20 20 21 %if TEST_BITS == 64 21 %if TEST_BITS == 64 ; check that these come out with qword values and not words or dwords. 22 22 add rax, strict byte 8 23 23 add rax, strict byte -1 -
trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp
r9098 r9099 402 402 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "stosw" : pCpu->opmode == CPUMODE_32BIT ? "stosd" : "stosq"; 403 403 break; 404 case OP_CBW: 405 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "cbw" : pCpu->opmode == CPUMODE_32BIT ? "cwde" : "cdqe"; 406 break; 407 case OP_CWD: 408 pszFmt = pCpu->opmode == CPUMODE_16BIT ? "cwd" : pCpu->opmode == CPUMODE_32BIT ? "cdq" : "cqo"; 409 break; 404 410 case OP_SHL: 405 411 Assert(pszFmt[3] == '/'); … … 423 429 else if (pCpu->opcode == 0x1f) 424 430 { 425 PUT_SZ("db 01fh,"); 431 Assert(pCpu->opsize >= 3); 432 PUT_SZ("db 00fh, 01fh,"); 426 433 PUT_NUM_8(pCpu->ModRM.u); 427 for (unsigned i = 2; i < pCpu->opsize; i++)434 for (unsigned i = 3; i < pCpu->opsize; i++) 428 435 { 429 436 PUT_C(','); … … 531 538 532 539 /* 540 * Segment prefixing for instructions that doesn't do memory access. 541 */ 542 if ( (pCpu->prefix & PREFIX_SEG) 543 && !(pCpu->param1.flags & USE_EFFICIENT_ADDRESS) 544 && !(pCpu->param2.flags & USE_EFFICIENT_ADDRESS) 545 && !(pCpu->param3.flags & USE_EFFICIENT_ADDRESS)) 546 { 547 PUT_STR(s_szSegPrefix[pCpu->prefix_seg], 2); 548 PUT_C(' '); 549 } 550 551 552 /* 533 553 * The formatting loop. 534 554 */ … … 989 1009 * Check for multiple prefixes of the same kind. 990 1010 */ 991 bool fSegmentPrefix = false; 992 bool fLockPrefix = false; 993 bool fAddressSize = false; 994 bool fOperandSize = false; 995 bool fRepPrefix = false; 996 bool fRex = false; 1011 uint32_t fPrefixes = 0; 997 1012 for (uint8_t const *pu8 = pState->pbInstr;; pu8++) 998 1013 { 999 bool *pf;1014 uint32_t f; 1000 1015 switch (*pu8) 1001 1016 { 1002 1017 case 0xf0: 1003 pf = &fLockPrefix;1018 f = PREFIX_LOCK; 1004 1019 break; 1005 1020 1006 1021 case 0xf2: 1007 1022 case 0xf3: 1008 pf = &fRepPrefix;1023 f = PREFIX_REP; /* yes, both */ 1009 1024 break; 1010 1025 … … 1015 1030 case 0x64: 1016 1031 case 0x65: 1017 pf = &fSegmentPrefix;1032 f = PREFIX_SEG; 1018 1033 break; 1019 1034 1020 1035 case 0x66: 1021 pf = &fOperandSize;1036 f = PREFIX_OPSIZE; 1022 1037 break; 1023 1038 1024 1039 case 0x67: 1025 pf = &fAddressSize;1040 f = PREFIX_ADDRSIZE; 1026 1041 break; 1027 1042 1028 1043 case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47: 1029 1044 case 0x48: case 0x49: case 0x4a: case 0x4b: case 0x4c: case 0x4d: case 0x4e: case 0x4f: 1030 pf = pState->Cpu.mode == CPUMODE_64BIT ? &fRex : NULL;1045 f = pState->Cpu.mode == CPUMODE_64BIT ? PREFIX_REX : 0; 1031 1046 break; 1032 1047 1033 1048 default: 1034 pf = NULL;1035 break; 1036 } 1037 if (! pf)1049 f = 0; 1050 break; 1051 } 1052 if (!f) 1038 1053 break; /* done */ 1039 if ( *pf)1054 if (fPrefixes & f) 1040 1055 return true; 1041 *pf = true;1056 fPrefixes |= f; 1042 1057 } 1043 1058 1044 1059 /* segment overrides are fun */ 1045 if (f SegmentPrefix)1060 if (fPrefixes & PREFIX_SEG) 1046 1061 { 1047 1062 /* no efficient address which it may apply to. */ … … 1054 1069 1055 1070 /* fixed register + addr override doesn't go down all that well. */ 1056 if (f AddressSize)1071 if (fPrefixes & PREFIX_ADDRSIZE) 1057 1072 { 1058 1073 Assert(pState->Cpu.prefix & PREFIX_ADDRSIZE); … … 1064 1079 } 1065 1080 1081 /* nop w/ prefix(es). */ 1082 if ( fPrefixes 1083 && pState->Cpu.pCurInstr->opcode == OP_NOP) 1084 return true; 1085 1086 /* There are probably a whole bunch of these... */ 1087 if (fPrefixes & ~PREFIX_SEG) 1088 { 1089 switch (pState->Cpu.pCurInstr->opcode) 1090 { 1091 case OP_POP: 1092 case OP_PUSH: 1093 if ( pState->Cpu.pCurInstr->param1 >= OP_PARM_REG_SEG_START 1094 && pState->Cpu.pCurInstr->param1 <= OP_PARM_REG_SEG_END) 1095 return true; 1096 if ( (fPrefixes & ~PREFIX_OPSIZE) 1097 && pState->Cpu.pCurInstr->param1 >= OP_PARM_REG_GEN32_START 1098 && pState->Cpu.pCurInstr->param1 <= OP_PARM_REG_GEN32_END) 1099 return true; 1100 break; 1101 1102 case OP_POPA: 1103 case OP_POPF: 1104 case OP_PUSHA: 1105 case OP_PUSHF: 1106 if (fPrefixes & ~PREFIX_OPSIZE) 1107 return true; 1108 break; 1109 } 1110 } 1111 1066 1112 1067 1113 /* check for the version of xyz reg,reg instruction that the assembler doesn't use. … … 1072 1118 switch (pState->Cpu.pCurInstr->opcode) 1073 1119 { 1120 case OP_ADD: 1121 case OP_OR: 1074 1122 case OP_ADC: 1075 case OP_ ADD:1123 case OP_SBB: 1076 1124 case OP_AND: 1077 case OP_OR:1078 1125 case OP_SUB: 1079 case OP_SBB:1080 1126 case OP_XOR: 1127 case OP_CMP: 1081 1128 if ( ( pState->Cpu.pCurInstr->param1 == OP_PARM_Gb /* r8 */ 1082 1129 && pState->Cpu.pCurInstr->param2 == OP_PARM_Eb /* r8/mem8 */) … … 1084 1131 && pState->Cpu.pCurInstr->param2 == OP_PARM_Ev /* rX/memX */)) 1085 1132 return true; 1133 1134 /* 82 (see table A-6). */ 1135 if (pState->Cpu.opcode == 0x82) 1136 return true; 1086 1137 break; 1087 1138 … … 1091 1142 return true; 1092 1143 1144 case OP_POP: 1145 case OP_PUSH: 1146 Assert(pState->Cpu.opcode == 0x8f); 1147 return true; 1148 1093 1149 default: 1094 1150 break; 1095 1151 } 1096 1152 } 1153 1154 /* And some more - see table A-6. */ 1155 if (pState->Cpu.opcode == 0x82) 1156 { 1157 switch (pState->Cpu.pCurInstr->opcode) 1158 { 1159 case OP_ADD: 1160 case OP_OR: 1161 case OP_ADC: 1162 case OP_SBB: 1163 case OP_AND: 1164 case OP_SUB: 1165 case OP_XOR: 1166 case OP_CMP: 1167 return true; 1168 break; 1169 } 1170 } 1171 1097 1172 1098 1173 /* check for REX.X = 1 without SIB. */ … … 1123 1198 break; 1124 1199 } 1200 1201 /* 1202 * The MOVZX reg32,mem16 instruction without an operand size prefix 1203 * doesn't quite make sense... 1204 */ 1205 if ( pState->Cpu.pCurInstr->opcode == OP_MOVZX 1206 && pState->Cpu.opcode == 0xB7 1207 && (pState->Cpu.mode == CPUMODE_16BIT) != !!(fPrefixes & PREFIX_OPSIZE)) 1208 return true; 1125 1209 1126 1210 return false;
Note:
See TracChangeset
for help on using the changeset viewer.