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,2221 @@
|
|
|
1
|
+
/* Capstone Disassembly Engine */
|
|
2
|
+
/* By Yoshinori Sato, 2022 */
|
|
3
|
+
|
|
4
|
+
#include <string.h>
|
|
5
|
+
#include <stdarg.h>
|
|
6
|
+
#include "../../cs_priv.h"
|
|
7
|
+
#include "../../MCInst.h"
|
|
8
|
+
#include "../../MCDisassembler.h"
|
|
9
|
+
#include "../../utils.h"
|
|
10
|
+
#include "SHDisassembler.h"
|
|
11
|
+
#include "capstone/sh.h"
|
|
12
|
+
|
|
13
|
+
#define regs_read(_detail, _reg) \
|
|
14
|
+
if (_detail) \
|
|
15
|
+
_detail->regs_read[_detail->regs_read_count++] = _reg
|
|
16
|
+
#define regs_write(_detail, _reg) \
|
|
17
|
+
if (_detail) \
|
|
18
|
+
_detail->regs_write[_detail->regs_write_count++] = _reg
|
|
19
|
+
|
|
20
|
+
enum direction {read, write};
|
|
21
|
+
|
|
22
|
+
static void regs_rw(cs_detail *detail, enum direction rw, sh_reg reg)
|
|
23
|
+
{
|
|
24
|
+
switch(rw) {
|
|
25
|
+
case read:
|
|
26
|
+
regs_read(detail, reg);
|
|
27
|
+
break;
|
|
28
|
+
case write:
|
|
29
|
+
regs_write(detail, reg);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static void set_reg_n(sh_info *info, sh_reg reg, int pos,
|
|
35
|
+
enum direction rw, cs_detail *detail)
|
|
36
|
+
{
|
|
37
|
+
info->op.operands[pos].type = SH_OP_REG;
|
|
38
|
+
info->op.operands[pos].reg = reg;
|
|
39
|
+
regs_rw(detail, rw, reg);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static void set_reg(sh_info *info, sh_reg reg, enum direction rw,
|
|
43
|
+
cs_detail *detail)
|
|
44
|
+
{
|
|
45
|
+
set_reg_n(info, reg, info->op.op_count, rw, detail);
|
|
46
|
+
info->op.op_count++;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static void set_mem_n(sh_info *info, sh_op_mem_type address,
|
|
50
|
+
sh_reg reg, uint32_t disp, int sz, int pos,
|
|
51
|
+
cs_detail *detail)
|
|
52
|
+
{
|
|
53
|
+
info->op.operands[pos].type = SH_OP_MEM;
|
|
54
|
+
info->op.operands[pos].mem.address = address;
|
|
55
|
+
info->op.operands[pos].mem.reg = reg;
|
|
56
|
+
info->op.operands[pos].mem.disp = disp;
|
|
57
|
+
if (sz > 0)
|
|
58
|
+
info->op.size = sz;
|
|
59
|
+
switch (address) {
|
|
60
|
+
case SH_OP_MEM_REG_POST:
|
|
61
|
+
case SH_OP_MEM_REG_PRE:
|
|
62
|
+
regs_write(detail, reg);
|
|
63
|
+
break;
|
|
64
|
+
case SH_OP_MEM_GBR_R0:
|
|
65
|
+
regs_read(detail, SH_REG_GBR);
|
|
66
|
+
regs_read(detail, SH_REG_R0);
|
|
67
|
+
break;
|
|
68
|
+
case SH_OP_MEM_REG_R0:
|
|
69
|
+
regs_read(detail, SH_REG_R0);
|
|
70
|
+
regs_read(detail, reg);
|
|
71
|
+
break;
|
|
72
|
+
case SH_OP_MEM_PCR:
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
regs_read(detail, reg);
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
static void set_mem(sh_info *info, sh_op_mem_type address,
|
|
81
|
+
sh_reg reg, uint32_t disp, int sz, cs_detail *detail)
|
|
82
|
+
{
|
|
83
|
+
set_mem_n(info, address, reg, disp, sz, info->op.op_count, detail);
|
|
84
|
+
info->op.op_count++;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static void set_imm(sh_info *info, int sign, uint64_t imm)
|
|
88
|
+
{
|
|
89
|
+
info->op.operands[info->op.op_count].type = SH_OP_IMM;
|
|
90
|
+
if (sign && imm >= 128)
|
|
91
|
+
imm = -256 + imm;
|
|
92
|
+
info->op.operands[info->op.op_count].imm = imm;
|
|
93
|
+
info->op.op_count++;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static void set_groups(cs_detail *detail, int n, ...)
|
|
97
|
+
{
|
|
98
|
+
va_list g;
|
|
99
|
+
va_start(g, n);
|
|
100
|
+
while (n > 0) {
|
|
101
|
+
sh_insn_group grp;
|
|
102
|
+
grp = va_arg(g, sh_insn_group);
|
|
103
|
+
if (detail) {
|
|
104
|
+
detail->groups[detail->groups_count] = grp;
|
|
105
|
+
detail->groups_count++;
|
|
106
|
+
}
|
|
107
|
+
n--;
|
|
108
|
+
}
|
|
109
|
+
va_end(g);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
enum {
|
|
113
|
+
ISA_ALL = 1,
|
|
114
|
+
ISA_SH2 = 2,
|
|
115
|
+
ISA_SH2A = 3,
|
|
116
|
+
ISA_SH3 = 4,
|
|
117
|
+
ISA_SH4 = 5,
|
|
118
|
+
ISA_SH4A = 6,
|
|
119
|
+
ISA_MAX = 7,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
static int isalevel(cs_mode mode)
|
|
123
|
+
{
|
|
124
|
+
int level;
|
|
125
|
+
mode >>= 1; /* skip endian */
|
|
126
|
+
for (level = 2; level < ISA_MAX; level++) {
|
|
127
|
+
if (mode & 1)
|
|
128
|
+
return level;
|
|
129
|
+
mode >>= 1;
|
|
130
|
+
}
|
|
131
|
+
return ISA_ALL;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
enum co_processor {none, shfpu, shdsp};
|
|
135
|
+
typedef union reg_insn {
|
|
136
|
+
sh_reg reg;
|
|
137
|
+
sh_insn insn;
|
|
138
|
+
} reg_insn;
|
|
139
|
+
struct ri_list {
|
|
140
|
+
int no;
|
|
141
|
+
int /* reg_insn */ri;
|
|
142
|
+
int level;
|
|
143
|
+
enum co_processor cp;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
static const struct ri_list ldc_stc_regs[] = {
|
|
147
|
+
{0, SH_REG_SR, ISA_ALL, none},
|
|
148
|
+
{1, SH_REG_GBR, ISA_ALL, none},
|
|
149
|
+
{2, SH_REG_VBR, ISA_ALL, none},
|
|
150
|
+
{3, SH_REG_SSR, ISA_SH3, none},
|
|
151
|
+
{4, SH_REG_SPC, ISA_SH3, none},
|
|
152
|
+
{5, SH_REG_MOD, ISA_ALL, shdsp},
|
|
153
|
+
{6, SH_REG_RS, ISA_ALL, shdsp},
|
|
154
|
+
{7, SH_REG_RE, ISA_ALL, shdsp},
|
|
155
|
+
{8, SH_REG_R0_BANK, ISA_SH3, none},
|
|
156
|
+
{9, SH_REG_R1_BANK, ISA_SH3, none},
|
|
157
|
+
{10, SH_REG_R2_BANK, ISA_SH3, none},
|
|
158
|
+
{11, SH_REG_R3_BANK, ISA_SH3, none},
|
|
159
|
+
{12, SH_REG_R4_BANK, ISA_SH3, none},
|
|
160
|
+
{13, SH_REG_R5_BANK, ISA_SH3, none},
|
|
161
|
+
{14, SH_REG_R6_BANK, ISA_SH3, none},
|
|
162
|
+
{15, SH_REG_R7_BANK, ISA_SH3, none},
|
|
163
|
+
{-1, SH_REG_INVALID, ISA_ALL, none},
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
static sh_insn lookup_insn(const struct ri_list *list,
|
|
167
|
+
int no, cs_mode mode)
|
|
168
|
+
{
|
|
169
|
+
int level = isalevel(mode);
|
|
170
|
+
sh_insn error = SH_INS_INVALID;
|
|
171
|
+
for(; list->no >= 0; list++) {
|
|
172
|
+
if (no != list->no)
|
|
173
|
+
continue;
|
|
174
|
+
if (((level >= 0) && (level < list->level)) ||
|
|
175
|
+
((level < 0) && (-(level) != list->level)))
|
|
176
|
+
continue;
|
|
177
|
+
if ((list->cp == none) ||
|
|
178
|
+
((list->cp == shfpu) && (mode & CS_MODE_SHFPU)) ||
|
|
179
|
+
((list->cp == shdsp) && (mode & CS_MODE_SHDSP))) {
|
|
180
|
+
return list->ri;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return error;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static sh_reg lookup_regs(const struct ri_list *list,
|
|
187
|
+
int no, cs_mode mode)
|
|
188
|
+
{
|
|
189
|
+
int level = isalevel(mode);
|
|
190
|
+
sh_reg error = SH_REG_INVALID;
|
|
191
|
+
for(; list->no >= 0; list++) {
|
|
192
|
+
if (no != list->no)
|
|
193
|
+
continue;
|
|
194
|
+
if (((level >= 0) && (level < list->level)) ||
|
|
195
|
+
((level < 0) && (-(level) != list->level)))
|
|
196
|
+
continue;
|
|
197
|
+
if ((list->cp == none) ||
|
|
198
|
+
((list->cp == shfpu) && (mode & CS_MODE_SHFPU)) ||
|
|
199
|
+
((list->cp == shdsp) && (mode & CS_MODE_SHDSP))) {
|
|
200
|
+
return list->ri;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return error;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// #define lookup_regs(list, no, mode) ((reg_insn)(lookup(reg, list, no, mode).reg))
|
|
207
|
+
// #define lookup_insn(list, no, mode) ((sh_insn)(lookup(insn, list, no, mode).insn))
|
|
208
|
+
|
|
209
|
+
static sh_reg opSTCsrc(uint16_t code, MCInst *MI, cs_mode mode,
|
|
210
|
+
sh_info *info, cs_detail *detail)
|
|
211
|
+
{
|
|
212
|
+
int s = (code >> 4) & 0x0f;
|
|
213
|
+
int d = (code >> 8) & 0x0f;
|
|
214
|
+
sh_reg sreg;
|
|
215
|
+
MCInst_setOpcode(MI, SH_INS_STC);
|
|
216
|
+
sreg = lookup_regs(ldc_stc_regs, s, mode);
|
|
217
|
+
if (sreg != SH_REG_INVALID) {
|
|
218
|
+
set_reg(info, sreg, read, detail);
|
|
219
|
+
return SH_REG_R0 + d;
|
|
220
|
+
} else {
|
|
221
|
+
return SH_REG_INVALID;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static bool opSTC(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
226
|
+
sh_info *info, cs_detail *detail)
|
|
227
|
+
{
|
|
228
|
+
sh_reg d;
|
|
229
|
+
d = opSTCsrc(code, MI, mode, info, detail);
|
|
230
|
+
if (d != SH_REG_INVALID) {
|
|
231
|
+
set_reg(info, d, write, detail);
|
|
232
|
+
return MCDisassembler_Success;
|
|
233
|
+
} else {
|
|
234
|
+
return MCDisassembler_Fail;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
static bool op0xx3(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
239
|
+
sh_info *info, cs_detail *detail)
|
|
240
|
+
{
|
|
241
|
+
int r = (code >> 8) & 0x0f;
|
|
242
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
243
|
+
static const struct ri_list list[] = {
|
|
244
|
+
{0, SH_INS_BSRF, ISA_SH2, none},
|
|
245
|
+
{2, SH_INS_BRAF, ISA_SH2, none},
|
|
246
|
+
{6, SH_INS_MOVLI, ISA_SH4A, none},
|
|
247
|
+
{7, SH_INS_MOVCO, ISA_SH4A, none},
|
|
248
|
+
{8, SH_INS_PREF, ISA_SH2A, none},
|
|
249
|
+
{9, SH_INS_OCBI, ISA_SH4, none},
|
|
250
|
+
{10, SH_INS_OCBP, ISA_SH4, none},
|
|
251
|
+
{11, SH_INS_OCBWB, ISA_SH4, none},
|
|
252
|
+
{12, SH_INS_MOVCA, ISA_SH4, none},
|
|
253
|
+
{13, SH_INS_PREFI, ISA_SH4A, none},
|
|
254
|
+
{14, SH_INS_ICBI, ISA_SH4A, none},
|
|
255
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
256
|
+
};
|
|
257
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
258
|
+
|
|
259
|
+
if (insn != SH_INS_INVALID) {
|
|
260
|
+
MCInst_setOpcode(MI, insn);
|
|
261
|
+
switch (insn_code) {
|
|
262
|
+
case 0: /// bsrf Rn
|
|
263
|
+
case 2: /// braf Rn
|
|
264
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
265
|
+
if (detail)
|
|
266
|
+
set_groups(detail, 2,
|
|
267
|
+
SH_GRP_JUMP,
|
|
268
|
+
SH_GRP_BRANCH_RELATIVE);
|
|
269
|
+
break;
|
|
270
|
+
case 8: /// pref @Rn
|
|
271
|
+
case 9: /// ocbi @Rn
|
|
272
|
+
case 10: /// ocbp @Rn
|
|
273
|
+
case 11: /// ocbwb @Rn
|
|
274
|
+
case 13: /// prefi @Rn
|
|
275
|
+
case 14: /// icbi @Rn
|
|
276
|
+
set_mem(info, SH_OP_MEM_REG_IND,
|
|
277
|
+
SH_REG_R0 + r, 0, 0, detail);
|
|
278
|
+
break;
|
|
279
|
+
case 6: /// movli @Rn, R0
|
|
280
|
+
set_mem(info, SH_OP_MEM_REG_IND,
|
|
281
|
+
SH_REG_R0 + r, 0, 32, detail);
|
|
282
|
+
set_reg(info, SH_REG_R0, write, detail);
|
|
283
|
+
break;
|
|
284
|
+
case 7: /// movco R0,@Rn
|
|
285
|
+
case 12: /// movca R0,@Rn
|
|
286
|
+
set_reg(info, SH_REG_R0, read, detail);
|
|
287
|
+
set_mem(info, SH_OP_MEM_REG_IND,
|
|
288
|
+
SH_REG_R0 + r, 0, 32, detail);
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
return MCDisassembler_Success;
|
|
292
|
+
} else {
|
|
293
|
+
return MCDisassembler_Fail;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
#define nm(code, dir) \
|
|
298
|
+
int m, n; \
|
|
299
|
+
m = (code >> (4 * (dir + 1))) & 0x0f; \
|
|
300
|
+
n = (code >> (8 - 4 * dir)) & 0x0f
|
|
301
|
+
|
|
302
|
+
static bool opMOVx(uint16_t code, uint64_t address, MCInst *MI,
|
|
303
|
+
cs_mode mode, int size, sh_info *info, cs_detail *detail)
|
|
304
|
+
{
|
|
305
|
+
int ad = ((code >> 10) & 0x3c) | ((code >> 2) & 0x03);
|
|
306
|
+
enum direction rw;
|
|
307
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
308
|
+
switch (ad) {
|
|
309
|
+
case 0x01: /// mov.X Rs,@(R0, Rd)
|
|
310
|
+
case 0x03: /// mov.X @(R0, Rs), Rd
|
|
311
|
+
rw = (ad >> 1);
|
|
312
|
+
{
|
|
313
|
+
nm(code, rw);
|
|
314
|
+
set_reg_n(info, SH_REG_R0 + m, rw, rw, detail);
|
|
315
|
+
set_mem_n(info, SH_OP_MEM_REG_R0, SH_REG_R0 + n,
|
|
316
|
+
0, size, 1 - rw, detail);
|
|
317
|
+
info->op.op_count = 2;
|
|
318
|
+
}
|
|
319
|
+
break;
|
|
320
|
+
case 0x20: /// mov.X Rs,@-Rd
|
|
321
|
+
case 0x60: /// mov.X @Rs+,Rd
|
|
322
|
+
rw = (ad >> 6) & 1;
|
|
323
|
+
{
|
|
324
|
+
nm(code, rw);
|
|
325
|
+
set_reg_n(info, SH_REG_R0 + m, rw, rw, detail);
|
|
326
|
+
set_mem_n(info, SH_OP_MEM_REG_PRE, SH_REG_R0 + n,
|
|
327
|
+
0, size, 1 - rw, detail);
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
default:
|
|
331
|
+
return MCDisassembler_Fail;
|
|
332
|
+
}
|
|
333
|
+
return MCDisassembler_Success;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
static bool opMOV_B(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
337
|
+
sh_info *info, cs_detail *detail)
|
|
338
|
+
{
|
|
339
|
+
return opMOVx(code, address, MI, mode, 8, info, detail);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
static bool opMOV_W(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
343
|
+
sh_info *info, cs_detail *detail)
|
|
344
|
+
{
|
|
345
|
+
return opMOVx(code, address, MI, mode, 16, info, detail);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
static bool opMOV_L(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
349
|
+
sh_info *info, cs_detail *detail)
|
|
350
|
+
{
|
|
351
|
+
return opMOVx(code, address, MI, mode, 32, info, detail);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
static bool opRRfn(uint16_t code, MCInst *MI, sh_insn insn, cs_mode mode,
|
|
355
|
+
int size, int level, sh_info *info, cs_detail *detail)
|
|
356
|
+
{
|
|
357
|
+
int m = (code >> 4) & 0x0f;
|
|
358
|
+
int n = (code >> 8) & 0x0f;
|
|
359
|
+
if (level > isalevel(mode))
|
|
360
|
+
return MCDisassembler_Fail;
|
|
361
|
+
MCInst_setOpcode(MI, insn);
|
|
362
|
+
set_reg(info, SH_REG_R0 + m, read, detail);
|
|
363
|
+
set_reg(info, SH_REG_R0 + n, write, detail);
|
|
364
|
+
info->op.size = size;
|
|
365
|
+
return MCDisassembler_Success;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
#define opRR(level, __insn, __size) \
|
|
369
|
+
static bool op##__insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
370
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
371
|
+
{ \
|
|
372
|
+
return opRRfn(code, MI, SH_INS_##__insn, mode, __size, level, \
|
|
373
|
+
info, detail); \
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/* mul.l - SH2 */
|
|
377
|
+
opRR(ISA_SH2, MUL_L, 0)
|
|
378
|
+
|
|
379
|
+
static bool op0xx8(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
380
|
+
sh_info *info, cs_detail *detail)
|
|
381
|
+
{
|
|
382
|
+
int insn_code = (code >> 4) & 0xf;
|
|
383
|
+
static const struct ri_list list[] = {
|
|
384
|
+
{0, SH_INS_CLRT, ISA_ALL, none},
|
|
385
|
+
{1, SH_INS_SETT, ISA_ALL, none},
|
|
386
|
+
{2, SH_INS_CLRMAC, ISA_ALL, none},
|
|
387
|
+
{3, SH_INS_LDTLB, ISA_SH3, none},
|
|
388
|
+
{4, SH_INS_CLRS, ISA_SH3, none},
|
|
389
|
+
{5, SH_INS_SETS, ISA_SH3, none},
|
|
390
|
+
{6, SH_INS_NOTT, -(ISA_SH2A), none},
|
|
391
|
+
{8, SH_INS_CLRDMXY, ISA_SH4A, shdsp},
|
|
392
|
+
{9, SH_INS_SETDMX, ISA_SH4A, shdsp},
|
|
393
|
+
{12, SH_INS_SETDMY, ISA_SH4A, shdsp},
|
|
394
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
398
|
+
if (code & 0x0f00)
|
|
399
|
+
return MCDisassembler_Fail;
|
|
400
|
+
|
|
401
|
+
if (insn != SH_INS_INVALID) {
|
|
402
|
+
MCInst_setOpcode(MI, insn);
|
|
403
|
+
return MCDisassembler_Success;
|
|
404
|
+
} else {
|
|
405
|
+
return MCDisassembler_Fail;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
static bool op0xx9(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
410
|
+
sh_info *info, cs_detail *detail)
|
|
411
|
+
{
|
|
412
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
413
|
+
int r = (code >> 8) & 0x0f;
|
|
414
|
+
static const struct ri_list list[] = {
|
|
415
|
+
{0, SH_INS_NOP, ISA_ALL, none},
|
|
416
|
+
{1, SH_INS_DIV0U, ISA_ALL, none},
|
|
417
|
+
{2, SH_INS_MOVT, ISA_ALL, none},
|
|
418
|
+
{3, SH_INS_MOVRT, -(ISA_SH2A), none},
|
|
419
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
420
|
+
};
|
|
421
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
422
|
+
if (insn != SH_INS_INVALID) {
|
|
423
|
+
if (insn_code >= 2) {
|
|
424
|
+
/// movt / movrt Rn
|
|
425
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
426
|
+
} else if (r > 0) {
|
|
427
|
+
insn = SH_INS_INVALID;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (insn != SH_INS_INVALID) {
|
|
431
|
+
MCInst_setOpcode(MI, insn);
|
|
432
|
+
return MCDisassembler_Success;
|
|
433
|
+
} else {
|
|
434
|
+
return MCDisassembler_Fail;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
static const struct ri_list sts_lds_regs[] = {
|
|
439
|
+
{0, SH_REG_MACH, ISA_ALL, none},
|
|
440
|
+
{1, SH_REG_MACL, ISA_ALL, none},
|
|
441
|
+
{2, SH_REG_PR, ISA_ALL, none},
|
|
442
|
+
{3, SH_REG_SGR, ISA_SH4, none},
|
|
443
|
+
{4, SH_REG_TBR, -(ISA_SH2A), none},
|
|
444
|
+
{5, SH_REG_FPUL, ISA_ALL, shfpu},
|
|
445
|
+
{6, SH_REG_FPSCR, ISA_ALL, shfpu},
|
|
446
|
+
{6, SH_REG_DSP_DSR, ISA_ALL, shdsp},
|
|
447
|
+
{7, SH_REG_DSP_A0, ISA_ALL, shdsp},
|
|
448
|
+
{8, SH_REG_DSP_X0, ISA_ALL, shdsp},
|
|
449
|
+
{9, SH_REG_DSP_X1, ISA_ALL, shdsp},
|
|
450
|
+
{10, SH_REG_DSP_Y0, ISA_ALL, shdsp},
|
|
451
|
+
{11, SH_REG_DSP_Y1, ISA_ALL, shdsp},
|
|
452
|
+
{15, SH_REG_DBR, ISA_SH4, none},
|
|
453
|
+
{-1, SH_REG_INVALID, ISA_ALL, none},
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
static sh_reg opSTCSTS(uint16_t code, MCInst *MI, cs_mode mode, sh_info *info,
|
|
457
|
+
cs_detail *detail)
|
|
458
|
+
{
|
|
459
|
+
int s = (code >> 4) & 0x0f;
|
|
460
|
+
int d = (code >> 8) & 0x0f;
|
|
461
|
+
sh_reg reg;
|
|
462
|
+
sh_insn insn;
|
|
463
|
+
|
|
464
|
+
reg = lookup_regs(sts_lds_regs, s, mode);
|
|
465
|
+
if (reg != SH_REG_INVALID) {
|
|
466
|
+
if (s == 3 || s == 4 || s == 15) {
|
|
467
|
+
insn = SH_INS_STC;
|
|
468
|
+
} else {
|
|
469
|
+
insn = SH_INS_STS;
|
|
470
|
+
}
|
|
471
|
+
MCInst_setOpcode(MI, insn);
|
|
472
|
+
set_reg(info, reg, read, detail);
|
|
473
|
+
return SH_REG_R0 + d;
|
|
474
|
+
} else {
|
|
475
|
+
return SH_REG_INVALID;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
static bool op0xxa(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
480
|
+
sh_info *info, cs_detail *detail)
|
|
481
|
+
{
|
|
482
|
+
sh_reg r = opSTCSTS(code, MI, mode, info, detail);
|
|
483
|
+
if (r != SH_REG_INVALID) {
|
|
484
|
+
set_reg(info, r, write, detail);
|
|
485
|
+
return MCDisassembler_Success;
|
|
486
|
+
} else
|
|
487
|
+
return MCDisassembler_Fail;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
static bool op0xxb(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
491
|
+
sh_info *info, cs_detail *detail)
|
|
492
|
+
{
|
|
493
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
494
|
+
int r = (code >> 8) & 0x0f;
|
|
495
|
+
static const struct ri_list list[] = {
|
|
496
|
+
{0, SH_INS_RTS, ISA_ALL, none},
|
|
497
|
+
{1, SH_INS_SLEEP, ISA_ALL, none},
|
|
498
|
+
{2, SH_INS_RTE, ISA_ALL, none},
|
|
499
|
+
{5, SH_INS_RESBANK, -(ISA_SH2A), none},
|
|
500
|
+
{6, SH_INS_RTS_N, -(ISA_SH2A), none},
|
|
501
|
+
{7, SH_INS_RTV_N, -(ISA_SH2A), none},
|
|
502
|
+
{10, SH_INS_SYNCO, -(ISA_SH4A), none},
|
|
503
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
507
|
+
if (insn_code == 7) {
|
|
508
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
509
|
+
regs_write(detail, SH_REG_R0);
|
|
510
|
+
} else if (r > 0) {
|
|
511
|
+
insn = SH_INS_INVALID;
|
|
512
|
+
}
|
|
513
|
+
if (insn != SH_INS_INVALID) {
|
|
514
|
+
MCInst_setOpcode(MI, insn);
|
|
515
|
+
return MCDisassembler_Success;
|
|
516
|
+
} else {
|
|
517
|
+
return MCDisassembler_Fail;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
static bool opMAC(uint16_t code, sh_insn op, MCInst *MI, sh_info *info,
|
|
522
|
+
cs_detail *detail)
|
|
523
|
+
{
|
|
524
|
+
nm(code, 0);
|
|
525
|
+
MCInst_setOpcode(MI, op);
|
|
526
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R0 + m, 0, 0, detail);
|
|
527
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R0 + n, 0, 0, detail);
|
|
528
|
+
return MCDisassembler_Success;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/// mac.l - sh2+
|
|
532
|
+
static bool opMAC_L(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
533
|
+
sh_info *info, cs_detail *detail)
|
|
534
|
+
{
|
|
535
|
+
if (isalevel(mode) < ISA_SH2)
|
|
536
|
+
return MCDisassembler_Fail;
|
|
537
|
+
return opMAC(code, SH_INS_MAC_L, MI, info, detail);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
static bool opMAC_W(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
541
|
+
sh_info *info, cs_detail *detail)
|
|
542
|
+
{
|
|
543
|
+
return opMAC(code, SH_INS_MAC_W, MI, info, detail);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
static bool opMOV_L_dsp(uint16_t code, uint64_t address, MCInst *MI,
|
|
547
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
548
|
+
{
|
|
549
|
+
int dsp = (code & 0x0f) * 4;
|
|
550
|
+
int rw = (code >> 14) & 1;
|
|
551
|
+
nm(code, rw);
|
|
552
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
553
|
+
set_mem_n(info, SH_OP_MEM_REG_DISP, SH_REG_R0 + n, dsp,
|
|
554
|
+
32, 1 - rw, detail);
|
|
555
|
+
set_reg_n(info, SH_REG_R0 + m, rw, rw, detail);
|
|
556
|
+
info->op.op_count = 2;
|
|
557
|
+
return MCDisassembler_Success;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
static bool opMOV_rind(uint16_t code, uint64_t address, MCInst *MI,
|
|
561
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
562
|
+
{
|
|
563
|
+
int sz = (code & 0x03);
|
|
564
|
+
int rw = (code >> 14) & 1;
|
|
565
|
+
nm(code, rw);
|
|
566
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
567
|
+
sz = 8 << sz;
|
|
568
|
+
set_mem_n(info, SH_OP_MEM_REG_IND, SH_REG_R0 + n, 0,
|
|
569
|
+
sz, 1 - rw, detail);
|
|
570
|
+
set_reg_n(info, SH_REG_R0 + m, rw, rw, detail);
|
|
571
|
+
info->op.op_count = 2;
|
|
572
|
+
return MCDisassembler_Success;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
static bool opMOV_rpd(uint16_t code, uint64_t address, MCInst *MI,
|
|
576
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
577
|
+
{
|
|
578
|
+
nm(code, 0);
|
|
579
|
+
int sz = (code & 0x03);
|
|
580
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
581
|
+
set_reg(info, SH_REG_R0 + m, read, detail);
|
|
582
|
+
set_mem(info, SH_OP_MEM_REG_PRE, SH_REG_R0 + n, 0, 8 << sz, detail);
|
|
583
|
+
return MCDisassembler_Success;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
opRR(ISA_ALL, TST, 0)
|
|
587
|
+
opRR(ISA_ALL, AND, 0)
|
|
588
|
+
opRR(ISA_ALL, XOR, 0)
|
|
589
|
+
opRR(ISA_ALL, OR, 0)
|
|
590
|
+
opRR(ISA_ALL, CMP_STR, 0)
|
|
591
|
+
opRR(ISA_ALL, XTRCT, 0)
|
|
592
|
+
opRR(ISA_ALL, MULU_W, 16)
|
|
593
|
+
opRR(ISA_ALL, MULS_W, 16)
|
|
594
|
+
opRR(ISA_ALL, CMP_EQ, 0)
|
|
595
|
+
opRR(ISA_ALL, CMP_HI, 0)
|
|
596
|
+
opRR(ISA_ALL, CMP_HS, 0)
|
|
597
|
+
opRR(ISA_ALL, CMP_GE, 0)
|
|
598
|
+
opRR(ISA_ALL, CMP_GT, 0)
|
|
599
|
+
opRR(ISA_ALL, SUB, 0)
|
|
600
|
+
opRR(ISA_ALL, SUBC, 0)
|
|
601
|
+
opRR(ISA_ALL, SUBV, 0)
|
|
602
|
+
opRR(ISA_ALL, ADD_r, 0)
|
|
603
|
+
opRR(ISA_ALL, ADDC, 0)
|
|
604
|
+
opRR(ISA_ALL, ADDV, 0)
|
|
605
|
+
opRR(ISA_ALL, DIV0S, 0)
|
|
606
|
+
opRR(ISA_ALL, DIV1, 0)
|
|
607
|
+
/// DMULS / DMULU - SH2
|
|
608
|
+
opRR(ISA_SH2, DMULS_L, 0)
|
|
609
|
+
opRR(ISA_SH2, DMULU_L, 0)
|
|
610
|
+
|
|
611
|
+
static bool op4xx0(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
612
|
+
sh_info *info, cs_detail *detail)
|
|
613
|
+
{
|
|
614
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
615
|
+
int r = (code >> 8) & 0x0f;
|
|
616
|
+
static const struct ri_list list[] = {
|
|
617
|
+
{0, SH_INS_SHLL, ISA_ALL, none},
|
|
618
|
+
{1, SH_INS_DT, ISA_SH2, none},
|
|
619
|
+
{2, SH_INS_SHAL, ISA_ALL, none},
|
|
620
|
+
{8, SH_INS_MULR, -(ISA_SH2A), none},
|
|
621
|
+
{15, SH_INS_MOVMU, -(ISA_SH2A), none},
|
|
622
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
623
|
+
};
|
|
624
|
+
sh_insn insn = lookup_insn(list, insn_code,mode);
|
|
625
|
+
if (insn != SH_INS_INVALID) {
|
|
626
|
+
MCInst_setOpcode(MI, insn);
|
|
627
|
+
if (insn_code < 8) {
|
|
628
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
629
|
+
} else {
|
|
630
|
+
switch(insn_code) {
|
|
631
|
+
case 0x08:
|
|
632
|
+
set_reg(info, SH_REG_R0, read, detail);
|
|
633
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
634
|
+
break;
|
|
635
|
+
case 0x0f:
|
|
636
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
637
|
+
set_mem(info, SH_OP_MEM_REG_PRE, SH_REG_R15, 0, 32, detail);
|
|
638
|
+
break;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return MCDisassembler_Success;
|
|
642
|
+
} else {
|
|
643
|
+
return MCDisassembler_Fail;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
static bool op4xx1(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
648
|
+
sh_info *info, cs_detail *detail)
|
|
649
|
+
{
|
|
650
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
651
|
+
int r = (code >> 8) & 0x0f;
|
|
652
|
+
static const struct ri_list list[] = {
|
|
653
|
+
{0, SH_INS_SHLR, ISA_ALL, none},
|
|
654
|
+
{1, SH_INS_CMP_PZ, ISA_ALL, none},
|
|
655
|
+
{2, SH_INS_SHAR, ISA_ALL, none},
|
|
656
|
+
{8, SH_INS_CLIPU, -(ISA_SH2A), none},
|
|
657
|
+
{9, SH_INS_CLIPS, -(ISA_SH2A), none},
|
|
658
|
+
{14, SH_INS_STBANK, -(ISA_SH2A), none},
|
|
659
|
+
{15, SH_INS_MOVML, -(ISA_SH2A), none},
|
|
660
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
661
|
+
};
|
|
662
|
+
sh_insn insn = lookup_insn(list, insn_code,mode);
|
|
663
|
+
if (insn != SH_INS_INVALID) {
|
|
664
|
+
MCInst_setOpcode(MI, insn);
|
|
665
|
+
switch(insn_code) {
|
|
666
|
+
case 14:
|
|
667
|
+
set_reg(info, SH_REG_R0, read, detail);
|
|
668
|
+
set_mem(info, SH_OP_MEM_REG_IND, SH_REG_R0 + r, 0,
|
|
669
|
+
0, detail);
|
|
670
|
+
break;
|
|
671
|
+
case 15:
|
|
672
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
673
|
+
set_mem(info, SH_OP_MEM_REG_PRE, SH_REG_R15, 0,
|
|
674
|
+
32, detail);
|
|
675
|
+
break;
|
|
676
|
+
default:
|
|
677
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
678
|
+
if (insn_code >= 8)
|
|
679
|
+
info->op.size = 8;
|
|
680
|
+
break;
|
|
681
|
+
}
|
|
682
|
+
return MCDisassembler_Success;
|
|
683
|
+
} else {
|
|
684
|
+
return MCDisassembler_Fail;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
static bool op4xx2(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
689
|
+
sh_info *info, cs_detail *detail)
|
|
690
|
+
{
|
|
691
|
+
sh_reg r = opSTCSTS(code, MI, mode, info, detail);
|
|
692
|
+
if (r != SH_REG_INVALID) {
|
|
693
|
+
set_mem(info, SH_OP_MEM_REG_PRE, r, 0, 32, detail);
|
|
694
|
+
return MCDisassembler_Success;
|
|
695
|
+
} else {
|
|
696
|
+
return MCDisassembler_Fail;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
static bool opSTC_L(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
701
|
+
sh_info *info, cs_detail *detail)
|
|
702
|
+
{
|
|
703
|
+
sh_reg r = opSTCsrc(code, MI, mode, info, detail);
|
|
704
|
+
if (r != SH_REG_INVALID) {
|
|
705
|
+
set_mem(info, SH_OP_MEM_REG_PRE, r, 0, 32, detail);
|
|
706
|
+
return MCDisassembler_Success;
|
|
707
|
+
} else {
|
|
708
|
+
return MCDisassembler_Fail;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
static bool op4xx4(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
713
|
+
sh_info *info, cs_detail *detail)
|
|
714
|
+
{
|
|
715
|
+
int r = (code >> 8) & 0x0f;
|
|
716
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
717
|
+
static const struct ri_list list[] = {
|
|
718
|
+
{0, SH_INS_ROTL, ISA_ALL, none},
|
|
719
|
+
{1, SH_INS_SETRC, ISA_ALL, shdsp},
|
|
720
|
+
{2, SH_INS_ROTCL, ISA_ALL, none},
|
|
721
|
+
{3, SH_INS_LDRC, ISA_ALL, shdsp},
|
|
722
|
+
{8, SH_INS_DIVU, -(ISA_SH2A), none},
|
|
723
|
+
{9, SH_INS_DIVS, -(ISA_SH2A), none},
|
|
724
|
+
{15, SH_INS_MOVMU, -(ISA_SH2A), none},
|
|
725
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
726
|
+
};
|
|
727
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
728
|
+
if (insn != SH_INS_INVALID) {
|
|
729
|
+
MCInst_setOpcode(MI, insn);
|
|
730
|
+
switch(insn_code) {
|
|
731
|
+
case 8:
|
|
732
|
+
case 9:
|
|
733
|
+
set_reg(info, SH_REG_R0, read, detail);
|
|
734
|
+
break;
|
|
735
|
+
case 15:
|
|
736
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R15, 0,
|
|
737
|
+
32, detail);
|
|
738
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
739
|
+
return MCDisassembler_Success;
|
|
740
|
+
}
|
|
741
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
742
|
+
return MCDisassembler_Success;
|
|
743
|
+
} else {
|
|
744
|
+
return MCDisassembler_Fail;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
static bool op4xx5(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
749
|
+
sh_info *info, cs_detail *detail)
|
|
750
|
+
{
|
|
751
|
+
int r = (code >> 8) & 0x0f;
|
|
752
|
+
enum direction rw = read;
|
|
753
|
+
static const struct ri_list list[] = {
|
|
754
|
+
{0, SH_INS_ROTR, ISA_ALL, none},
|
|
755
|
+
{1, SH_INS_CMP_PL, ISA_ALL, none},
|
|
756
|
+
{2, SH_INS_ROTCR, ISA_ALL, none},
|
|
757
|
+
{8, SH_INS_CLIPU, -(ISA_SH2A), none},
|
|
758
|
+
{9, SH_INS_CLIPS, -(ISA_SH2A), none},
|
|
759
|
+
{14, SH_INS_LDBANK, -(ISA_SH2A), none},
|
|
760
|
+
{15, SH_INS_MOVML, -(ISA_SH2A), none},
|
|
761
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
762
|
+
};
|
|
763
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
764
|
+
sh_insn insn = lookup_insn(list, insn_code,mode);
|
|
765
|
+
if (insn != SH_INS_INVALID) {
|
|
766
|
+
MCInst_setOpcode(MI, insn);
|
|
767
|
+
switch (insn_code) {
|
|
768
|
+
case 0:
|
|
769
|
+
case 2:
|
|
770
|
+
rw = write;
|
|
771
|
+
break;
|
|
772
|
+
case 1:
|
|
773
|
+
rw = read;
|
|
774
|
+
break;
|
|
775
|
+
case 8:
|
|
776
|
+
case 9:
|
|
777
|
+
info->op.size = 16;
|
|
778
|
+
rw = write;
|
|
779
|
+
break;
|
|
780
|
+
case 0x0e:
|
|
781
|
+
set_mem(info, SH_OP_MEM_REG_IND, SH_REG_R0 + r, 0,
|
|
782
|
+
0, detail);
|
|
783
|
+
set_reg(info, SH_REG_R0, write, detail);
|
|
784
|
+
return MCDisassembler_Success;
|
|
785
|
+
case 0x0f:
|
|
786
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R15, 0,
|
|
787
|
+
32, detail);
|
|
788
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
789
|
+
return MCDisassembler_Success;
|
|
790
|
+
}
|
|
791
|
+
set_reg(info, SH_REG_R0 + r, rw, detail);
|
|
792
|
+
return MCDisassembler_Success;
|
|
793
|
+
} else {
|
|
794
|
+
return MCDisassembler_Fail;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
static bool opLDCLDS(uint16_t code, MCInst *MI, cs_mode mode,
|
|
799
|
+
sh_info *info, cs_detail *detail)
|
|
800
|
+
{
|
|
801
|
+
int d = (code >> 4) & 0x0f;
|
|
802
|
+
sh_reg reg = lookup_regs(sts_lds_regs, d, mode);
|
|
803
|
+
sh_insn insn;
|
|
804
|
+
if (reg != SH_REG_INVALID) {
|
|
805
|
+
if (d == 3 || d == 4 || d == 15) {
|
|
806
|
+
insn = SH_INS_LDC;
|
|
807
|
+
} else {
|
|
808
|
+
insn = SH_INS_LDS;
|
|
809
|
+
}
|
|
810
|
+
MCInst_setOpcode(MI, insn);
|
|
811
|
+
set_reg(info, reg, write, detail);
|
|
812
|
+
return MCDisassembler_Success;
|
|
813
|
+
} else {
|
|
814
|
+
return MCDisassembler_Fail;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
static bool op4xx6(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
819
|
+
sh_info *info, cs_detail *detail)
|
|
820
|
+
{
|
|
821
|
+
int r = (code >> 8) & 0x0f;
|
|
822
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R0 + r, 0, 32, detail);
|
|
823
|
+
return opLDCLDS(code, MI, mode, info, detail);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
static bool opLDCdst(uint16_t code, MCInst *MI, cs_mode mode,
|
|
827
|
+
sh_info *info, cs_detail *detail)
|
|
828
|
+
{
|
|
829
|
+
int d = (code >> 4) & 0x0f;
|
|
830
|
+
sh_reg dreg = lookup_regs(ldc_stc_regs, d, mode);
|
|
831
|
+
if (dreg == SH_REG_INVALID)
|
|
832
|
+
return MCDisassembler_Fail;
|
|
833
|
+
MCInst_setOpcode(MI, SH_INS_LDC);
|
|
834
|
+
set_reg(info, dreg, write, detail);
|
|
835
|
+
return MCDisassembler_Success;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
static bool opLDC_L(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
839
|
+
sh_info *info, cs_detail *detail)
|
|
840
|
+
{
|
|
841
|
+
int s = (code >> 8) & 0x0f;
|
|
842
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R0 + s, 0, 32, detail);
|
|
843
|
+
return opLDCdst(code, MI, mode, info, detail);
|
|
844
|
+
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
static bool op4xx8(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
848
|
+
sh_info *info, cs_detail *detail)
|
|
849
|
+
{
|
|
850
|
+
int r = (code >> 8) & 0x0f;
|
|
851
|
+
sh_insn insn[] = { SH_INS_SHLL2, SH_INS_SHLL8, SH_INS_SHLL16};
|
|
852
|
+
int size = (code >> 4) & 0x0f;
|
|
853
|
+
if (size >= ARR_SIZE(insn)) {
|
|
854
|
+
return MCDisassembler_Fail;
|
|
855
|
+
}
|
|
856
|
+
MCInst_setOpcode(MI, insn[size]);
|
|
857
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
858
|
+
return MCDisassembler_Success;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
static bool op4xx9(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
862
|
+
sh_info *info, cs_detail *detail)
|
|
863
|
+
{
|
|
864
|
+
int r = (code >> 8) & 0x0f;
|
|
865
|
+
static const struct ri_list list[] = {
|
|
866
|
+
{0, SH_INS_SHLR2, ISA_ALL, none},
|
|
867
|
+
{1, SH_INS_SHLR8, ISA_ALL, none},
|
|
868
|
+
{2, SH_INS_SHLR16, ISA_ALL, none},
|
|
869
|
+
{10, SH_INS_MOVUA, -(ISA_SH4A), none},
|
|
870
|
+
{14, SH_INS_MOVUA, -(ISA_SH4A), none},
|
|
871
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
872
|
+
};
|
|
873
|
+
int op = (code >> 4) & 0x0f;
|
|
874
|
+
sh_insn insn = lookup_insn(list, op, mode);
|
|
875
|
+
sh_op_mem_type memop = SH_OP_MEM_INVALID;
|
|
876
|
+
if (insn != SH_INS_INVALID) {
|
|
877
|
+
MCInst_setOpcode(MI, insn);
|
|
878
|
+
if (op < 8) {
|
|
879
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
880
|
+
} else {
|
|
881
|
+
memop = (op&4)?SH_OP_MEM_REG_POST:SH_OP_MEM_REG_IND;
|
|
882
|
+
set_mem(info, memop, SH_REG_R0 + r, 0, 32, detail);
|
|
883
|
+
set_reg(info, SH_REG_R0, write, detail);
|
|
884
|
+
}
|
|
885
|
+
return MCDisassembler_Success;
|
|
886
|
+
} else {
|
|
887
|
+
return MCDisassembler_Fail;
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
static bool op4xxa(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
892
|
+
sh_info *info, cs_detail *detail)
|
|
893
|
+
{
|
|
894
|
+
int r = (code >> 8) & 0x0f;
|
|
895
|
+
set_reg(info, SH_REG_R0 + r, read, detail);
|
|
896
|
+
return opLDCLDS(code, MI, mode, info, detail);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
static bool op4xxb(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
900
|
+
sh_info *info, cs_detail *detail)
|
|
901
|
+
{
|
|
902
|
+
int r = (code >> 8) & 0x0f;
|
|
903
|
+
int insn_code = (code >> 4) & 0x0f;
|
|
904
|
+
int sz = 0;
|
|
905
|
+
int grp = SH_GRP_INVALID;
|
|
906
|
+
sh_op_mem_type memop = SH_OP_MEM_INVALID;
|
|
907
|
+
enum direction rw = read;
|
|
908
|
+
static const struct ri_list list[] = {
|
|
909
|
+
{0, SH_INS_JSR, ISA_ALL, none},
|
|
910
|
+
{1, SH_INS_TAS, ISA_ALL, none},
|
|
911
|
+
{2, SH_INS_JMP, ISA_ALL, none},
|
|
912
|
+
{4, SH_INS_JSR_N, -(ISA_SH2A), none},
|
|
913
|
+
{8, SH_INS_MOV, -(ISA_SH2A), none},
|
|
914
|
+
{9, SH_INS_MOV, -(ISA_SH2A), none},
|
|
915
|
+
{10, SH_INS_MOV, -(ISA_SH2A), none},
|
|
916
|
+
{12, SH_INS_MOV, -(ISA_SH2A), none},
|
|
917
|
+
{13, SH_INS_MOV, -(ISA_SH2A), none},
|
|
918
|
+
{14, SH_INS_MOV, -(ISA_SH2A), none},
|
|
919
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
920
|
+
};
|
|
921
|
+
sh_insn insn = lookup_insn(list, insn_code, mode);
|
|
922
|
+
if (insn != SH_INS_INVALID) {
|
|
923
|
+
MCInst_setOpcode(MI, insn);
|
|
924
|
+
sz = 8 << ((code >> 4) & 3);
|
|
925
|
+
switch (insn_code) {
|
|
926
|
+
case 0:
|
|
927
|
+
case 4:
|
|
928
|
+
memop = SH_OP_MEM_REG_IND;
|
|
929
|
+
grp = SH_GRP_CALL;
|
|
930
|
+
break;
|
|
931
|
+
case 1:
|
|
932
|
+
memop = SH_OP_MEM_REG_IND;
|
|
933
|
+
sz = 8;
|
|
934
|
+
rw = write;
|
|
935
|
+
break;
|
|
936
|
+
case 2:
|
|
937
|
+
insn = SH_INS_JMP;
|
|
938
|
+
grp = SH_GRP_JUMP;
|
|
939
|
+
break;
|
|
940
|
+
case 8:
|
|
941
|
+
case 9:
|
|
942
|
+
case 10:
|
|
943
|
+
memop = SH_OP_MEM_REG_POST;
|
|
944
|
+
rw = read;
|
|
945
|
+
break;
|
|
946
|
+
case 12:
|
|
947
|
+
case 13:
|
|
948
|
+
case 14:
|
|
949
|
+
memop = SH_OP_MEM_REG_PRE;
|
|
950
|
+
rw = write;
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
if (grp != SH_GRP_INVALID) {
|
|
954
|
+
set_mem(info, SH_OP_MEM_REG_IND, SH_REG_R0 + r, 0,
|
|
955
|
+
0, detail);
|
|
956
|
+
if (detail)
|
|
957
|
+
set_groups(detail, 1, grp);
|
|
958
|
+
} else {
|
|
959
|
+
if (insn_code != 1) {
|
|
960
|
+
set_reg_n(info, SH_REG_R0, rw, rw, detail);
|
|
961
|
+
info->op.op_count++;
|
|
962
|
+
}
|
|
963
|
+
set_mem_n(info, memop, SH_REG_R0 + r, 0, sz,
|
|
964
|
+
1 - rw, detail);
|
|
965
|
+
info->op.op_count++;
|
|
966
|
+
}
|
|
967
|
+
return MCDisassembler_Success;
|
|
968
|
+
} else {
|
|
969
|
+
return MCDisassembler_Fail;
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
/* SHAD / SHLD - SH2A */
|
|
974
|
+
opRR(ISA_SH2A, SHAD, 0)
|
|
975
|
+
opRR(ISA_SH2A, SHLD, 0)
|
|
976
|
+
|
|
977
|
+
static bool opLDC(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
978
|
+
sh_info *info, cs_detail *detail)
|
|
979
|
+
{
|
|
980
|
+
int s = (code >> 8) & 0x0f;
|
|
981
|
+
set_reg(info, SH_REG_R0 + s, read, detail);
|
|
982
|
+
return opLDCdst(code, MI, mode, info, detail);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
opRR(ISA_ALL, MOV, 0)
|
|
986
|
+
|
|
987
|
+
static bool opMOV_rpi(uint16_t code, uint64_t address, MCInst *MI,
|
|
988
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
989
|
+
{
|
|
990
|
+
int sz = (code & 0x03);
|
|
991
|
+
nm(code, 0);
|
|
992
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
993
|
+
set_mem(info, SH_OP_MEM_REG_POST, SH_REG_R0 + m, 0, 8 << sz, detail);
|
|
994
|
+
set_reg(info, SH_REG_R0 + n, write, detail);
|
|
995
|
+
return MCDisassembler_Success;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
opRR(ISA_ALL, NOT, 0)
|
|
999
|
+
opRR(ISA_ALL, SWAP_B, 8)
|
|
1000
|
+
opRR(ISA_ALL, SWAP_W, 16)
|
|
1001
|
+
opRR(ISA_ALL, NEGC, 0)
|
|
1002
|
+
opRR(ISA_ALL, NEG, 0)
|
|
1003
|
+
opRR(ISA_ALL, EXTU_B, 8)
|
|
1004
|
+
opRR(ISA_ALL, EXTU_W, 16)
|
|
1005
|
+
opRR(ISA_ALL, EXTS_B, 8)
|
|
1006
|
+
opRR(ISA_ALL, EXTS_W, 16)
|
|
1007
|
+
|
|
1008
|
+
static bool opADD_i(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1009
|
+
sh_info *info, cs_detail *detail)
|
|
1010
|
+
{
|
|
1011
|
+
int r = (code >> 8) & 0x0f;
|
|
1012
|
+
MCInst_setOpcode(MI, SH_INS_ADD);
|
|
1013
|
+
set_imm(info, 1, code & 0xff);
|
|
1014
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
1015
|
+
return MCDisassembler_Success;
|
|
1016
|
+
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
static bool opMOV_BW_dsp(uint16_t code, uint64_t address, MCInst *MI,
|
|
1020
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
1021
|
+
{
|
|
1022
|
+
int dsp = (code & 0x0f);
|
|
1023
|
+
int r = (code >> 4) & 0x0f;
|
|
1024
|
+
int size = 1 + ((code >> 8) & 1);
|
|
1025
|
+
int rw = (code >> 10) & 1;
|
|
1026
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
1027
|
+
set_mem_n(info, SH_OP_MEM_REG_DISP, SH_REG_R0 + r, dsp * size,
|
|
1028
|
+
8 * size, 1 - rw, detail);
|
|
1029
|
+
set_reg_n(info, SH_REG_R0, rw, rw, detail);
|
|
1030
|
+
info->op.op_count = 2;
|
|
1031
|
+
return MCDisassembler_Success;
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
static bool opSETRC(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1035
|
+
sh_info *info, cs_detail *detail)
|
|
1036
|
+
{
|
|
1037
|
+
int imm = code & 0xff;
|
|
1038
|
+
if (!(mode & CS_MODE_SHDSP))
|
|
1039
|
+
return MCDisassembler_Fail;
|
|
1040
|
+
MCInst_setOpcode(MI, SH_INS_SETRC);
|
|
1041
|
+
set_imm(info, 0, imm);
|
|
1042
|
+
return MCDisassembler_Success;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
static bool opJSR_N(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1046
|
+
sh_info *info, cs_detail *detail)
|
|
1047
|
+
{
|
|
1048
|
+
int dsp = code & 0xff;
|
|
1049
|
+
if (isalevel(mode) != ISA_SH2A)
|
|
1050
|
+
return MCDisassembler_Fail;
|
|
1051
|
+
MCInst_setOpcode(MI, SH_INS_JSR_N);
|
|
1052
|
+
set_mem(info, SH_OP_MEM_TBR_DISP, SH_REG_INVALID, dsp * 4, 0, detail);
|
|
1053
|
+
return MCDisassembler_Success;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
#define boperand(_code, _op, _imm, _reg) \
|
|
1057
|
+
int _op = (code >> 3) & 1; \
|
|
1058
|
+
int _imm = code & 7; \
|
|
1059
|
+
int _reg = (code >> 4) & 0x0f
|
|
1060
|
+
|
|
1061
|
+
static bool op86xx(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1062
|
+
sh_info *info, cs_detail *detail)
|
|
1063
|
+
{
|
|
1064
|
+
static const sh_insn bop[] = {SH_INS_BCLR, SH_INS_BSET};
|
|
1065
|
+
boperand(code, op, imm, reg);
|
|
1066
|
+
if (isalevel(mode) != ISA_SH2A)
|
|
1067
|
+
return MCDisassembler_Fail;
|
|
1068
|
+
MCInst_setOpcode(MI, bop[op]);
|
|
1069
|
+
set_imm(info, 0, imm);
|
|
1070
|
+
set_reg(info, SH_REG_R0 + reg, write, detail);
|
|
1071
|
+
return MCDisassembler_Success;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
static bool op87xx(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1075
|
+
sh_info *info, cs_detail *detail)
|
|
1076
|
+
{
|
|
1077
|
+
static const sh_insn bop[] = {SH_INS_BST, SH_INS_BLD};
|
|
1078
|
+
boperand(code, op, imm, reg);
|
|
1079
|
+
if (isalevel(mode) != ISA_SH2A)
|
|
1080
|
+
return MCDisassembler_Fail;
|
|
1081
|
+
MCInst_setOpcode(MI, bop[op]);
|
|
1082
|
+
set_imm(info, 0, imm);
|
|
1083
|
+
set_reg(info, SH_REG_R0 + reg, op?read:write, detail);
|
|
1084
|
+
return MCDisassembler_Success;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
static bool opCMP_EQi(uint16_t code, uint64_t address, MCInst *MI,
|
|
1088
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
1089
|
+
{
|
|
1090
|
+
MCInst_setOpcode(MI, SH_INS_CMP_EQ);
|
|
1091
|
+
set_imm(info, 1, code & 0x00ff);
|
|
1092
|
+
set_reg(info, SH_REG_R0, read, detail);
|
|
1093
|
+
return MCDisassembler_Success;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
#define opBranch(level, insn) \
|
|
1097
|
+
static bool op##insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1098
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1099
|
+
{ \
|
|
1100
|
+
int dsp = code & 0x00ff; \
|
|
1101
|
+
if (level > isalevel(mode)) \
|
|
1102
|
+
return MCDisassembler_Fail; \
|
|
1103
|
+
if (dsp >= 0x80) \
|
|
1104
|
+
dsp = -256 + dsp; \
|
|
1105
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1106
|
+
set_mem(info, SH_OP_MEM_PCR, SH_REG_INVALID, address + 4 + dsp * 2, \
|
|
1107
|
+
0, detail); \
|
|
1108
|
+
if (detail) \
|
|
1109
|
+
set_groups(detail, 2, SH_GRP_JUMP, SH_GRP_BRANCH_RELATIVE); \
|
|
1110
|
+
return MCDisassembler_Success; \
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
opBranch(ISA_ALL, BT)
|
|
1114
|
+
opBranch(ISA_ALL, BF)
|
|
1115
|
+
/* bt/s / bf/s - SH2 */
|
|
1116
|
+
opBranch(ISA_SH2, BT_S)
|
|
1117
|
+
opBranch(ISA_SH2, BF_S)
|
|
1118
|
+
|
|
1119
|
+
#define opLDRSE(insn) \
|
|
1120
|
+
static bool op##insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1121
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1122
|
+
{ \
|
|
1123
|
+
int dsp = code & 0xff; \
|
|
1124
|
+
if (!(mode & CS_MODE_SHDSP)) \
|
|
1125
|
+
return MCDisassembler_Fail; \
|
|
1126
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1127
|
+
set_mem(info, SH_OP_MEM_PCR, SH_REG_INVALID, address + 4 + dsp * 2, \
|
|
1128
|
+
0, detail); \
|
|
1129
|
+
return MCDisassembler_Success;\
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
static bool opLDRC(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1133
|
+
sh_info *info, cs_detail *detail)
|
|
1134
|
+
{
|
|
1135
|
+
int imm = code & 0xff;
|
|
1136
|
+
if (!(mode & CS_MODE_SHDSP) || isalevel(mode) != ISA_SH4A)
|
|
1137
|
+
return MCDisassembler_Fail;
|
|
1138
|
+
MCInst_setOpcode(MI, SH_INS_LDRC);
|
|
1139
|
+
set_imm(info, 0, imm);
|
|
1140
|
+
return MCDisassembler_Success;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
opLDRSE(LDRS)
|
|
1144
|
+
opLDRSE(LDRE)
|
|
1145
|
+
|
|
1146
|
+
#define opImmR0(insn) \
|
|
1147
|
+
static bool op##insn##_i(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1148
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1149
|
+
{ \
|
|
1150
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1151
|
+
set_imm(info, 0, code & 0xff); \
|
|
1152
|
+
set_reg(info, SH_REG_R0, write, detail); \
|
|
1153
|
+
return MCDisassembler_Success; \
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
opImmR0(TST)
|
|
1157
|
+
opImmR0(AND)
|
|
1158
|
+
opImmR0(XOR)
|
|
1159
|
+
opImmR0(OR)
|
|
1160
|
+
|
|
1161
|
+
#define opImmMem(insn) \
|
|
1162
|
+
static bool op##insn##_B(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1163
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1164
|
+
{ \
|
|
1165
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1166
|
+
set_imm(info, 0, code & 0xff); \
|
|
1167
|
+
set_mem(info, SH_OP_MEM_GBR_R0, SH_REG_R0, 0, 8, detail); \
|
|
1168
|
+
return MCDisassembler_Success; \
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
opImmMem(TST)
|
|
1172
|
+
opImmMem(AND)
|
|
1173
|
+
opImmMem(XOR)
|
|
1174
|
+
opImmMem(OR)
|
|
1175
|
+
|
|
1176
|
+
static bool opMOV_pc(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1177
|
+
sh_info *info, cs_detail *detail)
|
|
1178
|
+
{
|
|
1179
|
+
int sz = 16 << ((code >> 14) & 1);
|
|
1180
|
+
int dsp = (code & 0x00ff) * (sz / 8);
|
|
1181
|
+
int r = (code >> 8) & 0x0f;
|
|
1182
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
1183
|
+
if (sz == 32)
|
|
1184
|
+
address &= ~3;
|
|
1185
|
+
set_mem(info, SH_OP_MEM_PCR, SH_REG_INVALID, address + 4 + dsp,
|
|
1186
|
+
sz, detail);
|
|
1187
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
1188
|
+
return MCDisassembler_Success;
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
#define opBxx(insn, grp) \
|
|
1192
|
+
static bool op##insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1193
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1194
|
+
{ \
|
|
1195
|
+
int dsp = (code & 0x0fff); \
|
|
1196
|
+
if (dsp >= 0x800) \
|
|
1197
|
+
dsp = -0x1000 + dsp; \
|
|
1198
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1199
|
+
set_mem(info, SH_OP_MEM_PCR, SH_REG_INVALID, address + 4 + dsp * 2, \
|
|
1200
|
+
0, detail); \
|
|
1201
|
+
if (detail) \
|
|
1202
|
+
set_groups(detail, 2, grp, SH_GRP_BRANCH_RELATIVE); \
|
|
1203
|
+
return MCDisassembler_Success; \
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
opBxx(BRA, SH_GRP_JUMP)
|
|
1207
|
+
opBxx(BSR, SH_GRP_CALL)
|
|
1208
|
+
|
|
1209
|
+
static bool opMOV_gbr(uint16_t code, uint64_t address, MCInst *MI,
|
|
1210
|
+
cs_mode mode, sh_info *info, cs_detail *detail)
|
|
1211
|
+
{
|
|
1212
|
+
int sz = 8 << ((code >> 8) & 0x03);
|
|
1213
|
+
int dsp = (code & 0x00ff) * (sz / 8);
|
|
1214
|
+
int rw = (code >> 10) & 1;
|
|
1215
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
1216
|
+
set_mem_n(info, SH_OP_MEM_GBR_DISP, SH_REG_GBR, dsp, sz,
|
|
1217
|
+
1 - rw, detail);
|
|
1218
|
+
set_reg_n(info, SH_REG_R0, rw, rw, detail);
|
|
1219
|
+
info->op.op_count = 2;
|
|
1220
|
+
return MCDisassembler_Success;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
static bool opTRAPA(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1224
|
+
sh_info *info, cs_detail *detail)
|
|
1225
|
+
{
|
|
1226
|
+
MCInst_setOpcode(MI, SH_INS_TRAPA);
|
|
1227
|
+
set_imm(info, 0, code & 0xff);
|
|
1228
|
+
if (detail)
|
|
1229
|
+
set_groups(detail, 1, SH_GRP_INT);
|
|
1230
|
+
return MCDisassembler_Success;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1233
|
+
static bool opMOVA(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1234
|
+
sh_info *info, cs_detail *detail)
|
|
1235
|
+
{
|
|
1236
|
+
int dsp = (code & 0x00ff) * 4;
|
|
1237
|
+
MCInst_setOpcode(MI, SH_INS_MOVA);
|
|
1238
|
+
set_mem(info, SH_OP_MEM_PCR, SH_REG_INVALID, (address & ~3) + 4 + dsp,
|
|
1239
|
+
0, detail);
|
|
1240
|
+
set_reg(info, SH_REG_R0, write, detail);
|
|
1241
|
+
return MCDisassembler_Success;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
static bool opMOV_i(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1245
|
+
sh_info *info, cs_detail *detail)
|
|
1246
|
+
{
|
|
1247
|
+
int imm = (code & 0x00ff);
|
|
1248
|
+
int r = (code >> 8) & 0x0f;
|
|
1249
|
+
MCInst_setOpcode(MI, SH_INS_MOV);
|
|
1250
|
+
set_imm(info, 1, imm);
|
|
1251
|
+
set_reg(info, SH_REG_R0 + r, write, detail);
|
|
1252
|
+
return MCDisassembler_Success;
|
|
1253
|
+
}
|
|
1254
|
+
|
|
1255
|
+
/* FPU instructions */
|
|
1256
|
+
#define opFRR(insn) \
|
|
1257
|
+
static bool op##insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1258
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1259
|
+
{ \
|
|
1260
|
+
int m = (code >> 4) & 0x0f; \
|
|
1261
|
+
int n = (code >> 8) & 0x0f; \
|
|
1262
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1263
|
+
set_reg(info, SH_REG_FR0 + m, read, detail); \
|
|
1264
|
+
set_reg(info, SH_REG_FR0 + n, write, detail); \
|
|
1265
|
+
return MCDisassembler_Success; \
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
#define opFRRcmp(insn) \
|
|
1269
|
+
static bool op##insn(uint16_t code, uint64_t address, MCInst *MI, \
|
|
1270
|
+
cs_mode mode, sh_info *info, cs_detail *detail) \
|
|
1271
|
+
{ \
|
|
1272
|
+
int m = (code >> 4) & 0x0f; \
|
|
1273
|
+
int n = (code >> 8) & 0x0f; \
|
|
1274
|
+
MCInst_setOpcode(MI, SH_INS_##insn); \
|
|
1275
|
+
set_reg(info, SH_REG_FR0 + m, read, detail); \
|
|
1276
|
+
set_reg(info, SH_REG_FR0 + n, read, detail); \
|
|
1277
|
+
return MCDisassembler_Success; \
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
opFRR(FADD)
|
|
1281
|
+
opFRR(FSUB)
|
|
1282
|
+
opFRR(FMUL)
|
|
1283
|
+
opFRR(FDIV)
|
|
1284
|
+
opFRRcmp(FCMP_EQ)
|
|
1285
|
+
opFRRcmp(FCMP_GT)
|
|
1286
|
+
|
|
1287
|
+
static bool opFMOVm(MCInst *MI, enum direction rw, uint16_t code,
|
|
1288
|
+
sh_op_mem_type address, sh_info *info, cs_detail *detail)
|
|
1289
|
+
{
|
|
1290
|
+
nm(code, (1 - rw));
|
|
1291
|
+
MCInst_setOpcode(MI, SH_INS_FMOV);
|
|
1292
|
+
set_mem_n(info, address, SH_REG_R0 + m, 0, 0, 1 - rw, detail);
|
|
1293
|
+
set_reg_n(info, SH_REG_FR0 + n, rw, rw, detail);
|
|
1294
|
+
info->op.op_count = 2;
|
|
1295
|
+
return MCDisassembler_Success;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
static bool opfxx6(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1299
|
+
sh_info *info, cs_detail *detail)
|
|
1300
|
+
{
|
|
1301
|
+
return opFMOVm(MI, write, code, SH_OP_MEM_REG_R0, info, detail);
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
static bool opfxx7(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1305
|
+
sh_info *info, cs_detail *detail)
|
|
1306
|
+
{
|
|
1307
|
+
return opFMOVm(MI, read, code, SH_OP_MEM_REG_R0, info, detail);
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
static bool opfxx8(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1311
|
+
sh_info *info, cs_detail *detail)
|
|
1312
|
+
{
|
|
1313
|
+
return opFMOVm(MI, write, code, SH_OP_MEM_REG_IND, info, detail);
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
static bool opfxx9(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1317
|
+
sh_info *info, cs_detail *detail)
|
|
1318
|
+
{
|
|
1319
|
+
return opFMOVm(MI, write, code, SH_OP_MEM_REG_POST, info, detail);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
static bool opfxxa(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1323
|
+
sh_info *info, cs_detail *detail)
|
|
1324
|
+
{
|
|
1325
|
+
return opFMOVm(MI, read, code, SH_OP_MEM_REG_IND, info, detail);
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
static bool opfxxb(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1329
|
+
sh_info *info, cs_detail *detail)
|
|
1330
|
+
{
|
|
1331
|
+
return opFMOVm(MI, read, code, SH_OP_MEM_REG_PRE, info, detail);
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
static bool opFMOV(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1335
|
+
sh_info *info, cs_detail *detail)
|
|
1336
|
+
{
|
|
1337
|
+
nm(code, 0);
|
|
1338
|
+
MCInst_setOpcode(MI, SH_INS_FMOV);
|
|
1339
|
+
set_reg(info, SH_REG_FR0 + m, read, detail);
|
|
1340
|
+
set_reg(info, SH_REG_FR0 + n, write, detail);
|
|
1341
|
+
return MCDisassembler_Success;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
static bool opfxxd(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1345
|
+
sh_info *info, cs_detail *detail)
|
|
1346
|
+
{
|
|
1347
|
+
int fr = (code >> 8) & 0x0f;
|
|
1348
|
+
int dr = (code >> 9) & 0x07;
|
|
1349
|
+
int fvn = (code >> 10) & 0x03;
|
|
1350
|
+
int fvm = (code >> 8) & 0x03;
|
|
1351
|
+
sh_insn insn = SH_INS_INVALID;
|
|
1352
|
+
sh_reg s, d;
|
|
1353
|
+
static const struct ri_list list[] = {
|
|
1354
|
+
{0, SH_INS_FSTS, ISA_ALL, shfpu},
|
|
1355
|
+
{1, SH_INS_FLDS, ISA_ALL, shfpu},
|
|
1356
|
+
{2, SH_INS_FLOAT, ISA_ALL, shfpu},
|
|
1357
|
+
{3, SH_INS_FTRC, ISA_ALL, shfpu},
|
|
1358
|
+
{4, SH_INS_FNEG, ISA_ALL, shfpu},
|
|
1359
|
+
{5, SH_INS_FABS, ISA_ALL, shfpu},
|
|
1360
|
+
{6, SH_INS_FSQRT, ISA_ALL, shfpu},
|
|
1361
|
+
{7, SH_INS_FSRRA, ISA_ALL, shfpu},
|
|
1362
|
+
{8, SH_INS_FLDI0, ISA_ALL, shfpu},
|
|
1363
|
+
{9, SH_INS_FLDI1, ISA_ALL, shfpu},
|
|
1364
|
+
{10, SH_INS_FCNVSD, ISA_SH4A, shfpu},
|
|
1365
|
+
{11, SH_INS_FCNVDS, ISA_SH4A, shfpu},
|
|
1366
|
+
{14, SH_INS_FIPR, ISA_SH4A, shfpu},
|
|
1367
|
+
{-1, SH_INS_INVALID, ISA_ALL, none},
|
|
1368
|
+
};
|
|
1369
|
+
static const sh_insn chg[] = {
|
|
1370
|
+
SH_INS_FSCHG, SH_INS_FPCHG, SH_INS_FRCHG, SH_INS_INVALID
|
|
1371
|
+
};
|
|
1372
|
+
insn = lookup_insn(list, (code >> 4) & 0x0f, mode);
|
|
1373
|
+
s = d = SH_REG_FPUL;
|
|
1374
|
+
if (insn != SH_INS_INVALID) {
|
|
1375
|
+
switch((code >> 4) & 0x0f) {
|
|
1376
|
+
case 0:
|
|
1377
|
+
case 2:
|
|
1378
|
+
d = SH_REG_FR0 + fr;
|
|
1379
|
+
break;
|
|
1380
|
+
case 1:
|
|
1381
|
+
case 3:
|
|
1382
|
+
s = SH_REG_FR0 + fr;
|
|
1383
|
+
break;
|
|
1384
|
+
case 10:
|
|
1385
|
+
d = SH_REG_DR0 + dr;
|
|
1386
|
+
break;
|
|
1387
|
+
case 11:
|
|
1388
|
+
s = SH_REG_DR0 + dr;
|
|
1389
|
+
break;
|
|
1390
|
+
case 14:
|
|
1391
|
+
s = SH_REG_FV0 + fvm;
|
|
1392
|
+
d = SH_REG_FV0 + fvn;
|
|
1393
|
+
break;
|
|
1394
|
+
default:
|
|
1395
|
+
s = SH_REG_FR0 + fr;
|
|
1396
|
+
d = SH_REG_INVALID;
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
} else if ((code & 0x00f0) == 0x00f0) {
|
|
1400
|
+
if ((code & 0x01ff) == 0x00fd) {
|
|
1401
|
+
insn = SH_INS_FSCA;
|
|
1402
|
+
d = SH_REG_DR0 + dr;
|
|
1403
|
+
}
|
|
1404
|
+
if ((code & 0x03ff) == 0x01fd) {
|
|
1405
|
+
insn = SH_INS_FTRV;
|
|
1406
|
+
s = SH_REG_XMATRX;
|
|
1407
|
+
d = SH_REG_FV0 + fvn;
|
|
1408
|
+
}
|
|
1409
|
+
if ((code & 0x03ff) == 0x03fd) {
|
|
1410
|
+
insn = chg[(code >> 10) & 3];
|
|
1411
|
+
s = d = SH_REG_INVALID;
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
if (insn == SH_INS_INVALID) {
|
|
1415
|
+
return MCDisassembler_Fail;
|
|
1416
|
+
}
|
|
1417
|
+
MCInst_setOpcode(MI, insn);
|
|
1418
|
+
if (s != SH_REG_INVALID) {
|
|
1419
|
+
set_reg(info, s, read, detail);
|
|
1420
|
+
}
|
|
1421
|
+
if (d != SH_REG_INVALID) {
|
|
1422
|
+
set_reg(info, d, write, detail);
|
|
1423
|
+
}
|
|
1424
|
+
return MCDisassembler_Success;
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
static bool opFMAC(uint16_t code, uint64_t address, MCInst *MI, cs_mode mode,
|
|
1428
|
+
sh_info *info, cs_detail *detail)
|
|
1429
|
+
{
|
|
1430
|
+
int m = (code >> 4) & 0x0f;
|
|
1431
|
+
int n = (code >> 8) & 0x0f;
|
|
1432
|
+
MCInst_setOpcode(MI, SH_INS_FMAC);
|
|
1433
|
+
set_reg(info, SH_REG_FR0, read, detail);
|
|
1434
|
+
set_reg(info, SH_REG_FR0 + m, read, detail);
|
|
1435
|
+
set_reg(info, SH_REG_FR0 + n, write, detail);
|
|
1436
|
+
return MCDisassembler_Success;
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
#include "SHInsnTable.inc"
|
|
1440
|
+
|
|
1441
|
+
static bool decode_long(uint32_t code, uint64_t address, MCInst *MI,
|
|
1442
|
+
sh_info *info, cs_detail *detail)
|
|
1443
|
+
{
|
|
1444
|
+
uint32_t imm;
|
|
1445
|
+
sh_insn insn = SH_INS_INVALID;
|
|
1446
|
+
int m,n;
|
|
1447
|
+
int dsp;
|
|
1448
|
+
int sz;
|
|
1449
|
+
static const sh_insn bop[] = {
|
|
1450
|
+
SH_INS_BCLR, SH_INS_BSET, SH_INS_BST, SH_INS_BLD,
|
|
1451
|
+
SH_INS_BAND, SH_INS_BOR, SH_INS_BXOR, SH_INS_INVALID,
|
|
1452
|
+
SH_INS_INVALID, SH_INS_INVALID, SH_INS_INVALID, SH_INS_BLDNOT,
|
|
1453
|
+
SH_INS_BANDNOT, SH_INS_BORNOT, SH_INS_INVALID, SH_INS_INVALID,
|
|
1454
|
+
};
|
|
1455
|
+
switch (code >> 28) {
|
|
1456
|
+
case 0x0:
|
|
1457
|
+
imm = ((code >> 4) & 0x000f0000) | (code & 0xffff);
|
|
1458
|
+
n = (code >> 24) & 0x0f;
|
|
1459
|
+
if (code & 0x00010000) {
|
|
1460
|
+
// movi20s #imm,
|
|
1461
|
+
imm <<= 8;
|
|
1462
|
+
if (imm & (1 << (28 - 1)))
|
|
1463
|
+
imm |= ~((1 << 28) - 1);
|
|
1464
|
+
insn = SH_INS_MOVI20S;
|
|
1465
|
+
} else {
|
|
1466
|
+
// MOVI20
|
|
1467
|
+
if (imm & (1 << (28 - 1)))
|
|
1468
|
+
imm |= ~((1 << 20) - 1);
|
|
1469
|
+
insn = SH_INS_MOVI20;
|
|
1470
|
+
}
|
|
1471
|
+
set_imm(info, 0, imm);
|
|
1472
|
+
set_reg(info, SH_REG_R0 + n, write, detail);
|
|
1473
|
+
break;
|
|
1474
|
+
case 0x3:
|
|
1475
|
+
n = (code >> 24) & 0x0f;
|
|
1476
|
+
m = (code >> 20) & 0x0f;
|
|
1477
|
+
sz = (code >> 12) & 0x03;
|
|
1478
|
+
dsp = code & 0xfff;
|
|
1479
|
+
if (!(code & 0x80000)) {
|
|
1480
|
+
dsp <<= sz;
|
|
1481
|
+
switch((code >> 14) & 0x3) {
|
|
1482
|
+
case 0: // mov.[bwl] Rm,@(disp,Rn)
|
|
1483
|
+
// fmov.s DRm,@(disp,Rn)
|
|
1484
|
+
if (sz < 3) {
|
|
1485
|
+
insn = SH_INS_MOV;
|
|
1486
|
+
set_reg(info, SH_REG_R0 + m,
|
|
1487
|
+
read, detail);
|
|
1488
|
+
} else {
|
|
1489
|
+
insn = SH_INS_FMOV;
|
|
1490
|
+
set_reg(info, SH_REG_DR0 + (m >> 1),
|
|
1491
|
+
read, detail);
|
|
1492
|
+
}
|
|
1493
|
+
set_mem(info, SH_OP_MEM_REG_DISP,
|
|
1494
|
+
SH_REG_R0 + n, dsp, 8 << sz, detail);
|
|
1495
|
+
break;
|
|
1496
|
+
case 1: // mov.[bwl] @(disp,Rm),Rn
|
|
1497
|
+
// fmov.s @(disp,Rm),DRn
|
|
1498
|
+
set_mem(info, SH_OP_MEM_REG_DISP,
|
|
1499
|
+
SH_REG_R0 + m, dsp, 8 << sz, detail);
|
|
1500
|
+
if (sz < 3) {
|
|
1501
|
+
insn = SH_INS_MOV;
|
|
1502
|
+
set_reg(info, SH_REG_R0 + n,
|
|
1503
|
+
write, detail);
|
|
1504
|
+
} else {
|
|
1505
|
+
insn = SH_INS_FMOV;
|
|
1506
|
+
set_reg(info, SH_REG_DR0 + (n >> 1),
|
|
1507
|
+
write, detail);
|
|
1508
|
+
}
|
|
1509
|
+
break;
|
|
1510
|
+
case 2: // movu.[bwl] @(disp,Rm),Rn
|
|
1511
|
+
if (sz < 2) {
|
|
1512
|
+
insn = SH_INS_MOVU;
|
|
1513
|
+
set_mem(info, SH_OP_MEM_REG_DISP,
|
|
1514
|
+
SH_REG_R0 + m, dsp,
|
|
1515
|
+
8 << sz, detail);
|
|
1516
|
+
set_reg(info, SH_REG_R0 + n,
|
|
1517
|
+
write, detail);
|
|
1518
|
+
}
|
|
1519
|
+
break;
|
|
1520
|
+
}
|
|
1521
|
+
} else {
|
|
1522
|
+
// bitop #imm,@(disp,Rn)
|
|
1523
|
+
insn = bop[(code >> 12) & 0x0f];
|
|
1524
|
+
set_imm(info, 0, m & 7);
|
|
1525
|
+
set_mem(info, SH_OP_MEM_REG_DISP, SH_REG_R0 + n,
|
|
1526
|
+
dsp, 8, detail);
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
if (insn != SH_INS_INVALID) {
|
|
1530
|
+
MCInst_setOpcode(MI, insn);
|
|
1531
|
+
return MCDisassembler_Success;
|
|
1532
|
+
} else {
|
|
1533
|
+
return MCDisassembler_Fail;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1537
|
+
static const sh_reg dsp_areg[2][4] = {
|
|
1538
|
+
{SH_REG_R4, SH_REG_R0, SH_REG_R5, SH_REG_R1},
|
|
1539
|
+
{SH_REG_R6, SH_REG_R7, SH_REG_R2, SH_REG_R3},
|
|
1540
|
+
};
|
|
1541
|
+
|
|
1542
|
+
static bool decode_dsp_xy(sh_info *info, int xy, uint16_t code,
|
|
1543
|
+
cs_detail *detail)
|
|
1544
|
+
{
|
|
1545
|
+
int a = (code >> 8) & 3;
|
|
1546
|
+
int d = (code >> 6) & 3;
|
|
1547
|
+
int dir;
|
|
1548
|
+
int sz;
|
|
1549
|
+
int op;
|
|
1550
|
+
|
|
1551
|
+
static const sh_reg dreg[4][4] = {
|
|
1552
|
+
{SH_REG_DSP_A0, SH_REG_DSP_X0, SH_REG_DSP_A1, SH_REG_DSP_X1},
|
|
1553
|
+
{SH_REG_DSP_A0, SH_REG_DSP_A1, SH_REG_DSP_Y0, SH_REG_DSP_Y1},
|
|
1554
|
+
{SH_REG_DSP_X0, SH_REG_DSP_Y0, SH_REG_DSP_X1, SH_REG_DSP_Y1},
|
|
1555
|
+
{SH_REG_DSP_Y0, SH_REG_DSP_Y1, SH_REG_DSP_X0, SH_REG_DSP_X1},
|
|
1556
|
+
};
|
|
1557
|
+
|
|
1558
|
+
if (xy) {
|
|
1559
|
+
op = code & 3;
|
|
1560
|
+
dir = 1 - ((code >> 4) & 1);
|
|
1561
|
+
sz = (code >> 5) & 1;
|
|
1562
|
+
if (code & 0x0c) {
|
|
1563
|
+
info->op.operands[xy].dsp.insn = SH_INS_DSP_NOP;
|
|
1564
|
+
return MCDisassembler_Success;
|
|
1565
|
+
}
|
|
1566
|
+
} else {
|
|
1567
|
+
op = (code >> 2) & 3;
|
|
1568
|
+
dir = 1 - ((code >> 5) & 1);
|
|
1569
|
+
sz = (code >> 4) & 1;
|
|
1570
|
+
if (code & 0x03) {
|
|
1571
|
+
info->op.operands[xy].dsp.insn = SH_INS_DSP_NOP;
|
|
1572
|
+
return MCDisassembler_Success;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
info->op.operands[xy].dsp.size = 16 << sz;
|
|
1576
|
+
info->op.operands[xy].dsp.insn = SH_INS_DSP_MOV;
|
|
1577
|
+
info->op.operands[xy].dsp.operand[1 - dir] =
|
|
1578
|
+
SH_OP_DSP_REG_IND + (op - 1);
|
|
1579
|
+
info->op.operands[xy].dsp.operand[dir] = SH_OP_DSP_REG;
|
|
1580
|
+
info->op.operands[xy].dsp.r[1 - dir] = dsp_areg[xy][a];
|
|
1581
|
+
info->op.operands[xy].dsp.size = 16 << sz;
|
|
1582
|
+
regs_rw(detail, dir,
|
|
1583
|
+
info->op.operands[xy].dsp.r[dir] = dreg[xy * 2 + dir][d]);
|
|
1584
|
+
switch(op) {
|
|
1585
|
+
case 0x03:
|
|
1586
|
+
regs_read(detail, SH_REG_R8 + xy);
|
|
1587
|
+
// Fail through
|
|
1588
|
+
case 0x02:
|
|
1589
|
+
regs_write(detail, dsp_areg[xy][a]);
|
|
1590
|
+
break;
|
|
1591
|
+
case 0x01:
|
|
1592
|
+
regs_read(detail, dsp_areg[xy][a]);
|
|
1593
|
+
break;
|
|
1594
|
+
default:
|
|
1595
|
+
return MCDisassembler_Fail;
|
|
1596
|
+
}
|
|
1597
|
+
return MCDisassembler_Success;
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
static bool set_dsp_move_d(sh_info *info, int xy, uint16_t code, cs_mode mode, cs_detail *detail)
|
|
1601
|
+
{
|
|
1602
|
+
int a;
|
|
1603
|
+
int d;
|
|
1604
|
+
int dir;
|
|
1605
|
+
int op;
|
|
1606
|
+
static const sh_reg base[] = {SH_REG_DSP_A0, SH_REG_DSP_X0};
|
|
1607
|
+
switch (xy) {
|
|
1608
|
+
case 0:
|
|
1609
|
+
op = (code >> 2) & 3;
|
|
1610
|
+
dir = 1 - ((code >> 5) & 1);
|
|
1611
|
+
d = (code >> 7) & 1;
|
|
1612
|
+
a = (code >> 9) & 1;
|
|
1613
|
+
break;
|
|
1614
|
+
case 1:
|
|
1615
|
+
op = (code >> 0) & 3;
|
|
1616
|
+
dir = 1 - ((code >> 4) & 1);
|
|
1617
|
+
d = (code >> 6) & 1;
|
|
1618
|
+
a = (code >> 8) & 1;
|
|
1619
|
+
break;
|
|
1620
|
+
}
|
|
1621
|
+
if (op == 0x00) {
|
|
1622
|
+
if ((a || d || dir) && !(code & 0x0f))
|
|
1623
|
+
return MCDisassembler_Fail;
|
|
1624
|
+
info->op.operands[xy].dsp.insn = SH_INS_DSP_NOP;
|
|
1625
|
+
} else {
|
|
1626
|
+
info->op.operands[xy].dsp.insn = SH_INS_DSP_MOV;
|
|
1627
|
+
info->op.operands[xy].dsp.operand[1 - dir] =
|
|
1628
|
+
SH_OP_DSP_REG_IND + (op - 1);
|
|
1629
|
+
info->op.operands[xy].dsp.operand[dir] = SH_OP_DSP_REG;
|
|
1630
|
+
info->op.operands[xy].dsp.r[1 - dir] = SH_REG_R4 + xy * 2 + a;
|
|
1631
|
+
info->op.operands[xy].dsp.size = 16;
|
|
1632
|
+
regs_rw(detail, dir,
|
|
1633
|
+
info->op.operands[xy].dsp.r[dir] =
|
|
1634
|
+
base[dir] + d + dir?(xy * 2):0);
|
|
1635
|
+
switch(op) {
|
|
1636
|
+
case 0x03:
|
|
1637
|
+
regs_read(detail, SH_REG_R8 + a);
|
|
1638
|
+
// Fail through
|
|
1639
|
+
case 0x02:
|
|
1640
|
+
regs_write(detail, SH_REG_R4 + xy * 2 + a);
|
|
1641
|
+
break;
|
|
1642
|
+
case 0x01:
|
|
1643
|
+
regs_read(detail, SH_REG_R4 + xy * 2 + a);
|
|
1644
|
+
break;
|
|
1645
|
+
}
|
|
1646
|
+
}
|
|
1647
|
+
return MCDisassembler_Success;
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
static bool decode_dsp_d(const uint16_t code, MCInst *MI, cs_mode mode,
|
|
1651
|
+
sh_info *info, cs_detail *detail)
|
|
1652
|
+
{
|
|
1653
|
+
bool ret, dsp_long;
|
|
1654
|
+
MCInst_setOpcode(MI, SH_INS_DSP);
|
|
1655
|
+
if ((code & 0x3ff) == 0) {
|
|
1656
|
+
info->op.operands[0].dsp.insn =
|
|
1657
|
+
info->op.operands[1].dsp.insn = SH_INS_DSP_NOP;
|
|
1658
|
+
info->op.op_count = 2;
|
|
1659
|
+
return MCDisassembler_Success;
|
|
1660
|
+
}
|
|
1661
|
+
dsp_long = false;
|
|
1662
|
+
if (isalevel(mode) == ISA_SH4A) {
|
|
1663
|
+
if (!(code & 0x03) && (code & 0x0f) >= 0x04) {
|
|
1664
|
+
ret = decode_dsp_xy(info, 0, code, detail);
|
|
1665
|
+
ret &= set_dsp_move_d(info, 1, code, mode, detail);
|
|
1666
|
+
dsp_long |= true;
|
|
1667
|
+
}
|
|
1668
|
+
if ((code & 0x0f) <= 0x03 && (code & 0xff)) {
|
|
1669
|
+
ret = decode_dsp_xy(info, 1, code, detail);
|
|
1670
|
+
ret &= set_dsp_move_d(info, 0, code, mode, detail);
|
|
1671
|
+
dsp_long |= true;
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
if (!dsp_long) {
|
|
1675
|
+
/* X op */
|
|
1676
|
+
ret = set_dsp_move_d(info, 0, code, mode, detail);
|
|
1677
|
+
/* Y op */
|
|
1678
|
+
ret &= set_dsp_move_d(info, 1, code, mode, detail);
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
info->op.op_count = 2;
|
|
1682
|
+
return ret;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
static bool decode_dsp_s(const uint16_t code, MCInst *MI,
|
|
1686
|
+
sh_info *info, cs_detail *detail)
|
|
1687
|
+
{
|
|
1688
|
+
int d = code & 1;
|
|
1689
|
+
int s = (code >> 1) & 1;
|
|
1690
|
+
int opr = (code >> 2) & 3;
|
|
1691
|
+
int as = (code >> 8) & 3;
|
|
1692
|
+
int ds = (code >> 4) & 0x0f;
|
|
1693
|
+
static const sh_reg regs[] = {
|
|
1694
|
+
SH_REG_DSP_RSV0, SH_REG_DSP_RSV1, SH_REG_DSP_RSV2,
|
|
1695
|
+
SH_REG_DSP_RSV3,
|
|
1696
|
+
SH_REG_DSP_RSV4, SH_REG_DSP_A1, SH_REG_DSP_RSV6, SH_REG_DSP_A0,
|
|
1697
|
+
SH_REG_DSP_X0, SH_REG_DSP_X1, SH_REG_DSP_Y0, SH_REG_DSP_Y1,
|
|
1698
|
+
SH_REG_DSP_M0, SH_REG_DSP_A1G, SH_REG_DSP_M1, SH_REG_DSP_A0G,
|
|
1699
|
+
};
|
|
1700
|
+
|
|
1701
|
+
if (regs[ds] == SH_REG_INVALID)
|
|
1702
|
+
return MCDisassembler_Fail;
|
|
1703
|
+
|
|
1704
|
+
MCInst_setOpcode(MI, SH_INS_DSP);
|
|
1705
|
+
info->op.operands[0].dsp.insn = SH_INS_DSP_MOV;
|
|
1706
|
+
info->op.operands[0].dsp.operand[1 - d] = SH_OP_DSP_REG;
|
|
1707
|
+
info->op.operands[0].dsp.operand[d] = SH_OP_DSP_REG_PRE + opr;
|
|
1708
|
+
info->op.operands[0].dsp.r[1 - d] = regs[ds];
|
|
1709
|
+
info->op.operands[0].dsp.r[d] = SH_REG_R2 + ((as < 2)?(as+2):(as-2));
|
|
1710
|
+
switch (opr) {
|
|
1711
|
+
case 3:
|
|
1712
|
+
regs_read(detail, SH_REG_R8);
|
|
1713
|
+
/* Fail through */
|
|
1714
|
+
case 1:
|
|
1715
|
+
regs_read(detail, info->op.operands[0].dsp.r[d]);
|
|
1716
|
+
break;
|
|
1717
|
+
case 0:
|
|
1718
|
+
case 2:
|
|
1719
|
+
regs_write(detail, info->op.operands[0].dsp.r[d]);
|
|
1720
|
+
}
|
|
1721
|
+
regs_rw(detail, d, regs[ds]);
|
|
1722
|
+
info->op.operands[0].dsp.size = 16 << s;
|
|
1723
|
+
info->op.op_count = 1;
|
|
1724
|
+
return MCDisassembler_Success;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
static const sh_reg dsp_reg_sd[6][4] = {
|
|
1728
|
+
{SH_REG_DSP_X0, SH_REG_DSP_X1, SH_REG_DSP_Y0, SH_REG_DSP_A1},
|
|
1729
|
+
{SH_REG_DSP_Y0, SH_REG_DSP_Y1, SH_REG_DSP_X0, SH_REG_DSP_A1},
|
|
1730
|
+
{SH_REG_DSP_X0, SH_REG_DSP_X1, SH_REG_DSP_A0, SH_REG_DSP_A1},
|
|
1731
|
+
{SH_REG_DSP_Y0, SH_REG_DSP_Y1, SH_REG_DSP_M0, SH_REG_DSP_M1},
|
|
1732
|
+
{SH_REG_DSP_M0, SH_REG_DSP_M1, SH_REG_DSP_A0, SH_REG_DSP_A1},
|
|
1733
|
+
{SH_REG_DSP_X0, SH_REG_DSP_Y0, SH_REG_DSP_A0, SH_REG_DSP_A1},
|
|
1734
|
+
};
|
|
1735
|
+
typedef enum {f_se, f_sf, f_sx, f_sy, f_dg, f_du} dsp_reg_opr;
|
|
1736
|
+
static void set_reg_dsp_read(sh_info *info, int pos, dsp_reg_opr f, int r,
|
|
1737
|
+
cs_detail *detail)
|
|
1738
|
+
{
|
|
1739
|
+
info->op.operands[2].dsp.r[pos] = dsp_reg_sd[f][r];
|
|
1740
|
+
regs_read(detail, dsp_reg_sd[f][r]);
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
static void set_reg_dsp_write_gu(sh_info *info, int pos, dsp_reg_opr f, int r,
|
|
1744
|
+
cs_detail *detail)
|
|
1745
|
+
{
|
|
1746
|
+
info->op.operands[2].dsp.r[pos] = dsp_reg_sd[f][r];
|
|
1747
|
+
regs_write(detail, dsp_reg_sd[f][r]);
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
static const sh_reg regs_dz[] = {
|
|
1751
|
+
SH_REG_DSP_RSV0, SH_REG_DSP_RSV1, SH_REG_DSP_RSV2, SH_REG_DSP_RSV3,
|
|
1752
|
+
SH_REG_DSP_RSV4, SH_REG_DSP_A1, SH_REG_DSP_RSV6, SH_REG_DSP_A0,
|
|
1753
|
+
SH_REG_DSP_X0, SH_REG_DSP_X1, SH_REG_DSP_Y0, SH_REG_DSP_Y1,
|
|
1754
|
+
SH_REG_DSP_M0, SH_REG_DSP_A1G, SH_REG_DSP_M1, SH_REG_DSP_A0G,
|
|
1755
|
+
};
|
|
1756
|
+
|
|
1757
|
+
static void set_reg_dsp_write_z(sh_info *info, int pos, int r,
|
|
1758
|
+
cs_detail *detail)
|
|
1759
|
+
{
|
|
1760
|
+
info->op.operands[2].dsp.r[pos] = regs_dz[r];
|
|
1761
|
+
regs_write(detail, regs_dz[r]);
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
static bool dsp_op_cc_3opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
|
|
1765
|
+
sh_dsp_insn_type insn2, cs_detail *detail)
|
|
1766
|
+
{
|
|
1767
|
+
info->op.operands[2].dsp.cc = (code >> 8) & 3;
|
|
1768
|
+
if (info->op.operands[2].dsp.cc > 0) {
|
|
1769
|
+
info->op.operands[2].dsp.insn = insn;
|
|
1770
|
+
} else {
|
|
1771
|
+
if (insn2 != SH_INS_DSP_INVALID)
|
|
1772
|
+
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn2;
|
|
1773
|
+
else
|
|
1774
|
+
return MCDisassembler_Fail;
|
|
1775
|
+
}
|
|
1776
|
+
if (info->op.operands[2].dsp.insn != SH_INS_DSP_PSUBr) {
|
|
1777
|
+
set_reg_dsp_read(info, 0, f_sx, (code >> 6) & 3, detail);
|
|
1778
|
+
set_reg_dsp_read(info, 1, f_sy, (code >> 4) & 3, detail);
|
|
1779
|
+
} else {
|
|
1780
|
+
set_reg_dsp_read(info, 1, f_sx, (code >> 6) & 3, detail);
|
|
1781
|
+
set_reg_dsp_read(info, 0, f_sy, (code >> 4) & 3, detail);
|
|
1782
|
+
}
|
|
1783
|
+
set_reg_dsp_write_z(info, 2, code & 0x0f, detail);
|
|
1784
|
+
info->op.op_count = 3;
|
|
1785
|
+
return MCDisassembler_Success;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
static bool dsp_op_cc_2opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
|
|
1789
|
+
int xy, int b, cs_detail *detail)
|
|
1790
|
+
{
|
|
1791
|
+
if (((code >> 8) & 3) == 0)
|
|
1792
|
+
return MCDisassembler_Fail;
|
|
1793
|
+
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn;
|
|
1794
|
+
set_reg_dsp_read(info, 0, xy, (code >> b) & 3, detail);
|
|
1795
|
+
set_reg_dsp_write_z(info, 2, code & 0x0f, detail);
|
|
1796
|
+
info->op.operands[2].dsp.cc = (code >> 8) & 3;
|
|
1797
|
+
info->op.op_count = 3;
|
|
1798
|
+
return MCDisassembler_Success;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
static bool dsp_op_cc0_2opr(uint32_t code, sh_info *info, sh_dsp_insn insn,
|
|
1802
|
+
int xy, int b, cs_detail *detail)
|
|
1803
|
+
{
|
|
1804
|
+
info->op.operands[2].dsp.insn = (sh_dsp_insn) insn;
|
|
1805
|
+
set_reg_dsp_read(info, 0, xy, (code >> b) & 3, detail);
|
|
1806
|
+
set_reg_dsp_write_z(info, 2, code & 0x0f, detail);
|
|
1807
|
+
info->op.operands[2].dsp.cc = (code >> 8) & 3;
|
|
1808
|
+
if (info->op.operands[2].dsp.cc == 1)
|
|
1809
|
+
return MCDisassembler_Fail;
|
|
1810
|
+
if (info->op.operands[2].dsp.cc == 0)
|
|
1811
|
+
info->op.operands[2].dsp.cc = SH_DSP_CC_NONE;
|
|
1812
|
+
info->op.op_count = 3;
|
|
1813
|
+
return MCDisassembler_Success;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
static bool decode_dsp_3op(const uint32_t code, sh_info *info,
|
|
1817
|
+
cs_detail *detail)
|
|
1818
|
+
{
|
|
1819
|
+
int cc = (code >> 8) & 3;
|
|
1820
|
+
int sx = (code >> 6) & 3;
|
|
1821
|
+
int sy = (code >> 4) & 3;
|
|
1822
|
+
int dz = (code >> 0) & 0x0f;
|
|
1823
|
+
|
|
1824
|
+
if ((code & 0xef00) == 0x8000)
|
|
1825
|
+
return MCDisassembler_Fail;
|
|
1826
|
+
switch((code >> 10) & 0x1f) {
|
|
1827
|
+
case 0x00:
|
|
1828
|
+
return dsp_op_cc_3opr(code, info,
|
|
1829
|
+
SH_INS_DSP_PSHL, SH_INS_DSP_INVALID,
|
|
1830
|
+
detail);
|
|
1831
|
+
case 0x01:
|
|
1832
|
+
if (cc == 0) {
|
|
1833
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PCMP;
|
|
1834
|
+
set_reg_dsp_read(info, 0, f_sx, sx, detail);
|
|
1835
|
+
set_reg_dsp_read(info, 1, f_sy, sy, detail);
|
|
1836
|
+
info->op.op_count = 3;
|
|
1837
|
+
return MCDisassembler_Success;
|
|
1838
|
+
} else {
|
|
1839
|
+
return dsp_op_cc_3opr(code, info,
|
|
1840
|
+
SH_INS_DSP_PSUBr,
|
|
1841
|
+
SH_INS_DSP_INVALID, detail);
|
|
1842
|
+
}
|
|
1843
|
+
case 0x02:
|
|
1844
|
+
switch (sy) {
|
|
1845
|
+
case 0:
|
|
1846
|
+
if(cc == 0) {
|
|
1847
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PABS;
|
|
1848
|
+
set_reg_dsp_read(info, 0, f_sx, sx, detail);
|
|
1849
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
1850
|
+
info->op.op_count = 3;
|
|
1851
|
+
return MCDisassembler_Success;
|
|
1852
|
+
} else {
|
|
1853
|
+
return dsp_op_cc_2opr(code, info,
|
|
1854
|
+
SH_INS_DSP_PDEC,
|
|
1855
|
+
f_sx, 6, detail);
|
|
1856
|
+
}
|
|
1857
|
+
case 1:
|
|
1858
|
+
return dsp_op_cc0_2opr(code, info,
|
|
1859
|
+
SH_INS_DSP_PABS,
|
|
1860
|
+
f_sx, 6, detail);
|
|
1861
|
+
default:
|
|
1862
|
+
return MCDisassembler_Fail;
|
|
1863
|
+
}
|
|
1864
|
+
case 0x03:
|
|
1865
|
+
if (cc != 0) {
|
|
1866
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PCLR;
|
|
1867
|
+
info->op.operands[2].dsp.cc = cc;
|
|
1868
|
+
set_reg_dsp_write_z(info, 0, dz, detail);
|
|
1869
|
+
info->op.op_count = 3;
|
|
1870
|
+
return MCDisassembler_Success;
|
|
1871
|
+
} else
|
|
1872
|
+
return MCDisassembler_Fail;
|
|
1873
|
+
case 0x04:
|
|
1874
|
+
return dsp_op_cc_3opr(code, info,
|
|
1875
|
+
SH_INS_DSP_PSHA, SH_INS_DSP_INVALID,
|
|
1876
|
+
detail);
|
|
1877
|
+
case 0x05:
|
|
1878
|
+
return dsp_op_cc_3opr(code, info,
|
|
1879
|
+
SH_INS_DSP_PAND, SH_INS_DSP_INVALID,
|
|
1880
|
+
detail);
|
|
1881
|
+
case 0x06:
|
|
1882
|
+
switch (sy) {
|
|
1883
|
+
case 0:
|
|
1884
|
+
if (cc == 0) {
|
|
1885
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PRND;
|
|
1886
|
+
set_reg_dsp_read(info, 0, f_sx, sx, detail);
|
|
1887
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
1888
|
+
info->op.op_count = 3;
|
|
1889
|
+
return MCDisassembler_Success;
|
|
1890
|
+
} else {
|
|
1891
|
+
return dsp_op_cc_2opr(code, info,
|
|
1892
|
+
SH_INS_DSP_PINC,
|
|
1893
|
+
f_sx, 6, detail);
|
|
1894
|
+
}
|
|
1895
|
+
case 1:
|
|
1896
|
+
return dsp_op_cc0_2opr(code, info,
|
|
1897
|
+
SH_INS_DSP_PRND,
|
|
1898
|
+
f_sx, 6, detail);
|
|
1899
|
+
default:
|
|
1900
|
+
return MCDisassembler_Fail;
|
|
1901
|
+
}
|
|
1902
|
+
case 0x07:
|
|
1903
|
+
switch(sy) {
|
|
1904
|
+
case 0:
|
|
1905
|
+
return dsp_op_cc_2opr(code, info,
|
|
1906
|
+
SH_INS_DSP_PDMSB,
|
|
1907
|
+
f_sx, 6, detail);
|
|
1908
|
+
case 1:
|
|
1909
|
+
return dsp_op_cc_2opr(code, info,
|
|
1910
|
+
SH_INS_DSP_PSWAP,
|
|
1911
|
+
f_sx, 6, detail);
|
|
1912
|
+
default:
|
|
1913
|
+
return MCDisassembler_Fail;
|
|
1914
|
+
}
|
|
1915
|
+
case 0x08:
|
|
1916
|
+
return dsp_op_cc_3opr(code, info,
|
|
1917
|
+
SH_INS_DSP_PSUB, (sh_dsp_insn_type) SH_INS_DSP_PSUBC,
|
|
1918
|
+
detail);
|
|
1919
|
+
case 0x09:
|
|
1920
|
+
return dsp_op_cc_3opr(code, info,
|
|
1921
|
+
SH_INS_DSP_PXOR, (sh_dsp_insn_type) SH_INS_DSP_PWSB,
|
|
1922
|
+
detail);
|
|
1923
|
+
case 0x0a:
|
|
1924
|
+
switch(sx) {
|
|
1925
|
+
case 0:
|
|
1926
|
+
if (cc == 0) {
|
|
1927
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PABS;
|
|
1928
|
+
set_reg_dsp_read(info, 0, f_sy, sy, detail);
|
|
1929
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
1930
|
+
info->op.op_count = 3;
|
|
1931
|
+
return MCDisassembler_Success;
|
|
1932
|
+
} else {
|
|
1933
|
+
return dsp_op_cc_2opr(code, info,
|
|
1934
|
+
SH_INS_DSP_PDEC,
|
|
1935
|
+
f_sy, 4, detail);
|
|
1936
|
+
}
|
|
1937
|
+
case 1:
|
|
1938
|
+
return dsp_op_cc_2opr(code, info,
|
|
1939
|
+
SH_INS_DSP_PABS,
|
|
1940
|
+
f_sy, 4, detail);
|
|
1941
|
+
default:
|
|
1942
|
+
return MCDisassembler_Fail;
|
|
1943
|
+
}
|
|
1944
|
+
case 0x0c:
|
|
1945
|
+
if (cc == 0) {
|
|
1946
|
+
info->op.operands[2].dsp.insn
|
|
1947
|
+
= SH_INS_DSP_PADDC;
|
|
1948
|
+
set_reg_dsp_read(info, 0, f_sx, sx, detail);
|
|
1949
|
+
set_reg_dsp_read(info, 1, f_sy, sy, detail);
|
|
1950
|
+
set_reg_dsp_write_z(info, 2, dz, detail);
|
|
1951
|
+
info->op.op_count = 3;
|
|
1952
|
+
return MCDisassembler_Success;
|
|
1953
|
+
} else {
|
|
1954
|
+
return dsp_op_cc_3opr(code, info,
|
|
1955
|
+
SH_INS_DSP_PADD,
|
|
1956
|
+
SH_INS_DSP_INVALID, detail);
|
|
1957
|
+
}
|
|
1958
|
+
case 0x0d:
|
|
1959
|
+
return dsp_op_cc_3opr(code, info,
|
|
1960
|
+
SH_INS_DSP_POR,
|
|
1961
|
+
(sh_dsp_insn_type) SH_INS_DSP_PWAD,
|
|
1962
|
+
detail);
|
|
1963
|
+
case 0x0e:
|
|
1964
|
+
if (cc == 0) {
|
|
1965
|
+
if (sx != 0)
|
|
1966
|
+
return MCDisassembler_Fail;
|
|
1967
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PRND;
|
|
1968
|
+
set_reg_dsp_read(info, 0, f_sy, sy, detail);
|
|
1969
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
1970
|
+
info->op.op_count = 3;
|
|
1971
|
+
return MCDisassembler_Success;
|
|
1972
|
+
} else {
|
|
1973
|
+
switch(sx) {
|
|
1974
|
+
case 0:
|
|
1975
|
+
return dsp_op_cc_2opr(code, info,
|
|
1976
|
+
SH_INS_DSP_PINC,
|
|
1977
|
+
f_sy, 4, detail);
|
|
1978
|
+
case 1:
|
|
1979
|
+
return dsp_op_cc_2opr(code, info,
|
|
1980
|
+
SH_INS_DSP_PRND,
|
|
1981
|
+
f_sy, 4, detail);
|
|
1982
|
+
default:
|
|
1983
|
+
return MCDisassembler_Fail;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
case 0x0f:
|
|
1987
|
+
switch(sx) {
|
|
1988
|
+
case 0:
|
|
1989
|
+
return dsp_op_cc_2opr(code, info,
|
|
1990
|
+
SH_INS_DSP_PDMSB,
|
|
1991
|
+
f_sy, 4, detail);
|
|
1992
|
+
case 1:
|
|
1993
|
+
return dsp_op_cc_2opr(code, info,
|
|
1994
|
+
SH_INS_DSP_PSWAP,
|
|
1995
|
+
f_sy, 4, detail);
|
|
1996
|
+
default:
|
|
1997
|
+
return MCDisassembler_Fail;
|
|
1998
|
+
}
|
|
1999
|
+
case 0x12:
|
|
2000
|
+
return dsp_op_cc_2opr(code, info,
|
|
2001
|
+
SH_INS_DSP_PNEG, f_sx, 6, detail);
|
|
2002
|
+
case 0x13:
|
|
2003
|
+
case 0x17:
|
|
2004
|
+
if (cc > 0) {
|
|
2005
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PSTS;
|
|
2006
|
+
info->op.operands[2].dsp.cc = cc;
|
|
2007
|
+
regs_read(detail,
|
|
2008
|
+
info->op.operands[2].dsp.r[0]
|
|
2009
|
+
= SH_REG_MACH + ((code >> 12) & 1));
|
|
2010
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
2011
|
+
info->op.op_count = 3;
|
|
2012
|
+
return MCDisassembler_Success;
|
|
2013
|
+
} else {
|
|
2014
|
+
return MCDisassembler_Fail;
|
|
2015
|
+
}
|
|
2016
|
+
case 0x16:
|
|
2017
|
+
return dsp_op_cc_2opr(code, info,
|
|
2018
|
+
SH_INS_DSP_PCOPY, f_sx, 6, detail);
|
|
2019
|
+
case 0x1a:
|
|
2020
|
+
return dsp_op_cc_2opr(code, info,
|
|
2021
|
+
SH_INS_DSP_PNEG, f_sy, 4, detail);
|
|
2022
|
+
case 0x1b:
|
|
2023
|
+
case 0x1f:
|
|
2024
|
+
if (cc > 0) {
|
|
2025
|
+
info->op.operands[2].dsp.insn = SH_INS_DSP_PLDS;
|
|
2026
|
+
info->op.operands[2].dsp.cc = cc;
|
|
2027
|
+
info->op.operands[2].dsp.r[0] = regs_dz[dz];
|
|
2028
|
+
regs_read(detail, regs_dz[dz]);
|
|
2029
|
+
regs_write(detail,
|
|
2030
|
+
info->op.operands[2].dsp.r[1]
|
|
2031
|
+
= SH_REG_MACH + ((code >> 12) & 1));
|
|
2032
|
+
info->op.op_count = 3;
|
|
2033
|
+
return MCDisassembler_Success;
|
|
2034
|
+
} else {
|
|
2035
|
+
return MCDisassembler_Fail;
|
|
2036
|
+
}
|
|
2037
|
+
case 0x1e:
|
|
2038
|
+
return dsp_op_cc_2opr(code, info, SH_INS_DSP_PCOPY, f_sy, 4, detail);
|
|
2039
|
+
default:
|
|
2040
|
+
return MCDisassembler_Fail;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
static bool decode_dsp_p(const uint32_t code, MCInst *MI, cs_mode mode,
|
|
2045
|
+
sh_info *info, cs_detail *detail)
|
|
2046
|
+
{
|
|
2047
|
+
int dz = code & 0x0f;
|
|
2048
|
+
MCInst_setOpcode(MI, SH_INS_DSP);
|
|
2049
|
+
if (!decode_dsp_d(code >> 16, MI, mode, info, detail))
|
|
2050
|
+
return MCDisassembler_Fail;
|
|
2051
|
+
|
|
2052
|
+
switch((code >> 12) & 0x0f) {
|
|
2053
|
+
case 0x00:
|
|
2054
|
+
case 0x01:
|
|
2055
|
+
if ((code >> 11) & 1)
|
|
2056
|
+
return MCDisassembler_Fail;
|
|
2057
|
+
info->op.operands[2].dsp.insn
|
|
2058
|
+
= SH_INS_DSP_PSHL + ((code >> 12) & 1);
|
|
2059
|
+
info->op.operands[2].dsp.imm = (code >> 4) & 0x7f;
|
|
2060
|
+
set_reg_dsp_write_z(info, 1, dz, detail);
|
|
2061
|
+
info->op.op_count = 3;
|
|
2062
|
+
return MCDisassembler_Success;
|
|
2063
|
+
case 0x04:
|
|
2064
|
+
if ((((code >> 4) & 1) && isalevel(mode) != ISA_SH4A) ||
|
|
2065
|
+
(!((code >> 4) & 1) && (code &3)) ||
|
|
2066
|
+
((code >> 4) & 0x0f) >= 2)
|
|
2067
|
+
return MCDisassembler_Fail;
|
|
2068
|
+
|
|
2069
|
+
info->op.operands[2].dsp.insn
|
|
2070
|
+
= SH_INS_DSP_PMULS + ((code >> 4) & 1);
|
|
2071
|
+
set_reg_dsp_read(info, 0, f_se, (code >> 10) & 3, detail);
|
|
2072
|
+
set_reg_dsp_read(info, 1, f_sf, (code >> 8) & 3, detail);
|
|
2073
|
+
set_reg_dsp_write_gu(info, 2, f_dg, (code >> 2) & 3, detail);
|
|
2074
|
+
if ((code >> 4) & 1)
|
|
2075
|
+
set_reg_dsp_write_gu(info, 3, f_du,
|
|
2076
|
+
(code >> 0) & 3, detail);
|
|
2077
|
+
info->op.op_count = 3;
|
|
2078
|
+
return MCDisassembler_Success;
|
|
2079
|
+
case 0x06:
|
|
2080
|
+
case 0x07:
|
|
2081
|
+
info->op.operands[2].dsp.insn
|
|
2082
|
+
= SH_INS_DSP_PSUB_PMULS + ((code >> 12) & 1);
|
|
2083
|
+
set_reg_dsp_read(info, 0, f_sx, (code >> 6) & 3, detail);
|
|
2084
|
+
set_reg_dsp_read(info, 1, f_sy, (code >> 4) & 3, detail);
|
|
2085
|
+
set_reg_dsp_write_gu(info, 2, f_du, (code >> 0) & 3, detail);
|
|
2086
|
+
set_reg_dsp_read(info, 3, f_se, (code >> 10) & 3, detail);
|
|
2087
|
+
set_reg_dsp_read(info, 4, f_sf, (code >> 8) & 3, detail);
|
|
2088
|
+
set_reg_dsp_write_gu(info, 5, f_dg, (code >> 2) & 3, detail);
|
|
2089
|
+
info->op.op_count = 3;
|
|
2090
|
+
return MCDisassembler_Success;
|
|
2091
|
+
default:
|
|
2092
|
+
if ((code >> 15) & 1)
|
|
2093
|
+
return decode_dsp_3op(code, info, detail);
|
|
2094
|
+
}
|
|
2095
|
+
return MCDisassembler_Fail;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
static bool sh_disassemble(const uint8_t *code, MCInst *MI, uint64_t address,
|
|
2099
|
+
cs_mode mode, uint16_t *size, int code_len,
|
|
2100
|
+
sh_info *info, cs_detail *detail)
|
|
2101
|
+
{
|
|
2102
|
+
int idx;
|
|
2103
|
+
uint32_t insn;
|
|
2104
|
+
bool dsp_result;
|
|
2105
|
+
if (MODE_IS_BIG_ENDIAN(mode)) {
|
|
2106
|
+
insn = code[0] << 8 | code[1];
|
|
2107
|
+
} else {
|
|
2108
|
+
insn = code[1] << 8 | code[0];
|
|
2109
|
+
}
|
|
2110
|
+
if (mode & CS_MODE_SH2A) {
|
|
2111
|
+
/* SH2A 32bit instrcution test */
|
|
2112
|
+
if (((insn & 0xf007) == 0x3001 ||
|
|
2113
|
+
(insn & 0xf00e) == 0x0000)) {
|
|
2114
|
+
if (code_len < 4)
|
|
2115
|
+
return MCDisassembler_Fail;
|
|
2116
|
+
*size = 4;
|
|
2117
|
+
// SH2A is only BIG ENDIAN.
|
|
2118
|
+
insn <<= 16;
|
|
2119
|
+
insn |= code[2] << 8 | code[3];
|
|
2120
|
+
if (decode_long(insn, address, MI, info, detail))
|
|
2121
|
+
return MCDisassembler_Success;
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
/* Co-processor instructions */
|
|
2125
|
+
if ((insn & 0xf000) == 0xf000) {
|
|
2126
|
+
if (mode & CS_MODE_SHDSP) {
|
|
2127
|
+
dsp_result = MCDisassembler_Fail;
|
|
2128
|
+
switch(insn >> 10 & 3) {
|
|
2129
|
+
case 0:
|
|
2130
|
+
*size = 2;
|
|
2131
|
+
dsp_result = decode_dsp_d(insn, MI, mode,
|
|
2132
|
+
info, detail);
|
|
2133
|
+
break;
|
|
2134
|
+
case 1:
|
|
2135
|
+
*size = 2;
|
|
2136
|
+
dsp_result = decode_dsp_s(insn, MI,
|
|
2137
|
+
info, detail);
|
|
2138
|
+
break;
|
|
2139
|
+
case 2:
|
|
2140
|
+
if (code_len < 4)
|
|
2141
|
+
return MCDisassembler_Fail;
|
|
2142
|
+
*size = 4;
|
|
2143
|
+
if (MODE_IS_BIG_ENDIAN(mode)) {
|
|
2144
|
+
insn <<= 16;
|
|
2145
|
+
insn |= code[2] << 8 | code[3];
|
|
2146
|
+
} else
|
|
2147
|
+
insn |= (code[3] << 24)
|
|
2148
|
+
| (code[2] << 16);
|
|
2149
|
+
dsp_result = decode_dsp_p(insn, MI, mode,
|
|
2150
|
+
info, detail);
|
|
2151
|
+
break;
|
|
2152
|
+
}
|
|
2153
|
+
return dsp_result;
|
|
2154
|
+
}
|
|
2155
|
+
if ((mode & CS_MODE_SHFPU) == 0)
|
|
2156
|
+
return MCDisassembler_Fail;
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2159
|
+
*size = 2;
|
|
2160
|
+
if ((insn & 0xf000) >= 0x8000 && (insn & 0xf000) < 0xf000) {
|
|
2161
|
+
idx = insn >> 8;
|
|
2162
|
+
} else {
|
|
2163
|
+
idx = ((insn >> 8) & 0xf0) | (insn & 0x000f);
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
if (decode[idx]) {
|
|
2167
|
+
return decode[idx](insn, address, MI, mode, info, detail);
|
|
2168
|
+
} else {
|
|
2169
|
+
return MCDisassembler_Fail;
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
bool SH_getInstruction(csh ud, const uint8_t *code, size_t code_len,
|
|
2174
|
+
MCInst *MI, uint16_t *size, uint64_t address, void *inst_info)
|
|
2175
|
+
{
|
|
2176
|
+
|
|
2177
|
+
cs_struct* handle = (cs_struct *)ud;
|
|
2178
|
+
sh_info *info = (sh_info *)handle->printer_info;
|
|
2179
|
+
cs_detail *detail = MI->flat_insn->detail;
|
|
2180
|
+
|
|
2181
|
+
if (code_len < 2) {
|
|
2182
|
+
*size = 0;
|
|
2183
|
+
return MCDisassembler_Fail;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
if (detail) {
|
|
2187
|
+
memset(detail, 0, offsetof(cs_detail, sh)+sizeof(cs_sh));
|
|
2188
|
+
}
|
|
2189
|
+
memset(info, 0, sizeof(sh_info));
|
|
2190
|
+
if (sh_disassemble(code, MI, address, handle->mode,
|
|
2191
|
+
size, code_len, info, detail) == MCDisassembler_Fail) {
|
|
2192
|
+
*size = 0;
|
|
2193
|
+
return MCDisassembler_Fail;
|
|
2194
|
+
} else {
|
|
2195
|
+
return MCDisassembler_Success;
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
#ifndef CAPSTONE_DIET
|
|
2200
|
+
void SH_reg_access(const cs_insn *insn,
|
|
2201
|
+
cs_regs regs_read, uint8_t *regs_read_count,
|
|
2202
|
+
cs_regs regs_write, uint8_t *regs_write_count)
|
|
2203
|
+
{
|
|
2204
|
+
if (insn->detail == NULL) {
|
|
2205
|
+
*regs_read_count = 0;
|
|
2206
|
+
*regs_write_count = 0;
|
|
2207
|
+
}
|
|
2208
|
+
else {
|
|
2209
|
+
*regs_read_count = insn->detail->regs_read_count;
|
|
2210
|
+
*regs_write_count = insn->detail->regs_write_count;
|
|
2211
|
+
|
|
2212
|
+
memcpy(regs_read, insn->detail->regs_read,
|
|
2213
|
+
*regs_read_count * sizeof(insn->detail->regs_read[0]));
|
|
2214
|
+
memcpy(regs_write, insn->detail->regs_write,
|
|
2215
|
+
*regs_write_count *
|
|
2216
|
+
sizeof(insn->detail->regs_write[0]));
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
#endif
|
|
2220
|
+
|
|
2221
|
+
|