VirtualBox

Changeset 9099 in vbox for trunk/src


Ignore:
Timestamp:
May 25, 2008 11:54:49 PM (17 years ago)
Author:
vboxsync
Message:

More instruction filtering and hacking.

Location:
trunk/src/VBox/Disassembler/testcase
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Disassembler/testcase/Makefile.kmk

    r9098 r9099  
    4949
    5050# 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?
    5152VBOX_DISAS_TESTS_BINARIES := \
    52         $(PATH_SUB_CURRENT)/tstBinMovzx-1.bin
    53 #       $(PATH_SUB_CURRENT)/tstBin-1.bin \
     53        tstBinMovzx-1.bin
     54ifeq ($(USER),bird)
     55VBOX_DISAS_TESTS_BINARIES += \
     56        tstBin-1.bin \
     57        tstBin-2.bin \
     58        tstBin-3.bin \
    5459#       $(PATH_BIN)/testcase/tstDisasm-2$(SUFF_EXEC)
     60endif
    5561
    5662
     
    162168# Generate the rules for the binary tests.
    163169define 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)/
    165171        @$$(ECHO) "Generating: $$(@F) from $$(<F)"
    166172        $$(REDIRECT) -E VBOX_LOG_DEST=nofile -o $$@ -- $$(INSTARGET_tstDisasm-2) --style=yasm --cpumode=$(bits) --undef-op=db $$<
     
    171177
    172178$(outbase).tst: $(outbase).bin
    173         @$$(ECHO) "Verifying build: $$(<F) against $(not-dir $(binary))"
     179        @$$(ECHO) "Verifying build: $$(<F) against $(not-dir $(full_binary))"
    174180        @$$(RM) -f $$@
    175         $$(CMP) -l $(binary) $$<
    176         @$$(APPEND) $@ "done"
     181        $$(CMP) -l $(full_binary) $$<
     182        @$$(APPEND) $$@ "done"
    177183        @$$(ECHO) " PASSED:  $$(<F) [binary]"
    178184
    179185$(name).tst:: $(outbase).tst
    180186VBOX_DISAS_TEST_CLEAN += $(outbase).tst $(outbase).bin $(outbase).asm
     187VBOX_DISAS_TESTS += $(name)-rebuild-$(bits).tst
    181188endef # def_vbox_disas_binary_rules
    182189
    183190define def_vbox_disas_binary
    184191local name := $(notdir $(basename $(binary)))
    185 local name := $(notdir $(basename $(binary)))
     192local full_binary := $(abspathex $(binary),$(PATH_SUB_CURRENT))
    186193local outbase := $(VBOX_DISAS_TEST_PATH)/$(name)-rebuild-$(bits)
    187194$(eval $(def_vbox_disas_binary_rules))
    188195endef # def_vbox_disas_binary
    189196
    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).
    191198#$(foreach bits, 32 16 64, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary)))
    192199$(foreach bits, 32 16, $(foreach binary, $(VBOX_DISAS_TESTS_BINARIES), $(evalvalctx def_vbox_disas_binary)))
     
    216223# The test aliases
    217224#
    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#
    222228define def_vbox_test_aliases
    223229local test_base := $(basename $(test))
    224230local 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
    229237endef
    230238$(foreach test,$(VBOX_DISAS_TESTS),$(evalvalctx def_vbox_test_aliases))
  • trunk/src/VBox/Disassembler/testcase/tstAsmMovzx-1.asm

    r9098 r9099  
    88%if TEST_BITS != 64
    99    movzx ax, [bx+si+8]
    10     movzx ax, byte [bx+si+8]
    1110    movzx eax, byte [bx+si+8]
    1211    movzx eax, word [bx+si+8]
  • trunk/src/VBox/Disassembler/testcase/tstAsmSignExtend-1.asm

    r9098 r9099  
    1919    cmp bx, strict byte -1
    2020
    21 %if TEST_BITS == 64
     21%if TEST_BITS == 64 ; check that these come out with qword values and not words or dwords.
    2222    add rax, strict byte 8
    2323    add rax, strict byte -1
  • trunk/src/VBox/Disassembler/testcase/tstDisasm-2.cpp

    r9098 r9099  
    402402                pszFmt = pCpu->opmode == CPUMODE_16BIT ? "stosw"    : pCpu->opmode == CPUMODE_32BIT ? "stosd" : "stosq";
    403403                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;
    404410            case OP_SHL:
    405411                Assert(pszFmt[3] == '/');
     
    423429                else if (pCpu->opcode == 0x1f)
    424430                {
    425                     PUT_SZ("db 01fh,");
     431                    Assert(pCpu->opsize >= 3);
     432                    PUT_SZ("db 00fh, 01fh,");
    426433                    PUT_NUM_8(pCpu->ModRM.u);
    427                     for (unsigned i = 2; i < pCpu->opsize; i++)
     434                    for (unsigned i = 3; i < pCpu->opsize; i++)
    428435                    {
    429436                        PUT_C(',');
     
    531538
    532539        /*
     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        /*
    533553         * The formatting loop.
    534554         */
     
    9891009     * Check for multiple prefixes of the same kind.
    9901010     */
    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;
    9971012    for (uint8_t const *pu8 = pState->pbInstr;; pu8++)
    9981013    {
    999         bool *pf;
     1014        uint32_t f;
    10001015        switch (*pu8)
    10011016        {
    10021017            case 0xf0:
    1003                 pf = &fLockPrefix;
     1018                f = PREFIX_LOCK;
    10041019                break;
    10051020
    10061021            case 0xf2:
    10071022            case 0xf3:
    1008                 pf = &fRepPrefix;
     1023                f = PREFIX_REP; /* yes, both */
    10091024                break;
    10101025
     
    10151030            case 0x64:
    10161031            case 0x65:
    1017                 pf = &fSegmentPrefix;
     1032                f = PREFIX_SEG;
    10181033                break;
    10191034
    10201035            case 0x66:
    1021                 pf = &fOperandSize;
     1036                f = PREFIX_OPSIZE;
    10221037                break;
    10231038
    10241039            case 0x67:
    1025                 pf = &fAddressSize;
     1040                f = PREFIX_ADDRSIZE;
    10261041                break;
    10271042
    10281043            case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: case 0x47:
    10291044            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;
    10311046                break;
    10321047
    10331048            default:
    1034                 pf = NULL;
    1035                 break;
    1036         }
    1037         if (!pf)
     1049                f = 0;
     1050                break;
     1051        }
     1052        if (!f)
    10381053            break; /* done */
    1039         if (*pf)
     1054        if (fPrefixes & f)
    10401055            return true;
    1041         *pf = true;
     1056        fPrefixes |= f;
    10421057    }
    10431058
    10441059    /* segment overrides are fun */
    1045     if (fSegmentPrefix)
     1060    if (fPrefixes & PREFIX_SEG)
    10461061    {
    10471062        /* no efficient address which it may apply to. */
     
    10541069
    10551070    /* fixed register + addr override doesn't go down all that well. */
    1056     if (fAddressSize)
     1071    if (fPrefixes & PREFIX_ADDRSIZE)
    10571072    {
    10581073        Assert(pState->Cpu.prefix & PREFIX_ADDRSIZE);
     
    10641079    }
    10651080
     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
    10661112
    10671113    /* check for the version of xyz reg,reg instruction that the assembler doesn't use.
     
    10721118        switch (pState->Cpu.pCurInstr->opcode)
    10731119        {
     1120            case OP_ADD:
     1121            case OP_OR:
    10741122            case OP_ADC:
    1075             case OP_ADD:
     1123            case OP_SBB:
    10761124            case OP_AND:
    1077             case OP_OR:
    10781125            case OP_SUB:
    1079             case OP_SBB:
    10801126            case OP_XOR:
     1127            case OP_CMP:
    10811128                if (    (    pState->Cpu.pCurInstr->param1 == OP_PARM_Gb /* r8 */
    10821129                         && pState->Cpu.pCurInstr->param2 == OP_PARM_Eb /* r8/mem8 */)
     
    10841131                         && pState->Cpu.pCurInstr->param2 == OP_PARM_Ev /* rX/memX */))
    10851132                    return true;
     1133
     1134                /* 82 (see table A-6). */
     1135                if (pState->Cpu.opcode == 0x82)
     1136                    return true;
    10861137                break;
    10871138
     
    10911142                return true;
    10921143
     1144            case OP_POP:
     1145            case OP_PUSH:
     1146                Assert(pState->Cpu.opcode == 0x8f);
     1147                return true;
     1148
    10931149            default:
    10941150                break;
    10951151        }
    10961152    }
     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
    10971172
    10981173    /* check for REX.X = 1 without SIB. */
     
    11231198            break;
    11241199    }
     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;
    11251209
    11261210    return false;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette