hexcore-capstone 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/README.md +191 -0
- package/binding.gyp +168 -0
- package/deps/capstone/LEB128.h +38 -0
- package/deps/capstone/MCDisassembler.h +14 -0
- package/deps/capstone/MCFixedLenDisassembler.h +32 -0
- package/deps/capstone/MCInst.c +270 -0
- package/deps/capstone/MCInst.h +165 -0
- package/deps/capstone/MCInstrDesc.c +41 -0
- package/deps/capstone/MCInstrDesc.h +167 -0
- package/deps/capstone/MCRegisterInfo.c +151 -0
- package/deps/capstone/MCRegisterInfo.h +116 -0
- package/deps/capstone/Mapping.c +254 -0
- package/deps/capstone/Mapping.h +174 -0
- package/deps/capstone/MathExtras.h +442 -0
- package/deps/capstone/SStream.c +181 -0
- package/deps/capstone/SStream.h +40 -0
- package/deps/capstone/arch/AArch64/AArch64AddressingModes.h +945 -0
- package/deps/capstone/arch/AArch64/AArch64BaseInfo.c +77 -0
- package/deps/capstone/arch/AArch64/AArch64BaseInfo.h +585 -0
- package/deps/capstone/arch/AArch64/AArch64Disassembler.c +2280 -0
- package/deps/capstone/arch/AArch64/AArch64Disassembler.h +18 -0
- package/deps/capstone/arch/AArch64/AArch64GenAsmWriter.inc +26589 -0
- package/deps/capstone/arch/AArch64/AArch64GenDisassemblerTables.inc +27322 -0
- package/deps/capstone/arch/AArch64/AArch64GenInstrInfo.inc +13194 -0
- package/deps/capstone/arch/AArch64/AArch64GenRegisterInfo.inc +3814 -0
- package/deps/capstone/arch/AArch64/AArch64GenRegisterName.inc +714 -0
- package/deps/capstone/arch/AArch64/AArch64GenRegisterV.inc +673 -0
- package/deps/capstone/arch/AArch64/AArch64GenSubtargetInfo.inc +229 -0
- package/deps/capstone/arch/AArch64/AArch64GenSystemOperands.inc +2863 -0
- package/deps/capstone/arch/AArch64/AArch64GenSystemOperands_enum.inc +21 -0
- package/deps/capstone/arch/AArch64/AArch64InstPrinter.c +3029 -0
- package/deps/capstone/arch/AArch64/AArch64InstPrinter.h +28 -0
- package/deps/capstone/arch/AArch64/AArch64Mapping.c +883 -0
- package/deps/capstone/arch/AArch64/AArch64Mapping.h +43 -0
- package/deps/capstone/arch/AArch64/AArch64MappingInsn.inc +37790 -0
- package/deps/capstone/arch/AArch64/AArch64MappingInsnName.inc +1282 -0
- package/deps/capstone/arch/AArch64/AArch64MappingInsnOp.inc +26994 -0
- package/deps/capstone/arch/AArch64/AArch64Module.c +44 -0
- package/deps/capstone/arch/AArch64/AArch64Module.h +12 -0
- package/deps/capstone/arch/ARM/ARMAddressingModes.h +698 -0
- package/deps/capstone/arch/ARM/ARMBaseInfo.h +486 -0
- package/deps/capstone/arch/ARM/ARMDisassembler.c +5763 -0
- package/deps/capstone/arch/ARM/ARMDisassembler.h +18 -0
- package/deps/capstone/arch/ARM/ARMGenAsmWriter.inc +9545 -0
- package/deps/capstone/arch/ARM/ARMGenDisassemblerTables.inc +15185 -0
- package/deps/capstone/arch/ARM/ARMGenInstrInfo.inc +6632 -0
- package/deps/capstone/arch/ARM/ARMGenRegisterInfo.inc +2102 -0
- package/deps/capstone/arch/ARM/ARMGenRegisterName.inc +231 -0
- package/deps/capstone/arch/ARM/ARMGenRegisterName_digit.inc +231 -0
- package/deps/capstone/arch/ARM/ARMGenSubtargetInfo.inc +162 -0
- package/deps/capstone/arch/ARM/ARMGenSystemRegister.inc +270 -0
- package/deps/capstone/arch/ARM/ARMInstPrinter.c +3364 -0
- package/deps/capstone/arch/ARM/ARMInstPrinter.h +43 -0
- package/deps/capstone/arch/ARM/ARMMapping.c +551 -0
- package/deps/capstone/arch/ARM/ARMMapping.h +40 -0
- package/deps/capstone/arch/ARM/ARMMappingInsn.inc +18772 -0
- package/deps/capstone/arch/ARM/ARMMappingInsnName.inc +475 -0
- package/deps/capstone/arch/ARM/ARMMappingInsnOp.inc +10729 -0
- package/deps/capstone/arch/ARM/ARMModule.c +63 -0
- package/deps/capstone/arch/ARM/ARMModule.h +12 -0
- package/deps/capstone/arch/BPF/BPFConstants.h +88 -0
- package/deps/capstone/arch/BPF/BPFDisassembler.c +464 -0
- package/deps/capstone/arch/BPF/BPFDisassembler.h +27 -0
- package/deps/capstone/arch/BPF/BPFInstPrinter.c +285 -0
- package/deps/capstone/arch/BPF/BPFInstPrinter.h +16 -0
- package/deps/capstone/arch/BPF/BPFMapping.c +513 -0
- package/deps/capstone/arch/BPF/BPFMapping.h +21 -0
- package/deps/capstone/arch/BPF/BPFModule.c +34 -0
- package/deps/capstone/arch/BPF/BPFModule.h +12 -0
- package/deps/capstone/arch/EVM/EVMDisassembler.c +379 -0
- package/deps/capstone/arch/EVM/EVMDisassembler.h +12 -0
- package/deps/capstone/arch/EVM/EVMInstPrinter.c +20 -0
- package/deps/capstone/arch/EVM/EVMInstPrinter.h +17 -0
- package/deps/capstone/arch/EVM/EVMMapping.c +344 -0
- package/deps/capstone/arch/EVM/EVMMapping.h +8 -0
- package/deps/capstone/arch/EVM/EVMMappingInsn.inc +259 -0
- package/deps/capstone/arch/EVM/EVMModule.c +33 -0
- package/deps/capstone/arch/EVM/EVMModule.h +12 -0
- package/deps/capstone/arch/M680X/M680XDisassembler.c +2307 -0
- package/deps/capstone/arch/M680X/M680XDisassembler.h +17 -0
- package/deps/capstone/arch/M680X/M680XDisassemblerInternals.h +57 -0
- package/deps/capstone/arch/M680X/M680XInstPrinter.c +360 -0
- package/deps/capstone/arch/M680X/M680XInstPrinter.h +25 -0
- package/deps/capstone/arch/M680X/M680XModule.c +77 -0
- package/deps/capstone/arch/M680X/M680XModule.h +12 -0
- package/deps/capstone/arch/M680X/cpu12.inc +335 -0
- package/deps/capstone/arch/M680X/hcs08.inc +60 -0
- package/deps/capstone/arch/M680X/hd6301.inc +15 -0
- package/deps/capstone/arch/M680X/hd6309.inc +259 -0
- package/deps/capstone/arch/M680X/insn_props.inc +367 -0
- package/deps/capstone/arch/M680X/m6800.inc +277 -0
- package/deps/capstone/arch/M680X/m6801.inc +39 -0
- package/deps/capstone/arch/M680X/m6805.inc +277 -0
- package/deps/capstone/arch/M680X/m6808.inc +91 -0
- package/deps/capstone/arch/M680X/m6809.inc +352 -0
- package/deps/capstone/arch/M680X/m6811.inc +105 -0
- package/deps/capstone/arch/M68K/M68KDisassembler.c +3668 -0
- package/deps/capstone/arch/M68K/M68KDisassembler.h +30 -0
- package/deps/capstone/arch/M68K/M68KInstPrinter.c +387 -0
- package/deps/capstone/arch/M68K/M68KInstPrinter.h +21 -0
- package/deps/capstone/arch/M68K/M68KInstructionTable.inc +65540 -0
- package/deps/capstone/arch/M68K/M68KModule.c +42 -0
- package/deps/capstone/arch/M68K/M68KModule.h +12 -0
- package/deps/capstone/arch/MOS65XX/MOS65XXDisassembler.c +544 -0
- package/deps/capstone/arch/MOS65XX/MOS65XXDisassembler.h +22 -0
- package/deps/capstone/arch/MOS65XX/MOS65XXDisassemblerInternals.h +23 -0
- package/deps/capstone/arch/MOS65XX/MOS65XXModule.c +79 -0
- package/deps/capstone/arch/MOS65XX/MOS65XXModule.h +12 -0
- package/deps/capstone/arch/MOS65XX/instruction_info.inc +106 -0
- package/deps/capstone/arch/MOS65XX/m6502.inc +256 -0
- package/deps/capstone/arch/MOS65XX/m65816.inc +256 -0
- package/deps/capstone/arch/MOS65XX/m65c02.inc +256 -0
- package/deps/capstone/arch/MOS65XX/mw65c02.inc +256 -0
- package/deps/capstone/arch/Mips/MipsDisassembler.c +1794 -0
- package/deps/capstone/arch/Mips/MipsDisassembler.h +16 -0
- package/deps/capstone/arch/Mips/MipsGenAsmWriter.inc +5725 -0
- package/deps/capstone/arch/Mips/MipsGenDisassemblerTables.inc +6942 -0
- package/deps/capstone/arch/Mips/MipsGenInstrInfo.inc +1805 -0
- package/deps/capstone/arch/Mips/MipsGenRegisterInfo.inc +1679 -0
- package/deps/capstone/arch/Mips/MipsGenSubtargetInfo.inc +52 -0
- package/deps/capstone/arch/Mips/MipsInstPrinter.c +424 -0
- package/deps/capstone/arch/Mips/MipsInstPrinter.h +25 -0
- package/deps/capstone/arch/Mips/MipsMapping.c +1070 -0
- package/deps/capstone/arch/Mips/MipsMapping.h +25 -0
- package/deps/capstone/arch/Mips/MipsMappingInsn.inc +9315 -0
- package/deps/capstone/arch/Mips/MipsModule.c +52 -0
- package/deps/capstone/arch/Mips/MipsModule.h +12 -0
- package/deps/capstone/arch/PowerPC/PPCDisassembler.c +627 -0
- package/deps/capstone/arch/PowerPC/PPCDisassembler.h +17 -0
- package/deps/capstone/arch/PowerPC/PPCGenAsmWriter.inc +11451 -0
- package/deps/capstone/arch/PowerPC/PPCGenDisassemblerTables.inc +6886 -0
- package/deps/capstone/arch/PowerPC/PPCGenInstrInfo.inc +4772 -0
- package/deps/capstone/arch/PowerPC/PPCGenRegisterInfo.inc +1122 -0
- package/deps/capstone/arch/PowerPC/PPCGenRegisterName.inc +278 -0
- package/deps/capstone/arch/PowerPC/PPCGenSubtargetInfo.inc +90 -0
- package/deps/capstone/arch/PowerPC/PPCInstPrinter.c +1238 -0
- package/deps/capstone/arch/PowerPC/PPCInstPrinter.h +15 -0
- package/deps/capstone/arch/PowerPC/PPCMapping.c +570 -0
- package/deps/capstone/arch/PowerPC/PPCMapping.h +40 -0
- package/deps/capstone/arch/PowerPC/PPCMappingInsn.inc +13220 -0
- package/deps/capstone/arch/PowerPC/PPCMappingInsnName.inc +1731 -0
- package/deps/capstone/arch/PowerPC/PPCModule.c +45 -0
- package/deps/capstone/arch/PowerPC/PPCModule.h +12 -0
- package/deps/capstone/arch/PowerPC/PPCPredicates.h +62 -0
- package/deps/capstone/arch/RISCV/RISCVBaseInfo.h +106 -0
- package/deps/capstone/arch/RISCV/RISCVDisassembler.c +433 -0
- package/deps/capstone/arch/RISCV/RISCVDisassembler.h +18 -0
- package/deps/capstone/arch/RISCV/RISCVGenAsmWriter.inc +2651 -0
- package/deps/capstone/arch/RISCV/RISCVGenDisassemblerTables.inc +1776 -0
- package/deps/capstone/arch/RISCV/RISCVGenInsnNameMaps.inc +275 -0
- package/deps/capstone/arch/RISCV/RISCVGenInstrInfo.inc +470 -0
- package/deps/capstone/arch/RISCV/RISCVGenRegisterInfo.inc +426 -0
- package/deps/capstone/arch/RISCV/RISCVGenSubtargetInfo.inc +33 -0
- package/deps/capstone/arch/RISCV/RISCVInstPrinter.c +447 -0
- package/deps/capstone/arch/RISCV/RISCVInstPrinter.h +24 -0
- package/deps/capstone/arch/RISCV/RISCVMapping.c +366 -0
- package/deps/capstone/arch/RISCV/RISCVMapping.h +22 -0
- package/deps/capstone/arch/RISCV/RISCVMappingInsn.inc +1635 -0
- package/deps/capstone/arch/RISCV/RISCVModule.c +42 -0
- package/deps/capstone/arch/RISCV/RISCVModule.h +12 -0
- package/deps/capstone/arch/SH/SHDisassembler.c +2221 -0
- package/deps/capstone/arch/SH/SHDisassembler.h +19 -0
- package/deps/capstone/arch/SH/SHInsnTable.inc +66 -0
- package/deps/capstone/arch/SH/SHInstPrinter.c +438 -0
- package/deps/capstone/arch/SH/SHInstPrinter.h +23 -0
- package/deps/capstone/arch/SH/SHModule.c +39 -0
- package/deps/capstone/arch/SH/SHModule.h +12 -0
- package/deps/capstone/arch/SH/mktable.rb +390 -0
- package/deps/capstone/arch/Sparc/Sparc.h +63 -0
- package/deps/capstone/arch/Sparc/SparcDisassembler.c +500 -0
- package/deps/capstone/arch/Sparc/SparcDisassembler.h +17 -0
- package/deps/capstone/arch/Sparc/SparcGenAsmWriter.inc +5709 -0
- package/deps/capstone/arch/Sparc/SparcGenDisassemblerTables.inc +2028 -0
- package/deps/capstone/arch/Sparc/SparcGenInstrInfo.inc +514 -0
- package/deps/capstone/arch/Sparc/SparcGenRegisterInfo.inc +451 -0
- package/deps/capstone/arch/Sparc/SparcGenSubtargetInfo.inc +27 -0
- package/deps/capstone/arch/Sparc/SparcInstPrinter.c +446 -0
- package/deps/capstone/arch/Sparc/SparcInstPrinter.h +17 -0
- package/deps/capstone/arch/Sparc/SparcMapping.c +665 -0
- package/deps/capstone/arch/Sparc/SparcMapping.h +34 -0
- package/deps/capstone/arch/Sparc/SparcMappingInsn.inc +2643 -0
- package/deps/capstone/arch/Sparc/SparcModule.c +45 -0
- package/deps/capstone/arch/Sparc/SparcModule.h +12 -0
- package/deps/capstone/arch/SystemZ/SystemZDisassembler.c +484 -0
- package/deps/capstone/arch/SystemZ/SystemZDisassembler.h +17 -0
- package/deps/capstone/arch/SystemZ/SystemZGenAsmWriter.inc +11575 -0
- package/deps/capstone/arch/SystemZ/SystemZGenDisassemblerTables.inc +10262 -0
- package/deps/capstone/arch/SystemZ/SystemZGenInsnNameMaps.inc +2348 -0
- package/deps/capstone/arch/SystemZ/SystemZGenInstrInfo.inc +2820 -0
- package/deps/capstone/arch/SystemZ/SystemZGenRegisterInfo.inc +741 -0
- package/deps/capstone/arch/SystemZ/SystemZGenSubtargetInfo.inc +49 -0
- package/deps/capstone/arch/SystemZ/SystemZInstPrinter.c +433 -0
- package/deps/capstone/arch/SystemZ/SystemZInstPrinter.h +15 -0
- package/deps/capstone/arch/SystemZ/SystemZMCTargetDesc.c +195 -0
- package/deps/capstone/arch/SystemZ/SystemZMCTargetDesc.h +51 -0
- package/deps/capstone/arch/SystemZ/SystemZMapping.c +479 -0
- package/deps/capstone/arch/SystemZ/SystemZMapping.h +23 -0
- package/deps/capstone/arch/SystemZ/SystemZMappingInsn.inc +14175 -0
- package/deps/capstone/arch/SystemZ/SystemZModule.c +44 -0
- package/deps/capstone/arch/SystemZ/SystemZModule.h +12 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xDisassembler.c +628 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xDisassembler.h +19 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xGenAsmWriter.inc +684 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xGenDisassemblerTables.inc +1352 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xGenInstrInfo.inc +298 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xGenRegisterInfo.inc +277 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xInstPrinter.c +572 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xInstPrinter.h +15 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xMapping.c +1926 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xMapping.h +26 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xModule.c +39 -0
- package/deps/capstone/arch/TMS320C64x/TMS320C64xModule.h +12 -0
- package/deps/capstone/arch/TriCore/TriCore.td +134 -0
- package/deps/capstone/arch/TriCore/TriCoreCallingConv.td +61 -0
- package/deps/capstone/arch/TriCore/TriCoreDisassembler.c +1655 -0
- package/deps/capstone/arch/TriCore/TriCoreDisassembler.h +18 -0
- package/deps/capstone/arch/TriCore/TriCoreGenAsmWriter.inc +3691 -0
- package/deps/capstone/arch/TriCore/TriCoreGenCSFeatureName.inc +22 -0
- package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsn.inc +8938 -0
- package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsnName.inc +404 -0
- package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsnOp.inc +7994 -0
- package/deps/capstone/arch/TriCore/TriCoreGenCSOpGroup.inc +32 -0
- package/deps/capstone/arch/TriCore/TriCoreGenDisassemblerTables.inc +4044 -0
- package/deps/capstone/arch/TriCore/TriCoreGenInstrInfo.inc +2693 -0
- package/deps/capstone/arch/TriCore/TriCoreGenRegisterInfo.inc +295 -0
- package/deps/capstone/arch/TriCore/TriCoreGenSubtargetInfo.inc +40 -0
- package/deps/capstone/arch/TriCore/TriCoreInstPrinter.c +488 -0
- package/deps/capstone/arch/TriCore/TriCoreInstrFormats.td +773 -0
- package/deps/capstone/arch/TriCore/TriCoreInstrInfo.td +1873 -0
- package/deps/capstone/arch/TriCore/TriCoreLinkage.h +21 -0
- package/deps/capstone/arch/TriCore/TriCoreMapping.c +241 -0
- package/deps/capstone/arch/TriCore/TriCoreMapping.h +32 -0
- package/deps/capstone/arch/TriCore/TriCoreModule.c +44 -0
- package/deps/capstone/arch/TriCore/TriCoreModule.h +11 -0
- package/deps/capstone/arch/TriCore/TriCoreRegisterInfo.td +153 -0
- package/deps/capstone/arch/WASM/WASMDisassembler.c +1009 -0
- package/deps/capstone/arch/WASM/WASMDisassembler.h +12 -0
- package/deps/capstone/arch/WASM/WASMInstPrinter.c +47 -0
- package/deps/capstone/arch/WASM/WASMInstPrinter.h +18 -0
- package/deps/capstone/arch/WASM/WASMMapping.c +333 -0
- package/deps/capstone/arch/WASM/WASMMapping.h +9 -0
- package/deps/capstone/arch/WASM/WASMModule.c +33 -0
- package/deps/capstone/arch/WASM/WASMModule.h +12 -0
- package/deps/capstone/arch/X86/X86ATTInstPrinter.c +997 -0
- package/deps/capstone/arch/X86/X86BaseInfo.h +50 -0
- package/deps/capstone/arch/X86/X86Disassembler.c +1033 -0
- package/deps/capstone/arch/X86/X86Disassembler.h +28 -0
- package/deps/capstone/arch/X86/X86DisassemblerDecoder.c +2358 -0
- package/deps/capstone/arch/X86/X86DisassemblerDecoder.h +725 -0
- package/deps/capstone/arch/X86/X86DisassemblerDecoderCommon.h +483 -0
- package/deps/capstone/arch/X86/X86GenAsmWriter.inc +49199 -0
- package/deps/capstone/arch/X86/X86GenAsmWriter1.inc +33196 -0
- package/deps/capstone/arch/X86/X86GenAsmWriter1_reduce.inc +2531 -0
- package/deps/capstone/arch/X86/X86GenAsmWriter_reduce.inc +2855 -0
- package/deps/capstone/arch/X86/X86GenDisassemblerTables.inc +112961 -0
- package/deps/capstone/arch/X86/X86GenDisassemblerTables2.inc +102151 -0
- package/deps/capstone/arch/X86/X86GenDisassemblerTables_reduce.inc +28047 -0
- package/deps/capstone/arch/X86/X86GenDisassemblerTables_reduce2.inc +18827 -0
- package/deps/capstone/arch/X86/X86GenInstrInfo.inc +15158 -0
- package/deps/capstone/arch/X86/X86GenInstrInfo_reduce.inc +1564 -0
- package/deps/capstone/arch/X86/X86GenRegisterInfo.inc +1549 -0
- package/deps/capstone/arch/X86/X86GenRegisterName.inc +292 -0
- package/deps/capstone/arch/X86/X86GenRegisterName1.inc +291 -0
- package/deps/capstone/arch/X86/X86ImmSize.inc +335 -0
- package/deps/capstone/arch/X86/X86InstPrinter.h +26 -0
- package/deps/capstone/arch/X86/X86InstPrinterCommon.c +116 -0
- package/deps/capstone/arch/X86/X86InstPrinterCommon.h +16 -0
- package/deps/capstone/arch/X86/X86IntelInstPrinter.c +1061 -0
- package/deps/capstone/arch/X86/X86Lookup16.inc +16874 -0
- package/deps/capstone/arch/X86/X86Lookup16_reduce.inc +2308 -0
- package/deps/capstone/arch/X86/X86Mapping.c +2266 -0
- package/deps/capstone/arch/X86/X86Mapping.h +96 -0
- package/deps/capstone/arch/X86/X86MappingInsn.inc +105977 -0
- package/deps/capstone/arch/X86/X86MappingInsnName.inc +1527 -0
- package/deps/capstone/arch/X86/X86MappingInsnName_reduce.inc +348 -0
- package/deps/capstone/arch/X86/X86MappingInsnOp.inc +75700 -0
- package/deps/capstone/arch/X86/X86MappingInsnOp_reduce.inc +7729 -0
- package/deps/capstone/arch/X86/X86MappingInsn_reduce.inc +10819 -0
- package/deps/capstone/arch/X86/X86MappingReg.inc +280 -0
- package/deps/capstone/arch/X86/X86Module.c +94 -0
- package/deps/capstone/arch/X86/X86Module.h +12 -0
- package/deps/capstone/arch/XCore/XCoreDisassembler.c +794 -0
- package/deps/capstone/arch/XCore/XCoreDisassembler.h +17 -0
- package/deps/capstone/arch/XCore/XCoreGenAsmWriter.inc +772 -0
- package/deps/capstone/arch/XCore/XCoreGenDisassemblerTables.inc +853 -0
- package/deps/capstone/arch/XCore/XCoreGenInstrInfo.inc +267 -0
- package/deps/capstone/arch/XCore/XCoreGenRegisterInfo.inc +110 -0
- package/deps/capstone/arch/XCore/XCoreInstPrinter.c +250 -0
- package/deps/capstone/arch/XCore/XCoreInstPrinter.h +18 -0
- package/deps/capstone/arch/XCore/XCoreMapping.c +297 -0
- package/deps/capstone/arch/XCore/XCoreMapping.h +26 -0
- package/deps/capstone/arch/XCore/XCoreMappingInsn.inc +1287 -0
- package/deps/capstone/arch/XCore/XCoreModule.c +41 -0
- package/deps/capstone/arch/XCore/XCoreModule.h +12 -0
- package/deps/capstone/cs.c +1664 -0
- package/deps/capstone/cs_priv.h +101 -0
- package/deps/capstone/cs_simple_types.h +886 -0
- package/deps/capstone/include/capstone/arm.h +991 -0
- package/deps/capstone/include/capstone/arm64.h +3159 -0
- package/deps/capstone/include/capstone/bpf.h +209 -0
- package/deps/capstone/include/capstone/capstone.h +875 -0
- package/deps/capstone/include/capstone/evm.h +188 -0
- package/deps/capstone/include/capstone/m680x.h +537 -0
- package/deps/capstone/include/capstone/m68k.h +613 -0
- package/deps/capstone/include/capstone/mips.h +956 -0
- package/deps/capstone/include/capstone/mos65xx.h +204 -0
- package/deps/capstone/include/capstone/platform.h +122 -0
- package/deps/capstone/include/capstone/ppc.h +2108 -0
- package/deps/capstone/include/capstone/riscv.h +531 -0
- package/deps/capstone/include/capstone/sh.h +465 -0
- package/deps/capstone/include/capstone/sparc.h +520 -0
- package/deps/capstone/include/capstone/systemz.h +2601 -0
- package/deps/capstone/include/capstone/tms320c64x.h +359 -0
- package/deps/capstone/include/capstone/tricore.h +567 -0
- package/deps/capstone/include/capstone/wasm.h +250 -0
- package/deps/capstone/include/capstone/x86.h +1986 -0
- package/deps/capstone/include/capstone/xcore.h +235 -0
- package/deps/capstone/include/platform.h +110 -0
- package/deps/capstone/include/windowsce/intrin.h +12 -0
- package/deps/capstone/include/windowsce/stdint.h +133 -0
- package/deps/capstone/utils.c +140 -0
- package/deps/capstone/utils.h +54 -0
- package/index.d.ts +448 -0
- package/index.js +64 -0
- package/index.mjs +25 -0
- package/package.json +82 -0
- package/prebuilds/win32-x64/hexcore-capstone.node +0 -0
- package/src/capstone_wrapper.cpp +910 -0
- package/src/capstone_wrapper.h +147 -0
- package/src/disasm_async_worker.h +215 -0
- package/src/main.cpp +145 -0
|
@@ -0,0 +1,2307 @@
|
|
|
1
|
+
/* Capstone Disassembly Engine */
|
|
2
|
+
/* M680X Backend by Wolfgang Schwotzer <wolfgang.schwotzer@gmx.net> 2017 */
|
|
3
|
+
|
|
4
|
+
/* ======================================================================== */
|
|
5
|
+
/* ================================ INCLUDES ============================== */
|
|
6
|
+
/* ======================================================================== */
|
|
7
|
+
|
|
8
|
+
#include <stdlib.h>
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <string.h>
|
|
11
|
+
|
|
12
|
+
#include "../../cs_priv.h"
|
|
13
|
+
#include "../../utils.h"
|
|
14
|
+
|
|
15
|
+
#include "../../MCInst.h"
|
|
16
|
+
#include "../../MCInstrDesc.h"
|
|
17
|
+
#include "../../MCRegisterInfo.h"
|
|
18
|
+
#include "M680XInstPrinter.h"
|
|
19
|
+
#include "M680XDisassembler.h"
|
|
20
|
+
#include "M680XDisassemblerInternals.h"
|
|
21
|
+
|
|
22
|
+
#ifdef CAPSTONE_HAS_M680X
|
|
23
|
+
|
|
24
|
+
#ifndef DECL_SPEC
|
|
25
|
+
#ifdef _MSC_VER
|
|
26
|
+
#define DECL_SPEC __cdecl
|
|
27
|
+
#else
|
|
28
|
+
#define DECL_SPEC
|
|
29
|
+
#endif // _MSC_VER
|
|
30
|
+
#endif // DECL_SPEC
|
|
31
|
+
|
|
32
|
+
/* ======================================================================== */
|
|
33
|
+
/* ============================ GENERAL DEFINES =========================== */
|
|
34
|
+
/* ======================================================================== */
|
|
35
|
+
|
|
36
|
+
/* ======================================================================== */
|
|
37
|
+
/* =============================== PROTOTYPES ============================= */
|
|
38
|
+
/* ======================================================================== */
|
|
39
|
+
|
|
40
|
+
typedef enum insn_hdlr_id {
|
|
41
|
+
illgl_hid,
|
|
42
|
+
rel8_hid,
|
|
43
|
+
rel16_hid,
|
|
44
|
+
imm8_hid,
|
|
45
|
+
imm16_hid,
|
|
46
|
+
imm32_hid,
|
|
47
|
+
dir_hid,
|
|
48
|
+
ext_hid,
|
|
49
|
+
idxX_hid,
|
|
50
|
+
idxY_hid,
|
|
51
|
+
idx09_hid,
|
|
52
|
+
inh_hid,
|
|
53
|
+
rr09_hid,
|
|
54
|
+
rbits_hid,
|
|
55
|
+
bitmv_hid,
|
|
56
|
+
tfm_hid,
|
|
57
|
+
opidx_hid,
|
|
58
|
+
opidxdr_hid,
|
|
59
|
+
idxX0_hid,
|
|
60
|
+
idxX16_hid,
|
|
61
|
+
imm8rel_hid,
|
|
62
|
+
idxS_hid,
|
|
63
|
+
idxS16_hid,
|
|
64
|
+
idxXp_hid,
|
|
65
|
+
idxX0p_hid,
|
|
66
|
+
idx12_hid,
|
|
67
|
+
idx12s_hid,
|
|
68
|
+
rr12_hid,
|
|
69
|
+
loop_hid,
|
|
70
|
+
index_hid,
|
|
71
|
+
imm8i12x_hid,
|
|
72
|
+
imm16i12x_hid,
|
|
73
|
+
exti12x_hid,
|
|
74
|
+
HANDLER_ID_ENDING,
|
|
75
|
+
} insn_hdlr_id;
|
|
76
|
+
|
|
77
|
+
// Access modes for the first 4 operands. If there are more than
|
|
78
|
+
// four operands they use the same access mode as the 4th operand.
|
|
79
|
+
//
|
|
80
|
+
// u: unchanged
|
|
81
|
+
// r: (r)read access
|
|
82
|
+
// w: (w)write access
|
|
83
|
+
// m: (m)odify access (= read + write)
|
|
84
|
+
//
|
|
85
|
+
typedef enum e_access_mode {
|
|
86
|
+
|
|
87
|
+
uuuu,
|
|
88
|
+
rrrr,
|
|
89
|
+
wwww,
|
|
90
|
+
rwww,
|
|
91
|
+
rrrm,
|
|
92
|
+
rmmm,
|
|
93
|
+
wrrr,
|
|
94
|
+
mrrr,
|
|
95
|
+
mwww,
|
|
96
|
+
mmmm,
|
|
97
|
+
mwrr,
|
|
98
|
+
mmrr,
|
|
99
|
+
wmmm,
|
|
100
|
+
rruu,
|
|
101
|
+
muuu,
|
|
102
|
+
ACCESS_MODE_ENDING,
|
|
103
|
+
} e_access_mode;
|
|
104
|
+
|
|
105
|
+
// Access type values are compatible with enum cs_ac_type:
|
|
106
|
+
typedef enum e_access {
|
|
107
|
+
UNCHANGED = CS_AC_INVALID,
|
|
108
|
+
READ = CS_AC_READ,
|
|
109
|
+
WRITE = CS_AC_WRITE,
|
|
110
|
+
MODIFY = (CS_AC_READ | CS_AC_WRITE),
|
|
111
|
+
} e_access;
|
|
112
|
+
|
|
113
|
+
/* Properties of one instruction in PAGE1 (without prefix) */
|
|
114
|
+
typedef struct inst_page1 {
|
|
115
|
+
unsigned insn : 9; // A value of type m680x_insn
|
|
116
|
+
unsigned handler_id1 : 6; // Type insn_hdlr_id, first instr. handler id
|
|
117
|
+
unsigned handler_id2 : 6; // Type insn_hdlr_id, second instr. handler id
|
|
118
|
+
} inst_page1;
|
|
119
|
+
|
|
120
|
+
/* Properties of one instruction in any other PAGE X */
|
|
121
|
+
typedef struct inst_pageX {
|
|
122
|
+
unsigned opcode : 8; // The opcode byte
|
|
123
|
+
unsigned insn : 9; // A value of type m680x_insn
|
|
124
|
+
unsigned handler_id1 : 6; // Type insn_hdlr_id, first instr. handler id
|
|
125
|
+
unsigned handler_id2 : 6; // Type insn_hdlr_id, second instr. handler id
|
|
126
|
+
} inst_pageX;
|
|
127
|
+
|
|
128
|
+
typedef struct insn_props {
|
|
129
|
+
unsigned group : 4;
|
|
130
|
+
unsigned access_mode : 5; // A value of type e_access_mode
|
|
131
|
+
unsigned reg0 : 5; // A value of type m680x_reg
|
|
132
|
+
unsigned reg1 : 5; // A value of type m680x_reg
|
|
133
|
+
bool cc_modified : 1;
|
|
134
|
+
bool update_reg_access : 1;
|
|
135
|
+
} insn_props;
|
|
136
|
+
|
|
137
|
+
#include "m6800.inc"
|
|
138
|
+
#include "m6801.inc"
|
|
139
|
+
#include "hd6301.inc"
|
|
140
|
+
#include "m6811.inc"
|
|
141
|
+
#include "cpu12.inc"
|
|
142
|
+
#include "m6805.inc"
|
|
143
|
+
#include "m6808.inc"
|
|
144
|
+
#include "hcs08.inc"
|
|
145
|
+
#include "m6809.inc"
|
|
146
|
+
#include "hd6309.inc"
|
|
147
|
+
|
|
148
|
+
#include "insn_props.inc"
|
|
149
|
+
|
|
150
|
+
//////////////////////////////////////////////////////////////////////////////
|
|
151
|
+
|
|
152
|
+
// M680X instuctions have 1 up to 8 bytes (CPU12: MOVW IDX2,IDX2).
|
|
153
|
+
// A reader is needed to read a byte or word from a given memory address.
|
|
154
|
+
// See also X86 reader(...)
|
|
155
|
+
static bool read_byte(const m680x_info *info, uint8_t *byte, uint16_t address)
|
|
156
|
+
{
|
|
157
|
+
if (address < info->offset ||
|
|
158
|
+
(uint32_t)(address - info->offset) >= info->size)
|
|
159
|
+
// out of code buffer range
|
|
160
|
+
return false;
|
|
161
|
+
|
|
162
|
+
*byte = info->code[address - info->offset];
|
|
163
|
+
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static bool read_byte_sign_extended(const m680x_info *info, int16_t *word,
|
|
168
|
+
uint16_t address)
|
|
169
|
+
{
|
|
170
|
+
if (address < info->offset ||
|
|
171
|
+
(uint32_t)(address - info->offset) >= info->size)
|
|
172
|
+
// out of code buffer range
|
|
173
|
+
return false;
|
|
174
|
+
|
|
175
|
+
*word = (int16_t) info->code[address - info->offset];
|
|
176
|
+
|
|
177
|
+
if (*word & 0x80)
|
|
178
|
+
*word |= 0xFF00;
|
|
179
|
+
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static bool read_word(const m680x_info *info, uint16_t *word, uint16_t address)
|
|
184
|
+
{
|
|
185
|
+
if (address < info->offset ||
|
|
186
|
+
(uint32_t)(address + 1 - info->offset) >= info->size)
|
|
187
|
+
// out of code buffer range
|
|
188
|
+
return false;
|
|
189
|
+
|
|
190
|
+
*word = (uint16_t)info->code[address - info->offset] << 8;
|
|
191
|
+
*word |= (uint16_t)info->code[address + 1 - info->offset];
|
|
192
|
+
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
static bool read_sdword(const m680x_info *info, int32_t *sdword,
|
|
197
|
+
uint16_t address)
|
|
198
|
+
{
|
|
199
|
+
if (address < info->offset ||
|
|
200
|
+
(uint32_t)(address + 3 - info->offset) >= info->size)
|
|
201
|
+
// out of code buffer range
|
|
202
|
+
return false;
|
|
203
|
+
|
|
204
|
+
*sdword = (uint32_t)info->code[address - info->offset] << 24;
|
|
205
|
+
*sdword |= (uint32_t)info->code[address + 1 - info->offset] << 16;
|
|
206
|
+
*sdword |= (uint32_t)info->code[address + 2 - info->offset] << 8;
|
|
207
|
+
*sdword |= (uint32_t)info->code[address + 3 - info->offset];
|
|
208
|
+
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// For PAGE2 and PAGE3 opcodes when using an an array of inst_page1 most
|
|
213
|
+
// entries have M680X_INS_ILLGL. To avoid wasting memory an inst_pageX is
|
|
214
|
+
// used which contains the opcode. Using a binary search for the right opcode
|
|
215
|
+
// is much faster (= O(log n) ) in comparison to a linear search ( = O(n) ).
|
|
216
|
+
static int binary_search(const inst_pageX *const inst_pageX_table,
|
|
217
|
+
size_t table_size, unsigned int opcode)
|
|
218
|
+
{
|
|
219
|
+
// As part of the algorithm last may get negative.
|
|
220
|
+
// => signed integer has to be used.
|
|
221
|
+
int first = 0;
|
|
222
|
+
int last = (int)table_size - 1;
|
|
223
|
+
int middle = (first + last) / 2;
|
|
224
|
+
|
|
225
|
+
while (first <= last) {
|
|
226
|
+
if (inst_pageX_table[middle].opcode < opcode) {
|
|
227
|
+
first = middle + 1;
|
|
228
|
+
}
|
|
229
|
+
else if (inst_pageX_table[middle].opcode == opcode) {
|
|
230
|
+
return middle; /* item found */
|
|
231
|
+
}
|
|
232
|
+
else
|
|
233
|
+
last = middle - 1;
|
|
234
|
+
|
|
235
|
+
middle = (first + last) / 2;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
if (first > last)
|
|
239
|
+
return -1; /* item not found */
|
|
240
|
+
|
|
241
|
+
return -2;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
void M680X_get_insn_id(cs_struct *handle, cs_insn *insn, unsigned int id)
|
|
245
|
+
{
|
|
246
|
+
const m680x_info *const info = (const m680x_info *)handle->printer_info;
|
|
247
|
+
const cpu_tables *cpu = info->cpu;
|
|
248
|
+
uint8_t insn_prefix = (id >> 8) & 0xff;
|
|
249
|
+
// opcode is the first instruction byte without the prefix.
|
|
250
|
+
uint8_t opcode = id & 0xff;
|
|
251
|
+
int index;
|
|
252
|
+
int i;
|
|
253
|
+
|
|
254
|
+
insn->id = M680X_INS_ILLGL;
|
|
255
|
+
|
|
256
|
+
for (i = 0; i < ARR_SIZE(cpu->pageX_prefix); ++i) {
|
|
257
|
+
if (cpu->pageX_table_size[i] == 0 ||
|
|
258
|
+
(cpu->inst_pageX_table[i] == NULL))
|
|
259
|
+
break;
|
|
260
|
+
|
|
261
|
+
if (cpu->pageX_prefix[i] == insn_prefix) {
|
|
262
|
+
index = binary_search(cpu->inst_pageX_table[i],
|
|
263
|
+
cpu->pageX_table_size[i], opcode);
|
|
264
|
+
insn->id = (index >= 0) ?
|
|
265
|
+
cpu->inst_pageX_table[i][index].insn :
|
|
266
|
+
M680X_INS_ILLGL;
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (insn_prefix != 0)
|
|
272
|
+
return;
|
|
273
|
+
|
|
274
|
+
insn->id = cpu->inst_page1_table[id].insn;
|
|
275
|
+
|
|
276
|
+
if (insn->id != M680X_INS_ILLGL)
|
|
277
|
+
return;
|
|
278
|
+
|
|
279
|
+
// Check if opcode byte is present in an overlay table
|
|
280
|
+
for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
|
|
281
|
+
if (cpu->overlay_table_size[i] == 0 ||
|
|
282
|
+
(cpu->inst_overlay_table[i] == NULL))
|
|
283
|
+
break;
|
|
284
|
+
|
|
285
|
+
if ((index = binary_search(cpu->inst_overlay_table[i],
|
|
286
|
+
cpu->overlay_table_size[i],
|
|
287
|
+
opcode)) >= 0) {
|
|
288
|
+
insn->id = cpu->inst_overlay_table[i][index].insn;
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
static void add_insn_group(cs_detail *detail, m680x_group_type group)
|
|
295
|
+
{
|
|
296
|
+
if (detail != NULL &&
|
|
297
|
+
(group != M680X_GRP_INVALID) && (group != M680X_GRP_ENDING))
|
|
298
|
+
detail->groups[detail->groups_count++] = (uint8_t)group;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
static bool exists_reg_list(uint16_t *regs, uint8_t count, m680x_reg reg)
|
|
302
|
+
{
|
|
303
|
+
uint8_t i;
|
|
304
|
+
|
|
305
|
+
for (i = 0; i < count; ++i) {
|
|
306
|
+
if (regs[i] == (uint16_t)reg)
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
static void add_reg_to_rw_list(MCInst *MI, m680x_reg reg, e_access access)
|
|
314
|
+
{
|
|
315
|
+
cs_detail *detail = MI->flat_insn->detail;
|
|
316
|
+
|
|
317
|
+
if (detail == NULL || (reg == M680X_REG_INVALID))
|
|
318
|
+
return;
|
|
319
|
+
|
|
320
|
+
switch (access) {
|
|
321
|
+
case MODIFY:
|
|
322
|
+
if (!exists_reg_list(detail->regs_read,
|
|
323
|
+
detail->regs_read_count, reg))
|
|
324
|
+
detail->regs_read[detail->regs_read_count++] =
|
|
325
|
+
(uint16_t)reg;
|
|
326
|
+
|
|
327
|
+
// intentionally fall through
|
|
328
|
+
|
|
329
|
+
case WRITE:
|
|
330
|
+
if (!exists_reg_list(detail->regs_write,
|
|
331
|
+
detail->regs_write_count, reg))
|
|
332
|
+
detail->regs_write[detail->regs_write_count++] =
|
|
333
|
+
(uint16_t)reg;
|
|
334
|
+
|
|
335
|
+
break;
|
|
336
|
+
|
|
337
|
+
case READ:
|
|
338
|
+
if (!exists_reg_list(detail->regs_read,
|
|
339
|
+
detail->regs_read_count, reg))
|
|
340
|
+
detail->regs_read[detail->regs_read_count++] =
|
|
341
|
+
(uint16_t)reg;
|
|
342
|
+
|
|
343
|
+
break;
|
|
344
|
+
|
|
345
|
+
case UNCHANGED:
|
|
346
|
+
default:
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
static void update_am_reg_list(MCInst *MI, m680x_info *info, cs_m680x_op *op,
|
|
352
|
+
e_access access)
|
|
353
|
+
{
|
|
354
|
+
if (MI->flat_insn->detail == NULL)
|
|
355
|
+
return;
|
|
356
|
+
|
|
357
|
+
switch (op->type) {
|
|
358
|
+
case M680X_OP_REGISTER:
|
|
359
|
+
add_reg_to_rw_list(MI, op->reg, access);
|
|
360
|
+
break;
|
|
361
|
+
|
|
362
|
+
case M680X_OP_INDEXED:
|
|
363
|
+
add_reg_to_rw_list(MI, op->idx.base_reg, READ);
|
|
364
|
+
|
|
365
|
+
if (op->idx.base_reg == M680X_REG_X &&
|
|
366
|
+
info->cpu->reg_byte_size[M680X_REG_H])
|
|
367
|
+
add_reg_to_rw_list(MI, M680X_REG_H, READ);
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
if (op->idx.offset_reg != M680X_REG_INVALID)
|
|
371
|
+
add_reg_to_rw_list(MI, op->idx.offset_reg, READ);
|
|
372
|
+
|
|
373
|
+
if (op->idx.inc_dec) {
|
|
374
|
+
add_reg_to_rw_list(MI, op->idx.base_reg, WRITE);
|
|
375
|
+
|
|
376
|
+
if (op->idx.base_reg == M680X_REG_X &&
|
|
377
|
+
info->cpu->reg_byte_size[M680X_REG_H])
|
|
378
|
+
add_reg_to_rw_list(MI, M680X_REG_H, WRITE);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
break;
|
|
382
|
+
|
|
383
|
+
default:
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
static const e_access g_access_mode_to_access[4][15] = {
|
|
389
|
+
{
|
|
390
|
+
UNCHANGED, READ, WRITE, READ, READ, READ, WRITE, MODIFY,
|
|
391
|
+
MODIFY, MODIFY, MODIFY, MODIFY, WRITE, READ, MODIFY,
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
|
|
395
|
+
WRITE, MODIFY, WRITE, MODIFY, MODIFY, READ, UNCHANGED,
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
UNCHANGED, READ, WRITE, WRITE, READ, MODIFY, READ, READ,
|
|
399
|
+
WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
|
|
400
|
+
},
|
|
401
|
+
{
|
|
402
|
+
UNCHANGED, READ, WRITE, WRITE, MODIFY, MODIFY, READ, READ,
|
|
403
|
+
WRITE, MODIFY, READ, READ, MODIFY, UNCHANGED, UNCHANGED,
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
static e_access get_access(int operator_index, e_access_mode access_mode)
|
|
408
|
+
{
|
|
409
|
+
int idx = (operator_index > 3) ? 3 : operator_index;
|
|
410
|
+
|
|
411
|
+
return g_access_mode_to_access[idx][access_mode];
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
static void build_regs_read_write_counts(MCInst *MI, m680x_info *info,
|
|
415
|
+
e_access_mode access_mode)
|
|
416
|
+
{
|
|
417
|
+
cs_m680x *m680x = &info->m680x;
|
|
418
|
+
int i;
|
|
419
|
+
|
|
420
|
+
if (MI->flat_insn->detail == NULL || (!m680x->op_count))
|
|
421
|
+
return;
|
|
422
|
+
|
|
423
|
+
for (i = 0; i < m680x->op_count; ++i) {
|
|
424
|
+
|
|
425
|
+
e_access access = get_access(i, access_mode);
|
|
426
|
+
update_am_reg_list(MI, info, &m680x->operands[i], access);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
static void add_operators_access(MCInst *MI, m680x_info *info,
|
|
431
|
+
e_access_mode access_mode)
|
|
432
|
+
{
|
|
433
|
+
cs_m680x *m680x = &info->m680x;
|
|
434
|
+
int offset = 0;
|
|
435
|
+
int i;
|
|
436
|
+
|
|
437
|
+
if (MI->flat_insn->detail == NULL || (!m680x->op_count) ||
|
|
438
|
+
(access_mode == uuuu))
|
|
439
|
+
return;
|
|
440
|
+
|
|
441
|
+
for (i = 0; i < m680x->op_count; ++i) {
|
|
442
|
+
e_access access;
|
|
443
|
+
|
|
444
|
+
// Ugly fix: MULD has a register operand, an immediate operand
|
|
445
|
+
// AND an implicitly changed register W
|
|
446
|
+
if (info->insn == M680X_INS_MULD && (i == 1))
|
|
447
|
+
offset = 1;
|
|
448
|
+
|
|
449
|
+
access = get_access(i + offset, access_mode);
|
|
450
|
+
m680x->operands[i].access = access;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
typedef struct insn_to_changed_regs {
|
|
455
|
+
m680x_insn insn;
|
|
456
|
+
e_access_mode access_mode;
|
|
457
|
+
m680x_reg regs[10];
|
|
458
|
+
} insn_to_changed_regs;
|
|
459
|
+
|
|
460
|
+
static void set_changed_regs_read_write_counts(MCInst *MI, m680x_info *info)
|
|
461
|
+
{
|
|
462
|
+
//TABLE
|
|
463
|
+
#define EOL M680X_REG_INVALID
|
|
464
|
+
static const insn_to_changed_regs changed_regs[] = {
|
|
465
|
+
{ M680X_INS_BSR, mmmm, { M680X_REG_S, EOL } },
|
|
466
|
+
{ M680X_INS_CALL, mmmm, { M680X_REG_S, EOL } },
|
|
467
|
+
{
|
|
468
|
+
M680X_INS_CWAI, mrrr, {
|
|
469
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_U,
|
|
470
|
+
M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
|
|
471
|
+
M680X_REG_D, M680X_REG_CC, EOL
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
{ M680X_INS_DAA, mrrr, { M680X_REG_A, EOL } },
|
|
475
|
+
{
|
|
476
|
+
M680X_INS_DIV, mmrr, {
|
|
477
|
+
M680X_REG_A, M680X_REG_H, M680X_REG_X, EOL
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
M680X_INS_EDIV, mmrr, {
|
|
482
|
+
M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
M680X_INS_EDIVS, mmrr, {
|
|
487
|
+
M680X_REG_D, M680X_REG_Y, M680X_REG_X, EOL
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
{ M680X_INS_EMACS, mrrr, { M680X_REG_X, M680X_REG_Y, EOL } },
|
|
491
|
+
{ M680X_INS_EMAXM, rrrr, { M680X_REG_D, EOL } },
|
|
492
|
+
{ M680X_INS_EMINM, rrrr, { M680X_REG_D, EOL } },
|
|
493
|
+
{ M680X_INS_EMUL, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
|
|
494
|
+
{ M680X_INS_EMULS, mmrr, { M680X_REG_D, M680X_REG_Y, EOL } },
|
|
495
|
+
{ M680X_INS_ETBL, wmmm, { M680X_REG_A, M680X_REG_B, EOL } },
|
|
496
|
+
{ M680X_INS_FDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
|
|
497
|
+
{ M680X_INS_IDIV, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
|
|
498
|
+
{ M680X_INS_IDIVS, mmmm, { M680X_REG_D, M680X_REG_X, EOL } },
|
|
499
|
+
{ M680X_INS_JSR, mmmm, { M680X_REG_S, EOL } },
|
|
500
|
+
{ M680X_INS_LBSR, mmmm, { M680X_REG_S, EOL } },
|
|
501
|
+
{ M680X_INS_MAXM, rrrr, { M680X_REG_A, EOL } },
|
|
502
|
+
{ M680X_INS_MINM, rrrr, { M680X_REG_A, EOL } },
|
|
503
|
+
{
|
|
504
|
+
M680X_INS_MEM, mmrr, {
|
|
505
|
+
M680X_REG_X, M680X_REG_Y, M680X_REG_A, EOL
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
{ M680X_INS_MUL, mmmm, { M680X_REG_A, M680X_REG_B, EOL } },
|
|
509
|
+
{ M680X_INS_MULD, mwrr, { M680X_REG_D, M680X_REG_W, EOL } },
|
|
510
|
+
{ M680X_INS_PSHA, rmmm, { M680X_REG_A, M680X_REG_S, EOL } },
|
|
511
|
+
{ M680X_INS_PSHB, rmmm, { M680X_REG_B, M680X_REG_S, EOL } },
|
|
512
|
+
{ M680X_INS_PSHC, rmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
|
|
513
|
+
{ M680X_INS_PSHD, rmmm, { M680X_REG_D, M680X_REG_S, EOL } },
|
|
514
|
+
{ M680X_INS_PSHH, rmmm, { M680X_REG_H, M680X_REG_S, EOL } },
|
|
515
|
+
{ M680X_INS_PSHX, rmmm, { M680X_REG_X, M680X_REG_S, EOL } },
|
|
516
|
+
{ M680X_INS_PSHY, rmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
|
|
517
|
+
{ M680X_INS_PULA, wmmm, { M680X_REG_A, M680X_REG_S, EOL } },
|
|
518
|
+
{ M680X_INS_PULB, wmmm, { M680X_REG_B, M680X_REG_S, EOL } },
|
|
519
|
+
{ M680X_INS_PULC, wmmm, { M680X_REG_CC, M680X_REG_S, EOL } },
|
|
520
|
+
{ M680X_INS_PULD, wmmm, { M680X_REG_D, M680X_REG_S, EOL } },
|
|
521
|
+
{ M680X_INS_PULH, wmmm, { M680X_REG_H, M680X_REG_S, EOL } },
|
|
522
|
+
{ M680X_INS_PULX, wmmm, { M680X_REG_X, M680X_REG_S, EOL } },
|
|
523
|
+
{ M680X_INS_PULY, wmmm, { M680X_REG_Y, M680X_REG_S, EOL } },
|
|
524
|
+
{
|
|
525
|
+
M680X_INS_REV, mmrr, {
|
|
526
|
+
M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
M680X_INS_REVW, mmmm, {
|
|
531
|
+
M680X_REG_A, M680X_REG_X, M680X_REG_Y, EOL
|
|
532
|
+
}
|
|
533
|
+
},
|
|
534
|
+
{ M680X_INS_RTC, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
|
|
535
|
+
{
|
|
536
|
+
M680X_INS_RTI, mwww, {
|
|
537
|
+
M680X_REG_S, M680X_REG_CC, M680X_REG_B,
|
|
538
|
+
M680X_REG_A, M680X_REG_DP, M680X_REG_X,
|
|
539
|
+
M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
|
|
540
|
+
EOL
|
|
541
|
+
},
|
|
542
|
+
},
|
|
543
|
+
{ M680X_INS_RTS, mwww, { M680X_REG_S, M680X_REG_PC, EOL } },
|
|
544
|
+
{ M680X_INS_SEX, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
|
|
545
|
+
{ M680X_INS_SEXW, rwww, { M680X_REG_W, M680X_REG_D, EOL } },
|
|
546
|
+
{
|
|
547
|
+
M680X_INS_SWI, mmrr, {
|
|
548
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_U,
|
|
549
|
+
M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
|
|
550
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC,
|
|
551
|
+
EOL
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
M680X_INS_SWI2, mmrr, {
|
|
556
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_U,
|
|
557
|
+
M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
|
|
558
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC,
|
|
559
|
+
EOL
|
|
560
|
+
},
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
M680X_INS_SWI3, mmrr, {
|
|
564
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_U,
|
|
565
|
+
M680X_REG_Y, M680X_REG_X, M680X_REG_DP,
|
|
566
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC,
|
|
567
|
+
EOL
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
{ M680X_INS_TBL, wrrr, { M680X_REG_A, M680X_REG_B, EOL } },
|
|
571
|
+
{
|
|
572
|
+
M680X_INS_WAI, mrrr, {
|
|
573
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_X,
|
|
574
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC,
|
|
575
|
+
EOL
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
M680X_INS_WAV, rmmm, {
|
|
580
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_X,
|
|
581
|
+
M680X_REG_Y, EOL
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
M680X_INS_WAVR, rmmm, {
|
|
586
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_X,
|
|
587
|
+
M680X_REG_Y, EOL
|
|
588
|
+
}
|
|
589
|
+
},
|
|
590
|
+
};
|
|
591
|
+
|
|
592
|
+
int i, j;
|
|
593
|
+
|
|
594
|
+
if (MI->flat_insn->detail == NULL)
|
|
595
|
+
return;
|
|
596
|
+
|
|
597
|
+
for (i = 0; i < ARR_SIZE(changed_regs); ++i) {
|
|
598
|
+
if (info->insn == changed_regs[i].insn) {
|
|
599
|
+
e_access_mode access_mode = changed_regs[i].access_mode;
|
|
600
|
+
|
|
601
|
+
for (j = 0; changed_regs[i].regs[j] != EOL; ++j) {
|
|
602
|
+
e_access access;
|
|
603
|
+
|
|
604
|
+
m680x_reg reg = changed_regs[i].regs[j];
|
|
605
|
+
|
|
606
|
+
if (!info->cpu->reg_byte_size[reg]) {
|
|
607
|
+
if (info->insn != M680X_INS_MUL)
|
|
608
|
+
continue;
|
|
609
|
+
|
|
610
|
+
// Hack for M68HC05: MUL uses reg. A,X
|
|
611
|
+
reg = M680X_REG_X;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
access = get_access(j, access_mode);
|
|
615
|
+
add_reg_to_rw_list(MI, reg, access);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
#undef EOL
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
typedef struct insn_desc {
|
|
624
|
+
uint32_t opcode;
|
|
625
|
+
m680x_insn insn;
|
|
626
|
+
insn_hdlr_id hid[2];
|
|
627
|
+
uint16_t insn_size;
|
|
628
|
+
} insn_desc;
|
|
629
|
+
|
|
630
|
+
// If successfull return the additional byte size needed for M6809
|
|
631
|
+
// indexed addressing mode (including the indexed addressing post_byte).
|
|
632
|
+
// On error return -1.
|
|
633
|
+
static int get_indexed09_post_byte_size(const m680x_info *info,
|
|
634
|
+
uint16_t address)
|
|
635
|
+
{
|
|
636
|
+
uint8_t ir = 0;
|
|
637
|
+
uint8_t post_byte;
|
|
638
|
+
|
|
639
|
+
// Read the indexed addressing post byte.
|
|
640
|
+
if (!read_byte(info, &post_byte, address))
|
|
641
|
+
return -1;
|
|
642
|
+
|
|
643
|
+
// Depending on the indexed addressing mode more bytes have to be read.
|
|
644
|
+
switch (post_byte & 0x9F) {
|
|
645
|
+
case 0x87:
|
|
646
|
+
case 0x8A:
|
|
647
|
+
case 0x8E:
|
|
648
|
+
case 0x8F:
|
|
649
|
+
case 0x90:
|
|
650
|
+
case 0x92:
|
|
651
|
+
case 0x97:
|
|
652
|
+
case 0x9A:
|
|
653
|
+
case 0x9E:
|
|
654
|
+
return -1; // illegal indexed post bytes
|
|
655
|
+
|
|
656
|
+
case 0x88: // n8,R
|
|
657
|
+
case 0x8C: // n8,PCR
|
|
658
|
+
case 0x98: // [n8,R]
|
|
659
|
+
case 0x9C: // [n8,PCR]
|
|
660
|
+
if (!read_byte(info, &ir, address + 1))
|
|
661
|
+
return -1;
|
|
662
|
+
return 2;
|
|
663
|
+
|
|
664
|
+
case 0x89: // n16,R
|
|
665
|
+
case 0x8D: // n16,PCR
|
|
666
|
+
case 0x99: // [n16,R]
|
|
667
|
+
case 0x9D: // [n16,PCR]
|
|
668
|
+
if (!read_byte(info, &ir, address + 2))
|
|
669
|
+
return -1;
|
|
670
|
+
return 3;
|
|
671
|
+
|
|
672
|
+
case 0x9F: // [n]
|
|
673
|
+
if ((post_byte & 0x60) != 0 ||
|
|
674
|
+
!read_byte(info, &ir, address + 2))
|
|
675
|
+
return -1;
|
|
676
|
+
return 3;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
// Any other indexed post byte is valid and
|
|
680
|
+
// no additional bytes have to be read.
|
|
681
|
+
return 1;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// If successfull return the additional byte size needed for CPU12
|
|
685
|
+
// indexed addressing mode (including the indexed addressing post_byte).
|
|
686
|
+
// On error return -1.
|
|
687
|
+
static int get_indexed12_post_byte_size(const m680x_info *info,
|
|
688
|
+
uint16_t address, bool is_subset)
|
|
689
|
+
{
|
|
690
|
+
uint8_t ir;
|
|
691
|
+
uint8_t post_byte;
|
|
692
|
+
|
|
693
|
+
// Read the indexed addressing post byte.
|
|
694
|
+
if (!read_byte(info, &post_byte, address))
|
|
695
|
+
return -1;
|
|
696
|
+
|
|
697
|
+
// Depending on the indexed addressing mode more bytes have to be read.
|
|
698
|
+
if (!(post_byte & 0x20)) // n5,R
|
|
699
|
+
return 1;
|
|
700
|
+
|
|
701
|
+
switch (post_byte & 0xe7) {
|
|
702
|
+
case 0xe0:
|
|
703
|
+
case 0xe1: // n9,R
|
|
704
|
+
if (is_subset)
|
|
705
|
+
return -1;
|
|
706
|
+
|
|
707
|
+
if (!read_byte(info, &ir, address))
|
|
708
|
+
return -1;
|
|
709
|
+
return 2;
|
|
710
|
+
|
|
711
|
+
case 0xe2: // n16,R
|
|
712
|
+
case 0xe3: // [n16,R]
|
|
713
|
+
if (is_subset)
|
|
714
|
+
return -1;
|
|
715
|
+
|
|
716
|
+
if (!read_byte(info, &ir, address + 1))
|
|
717
|
+
return -1;
|
|
718
|
+
return 3;
|
|
719
|
+
|
|
720
|
+
case 0xe4: // A,R
|
|
721
|
+
case 0xe5: // B,R
|
|
722
|
+
case 0xe6: // D,R
|
|
723
|
+
case 0xe7: // [D,R]
|
|
724
|
+
default: // n,-r n,+r n,r- n,r+
|
|
725
|
+
break;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
return 1;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// Check for M6809/HD6309 TFR/EXG instruction for valid register
|
|
732
|
+
static bool is_tfr09_reg_valid(const m680x_info *info, uint8_t reg_nibble)
|
|
733
|
+
{
|
|
734
|
+
if (info->cpu->tfr_reg_valid != NULL)
|
|
735
|
+
return info->cpu->tfr_reg_valid[reg_nibble];
|
|
736
|
+
|
|
737
|
+
return true; // e.g. for the M6309 all registers are valid
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// Check for CPU12 TFR/EXG instruction for valid register
|
|
741
|
+
static bool is_exg_tfr12_post_byte_valid(const m680x_info *info,
|
|
742
|
+
uint8_t post_byte)
|
|
743
|
+
{
|
|
744
|
+
return !(post_byte & 0x08);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
static bool is_tfm_reg_valid(const m680x_info *info, uint8_t reg_nibble)
|
|
748
|
+
{
|
|
749
|
+
// HD6809 TFM instruction: Only register X,Y,U,S,D is allowed
|
|
750
|
+
return reg_nibble <= 4;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// If successfull return the additional byte size needed for CPU12
|
|
754
|
+
// loop instructions DBEQ/DBNE/IBEQ/IBNE/TBEQ/TBNE (including the post byte).
|
|
755
|
+
// On error return -1.
|
|
756
|
+
static int get_loop_post_byte_size(const m680x_info *info, uint16_t address)
|
|
757
|
+
{
|
|
758
|
+
uint8_t post_byte;
|
|
759
|
+
uint8_t rr;
|
|
760
|
+
|
|
761
|
+
if (!read_byte(info, &post_byte, address))
|
|
762
|
+
return -1;
|
|
763
|
+
|
|
764
|
+
// According to documentation bit 3 is don't care and not checked here.
|
|
765
|
+
if ((post_byte >= 0xc0) ||
|
|
766
|
+
((post_byte & 0x07) == 2) || ((post_byte & 0x07) == 3))
|
|
767
|
+
return -1;
|
|
768
|
+
|
|
769
|
+
if (!read_byte(info, &rr, address + 1))
|
|
770
|
+
return -1;
|
|
771
|
+
|
|
772
|
+
return 2;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
// If successfull return the additional byte size needed for HD6309
|
|
776
|
+
// bit move instructions BAND/BEOR/BIAND/BIEOR/BIOR/BOR/LDBT/STBT
|
|
777
|
+
// (including the post byte).
|
|
778
|
+
// On error return -1.
|
|
779
|
+
static int get_bitmv_post_byte_size(const m680x_info *info, uint16_t address)
|
|
780
|
+
{
|
|
781
|
+
uint8_t post_byte;
|
|
782
|
+
uint8_t rr;
|
|
783
|
+
|
|
784
|
+
if (!read_byte(info, &post_byte, address))
|
|
785
|
+
return -1;
|
|
786
|
+
|
|
787
|
+
if ((post_byte & 0xc0) == 0xc0)
|
|
788
|
+
return -1; // Invalid register specified
|
|
789
|
+
else {
|
|
790
|
+
if (!read_byte(info, &rr, address + 1))
|
|
791
|
+
return -1;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
return 2;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
|
|
798
|
+
insn_desc *insn_description)
|
|
799
|
+
{
|
|
800
|
+
int i;
|
|
801
|
+
bool retval = true;
|
|
802
|
+
uint16_t size = 0;
|
|
803
|
+
int sz;
|
|
804
|
+
|
|
805
|
+
for (i = 0; i < 2; i++) {
|
|
806
|
+
uint8_t ir = 0;
|
|
807
|
+
bool is_subset = false;
|
|
808
|
+
|
|
809
|
+
switch (insn_description->hid[i]) {
|
|
810
|
+
|
|
811
|
+
case imm32_hid:
|
|
812
|
+
if ((retval = read_byte(info, &ir, address + size + 3)))
|
|
813
|
+
size += 4;
|
|
814
|
+
break;
|
|
815
|
+
|
|
816
|
+
case ext_hid:
|
|
817
|
+
case imm16_hid:
|
|
818
|
+
case rel16_hid:
|
|
819
|
+
case imm8rel_hid:
|
|
820
|
+
case opidxdr_hid:
|
|
821
|
+
case idxX16_hid:
|
|
822
|
+
case idxS16_hid:
|
|
823
|
+
if ((retval = read_byte(info, &ir, address + size + 1)))
|
|
824
|
+
size += 2;
|
|
825
|
+
break;
|
|
826
|
+
|
|
827
|
+
case rel8_hid:
|
|
828
|
+
case dir_hid:
|
|
829
|
+
case rbits_hid:
|
|
830
|
+
case imm8_hid:
|
|
831
|
+
case idxX_hid:
|
|
832
|
+
case idxXp_hid:
|
|
833
|
+
case idxY_hid:
|
|
834
|
+
case idxS_hid:
|
|
835
|
+
case index_hid:
|
|
836
|
+
if ((retval = read_byte(info, &ir, address + size)))
|
|
837
|
+
size++;
|
|
838
|
+
break;
|
|
839
|
+
|
|
840
|
+
case illgl_hid:
|
|
841
|
+
case inh_hid:
|
|
842
|
+
case idxX0_hid:
|
|
843
|
+
case idxX0p_hid:
|
|
844
|
+
case opidx_hid:
|
|
845
|
+
retval = true;
|
|
846
|
+
break;
|
|
847
|
+
|
|
848
|
+
case idx09_hid:
|
|
849
|
+
sz = get_indexed09_post_byte_size(info, address + size);
|
|
850
|
+
if (sz >= 0)
|
|
851
|
+
size += sz;
|
|
852
|
+
else
|
|
853
|
+
retval = false;
|
|
854
|
+
break;
|
|
855
|
+
|
|
856
|
+
case idx12s_hid:
|
|
857
|
+
is_subset = true;
|
|
858
|
+
|
|
859
|
+
// intentionally fall through
|
|
860
|
+
|
|
861
|
+
case idx12_hid:
|
|
862
|
+
sz = get_indexed12_post_byte_size(info,
|
|
863
|
+
address + size, is_subset);
|
|
864
|
+
if (sz >= 0)
|
|
865
|
+
size += sz;
|
|
866
|
+
else
|
|
867
|
+
retval = false;
|
|
868
|
+
break;
|
|
869
|
+
|
|
870
|
+
case exti12x_hid:
|
|
871
|
+
case imm16i12x_hid:
|
|
872
|
+
sz = get_indexed12_post_byte_size(info,
|
|
873
|
+
address + size, false);
|
|
874
|
+
if (sz >= 0) {
|
|
875
|
+
size += sz;
|
|
876
|
+
if ((retval = read_byte(info, &ir,
|
|
877
|
+
address + size + 1)))
|
|
878
|
+
size += 2;
|
|
879
|
+
} else
|
|
880
|
+
retval = false;
|
|
881
|
+
break;
|
|
882
|
+
|
|
883
|
+
case imm8i12x_hid:
|
|
884
|
+
sz = get_indexed12_post_byte_size(info,
|
|
885
|
+
address + size, false);
|
|
886
|
+
if (sz >= 0) {
|
|
887
|
+
size += sz;
|
|
888
|
+
if ((retval = read_byte(info, &ir,
|
|
889
|
+
address + size)))
|
|
890
|
+
size++;
|
|
891
|
+
} else
|
|
892
|
+
retval = false;
|
|
893
|
+
break;
|
|
894
|
+
|
|
895
|
+
case tfm_hid:
|
|
896
|
+
if ((retval = read_byte(info, &ir, address + size))) {
|
|
897
|
+
size++;
|
|
898
|
+
retval = is_tfm_reg_valid(info, (ir >> 4) & 0x0F) &&
|
|
899
|
+
is_tfm_reg_valid(info, ir & 0x0F);
|
|
900
|
+
}
|
|
901
|
+
break;
|
|
902
|
+
|
|
903
|
+
case rr09_hid:
|
|
904
|
+
if ((retval = read_byte(info, &ir, address + size))) {
|
|
905
|
+
size++;
|
|
906
|
+
retval = is_tfr09_reg_valid(info, (ir >> 4) & 0x0F) &&
|
|
907
|
+
is_tfr09_reg_valid(info, ir & 0x0F);
|
|
908
|
+
}
|
|
909
|
+
break;
|
|
910
|
+
|
|
911
|
+
case rr12_hid:
|
|
912
|
+
if ((retval = read_byte(info, &ir, address + size))) {
|
|
913
|
+
size++;
|
|
914
|
+
retval = is_exg_tfr12_post_byte_valid(info, ir);
|
|
915
|
+
}
|
|
916
|
+
break;
|
|
917
|
+
|
|
918
|
+
case bitmv_hid:
|
|
919
|
+
sz = get_bitmv_post_byte_size(info, address + size);
|
|
920
|
+
if (sz >= 0)
|
|
921
|
+
size += sz;
|
|
922
|
+
else
|
|
923
|
+
retval = false;
|
|
924
|
+
break;
|
|
925
|
+
|
|
926
|
+
case loop_hid:
|
|
927
|
+
sz = get_loop_post_byte_size(info, address + size);
|
|
928
|
+
if (sz >= 0)
|
|
929
|
+
size += sz;
|
|
930
|
+
else
|
|
931
|
+
retval = false;
|
|
932
|
+
break;
|
|
933
|
+
|
|
934
|
+
default:
|
|
935
|
+
CS_ASSERT(0 && "Unexpected instruction handler id");
|
|
936
|
+
retval = false;
|
|
937
|
+
break;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
if (!retval)
|
|
941
|
+
return false;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
insn_description->insn_size += size;
|
|
945
|
+
|
|
946
|
+
return retval;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// Check for a valid M680X instruction AND for enough bytes in the code buffer
|
|
950
|
+
// Return an instruction description in insn_desc.
|
|
951
|
+
static bool decode_insn(const m680x_info *info, uint16_t address,
|
|
952
|
+
insn_desc *insn_description)
|
|
953
|
+
{
|
|
954
|
+
const inst_pageX *inst_table = NULL;
|
|
955
|
+
const cpu_tables *cpu = info->cpu;
|
|
956
|
+
size_t table_size = 0;
|
|
957
|
+
uint16_t base_address = address;
|
|
958
|
+
uint8_t ir; // instruction register
|
|
959
|
+
int i;
|
|
960
|
+
int index;
|
|
961
|
+
|
|
962
|
+
if (!read_byte(info, &ir, address++))
|
|
963
|
+
return false;
|
|
964
|
+
|
|
965
|
+
insn_description->insn = M680X_INS_ILLGL;
|
|
966
|
+
insn_description->opcode = ir;
|
|
967
|
+
|
|
968
|
+
// Check if a page prefix byte is present
|
|
969
|
+
for (i = 0; i < ARR_SIZE(cpu->pageX_table_size); ++i) {
|
|
970
|
+
if (cpu->pageX_table_size[i] == 0 ||
|
|
971
|
+
(cpu->inst_pageX_table[i] == NULL))
|
|
972
|
+
break;
|
|
973
|
+
|
|
974
|
+
if ((cpu->pageX_prefix[i] == ir)) {
|
|
975
|
+
// Get pageX instruction and handler id.
|
|
976
|
+
// Abort for illegal instr.
|
|
977
|
+
inst_table = cpu->inst_pageX_table[i];
|
|
978
|
+
table_size = cpu->pageX_table_size[i];
|
|
979
|
+
|
|
980
|
+
if (!read_byte(info, &ir, address++))
|
|
981
|
+
return false;
|
|
982
|
+
|
|
983
|
+
insn_description->opcode =
|
|
984
|
+
(insn_description->opcode << 8) | ir;
|
|
985
|
+
|
|
986
|
+
if ((index = binary_search(inst_table, table_size,
|
|
987
|
+
ir)) < 0)
|
|
988
|
+
return false;
|
|
989
|
+
|
|
990
|
+
insn_description->hid[0] =
|
|
991
|
+
inst_table[index].handler_id1;
|
|
992
|
+
insn_description->hid[1] =
|
|
993
|
+
inst_table[index].handler_id2;
|
|
994
|
+
insn_description->insn = inst_table[index].insn;
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
if (insn_description->insn == M680X_INS_ILLGL) {
|
|
1000
|
+
// Get page1 insn description
|
|
1001
|
+
insn_description->insn = cpu->inst_page1_table[ir].insn;
|
|
1002
|
+
insn_description->hid[0] =
|
|
1003
|
+
cpu->inst_page1_table[ir].handler_id1;
|
|
1004
|
+
insn_description->hid[1] =
|
|
1005
|
+
cpu->inst_page1_table[ir].handler_id2;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
if (insn_description->insn == M680X_INS_ILLGL) {
|
|
1009
|
+
// Check if opcode byte is present in an overlay table
|
|
1010
|
+
for (i = 0; i < ARR_SIZE(cpu->overlay_table_size); ++i) {
|
|
1011
|
+
if (cpu->overlay_table_size[i] == 0 ||
|
|
1012
|
+
(cpu->inst_overlay_table[i] == NULL))
|
|
1013
|
+
break;
|
|
1014
|
+
|
|
1015
|
+
inst_table = cpu->inst_overlay_table[i];
|
|
1016
|
+
table_size = cpu->overlay_table_size[i];
|
|
1017
|
+
|
|
1018
|
+
if ((index = binary_search(inst_table, table_size,
|
|
1019
|
+
ir)) >= 0) {
|
|
1020
|
+
insn_description->hid[0] =
|
|
1021
|
+
inst_table[index].handler_id1;
|
|
1022
|
+
insn_description->hid[1] =
|
|
1023
|
+
inst_table[index].handler_id2;
|
|
1024
|
+
insn_description->insn = inst_table[index].insn;
|
|
1025
|
+
break;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
insn_description->insn_size = address - base_address;
|
|
1031
|
+
|
|
1032
|
+
return (insn_description->insn != M680X_INS_ILLGL) &&
|
|
1033
|
+
(insn_description->insn != M680X_INS_INVLD) &&
|
|
1034
|
+
is_sufficient_code_size(info, address, insn_description);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
static void illegal_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1038
|
+
{
|
|
1039
|
+
cs_m680x_op *op0 = &info->m680x.operands[info->m680x.op_count++];
|
|
1040
|
+
uint8_t temp8 = 0;
|
|
1041
|
+
|
|
1042
|
+
info->insn = M680X_INS_ILLGL;
|
|
1043
|
+
read_byte(info, &temp8, (*address)++);
|
|
1044
|
+
op0->imm = (int32_t)temp8 & 0xff;
|
|
1045
|
+
op0->type = M680X_OP_IMMEDIATE;
|
|
1046
|
+
op0->size = 1;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
static void inherent_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1050
|
+
{
|
|
1051
|
+
// There is nothing to do here :-)
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
static void add_reg_operand(m680x_info *info, m680x_reg reg)
|
|
1055
|
+
{
|
|
1056
|
+
cs_m680x *m680x = &info->m680x;
|
|
1057
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1058
|
+
|
|
1059
|
+
op->type = M680X_OP_REGISTER;
|
|
1060
|
+
op->reg = reg;
|
|
1061
|
+
op->size = info->cpu->reg_byte_size[reg];
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
static void set_operand_size(m680x_info *info, cs_m680x_op *op,
|
|
1065
|
+
uint8_t default_size)
|
|
1066
|
+
{
|
|
1067
|
+
cs_m680x *m680x = &info->m680x;
|
|
1068
|
+
|
|
1069
|
+
if (info->insn == M680X_INS_JMP || info->insn == M680X_INS_JSR)
|
|
1070
|
+
op->size = 0;
|
|
1071
|
+
else if (info->insn == M680X_INS_DIVD ||
|
|
1072
|
+
((info->insn == M680X_INS_AIS || info->insn == M680X_INS_AIX) &&
|
|
1073
|
+
op->type != M680X_OP_REGISTER))
|
|
1074
|
+
op->size = 1;
|
|
1075
|
+
else if (info->insn == M680X_INS_DIVQ ||
|
|
1076
|
+
info->insn == M680X_INS_MOVW)
|
|
1077
|
+
op->size = 2;
|
|
1078
|
+
else if (info->insn == M680X_INS_EMACS)
|
|
1079
|
+
op->size = 4;
|
|
1080
|
+
else if ((m680x->op_count > 0) &&
|
|
1081
|
+
(m680x->operands[0].type == M680X_OP_REGISTER))
|
|
1082
|
+
op->size = m680x->operands[0].size;
|
|
1083
|
+
else
|
|
1084
|
+
op->size = default_size;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
static const m680x_reg reg_s_reg_ids[] = {
|
|
1088
|
+
M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
|
|
1089
|
+
M680X_REG_X, M680X_REG_Y, M680X_REG_U, M680X_REG_PC,
|
|
1090
|
+
};
|
|
1091
|
+
|
|
1092
|
+
static const m680x_reg reg_u_reg_ids[] = {
|
|
1093
|
+
M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_DP,
|
|
1094
|
+
M680X_REG_X, M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
|
|
1095
|
+
};
|
|
1096
|
+
|
|
1097
|
+
static void reg_bits_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1098
|
+
{
|
|
1099
|
+
cs_m680x_op *op0 = &info->m680x.operands[0];
|
|
1100
|
+
uint8_t reg_bits = 0;
|
|
1101
|
+
uint16_t bit_index;
|
|
1102
|
+
const m680x_reg *reg_to_reg_ids = NULL;
|
|
1103
|
+
|
|
1104
|
+
read_byte(info, ®_bits, (*address)++);
|
|
1105
|
+
|
|
1106
|
+
switch (op0->reg) {
|
|
1107
|
+
case M680X_REG_U:
|
|
1108
|
+
reg_to_reg_ids = ®_u_reg_ids[0];
|
|
1109
|
+
break;
|
|
1110
|
+
|
|
1111
|
+
case M680X_REG_S:
|
|
1112
|
+
reg_to_reg_ids = ®_s_reg_ids[0];
|
|
1113
|
+
break;
|
|
1114
|
+
|
|
1115
|
+
default:
|
|
1116
|
+
CS_ASSERT(0 && "Unexpected operand0 register");
|
|
1117
|
+
break;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
if ((info->insn == M680X_INS_PULU ||
|
|
1121
|
+
(info->insn == M680X_INS_PULS)) &&
|
|
1122
|
+
((reg_bits & 0x80) != 0))
|
|
1123
|
+
// PULS xxx,PC or PULU xxx,PC which is like return from
|
|
1124
|
+
// subroutine (RTS)
|
|
1125
|
+
add_insn_group(MI->flat_insn->detail, M680X_GRP_RET);
|
|
1126
|
+
|
|
1127
|
+
for (bit_index = 0; bit_index < 8; ++bit_index) {
|
|
1128
|
+
if (reg_bits & (1 << bit_index))
|
|
1129
|
+
add_reg_operand(info, reg_to_reg_ids[bit_index]);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
static const m680x_reg g_tfr_exg_reg_ids[] = {
|
|
1134
|
+
/* 16-bit registers */
|
|
1135
|
+
M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_U,
|
|
1136
|
+
M680X_REG_S, M680X_REG_PC, M680X_REG_W, M680X_REG_V,
|
|
1137
|
+
/* 8-bit registers */
|
|
1138
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_DP,
|
|
1139
|
+
M680X_REG_0, M680X_REG_0, M680X_REG_E, M680X_REG_F,
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
static void reg_reg09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1143
|
+
{
|
|
1144
|
+
uint8_t regs = 0;
|
|
1145
|
+
|
|
1146
|
+
read_byte(info, ®s, (*address)++);
|
|
1147
|
+
|
|
1148
|
+
add_reg_operand(info, g_tfr_exg_reg_ids[regs >> 4]);
|
|
1149
|
+
add_reg_operand(info, g_tfr_exg_reg_ids[regs & 0x0f]);
|
|
1150
|
+
|
|
1151
|
+
if ((regs & 0x0f) == 0x05) {
|
|
1152
|
+
// EXG xxx,PC or TFR xxx,PC which is like a JMP
|
|
1153
|
+
add_insn_group(MI->flat_insn->detail, M680X_GRP_JUMP);
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
|
|
1158
|
+
static void reg_reg12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1159
|
+
{
|
|
1160
|
+
static const m680x_reg g_tfr_exg12_reg0_ids[] = {
|
|
1161
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_TMP3,
|
|
1162
|
+
M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
|
|
1163
|
+
};
|
|
1164
|
+
static const m680x_reg g_tfr_exg12_reg1_ids[] = {
|
|
1165
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_CC, M680X_REG_TMP2,
|
|
1166
|
+
M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
|
|
1167
|
+
};
|
|
1168
|
+
uint8_t regs = 0;
|
|
1169
|
+
|
|
1170
|
+
read_byte(info, ®s, (*address)++);
|
|
1171
|
+
|
|
1172
|
+
// The opcode of this instruction depends on
|
|
1173
|
+
// the msb of its post byte.
|
|
1174
|
+
if (regs & 0x80)
|
|
1175
|
+
info->insn = M680X_INS_EXG;
|
|
1176
|
+
else
|
|
1177
|
+
info->insn = M680X_INS_TFR;
|
|
1178
|
+
|
|
1179
|
+
add_reg_operand(info, g_tfr_exg12_reg0_ids[(regs >> 4) & 0x07]);
|
|
1180
|
+
add_reg_operand(info, g_tfr_exg12_reg1_ids[regs & 0x07]);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
static void add_rel_operand(m680x_info *info, int16_t offset, uint16_t address)
|
|
1184
|
+
{
|
|
1185
|
+
cs_m680x *m680x = &info->m680x;
|
|
1186
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1187
|
+
|
|
1188
|
+
op->type = M680X_OP_RELATIVE;
|
|
1189
|
+
op->size = 0;
|
|
1190
|
+
op->rel.offset = offset;
|
|
1191
|
+
op->rel.address = address;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
static void relative8_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1195
|
+
{
|
|
1196
|
+
int16_t offset = 0;
|
|
1197
|
+
|
|
1198
|
+
read_byte_sign_extended(info, &offset, (*address)++);
|
|
1199
|
+
add_rel_operand(info, offset, *address + offset);
|
|
1200
|
+
add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
|
|
1201
|
+
|
|
1202
|
+
if ((info->insn != M680X_INS_BRA) &&
|
|
1203
|
+
(info->insn != M680X_INS_BSR) &&
|
|
1204
|
+
(info->insn != M680X_INS_BRN))
|
|
1205
|
+
add_reg_to_rw_list(MI, M680X_REG_CC, READ);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
static void relative16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1209
|
+
{
|
|
1210
|
+
uint16_t offset = 0;
|
|
1211
|
+
|
|
1212
|
+
read_word(info, &offset, *address);
|
|
1213
|
+
*address += 2;
|
|
1214
|
+
add_rel_operand(info, (int16_t)offset, *address + offset);
|
|
1215
|
+
add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
|
|
1216
|
+
|
|
1217
|
+
if ((info->insn != M680X_INS_LBRA) &&
|
|
1218
|
+
(info->insn != M680X_INS_LBSR) &&
|
|
1219
|
+
(info->insn != M680X_INS_LBRN))
|
|
1220
|
+
add_reg_to_rw_list(MI, M680X_REG_CC, READ);
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
static const m680x_reg g_rr5_to_reg_ids[] = {
|
|
1224
|
+
M680X_REG_X, M680X_REG_Y, M680X_REG_U, M680X_REG_S,
|
|
1225
|
+
};
|
|
1226
|
+
|
|
1227
|
+
static void add_indexed_operand(m680x_info *info, m680x_reg base_reg,
|
|
1228
|
+
bool post_inc_dec, uint8_t inc_dec, uint8_t offset_bits,
|
|
1229
|
+
uint16_t offset, bool no_comma)
|
|
1230
|
+
{
|
|
1231
|
+
cs_m680x *m680x = &info->m680x;
|
|
1232
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1233
|
+
|
|
1234
|
+
op->type = M680X_OP_INDEXED;
|
|
1235
|
+
set_operand_size(info, op, 1);
|
|
1236
|
+
op->idx.base_reg = base_reg;
|
|
1237
|
+
op->idx.offset_reg = M680X_REG_INVALID;
|
|
1238
|
+
op->idx.inc_dec = inc_dec;
|
|
1239
|
+
|
|
1240
|
+
if (inc_dec && post_inc_dec)
|
|
1241
|
+
op->idx.flags |= M680X_IDX_POST_INC_DEC;
|
|
1242
|
+
|
|
1243
|
+
if (offset_bits != M680X_OFFSET_NONE) {
|
|
1244
|
+
op->idx.offset = offset;
|
|
1245
|
+
op->idx.offset_addr = 0;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
op->idx.offset_bits = offset_bits;
|
|
1249
|
+
op->idx.flags |= (no_comma ? M680X_IDX_NO_COMMA : 0);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
// M6800/1/2/3 indexed mode handler
|
|
1253
|
+
static void indexedX_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1254
|
+
{
|
|
1255
|
+
uint8_t offset = 0;
|
|
1256
|
+
|
|
1257
|
+
read_byte(info, &offset, (*address)++);
|
|
1258
|
+
|
|
1259
|
+
add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_8,
|
|
1260
|
+
(uint16_t)offset, false);
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
static void indexedY_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1264
|
+
{
|
|
1265
|
+
uint8_t offset = 0;
|
|
1266
|
+
|
|
1267
|
+
read_byte(info, &offset, (*address)++);
|
|
1268
|
+
|
|
1269
|
+
add_indexed_operand(info, M680X_REG_Y, false, 0, M680X_OFFSET_BITS_8,
|
|
1270
|
+
(uint16_t)offset, false);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
// M6809/M6309 indexed mode handler
|
|
1274
|
+
static void indexed09_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1275
|
+
{
|
|
1276
|
+
cs_m680x *m680x = &info->m680x;
|
|
1277
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1278
|
+
uint8_t post_byte = 0;
|
|
1279
|
+
uint16_t offset = 0;
|
|
1280
|
+
int16_t soffset = 0;
|
|
1281
|
+
|
|
1282
|
+
read_byte(info, &post_byte, (*address)++);
|
|
1283
|
+
|
|
1284
|
+
op->type = M680X_OP_INDEXED;
|
|
1285
|
+
set_operand_size(info, op, 1);
|
|
1286
|
+
op->idx.base_reg = g_rr5_to_reg_ids[(post_byte >> 5) & 0x03];
|
|
1287
|
+
op->idx.offset_reg = M680X_REG_INVALID;
|
|
1288
|
+
|
|
1289
|
+
if (!(post_byte & 0x80)) {
|
|
1290
|
+
// n5,R
|
|
1291
|
+
if ((post_byte & 0x10) == 0x10)
|
|
1292
|
+
op->idx.offset = post_byte | 0xfff0;
|
|
1293
|
+
else
|
|
1294
|
+
op->idx.offset = post_byte & 0x0f;
|
|
1295
|
+
|
|
1296
|
+
op->idx.offset_addr = op->idx.offset + *address;
|
|
1297
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_5;
|
|
1298
|
+
}
|
|
1299
|
+
else {
|
|
1300
|
+
if ((post_byte & 0x10) == 0x10)
|
|
1301
|
+
op->idx.flags |= M680X_IDX_INDIRECT;
|
|
1302
|
+
|
|
1303
|
+
// indexed addressing
|
|
1304
|
+
switch (post_byte & 0x1f) {
|
|
1305
|
+
case 0x00: // ,R+
|
|
1306
|
+
op->idx.inc_dec = 1;
|
|
1307
|
+
op->idx.flags |= M680X_IDX_POST_INC_DEC;
|
|
1308
|
+
break;
|
|
1309
|
+
|
|
1310
|
+
case 0x11: // [,R++]
|
|
1311
|
+
case 0x01: // ,R++
|
|
1312
|
+
op->idx.inc_dec = 2;
|
|
1313
|
+
op->idx.flags |= M680X_IDX_POST_INC_DEC;
|
|
1314
|
+
break;
|
|
1315
|
+
|
|
1316
|
+
case 0x02: // ,-R
|
|
1317
|
+
op->idx.inc_dec = -1;
|
|
1318
|
+
break;
|
|
1319
|
+
|
|
1320
|
+
case 0x13: // [,--R]
|
|
1321
|
+
case 0x03: // ,--R
|
|
1322
|
+
op->idx.inc_dec = -2;
|
|
1323
|
+
break;
|
|
1324
|
+
|
|
1325
|
+
case 0x14: // [,R]
|
|
1326
|
+
case 0x04: // ,R
|
|
1327
|
+
break;
|
|
1328
|
+
|
|
1329
|
+
case 0x15: // [B,R]
|
|
1330
|
+
case 0x05: // B,R
|
|
1331
|
+
op->idx.offset_reg = M680X_REG_B;
|
|
1332
|
+
break;
|
|
1333
|
+
|
|
1334
|
+
case 0x16: // [A,R]
|
|
1335
|
+
case 0x06: // A,R
|
|
1336
|
+
op->idx.offset_reg = M680X_REG_A;
|
|
1337
|
+
break;
|
|
1338
|
+
|
|
1339
|
+
case 0x1c: // [n8,PCR]
|
|
1340
|
+
case 0x0c: // n8,PCR
|
|
1341
|
+
op->idx.base_reg = M680X_REG_PC;
|
|
1342
|
+
read_byte_sign_extended(info, &soffset, (*address)++);
|
|
1343
|
+
op->idx.offset_addr = offset + *address;
|
|
1344
|
+
op->idx.offset = soffset;
|
|
1345
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_8;
|
|
1346
|
+
break;
|
|
1347
|
+
|
|
1348
|
+
case 0x18: // [n8,R]
|
|
1349
|
+
case 0x08: // n8,R
|
|
1350
|
+
read_byte_sign_extended(info, &soffset, (*address)++);
|
|
1351
|
+
op->idx.offset = soffset;
|
|
1352
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_8;
|
|
1353
|
+
break;
|
|
1354
|
+
|
|
1355
|
+
case 0x1d: // [n16,PCR]
|
|
1356
|
+
case 0x0d: // n16,PCR
|
|
1357
|
+
op->idx.base_reg = M680X_REG_PC;
|
|
1358
|
+
read_word(info, &offset, *address);
|
|
1359
|
+
*address += 2;
|
|
1360
|
+
op->idx.offset_addr = offset + *address;
|
|
1361
|
+
op->idx.offset = (int16_t)offset;
|
|
1362
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_16;
|
|
1363
|
+
break;
|
|
1364
|
+
|
|
1365
|
+
case 0x19: // [n16,R]
|
|
1366
|
+
case 0x09: // n16,R
|
|
1367
|
+
read_word(info, &offset, *address);
|
|
1368
|
+
*address += 2;
|
|
1369
|
+
op->idx.offset = (int16_t)offset;
|
|
1370
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_16;
|
|
1371
|
+
break;
|
|
1372
|
+
|
|
1373
|
+
case 0x1b: // [D,R]
|
|
1374
|
+
case 0x0b: // D,R
|
|
1375
|
+
op->idx.offset_reg = M680X_REG_D;
|
|
1376
|
+
break;
|
|
1377
|
+
|
|
1378
|
+
case 0x1f: // [n16]
|
|
1379
|
+
op->type = M680X_OP_EXTENDED;
|
|
1380
|
+
op->ext.indirect = true;
|
|
1381
|
+
read_word(info, &op->ext.address, *address);
|
|
1382
|
+
*address += 2;
|
|
1383
|
+
break;
|
|
1384
|
+
|
|
1385
|
+
default:
|
|
1386
|
+
op->idx.base_reg = M680X_REG_INVALID;
|
|
1387
|
+
break;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
if (((info->insn == M680X_INS_LEAU) ||
|
|
1392
|
+
(info->insn == M680X_INS_LEAS) ||
|
|
1393
|
+
(info->insn == M680X_INS_LEAX) ||
|
|
1394
|
+
(info->insn == M680X_INS_LEAY)) &&
|
|
1395
|
+
(m680x->operands[0].reg == M680X_REG_X ||
|
|
1396
|
+
(m680x->operands[0].reg == M680X_REG_Y)))
|
|
1397
|
+
// Only LEAX and LEAY modify CC register
|
|
1398
|
+
add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
|
|
1402
|
+
static const m680x_reg g_idx12_to_reg_ids[4] = {
|
|
1403
|
+
M680X_REG_X, M680X_REG_Y, M680X_REG_S, M680X_REG_PC,
|
|
1404
|
+
};
|
|
1405
|
+
|
|
1406
|
+
static const m680x_reg g_or12_to_reg_ids[3] = {
|
|
1407
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_D
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
// CPU12 indexed mode handler
|
|
1411
|
+
static void indexed12_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1412
|
+
{
|
|
1413
|
+
cs_m680x *m680x = &info->m680x;
|
|
1414
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1415
|
+
uint8_t post_byte = 0;
|
|
1416
|
+
uint8_t offset8 = 0;
|
|
1417
|
+
|
|
1418
|
+
read_byte(info, &post_byte, (*address)++);
|
|
1419
|
+
|
|
1420
|
+
op->type = M680X_OP_INDEXED;
|
|
1421
|
+
set_operand_size(info, op, 1);
|
|
1422
|
+
op->idx.offset_reg = M680X_REG_INVALID;
|
|
1423
|
+
|
|
1424
|
+
if (!(post_byte & 0x20)) {
|
|
1425
|
+
// n5,R n5 is a 5-bit signed offset
|
|
1426
|
+
op->idx.base_reg = g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
|
|
1427
|
+
|
|
1428
|
+
if ((post_byte & 0x10) == 0x10)
|
|
1429
|
+
op->idx.offset = post_byte | 0xfff0;
|
|
1430
|
+
else
|
|
1431
|
+
op->idx.offset = post_byte & 0x0f;
|
|
1432
|
+
|
|
1433
|
+
op->idx.offset_addr = op->idx.offset + *address;
|
|
1434
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_5;
|
|
1435
|
+
}
|
|
1436
|
+
else {
|
|
1437
|
+
if ((post_byte & 0xe0) == 0xe0)
|
|
1438
|
+
op->idx.base_reg =
|
|
1439
|
+
g_idx12_to_reg_ids[(post_byte >> 3) & 0x03];
|
|
1440
|
+
|
|
1441
|
+
switch (post_byte & 0xe7) {
|
|
1442
|
+
case 0xe0:
|
|
1443
|
+
case 0xe1: // n9,R
|
|
1444
|
+
read_byte(info, &offset8, (*address)++);
|
|
1445
|
+
op->idx.offset = offset8;
|
|
1446
|
+
|
|
1447
|
+
if (post_byte & 0x01) // sign extension
|
|
1448
|
+
op->idx.offset |= 0xff00;
|
|
1449
|
+
|
|
1450
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_9;
|
|
1451
|
+
|
|
1452
|
+
if (op->idx.base_reg == M680X_REG_PC)
|
|
1453
|
+
op->idx.offset_addr = op->idx.offset + *address;
|
|
1454
|
+
|
|
1455
|
+
break;
|
|
1456
|
+
|
|
1457
|
+
case 0xe3: // [n16,R]
|
|
1458
|
+
op->idx.flags |= M680X_IDX_INDIRECT;
|
|
1459
|
+
|
|
1460
|
+
// intentionally fall through
|
|
1461
|
+
case 0xe2: // n16,R
|
|
1462
|
+
read_word(info, (uint16_t *)&op->idx.offset, *address);
|
|
1463
|
+
(*address) += 2;
|
|
1464
|
+
op->idx.offset_bits = M680X_OFFSET_BITS_16;
|
|
1465
|
+
|
|
1466
|
+
if (op->idx.base_reg == M680X_REG_PC)
|
|
1467
|
+
op->idx.offset_addr = op->idx.offset + *address;
|
|
1468
|
+
|
|
1469
|
+
break;
|
|
1470
|
+
|
|
1471
|
+
case 0xe4: // A,R
|
|
1472
|
+
case 0xe5: // B,R
|
|
1473
|
+
case 0xe6: // D,R
|
|
1474
|
+
op->idx.offset_reg =
|
|
1475
|
+
g_or12_to_reg_ids[post_byte & 0x03];
|
|
1476
|
+
break;
|
|
1477
|
+
|
|
1478
|
+
case 0xe7: // [D,R]
|
|
1479
|
+
op->idx.offset_reg = M680X_REG_D;
|
|
1480
|
+
op->idx.flags |= M680X_IDX_INDIRECT;
|
|
1481
|
+
break;
|
|
1482
|
+
|
|
1483
|
+
default: // n,-r n,+r n,r- n,r+
|
|
1484
|
+
// PC is not allowed in this mode
|
|
1485
|
+
op->idx.base_reg =
|
|
1486
|
+
g_idx12_to_reg_ids[(post_byte >> 6) & 0x03];
|
|
1487
|
+
op->idx.inc_dec = post_byte & 0x0f;
|
|
1488
|
+
|
|
1489
|
+
if (op->idx.inc_dec & 0x08) // evtl. sign extend value
|
|
1490
|
+
op->idx.inc_dec |= 0xf0;
|
|
1491
|
+
|
|
1492
|
+
if (op->idx.inc_dec >= 0)
|
|
1493
|
+
op->idx.inc_dec++;
|
|
1494
|
+
|
|
1495
|
+
if (post_byte & 0x10)
|
|
1496
|
+
op->idx.flags |= M680X_IDX_POST_INC_DEC;
|
|
1497
|
+
|
|
1498
|
+
break;
|
|
1499
|
+
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
static void index_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1505
|
+
{
|
|
1506
|
+
cs_m680x *m680x = &info->m680x;
|
|
1507
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1508
|
+
|
|
1509
|
+
op->type = M680X_OP_CONSTANT;
|
|
1510
|
+
read_byte(info, &op->const_val, (*address)++);
|
|
1511
|
+
};
|
|
1512
|
+
|
|
1513
|
+
static void direct_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1514
|
+
{
|
|
1515
|
+
cs_m680x *m680x = &info->m680x;
|
|
1516
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1517
|
+
|
|
1518
|
+
op->type = M680X_OP_DIRECT;
|
|
1519
|
+
set_operand_size(info, op, 1);
|
|
1520
|
+
read_byte(info, &op->direct_addr, (*address)++);
|
|
1521
|
+
};
|
|
1522
|
+
|
|
1523
|
+
static void extended_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1524
|
+
{
|
|
1525
|
+
cs_m680x *m680x = &info->m680x;
|
|
1526
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1527
|
+
|
|
1528
|
+
op->type = M680X_OP_EXTENDED;
|
|
1529
|
+
set_operand_size(info, op, 1);
|
|
1530
|
+
read_word(info, &op->ext.address, *address);
|
|
1531
|
+
*address += 2;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
static void immediate_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1535
|
+
{
|
|
1536
|
+
cs_m680x *m680x = &info->m680x;
|
|
1537
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1538
|
+
uint16_t word = 0;
|
|
1539
|
+
int16_t sword = 0;
|
|
1540
|
+
|
|
1541
|
+
op->type = M680X_OP_IMMEDIATE;
|
|
1542
|
+
set_operand_size(info, op, 1);
|
|
1543
|
+
|
|
1544
|
+
switch (op->size) {
|
|
1545
|
+
case 1:
|
|
1546
|
+
read_byte_sign_extended(info, &sword, *address);
|
|
1547
|
+
op->imm = sword;
|
|
1548
|
+
break;
|
|
1549
|
+
|
|
1550
|
+
case 2:
|
|
1551
|
+
read_word(info, &word, *address);
|
|
1552
|
+
op->imm = (int16_t)word;
|
|
1553
|
+
break;
|
|
1554
|
+
|
|
1555
|
+
case 4:
|
|
1556
|
+
read_sdword(info, &op->imm, *address);
|
|
1557
|
+
break;
|
|
1558
|
+
|
|
1559
|
+
default:
|
|
1560
|
+
op->imm = 0;
|
|
1561
|
+
CS_ASSERT(0 && "Unexpected immediate byte size");
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
*address += op->size;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
// handler for bit move instructions, e.g: BAND A,5,1,$40 Used by HD6309
|
|
1568
|
+
static void bit_move_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1569
|
+
{
|
|
1570
|
+
static const m680x_reg m680x_reg[] = {
|
|
1571
|
+
M680X_REG_CC, M680X_REG_A, M680X_REG_B, M680X_REG_INVALID,
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
uint8_t post_byte = 0;
|
|
1575
|
+
cs_m680x *m680x = &info->m680x;
|
|
1576
|
+
cs_m680x_op *op;
|
|
1577
|
+
|
|
1578
|
+
read_byte(info, &post_byte, *address);
|
|
1579
|
+
(*address)++;
|
|
1580
|
+
|
|
1581
|
+
// operand[0] = register
|
|
1582
|
+
add_reg_operand(info, m680x_reg[post_byte >> 6]);
|
|
1583
|
+
|
|
1584
|
+
// operand[1] = bit index in source operand
|
|
1585
|
+
op = &m680x->operands[m680x->op_count++];
|
|
1586
|
+
op->type = M680X_OP_CONSTANT;
|
|
1587
|
+
op->const_val = (post_byte >> 3) & 0x07;
|
|
1588
|
+
|
|
1589
|
+
// operand[2] = bit index in destination operand
|
|
1590
|
+
op = &m680x->operands[m680x->op_count++];
|
|
1591
|
+
op->type = M680X_OP_CONSTANT;
|
|
1592
|
+
op->const_val = post_byte & 0x07;
|
|
1593
|
+
|
|
1594
|
+
direct_hdlr(MI, info, address);
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
// handler for TFM instruction, e.g: TFM X+,Y+ Used by HD6309
|
|
1598
|
+
static void tfm_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1599
|
+
{
|
|
1600
|
+
static const uint8_t inc_dec_r0[] = {
|
|
1601
|
+
1, -1, 1, 0,
|
|
1602
|
+
};
|
|
1603
|
+
static const uint8_t inc_dec_r1[] = {
|
|
1604
|
+
1, -1, 0, 1,
|
|
1605
|
+
};
|
|
1606
|
+
uint8_t regs = 0;
|
|
1607
|
+
uint8_t index = (MI->Opcode & 0xff) - 0x38;
|
|
1608
|
+
|
|
1609
|
+
read_byte(info, ®s, *address);
|
|
1610
|
+
|
|
1611
|
+
add_indexed_operand(info, g_tfr_exg_reg_ids[regs >> 4], true,
|
|
1612
|
+
inc_dec_r0[index], M680X_OFFSET_NONE, 0, true);
|
|
1613
|
+
add_indexed_operand(info, g_tfr_exg_reg_ids[regs & 0x0f], true,
|
|
1614
|
+
inc_dec_r1[index], M680X_OFFSET_NONE, 0, true);
|
|
1615
|
+
|
|
1616
|
+
add_reg_to_rw_list(MI, M680X_REG_W, READ | WRITE);
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1619
|
+
static void opidx_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1620
|
+
{
|
|
1621
|
+
cs_m680x *m680x = &info->m680x;
|
|
1622
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1623
|
+
|
|
1624
|
+
// bit index is coded in Opcode
|
|
1625
|
+
op->type = M680X_OP_CONSTANT;
|
|
1626
|
+
op->const_val = (MI->Opcode & 0x0e) >> 1;
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
// handler for bit test and branch instruction. Used by M6805.
|
|
1630
|
+
// The bit index is part of the opcode.
|
|
1631
|
+
// Example: BRSET 3,<$40,LOOP
|
|
1632
|
+
static void opidx_dir_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1633
|
+
{
|
|
1634
|
+
cs_m680x *m680x = &info->m680x;
|
|
1635
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1636
|
+
|
|
1637
|
+
// bit index is coded in Opcode
|
|
1638
|
+
op->type = M680X_OP_CONSTANT;
|
|
1639
|
+
op->const_val = (MI->Opcode & 0x0e) >> 1;
|
|
1640
|
+
direct_hdlr(MI, info, address);
|
|
1641
|
+
relative8_hdlr(MI, info, address);
|
|
1642
|
+
|
|
1643
|
+
add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
static void indexedX0_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1647
|
+
{
|
|
1648
|
+
add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_NONE,
|
|
1649
|
+
0, false);
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
static void indexedX16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1653
|
+
{
|
|
1654
|
+
uint16_t offset = 0;
|
|
1655
|
+
|
|
1656
|
+
read_word(info, &offset, *address);
|
|
1657
|
+
*address += 2;
|
|
1658
|
+
add_indexed_operand(info, M680X_REG_X, false, 0, M680X_OFFSET_BITS_16,
|
|
1659
|
+
offset, false);
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
static void imm_rel_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1663
|
+
{
|
|
1664
|
+
immediate_hdlr(MI, info, address);
|
|
1665
|
+
relative8_hdlr(MI, info, address);
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
static void indexedS_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1669
|
+
{
|
|
1670
|
+
uint8_t offset = 0;
|
|
1671
|
+
|
|
1672
|
+
read_byte(info, &offset, (*address)++);
|
|
1673
|
+
|
|
1674
|
+
add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_8,
|
|
1675
|
+
(uint16_t)offset, false);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
static void indexedS16_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1679
|
+
{
|
|
1680
|
+
uint16_t offset = 0;
|
|
1681
|
+
|
|
1682
|
+
read_word(info, &offset, *address);
|
|
1683
|
+
address += 2;
|
|
1684
|
+
|
|
1685
|
+
add_indexed_operand(info, M680X_REG_S, false, 0, M680X_OFFSET_BITS_16,
|
|
1686
|
+
offset, false);
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
static void indexedX0p_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1690
|
+
{
|
|
1691
|
+
add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_NONE,
|
|
1692
|
+
0, true);
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
static void indexedXp_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1696
|
+
{
|
|
1697
|
+
uint8_t offset = 0;
|
|
1698
|
+
|
|
1699
|
+
read_byte(info, &offset, (*address)++);
|
|
1700
|
+
|
|
1701
|
+
add_indexed_operand(info, M680X_REG_X, true, 1, M680X_OFFSET_BITS_8,
|
|
1702
|
+
(uint16_t)offset, false);
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
static void imm_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1706
|
+
{
|
|
1707
|
+
cs_m680x *m680x = &info->m680x;
|
|
1708
|
+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
|
|
1709
|
+
|
|
1710
|
+
indexed12_hdlr(MI, info, address);
|
|
1711
|
+
op->type = M680X_OP_IMMEDIATE;
|
|
1712
|
+
|
|
1713
|
+
if (info->insn == M680X_INS_MOVW) {
|
|
1714
|
+
uint16_t imm16 = 0;
|
|
1715
|
+
|
|
1716
|
+
read_word(info, &imm16, *address);
|
|
1717
|
+
op->imm = (int16_t)imm16;
|
|
1718
|
+
op->size = 2;
|
|
1719
|
+
}
|
|
1720
|
+
else {
|
|
1721
|
+
uint8_t imm8 = 0;
|
|
1722
|
+
|
|
1723
|
+
read_byte(info, &imm8, *address);
|
|
1724
|
+
op->imm = (int8_t)imm8;
|
|
1725
|
+
op->size = 1;
|
|
1726
|
+
}
|
|
1727
|
+
|
|
1728
|
+
set_operand_size(info, op, 1);
|
|
1729
|
+
}
|
|
1730
|
+
|
|
1731
|
+
static void ext_idx12_x_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1732
|
+
{
|
|
1733
|
+
cs_m680x *m680x = &info->m680x;
|
|
1734
|
+
cs_m680x_op *op0 = &m680x->operands[m680x->op_count++];
|
|
1735
|
+
uint16_t imm16 = 0;
|
|
1736
|
+
|
|
1737
|
+
indexed12_hdlr(MI, info, address);
|
|
1738
|
+
read_word(info, &imm16, *address);
|
|
1739
|
+
op0->type = M680X_OP_EXTENDED;
|
|
1740
|
+
op0->ext.address = (int16_t)imm16;
|
|
1741
|
+
set_operand_size(info, op0, 1);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
// handler for CPU12 DBEQ/DNBE/IBEQ/IBNE/TBEQ/TBNE instructions.
|
|
1745
|
+
// Example: DBNE X,$1000
|
|
1746
|
+
static void loop_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
|
|
1747
|
+
{
|
|
1748
|
+
static const m680x_reg index_to_reg_id[] = {
|
|
1749
|
+
M680X_REG_A, M680X_REG_B, M680X_REG_INVALID, M680X_REG_INVALID,
|
|
1750
|
+
M680X_REG_D, M680X_REG_X, M680X_REG_Y, M680X_REG_S,
|
|
1751
|
+
};
|
|
1752
|
+
static const m680x_insn index_to_insn_id[] = {
|
|
1753
|
+
M680X_INS_DBEQ, M680X_INS_DBNE, M680X_INS_TBEQ, M680X_INS_TBNE,
|
|
1754
|
+
M680X_INS_IBEQ, M680X_INS_IBNE, M680X_INS_ILLGL, M680X_INS_ILLGL
|
|
1755
|
+
};
|
|
1756
|
+
cs_m680x *m680x = &info->m680x;
|
|
1757
|
+
uint8_t post_byte = 0;
|
|
1758
|
+
uint8_t rel = 0;
|
|
1759
|
+
cs_m680x_op *op;
|
|
1760
|
+
|
|
1761
|
+
read_byte(info, &post_byte, (*address)++);
|
|
1762
|
+
|
|
1763
|
+
info->insn = index_to_insn_id[(post_byte >> 5) & 0x07];
|
|
1764
|
+
|
|
1765
|
+
if (info->insn == M680X_INS_ILLGL) {
|
|
1766
|
+
illegal_hdlr(MI, info, address);
|
|
1767
|
+
};
|
|
1768
|
+
|
|
1769
|
+
read_byte(info, &rel, (*address)++);
|
|
1770
|
+
|
|
1771
|
+
add_reg_operand(info, index_to_reg_id[post_byte & 0x07]);
|
|
1772
|
+
|
|
1773
|
+
op = &m680x->operands[m680x->op_count++];
|
|
1774
|
+
|
|
1775
|
+
op->type = M680X_OP_RELATIVE;
|
|
1776
|
+
|
|
1777
|
+
op->rel.offset = (post_byte & 0x10) ? 0xff00 | rel : rel;
|
|
1778
|
+
|
|
1779
|
+
op->rel.address = *address + op->rel.offset;
|
|
1780
|
+
|
|
1781
|
+
add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
|
|
1785
|
+
illegal_hdlr,
|
|
1786
|
+
relative8_hdlr,
|
|
1787
|
+
relative16_hdlr,
|
|
1788
|
+
immediate_hdlr, // 8-bit
|
|
1789
|
+
immediate_hdlr, // 16-bit
|
|
1790
|
+
immediate_hdlr, // 32-bit
|
|
1791
|
+
direct_hdlr,
|
|
1792
|
+
extended_hdlr,
|
|
1793
|
+
indexedX_hdlr,
|
|
1794
|
+
indexedY_hdlr,
|
|
1795
|
+
indexed09_hdlr,
|
|
1796
|
+
inherent_hdlr,
|
|
1797
|
+
reg_reg09_hdlr,
|
|
1798
|
+
reg_bits_hdlr,
|
|
1799
|
+
bit_move_hdlr,
|
|
1800
|
+
tfm_hdlr,
|
|
1801
|
+
opidx_hdlr,
|
|
1802
|
+
opidx_dir_rel_hdlr,
|
|
1803
|
+
indexedX0_hdlr,
|
|
1804
|
+
indexedX16_hdlr,
|
|
1805
|
+
imm_rel_hdlr,
|
|
1806
|
+
indexedS_hdlr,
|
|
1807
|
+
indexedS16_hdlr,
|
|
1808
|
+
indexedXp_hdlr,
|
|
1809
|
+
indexedX0p_hdlr,
|
|
1810
|
+
indexed12_hdlr,
|
|
1811
|
+
indexed12_hdlr, // subset of indexed12
|
|
1812
|
+
reg_reg12_hdlr,
|
|
1813
|
+
loop_hdlr,
|
|
1814
|
+
index_hdlr,
|
|
1815
|
+
imm_idx12_x_hdlr,
|
|
1816
|
+
imm_idx12_x_hdlr,
|
|
1817
|
+
ext_idx12_x_hdlr,
|
|
1818
|
+
}; /* handler function pointers */
|
|
1819
|
+
|
|
1820
|
+
/* Disasemble one instruction at address and store in str_buff */
|
|
1821
|
+
static unsigned int m680x_disassemble(MCInst *MI, m680x_info *info,
|
|
1822
|
+
uint16_t address)
|
|
1823
|
+
{
|
|
1824
|
+
cs_m680x *m680x = &info->m680x;
|
|
1825
|
+
cs_detail *detail = MI->flat_insn->detail;
|
|
1826
|
+
uint16_t base_address = address;
|
|
1827
|
+
insn_desc insn_description;
|
|
1828
|
+
e_access_mode access_mode;
|
|
1829
|
+
|
|
1830
|
+
if (detail != NULL) {
|
|
1831
|
+
memset(detail, 0, offsetof(cs_detail, m680x)+sizeof(cs_m680x));
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
memset(&insn_description, 0, sizeof(insn_description));
|
|
1835
|
+
memset(m680x, 0, sizeof(*m680x));
|
|
1836
|
+
info->insn_size = 1;
|
|
1837
|
+
|
|
1838
|
+
if (decode_insn(info, address, &insn_description)) {
|
|
1839
|
+
m680x_reg reg;
|
|
1840
|
+
|
|
1841
|
+
if (insn_description.opcode > 0xff)
|
|
1842
|
+
address += 2; // 8-bit opcode + page prefix
|
|
1843
|
+
else
|
|
1844
|
+
address++; // 8-bit opcode only
|
|
1845
|
+
|
|
1846
|
+
info->insn = insn_description.insn;
|
|
1847
|
+
|
|
1848
|
+
MCInst_setOpcode(MI, insn_description.opcode);
|
|
1849
|
+
|
|
1850
|
+
reg = g_insn_props[info->insn].reg0;
|
|
1851
|
+
|
|
1852
|
+
if (reg != M680X_REG_INVALID) {
|
|
1853
|
+
if (reg == M680X_REG_HX &&
|
|
1854
|
+
(!info->cpu->reg_byte_size[reg]))
|
|
1855
|
+
reg = M680X_REG_X;
|
|
1856
|
+
|
|
1857
|
+
add_reg_operand(info, reg);
|
|
1858
|
+
// First (or second) operand is a register which is
|
|
1859
|
+
// part of the mnemonic
|
|
1860
|
+
m680x->flags |= M680X_FIRST_OP_IN_MNEM;
|
|
1861
|
+
reg = g_insn_props[info->insn].reg1;
|
|
1862
|
+
|
|
1863
|
+
if (reg != M680X_REG_INVALID) {
|
|
1864
|
+
if (reg == M680X_REG_HX &&
|
|
1865
|
+
(!info->cpu->reg_byte_size[reg]))
|
|
1866
|
+
reg = M680X_REG_X;
|
|
1867
|
+
|
|
1868
|
+
add_reg_operand(info, reg);
|
|
1869
|
+
m680x->flags |= M680X_SECOND_OP_IN_MNEM;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
// Call addressing mode specific instruction handler
|
|
1874
|
+
(g_insn_handler[insn_description.hid[0]])(MI, info,
|
|
1875
|
+
&address);
|
|
1876
|
+
(g_insn_handler[insn_description.hid[1]])(MI, info,
|
|
1877
|
+
&address);
|
|
1878
|
+
|
|
1879
|
+
add_insn_group(detail, g_insn_props[info->insn].group);
|
|
1880
|
+
|
|
1881
|
+
if (g_insn_props[info->insn].cc_modified &&
|
|
1882
|
+
(info->cpu->insn_cc_not_modified[0] != info->insn) &&
|
|
1883
|
+
(info->cpu->insn_cc_not_modified[1] != info->insn))
|
|
1884
|
+
add_reg_to_rw_list(MI, M680X_REG_CC, MODIFY);
|
|
1885
|
+
|
|
1886
|
+
access_mode = g_insn_props[info->insn].access_mode;
|
|
1887
|
+
|
|
1888
|
+
// Fix for M6805 BSET/BCLR. It has a differnt operand order
|
|
1889
|
+
// in comparison to the M6811
|
|
1890
|
+
if ((info->cpu->insn_cc_not_modified[0] == info->insn) ||
|
|
1891
|
+
(info->cpu->insn_cc_not_modified[1] == info->insn))
|
|
1892
|
+
access_mode = rmmm;
|
|
1893
|
+
|
|
1894
|
+
build_regs_read_write_counts(MI, info, access_mode);
|
|
1895
|
+
add_operators_access(MI, info, access_mode);
|
|
1896
|
+
|
|
1897
|
+
if (g_insn_props[info->insn].update_reg_access)
|
|
1898
|
+
set_changed_regs_read_write_counts(MI, info);
|
|
1899
|
+
|
|
1900
|
+
info->insn_size = (uint8_t)insn_description.insn_size;
|
|
1901
|
+
|
|
1902
|
+
return info->insn_size;
|
|
1903
|
+
}
|
|
1904
|
+
else
|
|
1905
|
+
MCInst_setOpcode(MI, insn_description.opcode);
|
|
1906
|
+
|
|
1907
|
+
// Illegal instruction
|
|
1908
|
+
address = base_address;
|
|
1909
|
+
illegal_hdlr(MI, info, &address);
|
|
1910
|
+
return 1;
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// Tables to get the byte size of a register on the CPU
|
|
1914
|
+
// based on an enum m680x_reg value.
|
|
1915
|
+
// Invalid registers return 0.
|
|
1916
|
+
static const uint8_t g_m6800_reg_byte_size[22] = {
|
|
1917
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1918
|
+
0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
|
|
1919
|
+
};
|
|
1920
|
+
|
|
1921
|
+
static const uint8_t g_m6805_reg_byte_size[22] = {
|
|
1922
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1923
|
+
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0
|
|
1924
|
+
};
|
|
1925
|
+
|
|
1926
|
+
static const uint8_t g_m6808_reg_byte_size[22] = {
|
|
1927
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1928
|
+
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0
|
|
1929
|
+
};
|
|
1930
|
+
|
|
1931
|
+
static const uint8_t g_m6801_reg_byte_size[22] = {
|
|
1932
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1933
|
+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
|
|
1934
|
+
};
|
|
1935
|
+
|
|
1936
|
+
static const uint8_t g_m6811_reg_byte_size[22] = {
|
|
1937
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1938
|
+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0
|
|
1939
|
+
};
|
|
1940
|
+
|
|
1941
|
+
static const uint8_t g_cpu12_reg_byte_size[22] = {
|
|
1942
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1943
|
+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2
|
|
1944
|
+
};
|
|
1945
|
+
|
|
1946
|
+
static const uint8_t g_m6809_reg_byte_size[22] = {
|
|
1947
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1948
|
+
0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0
|
|
1949
|
+
};
|
|
1950
|
+
|
|
1951
|
+
static const uint8_t g_hd6309_reg_byte_size[22] = {
|
|
1952
|
+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
|
|
1953
|
+
0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
// Table to check for a valid register nibble on the M6809 CPU
|
|
1957
|
+
// used for TFR and EXG instruction.
|
|
1958
|
+
static const bool m6809_tfr_reg_valid[16] = {
|
|
1959
|
+
true, true, true, true, true, true, false, false,
|
|
1960
|
+
true, true, true, true, false, false, false, false,
|
|
1961
|
+
};
|
|
1962
|
+
|
|
1963
|
+
static const cpu_tables g_cpu_tables[] = {
|
|
1964
|
+
{
|
|
1965
|
+
// M680X_CPU_TYPE_INVALID
|
|
1966
|
+
NULL,
|
|
1967
|
+
{ NULL, NULL },
|
|
1968
|
+
{ 0, 0 },
|
|
1969
|
+
{ 0x00, 0x00, 0x00 },
|
|
1970
|
+
{ NULL, NULL, NULL },
|
|
1971
|
+
{ 0, 0, 0 },
|
|
1972
|
+
NULL,
|
|
1973
|
+
NULL,
|
|
1974
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
1975
|
+
},
|
|
1976
|
+
{
|
|
1977
|
+
// M680X_CPU_TYPE_6301
|
|
1978
|
+
&g_m6800_inst_page1_table[0],
|
|
1979
|
+
{ &g_m6801_inst_overlay_table[0], &g_hd6301_inst_overlay_table[0] },
|
|
1980
|
+
{
|
|
1981
|
+
ARR_SIZE(g_m6801_inst_overlay_table),
|
|
1982
|
+
ARR_SIZE(g_hd6301_inst_overlay_table)
|
|
1983
|
+
},
|
|
1984
|
+
{ 0x00, 0x00, 0x00 },
|
|
1985
|
+
{ NULL, NULL, NULL },
|
|
1986
|
+
{ 0, 0, 0 },
|
|
1987
|
+
&g_m6801_reg_byte_size[0],
|
|
1988
|
+
NULL,
|
|
1989
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
1990
|
+
},
|
|
1991
|
+
{
|
|
1992
|
+
// M680X_CPU_TYPE_6309
|
|
1993
|
+
&g_m6809_inst_page1_table[0],
|
|
1994
|
+
{ &g_hd6309_inst_overlay_table[0], NULL },
|
|
1995
|
+
{ ARR_SIZE(g_hd6309_inst_overlay_table), 0 },
|
|
1996
|
+
{ 0x10, 0x11, 0x00 },
|
|
1997
|
+
{ &g_hd6309_inst_page2_table[0], &g_hd6309_inst_page3_table[0], NULL },
|
|
1998
|
+
{
|
|
1999
|
+
ARR_SIZE(g_hd6309_inst_page2_table),
|
|
2000
|
+
ARR_SIZE(g_hd6309_inst_page3_table),
|
|
2001
|
+
0
|
|
2002
|
+
},
|
|
2003
|
+
&g_hd6309_reg_byte_size[0],
|
|
2004
|
+
NULL,
|
|
2005
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2006
|
+
},
|
|
2007
|
+
{
|
|
2008
|
+
// M680X_CPU_TYPE_6800
|
|
2009
|
+
&g_m6800_inst_page1_table[0],
|
|
2010
|
+
{ NULL, NULL },
|
|
2011
|
+
{ 0, 0 },
|
|
2012
|
+
{ 0x00, 0x00, 0x00 },
|
|
2013
|
+
{ NULL, NULL, NULL },
|
|
2014
|
+
{ 0, 0, 0 },
|
|
2015
|
+
&g_m6800_reg_byte_size[0],
|
|
2016
|
+
NULL,
|
|
2017
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2018
|
+
},
|
|
2019
|
+
{
|
|
2020
|
+
// M680X_CPU_TYPE_6801
|
|
2021
|
+
&g_m6800_inst_page1_table[0],
|
|
2022
|
+
{ &g_m6801_inst_overlay_table[0], NULL },
|
|
2023
|
+
{ ARR_SIZE(g_m6801_inst_overlay_table), 0 },
|
|
2024
|
+
{ 0x00, 0x00, 0x00 },
|
|
2025
|
+
{ NULL, NULL, NULL },
|
|
2026
|
+
{ 0, 0, 0 },
|
|
2027
|
+
&g_m6801_reg_byte_size[0],
|
|
2028
|
+
NULL,
|
|
2029
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2030
|
+
},
|
|
2031
|
+
{
|
|
2032
|
+
// M680X_CPU_TYPE_6805
|
|
2033
|
+
&g_m6805_inst_page1_table[0],
|
|
2034
|
+
{ NULL, NULL },
|
|
2035
|
+
{ 0, 0 },
|
|
2036
|
+
{ 0x00, 0x00, 0x00 },
|
|
2037
|
+
{ NULL, NULL, NULL },
|
|
2038
|
+
{ 0, 0, 0 },
|
|
2039
|
+
&g_m6805_reg_byte_size[0],
|
|
2040
|
+
NULL,
|
|
2041
|
+
{ M680X_INS_BCLR, M680X_INS_BSET }
|
|
2042
|
+
},
|
|
2043
|
+
{
|
|
2044
|
+
// M680X_CPU_TYPE_6808
|
|
2045
|
+
&g_m6805_inst_page1_table[0],
|
|
2046
|
+
{ &g_m6808_inst_overlay_table[0], NULL },
|
|
2047
|
+
{ ARR_SIZE(g_m6808_inst_overlay_table), 0 },
|
|
2048
|
+
{ 0x9E, 0x00, 0x00 },
|
|
2049
|
+
{ &g_m6808_inst_page2_table[0], NULL, NULL },
|
|
2050
|
+
{ ARR_SIZE(g_m6808_inst_page2_table), 0, 0 },
|
|
2051
|
+
&g_m6808_reg_byte_size[0],
|
|
2052
|
+
NULL,
|
|
2053
|
+
{ M680X_INS_BCLR, M680X_INS_BSET }
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
// M680X_CPU_TYPE_6809
|
|
2057
|
+
&g_m6809_inst_page1_table[0],
|
|
2058
|
+
{ NULL, NULL },
|
|
2059
|
+
{ 0, 0 },
|
|
2060
|
+
{ 0x10, 0x11, 0x00 },
|
|
2061
|
+
{
|
|
2062
|
+
&g_m6809_inst_page2_table[0],
|
|
2063
|
+
&g_m6809_inst_page3_table[0],
|
|
2064
|
+
NULL
|
|
2065
|
+
},
|
|
2066
|
+
{
|
|
2067
|
+
ARR_SIZE(g_m6809_inst_page2_table),
|
|
2068
|
+
ARR_SIZE(g_m6809_inst_page3_table),
|
|
2069
|
+
0
|
|
2070
|
+
},
|
|
2071
|
+
&g_m6809_reg_byte_size[0],
|
|
2072
|
+
&m6809_tfr_reg_valid[0],
|
|
2073
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
// M680X_CPU_TYPE_6811
|
|
2077
|
+
&g_m6800_inst_page1_table[0],
|
|
2078
|
+
{
|
|
2079
|
+
&g_m6801_inst_overlay_table[0],
|
|
2080
|
+
&g_m6811_inst_overlay_table[0]
|
|
2081
|
+
},
|
|
2082
|
+
{
|
|
2083
|
+
ARR_SIZE(g_m6801_inst_overlay_table),
|
|
2084
|
+
ARR_SIZE(g_m6811_inst_overlay_table)
|
|
2085
|
+
},
|
|
2086
|
+
{ 0x18, 0x1A, 0xCD },
|
|
2087
|
+
{
|
|
2088
|
+
&g_m6811_inst_page2_table[0],
|
|
2089
|
+
&g_m6811_inst_page3_table[0],
|
|
2090
|
+
&g_m6811_inst_page4_table[0]
|
|
2091
|
+
},
|
|
2092
|
+
{
|
|
2093
|
+
ARR_SIZE(g_m6811_inst_page2_table),
|
|
2094
|
+
ARR_SIZE(g_m6811_inst_page3_table),
|
|
2095
|
+
ARR_SIZE(g_m6811_inst_page4_table)
|
|
2096
|
+
},
|
|
2097
|
+
&g_m6811_reg_byte_size[0],
|
|
2098
|
+
NULL,
|
|
2099
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2100
|
+
},
|
|
2101
|
+
{
|
|
2102
|
+
// M680X_CPU_TYPE_CPU12
|
|
2103
|
+
&g_cpu12_inst_page1_table[0],
|
|
2104
|
+
{ NULL, NULL },
|
|
2105
|
+
{ 0, 0 },
|
|
2106
|
+
{ 0x18, 0x00, 0x00 },
|
|
2107
|
+
{ &g_cpu12_inst_page2_table[0], NULL, NULL },
|
|
2108
|
+
{ ARR_SIZE(g_cpu12_inst_page2_table), 0, 0 },
|
|
2109
|
+
&g_cpu12_reg_byte_size[0],
|
|
2110
|
+
NULL,
|
|
2111
|
+
{ M680X_INS_INVLD, M680X_INS_INVLD }
|
|
2112
|
+
},
|
|
2113
|
+
{
|
|
2114
|
+
// M680X_CPU_TYPE_HCS08
|
|
2115
|
+
&g_m6805_inst_page1_table[0],
|
|
2116
|
+
{
|
|
2117
|
+
&g_m6808_inst_overlay_table[0],
|
|
2118
|
+
&g_hcs08_inst_overlay_table[0]
|
|
2119
|
+
},
|
|
2120
|
+
{
|
|
2121
|
+
ARR_SIZE(g_m6808_inst_overlay_table),
|
|
2122
|
+
ARR_SIZE(g_hcs08_inst_overlay_table)
|
|
2123
|
+
},
|
|
2124
|
+
{ 0x9E, 0x00, 0x00 },
|
|
2125
|
+
{ &g_hcs08_inst_page2_table[0], NULL, NULL },
|
|
2126
|
+
{ ARR_SIZE(g_hcs08_inst_page2_table), 0, 0 },
|
|
2127
|
+
&g_m6808_reg_byte_size[0],
|
|
2128
|
+
NULL,
|
|
2129
|
+
{ M680X_INS_BCLR, M680X_INS_BSET }
|
|
2130
|
+
},
|
|
2131
|
+
};
|
|
2132
|
+
|
|
2133
|
+
static bool m680x_setup_internals(m680x_info *info, e_cpu_type cpu_type,
|
|
2134
|
+
uint16_t address,
|
|
2135
|
+
const uint8_t *code, uint16_t code_len)
|
|
2136
|
+
{
|
|
2137
|
+
if (cpu_type == M680X_CPU_TYPE_INVALID) {
|
|
2138
|
+
return false;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
info->code = code;
|
|
2142
|
+
info->size = code_len;
|
|
2143
|
+
info->offset = address;
|
|
2144
|
+
info->cpu_type = cpu_type;
|
|
2145
|
+
|
|
2146
|
+
info->cpu = &g_cpu_tables[info->cpu_type];
|
|
2147
|
+
|
|
2148
|
+
return true;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|
2152
|
+
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
|
2153
|
+
{
|
|
2154
|
+
unsigned int insn_size = 0;
|
|
2155
|
+
e_cpu_type cpu_type = M680X_CPU_TYPE_INVALID; // No default CPU type
|
|
2156
|
+
cs_struct *handle = (cs_struct *)ud;
|
|
2157
|
+
m680x_info *info = (m680x_info *)handle->printer_info;
|
|
2158
|
+
|
|
2159
|
+
MCInst_clear(MI);
|
|
2160
|
+
|
|
2161
|
+
if (handle->mode & CS_MODE_M680X_6800)
|
|
2162
|
+
cpu_type = M680X_CPU_TYPE_6800;
|
|
2163
|
+
|
|
2164
|
+
else if (handle->mode & CS_MODE_M680X_6801)
|
|
2165
|
+
cpu_type = M680X_CPU_TYPE_6801;
|
|
2166
|
+
|
|
2167
|
+
else if (handle->mode & CS_MODE_M680X_6805)
|
|
2168
|
+
cpu_type = M680X_CPU_TYPE_6805;
|
|
2169
|
+
|
|
2170
|
+
else if (handle->mode & CS_MODE_M680X_6808)
|
|
2171
|
+
cpu_type = M680X_CPU_TYPE_6808;
|
|
2172
|
+
|
|
2173
|
+
else if (handle->mode & CS_MODE_M680X_HCS08)
|
|
2174
|
+
cpu_type = M680X_CPU_TYPE_HCS08;
|
|
2175
|
+
|
|
2176
|
+
else if (handle->mode & CS_MODE_M680X_6809)
|
|
2177
|
+
cpu_type = M680X_CPU_TYPE_6809;
|
|
2178
|
+
|
|
2179
|
+
else if (handle->mode & CS_MODE_M680X_6301)
|
|
2180
|
+
cpu_type = M680X_CPU_TYPE_6301;
|
|
2181
|
+
|
|
2182
|
+
else if (handle->mode & CS_MODE_M680X_6309)
|
|
2183
|
+
cpu_type = M680X_CPU_TYPE_6309;
|
|
2184
|
+
|
|
2185
|
+
else if (handle->mode & CS_MODE_M680X_6811)
|
|
2186
|
+
cpu_type = M680X_CPU_TYPE_6811;
|
|
2187
|
+
|
|
2188
|
+
else if (handle->mode & CS_MODE_M680X_CPU12)
|
|
2189
|
+
cpu_type = M680X_CPU_TYPE_CPU12;
|
|
2190
|
+
|
|
2191
|
+
if (cpu_type != M680X_CPU_TYPE_INVALID &&
|
|
2192
|
+
m680x_setup_internals(info, cpu_type, (uint16_t)address, code,
|
|
2193
|
+
(uint16_t)code_len))
|
|
2194
|
+
insn_size = m680x_disassemble(MI, info, (uint16_t)address);
|
|
2195
|
+
|
|
2196
|
+
if (insn_size == 0) {
|
|
2197
|
+
*size = 1;
|
|
2198
|
+
return false;
|
|
2199
|
+
}
|
|
2200
|
+
|
|
2201
|
+
// Make sure we always stay within range
|
|
2202
|
+
if (insn_size > code_len) {
|
|
2203
|
+
*size = (uint16_t)code_len;
|
|
2204
|
+
return false;
|
|
2205
|
+
}
|
|
2206
|
+
else
|
|
2207
|
+
*size = (uint16_t)insn_size;
|
|
2208
|
+
|
|
2209
|
+
return true;
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
cs_err M680X_disassembler_init(cs_struct *ud)
|
|
2213
|
+
{
|
|
2214
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6800_reg_byte_size)) {
|
|
2215
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6800_reg_byte_size));
|
|
2216
|
+
|
|
2217
|
+
return CS_ERR_MODE;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6801_reg_byte_size)) {
|
|
2221
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6801_reg_byte_size));
|
|
2222
|
+
|
|
2223
|
+
return CS_ERR_MODE;
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2226
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6805_reg_byte_size)) {
|
|
2227
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6805_reg_byte_size));
|
|
2228
|
+
|
|
2229
|
+
return CS_ERR_MODE;
|
|
2230
|
+
}
|
|
2231
|
+
|
|
2232
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6808_reg_byte_size)) {
|
|
2233
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6808_reg_byte_size));
|
|
2234
|
+
|
|
2235
|
+
return CS_ERR_MODE;
|
|
2236
|
+
}
|
|
2237
|
+
|
|
2238
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6811_reg_byte_size)) {
|
|
2239
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6811_reg_byte_size));
|
|
2240
|
+
|
|
2241
|
+
return CS_ERR_MODE;
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_cpu12_reg_byte_size)) {
|
|
2245
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_cpu12_reg_byte_size));
|
|
2246
|
+
|
|
2247
|
+
return CS_ERR_MODE;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
if (M680X_REG_ENDING != ARR_SIZE(g_m6809_reg_byte_size)) {
|
|
2251
|
+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_m6809_reg_byte_size));
|
|
2252
|
+
|
|
2253
|
+
return CS_ERR_MODE;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
if (M680X_INS_ENDING != ARR_SIZE(g_insn_props)) {
|
|
2257
|
+
CS_ASSERT(M680X_INS_ENDING == ARR_SIZE(g_insn_props));
|
|
2258
|
+
|
|
2259
|
+
return CS_ERR_MODE;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
if (M680X_CPU_TYPE_ENDING != ARR_SIZE(g_cpu_tables)) {
|
|
2263
|
+
CS_ASSERT(M680X_CPU_TYPE_ENDING == ARR_SIZE(g_cpu_tables));
|
|
2264
|
+
|
|
2265
|
+
return CS_ERR_MODE;
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
if (HANDLER_ID_ENDING != ARR_SIZE(g_insn_handler)) {
|
|
2269
|
+
CS_ASSERT(HANDLER_ID_ENDING == ARR_SIZE(g_insn_handler));
|
|
2270
|
+
|
|
2271
|
+
return CS_ERR_MODE;
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2274
|
+
if (ACCESS_MODE_ENDING != MATRIX_SIZE(g_access_mode_to_access)) {
|
|
2275
|
+
CS_ASSERT(ACCESS_MODE_ENDING ==
|
|
2276
|
+
MATRIX_SIZE(g_access_mode_to_access));
|
|
2277
|
+
|
|
2278
|
+
return CS_ERR_MODE;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
return CS_ERR_OK;
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
#ifndef CAPSTONE_DIET
|
|
2285
|
+
void M680X_reg_access(const cs_insn *insn,
|
|
2286
|
+
cs_regs regs_read, uint8_t *regs_read_count,
|
|
2287
|
+
cs_regs regs_write, uint8_t *regs_write_count)
|
|
2288
|
+
{
|
|
2289
|
+
if (insn->detail == NULL) {
|
|
2290
|
+
*regs_read_count = 0;
|
|
2291
|
+
*regs_write_count = 0;
|
|
2292
|
+
}
|
|
2293
|
+
else {
|
|
2294
|
+
*regs_read_count = insn->detail->regs_read_count;
|
|
2295
|
+
*regs_write_count = insn->detail->regs_write_count;
|
|
2296
|
+
|
|
2297
|
+
memcpy(regs_read, insn->detail->regs_read,
|
|
2298
|
+
*regs_read_count * sizeof(insn->detail->regs_read[0]));
|
|
2299
|
+
memcpy(regs_write, insn->detail->regs_write,
|
|
2300
|
+
*regs_write_count *
|
|
2301
|
+
sizeof(insn->detail->regs_write[0]));
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
#endif
|
|
2305
|
+
|
|
2306
|
+
#endif
|
|
2307
|
+
|