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,3364 @@
|
|
|
1
|
+
//===-- ARMInstPrinter.cpp - Convert ARM MCInst to assembly syntax --------===//
|
|
2
|
+
//
|
|
3
|
+
// The LLVM Compiler Infrastructure
|
|
4
|
+
//
|
|
5
|
+
// This file is distributed under the University of Illinois Open Source
|
|
6
|
+
// License. See LICENSE.TXT for details.
|
|
7
|
+
//
|
|
8
|
+
//===----------------------------------------------------------------------===//
|
|
9
|
+
//
|
|
10
|
+
// This class prints an ARM MCInst to a .s file.
|
|
11
|
+
//
|
|
12
|
+
//===----------------------------------------------------------------------===//
|
|
13
|
+
|
|
14
|
+
/* Capstone Disassembly Engine */
|
|
15
|
+
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
|
|
16
|
+
|
|
17
|
+
#ifdef CAPSTONE_HAS_ARM
|
|
18
|
+
|
|
19
|
+
#include <stdio.h> // DEBUG
|
|
20
|
+
#include <stdlib.h>
|
|
21
|
+
#include <string.h>
|
|
22
|
+
#include <capstone/platform.h>
|
|
23
|
+
|
|
24
|
+
#include "ARMInstPrinter.h"
|
|
25
|
+
#include "ARMAddressingModes.h"
|
|
26
|
+
#include "ARMBaseInfo.h"
|
|
27
|
+
#include "ARMDisassembler.h"
|
|
28
|
+
#include "../../MCInst.h"
|
|
29
|
+
#include "../../SStream.h"
|
|
30
|
+
#include "../../MCRegisterInfo.h"
|
|
31
|
+
#include "../../utils.h"
|
|
32
|
+
#include "ARMMapping.h"
|
|
33
|
+
|
|
34
|
+
#define GET_SUBTARGETINFO_ENUM
|
|
35
|
+
#include "ARMGenSubtargetInfo.inc"
|
|
36
|
+
|
|
37
|
+
#include "ARMGenSystemRegister.inc"
|
|
38
|
+
|
|
39
|
+
static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo);
|
|
40
|
+
|
|
41
|
+
// Autogenerated by tblgen.
|
|
42
|
+
static void printInstruction(MCInst *MI, SStream *O);
|
|
43
|
+
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
|
|
44
|
+
static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
45
|
+
static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
46
|
+
|
|
47
|
+
static void printAddrModeTBB(MCInst *MI, unsigned OpNum, SStream *O);
|
|
48
|
+
static void printAddrModeTBH(MCInst *MI, unsigned OpNum, SStream *O);
|
|
49
|
+
static void printAddrMode2Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
50
|
+
static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned OpNum, SStream *O);
|
|
51
|
+
static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
52
|
+
static void printAddrMode3Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
|
|
53
|
+
static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
54
|
+
static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O, bool AlwaysPrintImm0);
|
|
55
|
+
static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
56
|
+
static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
57
|
+
static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
58
|
+
static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
|
|
59
|
+
static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
60
|
+
static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
61
|
+
static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
62
|
+
|
|
63
|
+
static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
64
|
+
static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O);
|
|
65
|
+
static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
66
|
+
static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
|
|
67
|
+
static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O);
|
|
68
|
+
static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned);
|
|
69
|
+
static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
70
|
+
static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O);
|
|
71
|
+
static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O);
|
|
72
|
+
static void printThumbAddrModeRROperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
73
|
+
static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned Scale);
|
|
74
|
+
static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
75
|
+
static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
76
|
+
static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
77
|
+
static void printThumbAddrModeSPOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
78
|
+
static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
79
|
+
static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
|
|
80
|
+
static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
|
|
81
|
+
static void printT2AddrModeImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O, bool);
|
|
82
|
+
static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
83
|
+
static void printT2AddrModeImm8OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
84
|
+
static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
85
|
+
static void printT2AddrModeSoRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
86
|
+
static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
87
|
+
static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O);
|
|
88
|
+
static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O);
|
|
89
|
+
static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
90
|
+
static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
91
|
+
static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
92
|
+
static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
93
|
+
static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O);
|
|
94
|
+
static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O);
|
|
95
|
+
static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O);
|
|
96
|
+
static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O);
|
|
97
|
+
static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O);
|
|
98
|
+
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
99
|
+
static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
100
|
+
static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
101
|
+
static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
102
|
+
static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
103
|
+
static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
104
|
+
static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O);
|
|
105
|
+
static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O);
|
|
106
|
+
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O);
|
|
107
|
+
static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O);
|
|
108
|
+
static void printVectorListTwo(MCInst *MI, unsigned OpNum, SStream *O);
|
|
109
|
+
static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum, SStream *O);
|
|
110
|
+
static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O);
|
|
111
|
+
static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O);
|
|
112
|
+
static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
113
|
+
static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
114
|
+
static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
115
|
+
static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
116
|
+
static void printVectorListTwoSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
117
|
+
static void printVectorListThreeSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
118
|
+
static void printVectorListFourSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O);
|
|
119
|
+
static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O);
|
|
120
|
+
static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O);
|
|
121
|
+
static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
122
|
+
static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
|
123
|
+
|
|
124
|
+
static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
|
|
125
|
+
static void printTraceSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
|
|
126
|
+
static void printComplexRotationOp(MCInst *MI, unsigned OpNo, SStream *O, int64_t Angle, int64_t Remainder);
|
|
127
|
+
static void printAddrMode5FP16Operand(MCInst *MI, unsigned OpNum, SStream *O, bool AlwaysPrintImm0);
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
#ifndef CAPSTONE_DIET
|
|
131
|
+
// copy & normalize access info
|
|
132
|
+
static uint8_t get_op_access(cs_struct *h, unsigned int id, unsigned int index)
|
|
133
|
+
{
|
|
134
|
+
const uint8_t *arr = ARM_get_op_access(h, id);
|
|
135
|
+
|
|
136
|
+
if (!arr || arr[index] == CS_AC_IGNORE)
|
|
137
|
+
return 0;
|
|
138
|
+
|
|
139
|
+
return arr[index];
|
|
140
|
+
}
|
|
141
|
+
#endif
|
|
142
|
+
|
|
143
|
+
static void set_mem_access(MCInst *MI, bool status)
|
|
144
|
+
{
|
|
145
|
+
if (MI->csh->detail != CS_OPT_ON)
|
|
146
|
+
return;
|
|
147
|
+
|
|
148
|
+
MI->csh->doing_mem = status;
|
|
149
|
+
if (status) {
|
|
150
|
+
#ifndef CAPSTONE_DIET
|
|
151
|
+
uint8_t access;
|
|
152
|
+
#endif
|
|
153
|
+
|
|
154
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
|
|
155
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_INVALID;
|
|
156
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
|
157
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
|
158
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
|
|
159
|
+
|
|
160
|
+
#ifndef CAPSTONE_DIET
|
|
161
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
162
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
163
|
+
MI->ac_idx++;
|
|
164
|
+
#endif
|
|
165
|
+
} else {
|
|
166
|
+
// done, create the next operand slot
|
|
167
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
static void op_addImm(MCInst *MI, int v)
|
|
172
|
+
{
|
|
173
|
+
if (MI->csh->detail) {
|
|
174
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
175
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = v;
|
|
176
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#define GET_INSTRINFO_ENUM
|
|
181
|
+
#include "ARMGenInstrInfo.inc"
|
|
182
|
+
|
|
183
|
+
static void printCustomAliasOperand(MCInst *MI,
|
|
184
|
+
unsigned OpIdx, unsigned PrintMethodIdx, SStream *OS);
|
|
185
|
+
|
|
186
|
+
#define PRINT_ALIAS_INSTR
|
|
187
|
+
#include "ARMGenAsmWriter.inc"
|
|
188
|
+
#include "ARMGenRegisterName.inc"
|
|
189
|
+
#include "ARMGenRegisterName_digit.inc"
|
|
190
|
+
|
|
191
|
+
void ARM_getRegName(cs_struct *handle, int value)
|
|
192
|
+
{
|
|
193
|
+
if (value == CS_OPT_SYNTAX_NOREGNAME) {
|
|
194
|
+
handle->get_regname = getRegisterName_digit;
|
|
195
|
+
handle->reg_name = ARM_reg_name2;
|
|
196
|
+
} else {
|
|
197
|
+
handle->get_regname = getRegisterName;
|
|
198
|
+
handle->reg_name = ARM_reg_name;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/// translateShiftImm - Convert shift immediate from 0-31 to 1-32 for printing.
|
|
203
|
+
///
|
|
204
|
+
/// getSORegOffset returns an integer from 0-31, representing '32' as 0.
|
|
205
|
+
static unsigned translateShiftImm(unsigned imm)
|
|
206
|
+
{
|
|
207
|
+
// lsr #32 and asr #32 exist, but should be encoded as a 0.
|
|
208
|
+
//assert((imm & ~0x1f) == 0 && "Invalid shift encoding");
|
|
209
|
+
if (imm == 0)
|
|
210
|
+
return 32;
|
|
211
|
+
return imm;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// Prints the shift value with an immediate value.
|
|
215
|
+
static void printRegImmShift(MCInst *MI, SStream *O, ARM_AM_ShiftOpc ShOpc, unsigned ShImm)
|
|
216
|
+
{
|
|
217
|
+
if (ShOpc == ARM_AM_no_shift || (ShOpc == ARM_AM_lsl && !ShImm))
|
|
218
|
+
return;
|
|
219
|
+
|
|
220
|
+
SStream_concat0(O, ", ");
|
|
221
|
+
|
|
222
|
+
//assert (!(ShOpc == ARM_AM_ror && !ShImm) && "Cannot have ror #0");
|
|
223
|
+
SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
|
|
224
|
+
|
|
225
|
+
if (MI->csh->detail) {
|
|
226
|
+
if (MI->csh->doing_mem)
|
|
227
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)ShOpc;
|
|
228
|
+
else
|
|
229
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = (arm_shifter)ShOpc;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (ShOpc != ARM_AM_rrx) {
|
|
233
|
+
SStream_concat0(O, " ");
|
|
234
|
+
SStream_concat(O, "#%u", translateShiftImm(ShImm));
|
|
235
|
+
if (MI->csh->detail) {
|
|
236
|
+
if (MI->csh->doing_mem)
|
|
237
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = translateShiftImm(ShImm);
|
|
238
|
+
else
|
|
239
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = translateShiftImm(ShImm);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static void printRegName(cs_struct *h, SStream *OS, unsigned RegNo)
|
|
245
|
+
{
|
|
246
|
+
#ifndef CAPSTONE_DIET
|
|
247
|
+
SStream_concat0(OS, h->get_regname(RegNo));
|
|
248
|
+
#endif
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// TODO
|
|
252
|
+
static const name_map insn_update_flgs[] = {
|
|
253
|
+
{ ARM_INS_CMN, "cmn" },
|
|
254
|
+
{ ARM_INS_CMP, "cmp" },
|
|
255
|
+
{ ARM_INS_TEQ, "teq" },
|
|
256
|
+
{ ARM_INS_TST, "tst" },
|
|
257
|
+
|
|
258
|
+
{ ARM_INS_ADC, "adcs" },
|
|
259
|
+
{ ARM_INS_ADD, "adds" },
|
|
260
|
+
{ ARM_INS_AND, "ands" },
|
|
261
|
+
{ ARM_INS_ASR, "asrs" },
|
|
262
|
+
{ ARM_INS_BIC, "bics" },
|
|
263
|
+
{ ARM_INS_EOR, "eors" },
|
|
264
|
+
{ ARM_INS_LSL, "lsls" },
|
|
265
|
+
{ ARM_INS_LSR, "lsrs" },
|
|
266
|
+
{ ARM_INS_MLA, "mlas" },
|
|
267
|
+
{ ARM_INS_MOV, "movs" },
|
|
268
|
+
{ ARM_INS_MUL, "muls" },
|
|
269
|
+
{ ARM_INS_MVN, "mvns" },
|
|
270
|
+
{ ARM_INS_ORN, "orns" },
|
|
271
|
+
{ ARM_INS_ORR, "orrs" },
|
|
272
|
+
{ ARM_INS_ROR, "rors" },
|
|
273
|
+
{ ARM_INS_RRX, "rrxs" },
|
|
274
|
+
{ ARM_INS_RSB, "rsbs" },
|
|
275
|
+
{ ARM_INS_RSC, "rscs" },
|
|
276
|
+
{ ARM_INS_SBC, "sbcs" },
|
|
277
|
+
{ ARM_INS_SMLAL, "smlals" },
|
|
278
|
+
{ ARM_INS_SMULL, "smulls" },
|
|
279
|
+
{ ARM_INS_SUB, "subs" },
|
|
280
|
+
{ ARM_INS_UMLAL, "umlals" },
|
|
281
|
+
{ ARM_INS_UMULL, "umulls" },
|
|
282
|
+
|
|
283
|
+
{ ARM_INS_UADD8, "uadd8" },
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
|
287
|
+
{
|
|
288
|
+
if (((cs_struct *)ud)->detail != CS_OPT_ON)
|
|
289
|
+
return;
|
|
290
|
+
|
|
291
|
+
// check if this insn requests write-back
|
|
292
|
+
if (mci->writeback || (strrchr(insn_asm, '!')) != NULL) {
|
|
293
|
+
insn->detail->arm.writeback = true;
|
|
294
|
+
} else if (mci->csh->mode & CS_MODE_THUMB) {
|
|
295
|
+
// handle some special instructions with writeback
|
|
296
|
+
//printf(">> Opcode = %u\n", mci->Opcode);
|
|
297
|
+
switch(mci->Opcode) {
|
|
298
|
+
default:
|
|
299
|
+
break;
|
|
300
|
+
case ARM_t2LDC2L_PRE:
|
|
301
|
+
case ARM_t2LDC2_PRE:
|
|
302
|
+
case ARM_t2LDCL_PRE:
|
|
303
|
+
case ARM_t2LDC_PRE:
|
|
304
|
+
|
|
305
|
+
case ARM_t2LDRB_PRE:
|
|
306
|
+
case ARM_t2LDRD_PRE:
|
|
307
|
+
case ARM_t2LDRH_PRE:
|
|
308
|
+
case ARM_t2LDRSB_PRE:
|
|
309
|
+
case ARM_t2LDRSH_PRE:
|
|
310
|
+
case ARM_t2LDR_PRE:
|
|
311
|
+
|
|
312
|
+
case ARM_t2STC2L_PRE:
|
|
313
|
+
case ARM_t2STC2_PRE:
|
|
314
|
+
case ARM_t2STCL_PRE:
|
|
315
|
+
case ARM_t2STC_PRE:
|
|
316
|
+
|
|
317
|
+
case ARM_t2STRB_PRE:
|
|
318
|
+
case ARM_t2STRD_PRE:
|
|
319
|
+
case ARM_t2STRH_PRE:
|
|
320
|
+
case ARM_t2STR_PRE:
|
|
321
|
+
insn->detail->arm.writeback = true;
|
|
322
|
+
break;
|
|
323
|
+
case ARM_t2LDC2L_POST:
|
|
324
|
+
case ARM_t2LDC2_POST:
|
|
325
|
+
case ARM_t2LDCL_POST:
|
|
326
|
+
case ARM_t2LDC_POST:
|
|
327
|
+
|
|
328
|
+
case ARM_t2LDRB_POST:
|
|
329
|
+
case ARM_t2LDRD_POST:
|
|
330
|
+
case ARM_t2LDRH_POST:
|
|
331
|
+
case ARM_t2LDRSB_POST:
|
|
332
|
+
case ARM_t2LDRSH_POST:
|
|
333
|
+
case ARM_t2LDR_POST:
|
|
334
|
+
|
|
335
|
+
case ARM_t2STC2L_POST:
|
|
336
|
+
case ARM_t2STC2_POST:
|
|
337
|
+
case ARM_t2STCL_POST:
|
|
338
|
+
case ARM_t2STC_POST:
|
|
339
|
+
|
|
340
|
+
case ARM_t2STRB_POST:
|
|
341
|
+
case ARM_t2STRD_POST:
|
|
342
|
+
case ARM_t2STRH_POST:
|
|
343
|
+
case ARM_t2STR_POST:
|
|
344
|
+
insn->detail->arm.writeback = true;
|
|
345
|
+
insn->detail->arm.post_index = true;
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
} else { // ARM mode
|
|
349
|
+
// handle some special instructions with writeback
|
|
350
|
+
//printf(">> Opcode = %u\n", mci->Opcode);
|
|
351
|
+
switch(mci->Opcode) {
|
|
352
|
+
default:
|
|
353
|
+
break;
|
|
354
|
+
case ARM_LDC2L_PRE:
|
|
355
|
+
case ARM_LDC2_PRE:
|
|
356
|
+
case ARM_LDCL_PRE:
|
|
357
|
+
case ARM_LDC_PRE:
|
|
358
|
+
|
|
359
|
+
case ARM_LDRD_PRE:
|
|
360
|
+
case ARM_LDRH_PRE:
|
|
361
|
+
case ARM_LDRSB_PRE:
|
|
362
|
+
case ARM_LDRSH_PRE:
|
|
363
|
+
|
|
364
|
+
case ARM_STC2L_PRE:
|
|
365
|
+
case ARM_STC2_PRE:
|
|
366
|
+
case ARM_STCL_PRE:
|
|
367
|
+
case ARM_STC_PRE:
|
|
368
|
+
|
|
369
|
+
case ARM_STRD_PRE:
|
|
370
|
+
case ARM_STRH_PRE:
|
|
371
|
+
insn->detail->arm.writeback = true;
|
|
372
|
+
break;
|
|
373
|
+
case ARM_LDC2L_POST:
|
|
374
|
+
case ARM_LDC2_POST:
|
|
375
|
+
case ARM_LDCL_POST:
|
|
376
|
+
case ARM_LDC_POST:
|
|
377
|
+
|
|
378
|
+
case ARM_LDRBT_POST:
|
|
379
|
+
case ARM_LDRD_POST:
|
|
380
|
+
case ARM_LDRH_POST:
|
|
381
|
+
case ARM_LDRSB_POST:
|
|
382
|
+
case ARM_LDRSH_POST:
|
|
383
|
+
|
|
384
|
+
case ARM_STC2L_POST:
|
|
385
|
+
case ARM_STC2_POST:
|
|
386
|
+
case ARM_STCL_POST:
|
|
387
|
+
case ARM_STC_POST:
|
|
388
|
+
|
|
389
|
+
case ARM_STRBT_POST:
|
|
390
|
+
case ARM_STRD_POST:
|
|
391
|
+
case ARM_STRH_POST:
|
|
392
|
+
|
|
393
|
+
case ARM_LDRB_POST_IMM:
|
|
394
|
+
case ARM_LDR_POST_IMM:
|
|
395
|
+
case ARM_LDR_POST_REG:
|
|
396
|
+
case ARM_STRB_POST_IMM:
|
|
397
|
+
|
|
398
|
+
case ARM_STR_POST_IMM:
|
|
399
|
+
case ARM_STR_POST_REG:
|
|
400
|
+
insn->detail->arm.writeback = true;
|
|
401
|
+
insn->detail->arm.post_index = true;
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// check if this insn requests update flags
|
|
407
|
+
if (insn->detail->arm.update_flags == false) {
|
|
408
|
+
// some insn still update flags, regardless of tabgen info
|
|
409
|
+
unsigned int i, j;
|
|
410
|
+
|
|
411
|
+
for (i = 0; i < ARR_SIZE(insn_update_flgs); i++) {
|
|
412
|
+
if (insn->id == insn_update_flgs[i].id &&
|
|
413
|
+
!strncmp(insn_asm, insn_update_flgs[i].name,
|
|
414
|
+
strlen(insn_update_flgs[i].name))) {
|
|
415
|
+
insn->detail->arm.update_flags = true;
|
|
416
|
+
// we have to update regs_write array as well
|
|
417
|
+
for (j = 0; j < ARR_SIZE(insn->detail->regs_write); j++) {
|
|
418
|
+
if (insn->detail->regs_write[j] == 0) {
|
|
419
|
+
insn->detail->regs_write[j] = ARM_REG_CPSR;
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
break;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// instruction should not have invalid CC
|
|
429
|
+
if (insn->detail->arm.cc == ARM_CC_INVALID) {
|
|
430
|
+
insn->detail->arm.cc = ARM_CC_AL;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// manual fix for some special instructions
|
|
434
|
+
// printf(">>> id: %u, mcid: %u\n", insn->id, mci->Opcode);
|
|
435
|
+
switch(mci->Opcode) {
|
|
436
|
+
default:
|
|
437
|
+
break;
|
|
438
|
+
case ARM_MOVPCLR:
|
|
439
|
+
insn->detail->arm.operands[0].type = ARM_OP_REG;
|
|
440
|
+
insn->detail->arm.operands[0].reg = ARM_REG_PC;
|
|
441
|
+
insn->detail->arm.operands[0].access = CS_AC_WRITE;
|
|
442
|
+
insn->detail->arm.operands[1].type = ARM_OP_REG;
|
|
443
|
+
insn->detail->arm.operands[1].reg = ARM_REG_LR;
|
|
444
|
+
insn->detail->arm.operands[1].access = CS_AC_READ;
|
|
445
|
+
insn->detail->arm.op_count = 2;
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
|
451
|
+
{
|
|
452
|
+
MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
|
|
453
|
+
unsigned Opcode = MCInst_getOpcode(MI), tmp, i;
|
|
454
|
+
|
|
455
|
+
//printf(">>> Opcode = %u\n", Opcode);
|
|
456
|
+
switch (Opcode) {
|
|
457
|
+
// Check for MOVs and print canonical forms, instead.
|
|
458
|
+
case ARM_MOVsr: {
|
|
459
|
+
// FIXME: Thumb variants?
|
|
460
|
+
unsigned int opc;
|
|
461
|
+
MCOperand *Dst = MCInst_getOperand(MI, 0);
|
|
462
|
+
MCOperand *MO1 = MCInst_getOperand(MI, 1);
|
|
463
|
+
MCOperand *MO2 = MCInst_getOperand(MI, 2);
|
|
464
|
+
MCOperand *MO3 = MCInst_getOperand(MI, 3);
|
|
465
|
+
|
|
466
|
+
opc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3));
|
|
467
|
+
SStream_concat0(O, ARM_AM_getShiftOpcStr(opc));
|
|
468
|
+
|
|
469
|
+
switch (opc) {
|
|
470
|
+
default: break;
|
|
471
|
+
case ARM_AM_asr:
|
|
472
|
+
MCInst_setOpcodePub(MI, ARM_INS_ASR);
|
|
473
|
+
break;
|
|
474
|
+
case ARM_AM_lsl:
|
|
475
|
+
MCInst_setOpcodePub(MI, ARM_INS_LSL);
|
|
476
|
+
break;
|
|
477
|
+
case ARM_AM_lsr:
|
|
478
|
+
MCInst_setOpcodePub(MI, ARM_INS_LSR);
|
|
479
|
+
break;
|
|
480
|
+
case ARM_AM_ror:
|
|
481
|
+
MCInst_setOpcodePub(MI, ARM_INS_ROR);
|
|
482
|
+
break;
|
|
483
|
+
case ARM_AM_rrx:
|
|
484
|
+
MCInst_setOpcodePub(MI, ARM_INS_RRX);
|
|
485
|
+
break;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
printSBitModifierOperand(MI, 6, O);
|
|
489
|
+
printPredicateOperand(MI, 4, O);
|
|
490
|
+
|
|
491
|
+
SStream_concat0(O, "\t");
|
|
492
|
+
printRegName(MI->csh, O, MCOperand_getReg(Dst));
|
|
493
|
+
|
|
494
|
+
if (MI->csh->detail) {
|
|
495
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
496
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
|
|
497
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
|
|
498
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
SStream_concat0(O, ", ");
|
|
502
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
503
|
+
|
|
504
|
+
if (MI->csh->detail) {
|
|
505
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
506
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
507
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
508
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
SStream_concat0(O, ", ");
|
|
512
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
513
|
+
|
|
514
|
+
if (MI->csh->detail) {
|
|
515
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
516
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO2);
|
|
517
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
518
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
case ARM_MOVsi: {
|
|
525
|
+
// FIXME: Thumb variants?
|
|
526
|
+
unsigned int opc;
|
|
527
|
+
MCOperand *Dst = MCInst_getOperand(MI, 0);
|
|
528
|
+
MCOperand *MO1 = MCInst_getOperand(MI, 1);
|
|
529
|
+
MCOperand *MO2 = MCInst_getOperand(MI, 2);
|
|
530
|
+
|
|
531
|
+
opc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2));
|
|
532
|
+
SStream_concat0(O, ARM_AM_getShiftOpcStr(opc));
|
|
533
|
+
|
|
534
|
+
switch(opc) {
|
|
535
|
+
default:
|
|
536
|
+
break;
|
|
537
|
+
case ARM_AM_asr:
|
|
538
|
+
MCInst_setOpcodePub(MI, ARM_INS_ASR);
|
|
539
|
+
break;
|
|
540
|
+
case ARM_AM_lsl:
|
|
541
|
+
MCInst_setOpcodePub(MI, ARM_INS_LSL);
|
|
542
|
+
break;
|
|
543
|
+
case ARM_AM_lsr:
|
|
544
|
+
MCInst_setOpcodePub(MI, ARM_INS_LSR);
|
|
545
|
+
break;
|
|
546
|
+
case ARM_AM_ror:
|
|
547
|
+
MCInst_setOpcodePub(MI, ARM_INS_ROR);
|
|
548
|
+
break;
|
|
549
|
+
case ARM_AM_rrx:
|
|
550
|
+
MCInst_setOpcodePub(MI, ARM_INS_RRX);
|
|
551
|
+
break;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
printSBitModifierOperand(MI, 5, O);
|
|
555
|
+
printPredicateOperand(MI, 3, O);
|
|
556
|
+
|
|
557
|
+
SStream_concat0(O, "\t");
|
|
558
|
+
printRegName(MI->csh, O, MCOperand_getReg(Dst));
|
|
559
|
+
|
|
560
|
+
if (MI->csh->detail) {
|
|
561
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
562
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
|
|
563
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
|
|
564
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
SStream_concat0(O, ", ");
|
|
568
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
569
|
+
if (MI->csh->detail) {
|
|
570
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
571
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
572
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
573
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
if (opc == ARM_AM_rrx) {
|
|
577
|
+
//printAnnotation(O, Annot);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
SStream_concat0(O, ", ");
|
|
582
|
+
tmp = translateShiftImm(getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
|
|
583
|
+
printUInt32Bang(O, tmp);
|
|
584
|
+
if (MI->csh->detail) {
|
|
585
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type =
|
|
586
|
+
(arm_shifter)opc;
|
|
587
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = tmp;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// A8.6.123 PUSH
|
|
594
|
+
case ARM_STMDB_UPD:
|
|
595
|
+
case ARM_t2STMDB_UPD:
|
|
596
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
|
|
597
|
+
MCInst_getNumOperands(MI) > 5) {
|
|
598
|
+
// Should only print PUSH if there are at least two registers in the list.
|
|
599
|
+
SStream_concat0(O, "push");
|
|
600
|
+
MCInst_setOpcodePub(MI, ARM_INS_PUSH);
|
|
601
|
+
printPredicateOperand(MI, 2, O);
|
|
602
|
+
|
|
603
|
+
if (Opcode == ARM_t2STMDB_UPD)
|
|
604
|
+
SStream_concat0(O, ".w");
|
|
605
|
+
|
|
606
|
+
SStream_concat0(O, "\t");
|
|
607
|
+
|
|
608
|
+
if (MI->csh->detail) {
|
|
609
|
+
MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
|
|
610
|
+
MI->flat_insn->detail->regs_read_count++;
|
|
611
|
+
MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
|
|
612
|
+
MI->flat_insn->detail->regs_write_count++;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
printRegisterList(MI, 4, O);
|
|
616
|
+
return;
|
|
617
|
+
} else
|
|
618
|
+
break;
|
|
619
|
+
|
|
620
|
+
case ARM_STR_PRE_IMM:
|
|
621
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP &&
|
|
622
|
+
MCOperand_getImm(MCInst_getOperand(MI, 3)) == -4) {
|
|
623
|
+
SStream_concat0(O, "push");
|
|
624
|
+
MCInst_setOpcodePub(MI, ARM_INS_PUSH);
|
|
625
|
+
|
|
626
|
+
printPredicateOperand(MI, 4, O);
|
|
627
|
+
|
|
628
|
+
SStream_concat0(O, "\t{");
|
|
629
|
+
|
|
630
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
|
|
631
|
+
|
|
632
|
+
if (MI->csh->detail) {
|
|
633
|
+
#ifndef CAPSTONE_DIET
|
|
634
|
+
uint8_t access;
|
|
635
|
+
#endif
|
|
636
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
637
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 1));
|
|
638
|
+
#ifndef CAPSTONE_DIET
|
|
639
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
640
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
641
|
+
MI->ac_idx++;
|
|
642
|
+
#endif
|
|
643
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
SStream_concat0(O, "}");
|
|
647
|
+
|
|
648
|
+
return;
|
|
649
|
+
} else
|
|
650
|
+
break;
|
|
651
|
+
|
|
652
|
+
// A8.6.122 POP
|
|
653
|
+
case ARM_LDMIA_UPD:
|
|
654
|
+
case ARM_t2LDMIA_UPD:
|
|
655
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP &&
|
|
656
|
+
MCInst_getNumOperands(MI) > 5) {
|
|
657
|
+
// Should only print POP if there are at least two registers in the list.
|
|
658
|
+
SStream_concat0(O, "pop");
|
|
659
|
+
MCInst_setOpcodePub(MI, ARM_INS_POP);
|
|
660
|
+
|
|
661
|
+
printPredicateOperand(MI, 2, O);
|
|
662
|
+
if (Opcode == ARM_t2LDMIA_UPD)
|
|
663
|
+
SStream_concat0(O, ".w");
|
|
664
|
+
|
|
665
|
+
SStream_concat0(O, "\t");
|
|
666
|
+
|
|
667
|
+
// unlike LDM, POP only write to registers, so skip the 1st access code
|
|
668
|
+
MI->ac_idx = 1;
|
|
669
|
+
if (MI->csh->detail) {
|
|
670
|
+
MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
|
|
671
|
+
MI->flat_insn->detail->regs_read_count++;
|
|
672
|
+
MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
|
|
673
|
+
MI->flat_insn->detail->regs_write_count++;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
printRegisterList(MI, 4, O);
|
|
677
|
+
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
break;
|
|
681
|
+
|
|
682
|
+
case ARM_LDR_POST_IMM:
|
|
683
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 2)) == ARM_SP) {
|
|
684
|
+
MCOperand *MO2 = MCInst_getOperand(MI, 4);
|
|
685
|
+
|
|
686
|
+
if (getAM2Offset((unsigned int)MCOperand_getImm(MO2)) == 4) {
|
|
687
|
+
SStream_concat0(O, "pop");
|
|
688
|
+
MCInst_setOpcodePub(MI, ARM_INS_POP);
|
|
689
|
+
printPredicateOperand(MI, 5, O);
|
|
690
|
+
SStream_concat0(O, "\t{");
|
|
691
|
+
|
|
692
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 0)));
|
|
693
|
+
|
|
694
|
+
if (MI->csh->detail) {
|
|
695
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
696
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
|
|
697
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
|
|
698
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
699
|
+
// this instruction implicitly read/write SP register
|
|
700
|
+
MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
|
|
701
|
+
MI->flat_insn->detail->regs_read_count++;
|
|
702
|
+
MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
|
|
703
|
+
MI->flat_insn->detail->regs_write_count++;
|
|
704
|
+
}
|
|
705
|
+
SStream_concat0(O, "}");
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
break;
|
|
710
|
+
|
|
711
|
+
// A8.6.355 VPUSH
|
|
712
|
+
case ARM_VSTMSDB_UPD:
|
|
713
|
+
case ARM_VSTMDDB_UPD:
|
|
714
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
|
|
715
|
+
SStream_concat0(O, "vpush");
|
|
716
|
+
MCInst_setOpcodePub(MI, ARM_INS_VPUSH);
|
|
717
|
+
printPredicateOperand(MI, 2, O);
|
|
718
|
+
SStream_concat0(O, "\t");
|
|
719
|
+
printRegisterList(MI, 4, O);
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
break;
|
|
723
|
+
|
|
724
|
+
// A8.6.354 VPOP
|
|
725
|
+
case ARM_VLDMSIA_UPD:
|
|
726
|
+
case ARM_VLDMDIA_UPD:
|
|
727
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, 0)) == ARM_SP) {
|
|
728
|
+
SStream_concat0(O, "vpop");
|
|
729
|
+
MCInst_setOpcodePub(MI, ARM_INS_VPOP);
|
|
730
|
+
printPredicateOperand(MI, 2, O);
|
|
731
|
+
SStream_concat0(O, "\t");
|
|
732
|
+
printRegisterList(MI, 4, O);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
break;
|
|
736
|
+
|
|
737
|
+
case ARM_tLDMIA: {
|
|
738
|
+
bool Writeback = true;
|
|
739
|
+
unsigned BaseReg = MCOperand_getReg(MCInst_getOperand(MI, 0));
|
|
740
|
+
unsigned i;
|
|
741
|
+
|
|
742
|
+
for (i = 3; i < MCInst_getNumOperands(MI); ++i) {
|
|
743
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, i)) == BaseReg)
|
|
744
|
+
Writeback = false;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
SStream_concat0(O, "ldm");
|
|
748
|
+
MCInst_setOpcodePub(MI, ARM_INS_LDM);
|
|
749
|
+
|
|
750
|
+
printPredicateOperand(MI, 1, O);
|
|
751
|
+
SStream_concat0(O, "\t");
|
|
752
|
+
printRegName(MI->csh, O, BaseReg);
|
|
753
|
+
if (MI->csh->detail) {
|
|
754
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
755
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
|
|
756
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ | CS_AC_WRITE;
|
|
757
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (Writeback) {
|
|
761
|
+
MI->writeback = true;
|
|
762
|
+
SStream_concat0(O, "!");
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
SStream_concat0(O, ", ");
|
|
766
|
+
printRegisterList(MI, 3, O);
|
|
767
|
+
return;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
// Combine 2 GPRs from disassember into a GPRPair to match with instr def.
|
|
771
|
+
// ldrexd/strexd require even/odd GPR pair. To enforce this constraint,
|
|
772
|
+
// a single GPRPair reg operand is used in the .td file to replace the two
|
|
773
|
+
// GPRs. However, when decoding them, the two GRPs cannot be automatically
|
|
774
|
+
// expressed as a GPRPair, so we have to manually merge them.
|
|
775
|
+
// FIXME: We would really like to be able to tablegen'erate this.
|
|
776
|
+
case ARM_LDREXD:
|
|
777
|
+
case ARM_STREXD:
|
|
778
|
+
case ARM_LDAEXD:
|
|
779
|
+
case ARM_STLEXD: {
|
|
780
|
+
const MCRegisterClass *MRC = MCRegisterInfo_getRegClass(MRI, ARM_GPRRegClassID);
|
|
781
|
+
bool isStore = Opcode == ARM_STREXD || Opcode == ARM_STLEXD;
|
|
782
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, isStore ? 1 : 0));
|
|
783
|
+
|
|
784
|
+
if (MCRegisterClass_contains(MRC, Reg)) {
|
|
785
|
+
MCInst NewMI;
|
|
786
|
+
|
|
787
|
+
MCInst_Init(&NewMI);
|
|
788
|
+
MCInst_setOpcode(&NewMI, Opcode);
|
|
789
|
+
|
|
790
|
+
if (isStore)
|
|
791
|
+
MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, 0));
|
|
792
|
+
|
|
793
|
+
MCOperand_CreateReg0(&NewMI, MCRegisterInfo_getMatchingSuperReg(MRI, Reg, ARM_gsub_0,
|
|
794
|
+
MCRegisterInfo_getRegClass(MRI, ARM_GPRPairRegClassID)));
|
|
795
|
+
|
|
796
|
+
// Copy the rest operands into NewMI.
|
|
797
|
+
for(i = isStore ? 3 : 2; i < MCInst_getNumOperands(MI); ++i)
|
|
798
|
+
MCInst_addOperand2(&NewMI, MCInst_getOperand(MI, i));
|
|
799
|
+
|
|
800
|
+
printInstruction(&NewMI, O);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
case ARM_TSB:
|
|
807
|
+
case ARM_t2TSB:
|
|
808
|
+
SStream_concat0(O, "tsb\tcsync");
|
|
809
|
+
MCInst_setOpcodePub(MI, ARM_INS_TSB);
|
|
810
|
+
// TODO: add csync to operands[]?
|
|
811
|
+
return;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
MI->MRI = MRI;
|
|
815
|
+
|
|
816
|
+
if (!printAliasInstr(MI, O)) {
|
|
817
|
+
printInstruction(MI, O);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
|
822
|
+
{
|
|
823
|
+
int32_t imm;
|
|
824
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNo);
|
|
825
|
+
|
|
826
|
+
if (MCOperand_isReg(Op)) {
|
|
827
|
+
unsigned Reg = MCOperand_getReg(Op);
|
|
828
|
+
|
|
829
|
+
printRegName(MI->csh, O, Reg);
|
|
830
|
+
|
|
831
|
+
if (MI->csh->detail) {
|
|
832
|
+
if (MI->csh->doing_mem) {
|
|
833
|
+
if (MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base == ARM_REG_INVALID)
|
|
834
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = Reg;
|
|
835
|
+
else
|
|
836
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = Reg;
|
|
837
|
+
} else {
|
|
838
|
+
#ifndef CAPSTONE_DIET
|
|
839
|
+
uint8_t access;
|
|
840
|
+
#endif
|
|
841
|
+
|
|
842
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
843
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
|
|
844
|
+
#ifndef CAPSTONE_DIET
|
|
845
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
846
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
847
|
+
MI->ac_idx++;
|
|
848
|
+
#endif
|
|
849
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
} else if (MCOperand_isImm(Op)) {
|
|
853
|
+
unsigned int opc = MCInst_getOpcode(MI);
|
|
854
|
+
|
|
855
|
+
imm = (int32_t)MCOperand_getImm(Op);
|
|
856
|
+
|
|
857
|
+
// relative branch only has relative offset, so we have to update it
|
|
858
|
+
// to reflect absolute address.
|
|
859
|
+
// Note: in ARM, PC is always 2 instructions ahead, so we have to
|
|
860
|
+
// add 8 in ARM mode, or 4 in Thumb mode
|
|
861
|
+
// printf(">> opcode: %u\n", MCInst_getOpcode(MI));
|
|
862
|
+
if (ARM_rel_branch(MI->csh, opc)) {
|
|
863
|
+
uint32_t address;
|
|
864
|
+
|
|
865
|
+
// only do this for relative branch
|
|
866
|
+
if (MI->csh->mode & CS_MODE_THUMB) {
|
|
867
|
+
address = (uint32_t)MI->address + 4;
|
|
868
|
+
if (ARM_blx_to_arm_mode(MI->csh, opc)) {
|
|
869
|
+
// here need to align down to the nearest 4-byte address
|
|
870
|
+
#define _ALIGN_DOWN(v, align_width) ((v/align_width)*align_width)
|
|
871
|
+
address = _ALIGN_DOWN(address, 4);
|
|
872
|
+
#undef _ALIGN_DOWN
|
|
873
|
+
}
|
|
874
|
+
} else {
|
|
875
|
+
address = (uint32_t)MI->address + 8;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
imm += address;
|
|
879
|
+
printUInt32Bang(O, imm);
|
|
880
|
+
} else {
|
|
881
|
+
switch(MI->flat_insn->id) {
|
|
882
|
+
default:
|
|
883
|
+
if (MI->csh->imm_unsigned)
|
|
884
|
+
printUInt32Bang(O, imm);
|
|
885
|
+
else
|
|
886
|
+
printInt32Bang(O, imm);
|
|
887
|
+
break;
|
|
888
|
+
case ARM_INS_AND:
|
|
889
|
+
case ARM_INS_ORR:
|
|
890
|
+
case ARM_INS_EOR:
|
|
891
|
+
case ARM_INS_BIC:
|
|
892
|
+
case ARM_INS_MVN:
|
|
893
|
+
// do not print number in negative form
|
|
894
|
+
printUInt32Bang(O, imm);
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
if (MI->csh->detail) {
|
|
900
|
+
if (MI->csh->doing_mem)
|
|
901
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = imm;
|
|
902
|
+
else {
|
|
903
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
904
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
|
|
905
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
912
|
+
{
|
|
913
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
914
|
+
int32_t OffImm;
|
|
915
|
+
bool isSub;
|
|
916
|
+
SStream_concat0(O, "[pc, ");
|
|
917
|
+
|
|
918
|
+
OffImm = (int32_t)MCOperand_getImm(MO1);
|
|
919
|
+
isSub = OffImm < 0;
|
|
920
|
+
|
|
921
|
+
// Special value for #-0. All others are normal.
|
|
922
|
+
if (OffImm == INT32_MIN)
|
|
923
|
+
OffImm = 0;
|
|
924
|
+
|
|
925
|
+
if (isSub) {
|
|
926
|
+
SStream_concat(O, "#-0x%x", -OffImm);
|
|
927
|
+
} else {
|
|
928
|
+
printUInt32Bang(O, OffImm);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
SStream_concat0(O, "]");
|
|
932
|
+
|
|
933
|
+
if (MI->csh->detail) {
|
|
934
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
|
|
935
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_PC;
|
|
936
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
|
937
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
|
938
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
|
|
939
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
940
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// so_reg is a 4-operand unit corresponding to register forms of the A5.1
|
|
945
|
+
// "Addressing Mode 1 - Data-processing operands" forms. This includes:
|
|
946
|
+
// REG 0 0 - e.g. R5
|
|
947
|
+
// REG REG 0,SH_OPC - e.g. R5, ROR R3
|
|
948
|
+
// REG 0 IMM,SH_OPC - e.g. R5, LSL #3
|
|
949
|
+
static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
950
|
+
{
|
|
951
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
952
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
953
|
+
MCOperand *MO3 = MCInst_getOperand(MI, OpNum + 2);
|
|
954
|
+
ARM_AM_ShiftOpc ShOpc;
|
|
955
|
+
|
|
956
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
957
|
+
|
|
958
|
+
if (MI->csh->detail) {
|
|
959
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
960
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
961
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
962
|
+
|
|
963
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (MCOperand_getImm(MO3) & 7) + ARM_SFT_ASR_REG - 1;
|
|
964
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// Print the shift opc.
|
|
968
|
+
ShOpc = ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO3));
|
|
969
|
+
SStream_concat0(O, ", ");
|
|
970
|
+
SStream_concat0(O, ARM_AM_getShiftOpcStr(ShOpc));
|
|
971
|
+
if (ShOpc == ARM_AM_rrx)
|
|
972
|
+
return;
|
|
973
|
+
|
|
974
|
+
SStream_concat0(O, " ");
|
|
975
|
+
|
|
976
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
977
|
+
|
|
978
|
+
if (MI->csh->detail)
|
|
979
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = MCOperand_getReg(MO2);
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
983
|
+
{
|
|
984
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
985
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
986
|
+
|
|
987
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
988
|
+
|
|
989
|
+
if (MI->csh->detail) {
|
|
990
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
991
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
992
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
993
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
// Print the shift opc.
|
|
997
|
+
printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
|
|
998
|
+
getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
//===--------------------------------------------------------------------===//
|
|
1002
|
+
// Addressing Mode #2
|
|
1003
|
+
//===--------------------------------------------------------------------===//
|
|
1004
|
+
|
|
1005
|
+
static void printAM2PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O)
|
|
1006
|
+
{
|
|
1007
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1008
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
|
|
1009
|
+
MCOperand *MO3 = MCInst_getOperand(MI, Op + 2);
|
|
1010
|
+
unsigned int imm3 = (unsigned int)MCOperand_getImm(MO3);
|
|
1011
|
+
ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO3));
|
|
1012
|
+
|
|
1013
|
+
SStream_concat0(O, "[");
|
|
1014
|
+
set_mem_access(MI, true);
|
|
1015
|
+
|
|
1016
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1017
|
+
if (MI->csh->detail) {
|
|
1018
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (!MCOperand_getReg(MO2)) {
|
|
1022
|
+
unsigned tmp = getAM2Offset(imm3);
|
|
1023
|
+
if (tmp) { // Don't print +0.
|
|
1024
|
+
subtracted = getAM2Op(imm3);
|
|
1025
|
+
|
|
1026
|
+
SStream_concat0(O, ", ");
|
|
1027
|
+
if (tmp > HEX_THRESHOLD)
|
|
1028
|
+
SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), tmp);
|
|
1029
|
+
else
|
|
1030
|
+
SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), tmp);
|
|
1031
|
+
if (MI->csh->detail) {
|
|
1032
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (arm_shifter)getAM2Op(imm3);
|
|
1033
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = tmp;
|
|
1034
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
SStream_concat0(O, "]");
|
|
1039
|
+
set_mem_access(MI, false);
|
|
1040
|
+
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
SStream_concat0(O, ", ");
|
|
1045
|
+
SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
|
|
1046
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
1047
|
+
if (MI->csh->detail) {
|
|
1048
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
|
|
1049
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
printRegImmShift(MI, O, getAM2ShiftOpc(imm3), getAM2Offset(imm3));
|
|
1053
|
+
SStream_concat0(O, "]");
|
|
1054
|
+
set_mem_access(MI, false);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
static void printAddrModeTBB(MCInst *MI, unsigned Op, SStream *O)
|
|
1058
|
+
{
|
|
1059
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1060
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
|
|
1061
|
+
|
|
1062
|
+
SStream_concat0(O, "[");
|
|
1063
|
+
set_mem_access(MI, true);
|
|
1064
|
+
|
|
1065
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1066
|
+
|
|
1067
|
+
if (MI->csh->detail)
|
|
1068
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1069
|
+
|
|
1070
|
+
SStream_concat0(O, ", ");
|
|
1071
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
1072
|
+
|
|
1073
|
+
if (MI->csh->detail)
|
|
1074
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
|
|
1075
|
+
|
|
1076
|
+
SStream_concat0(O, "]");
|
|
1077
|
+
set_mem_access(MI, false);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
static void printAddrModeTBH(MCInst *MI, unsigned Op, SStream *O)
|
|
1081
|
+
{
|
|
1082
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1083
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
|
|
1084
|
+
|
|
1085
|
+
SStream_concat0(O, "[");
|
|
1086
|
+
set_mem_access(MI, true);
|
|
1087
|
+
|
|
1088
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1089
|
+
|
|
1090
|
+
if (MI->csh->detail)
|
|
1091
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1092
|
+
|
|
1093
|
+
SStream_concat0(O, ", ");
|
|
1094
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
1095
|
+
|
|
1096
|
+
if (MI->csh->detail)
|
|
1097
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
|
|
1098
|
+
|
|
1099
|
+
SStream_concat0(O, ", lsl #1]");
|
|
1100
|
+
|
|
1101
|
+
if (MI->csh->detail) {
|
|
1102
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = ARM_SFT_LSL;
|
|
1103
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = 1;
|
|
1104
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.lshift = 1;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
set_mem_access(MI, false);
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
static void printAddrMode2Operand(MCInst *MI, unsigned Op, SStream *O)
|
|
1111
|
+
{
|
|
1112
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1113
|
+
|
|
1114
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
1115
|
+
printOperand(MI, Op, O);
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
//#ifndef NDEBUG
|
|
1120
|
+
// const MCOperand &MO3 = MI->getOperand(Op + 2);
|
|
1121
|
+
// unsigned IdxMode = ARM_AM::getAM2IdxMode(MO3.getImm());
|
|
1122
|
+
// assert(IdxMode != ARMII::IndexModePost && "Should be pre or offset index op");
|
|
1123
|
+
//#endif
|
|
1124
|
+
|
|
1125
|
+
printAM2PreOrOffsetIndexOp(MI, Op, O);
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1129
|
+
{
|
|
1130
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1131
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1132
|
+
ARM_AM_AddrOpc subtracted = getAM2Op((unsigned int)MCOperand_getImm(MO2));
|
|
1133
|
+
|
|
1134
|
+
if (!MCOperand_getReg(MO1)) {
|
|
1135
|
+
unsigned ImmOffs = getAM2Offset((unsigned int)MCOperand_getImm(MO2));
|
|
1136
|
+
if (ImmOffs > HEX_THRESHOLD)
|
|
1137
|
+
SStream_concat(O, "#%s0x%x",
|
|
1138
|
+
ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
|
|
1139
|
+
else
|
|
1140
|
+
SStream_concat(O, "#%s%u",
|
|
1141
|
+
ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
|
|
1142
|
+
|
|
1143
|
+
if (MI->csh->detail) {
|
|
1144
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1145
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
|
|
1146
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1147
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1148
|
+
}
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
|
|
1153
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1154
|
+
|
|
1155
|
+
if (MI->csh->detail) {
|
|
1156
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1157
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
1158
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1159
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1160
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
printRegImmShift(MI, O, getAM2ShiftOpc((unsigned int)MCOperand_getImm(MO2)),
|
|
1164
|
+
getAM2Offset((unsigned int)MCOperand_getImm(MO2)));
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
//===--------------------------------------------------------------------===//
|
|
1168
|
+
// Addressing Mode #3
|
|
1169
|
+
//===--------------------------------------------------------------------===//
|
|
1170
|
+
|
|
1171
|
+
static void printAM3PreOrOffsetIndexOp(MCInst *MI, unsigned Op, SStream *O,
|
|
1172
|
+
bool AlwaysPrintImm0)
|
|
1173
|
+
{
|
|
1174
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1175
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op+1);
|
|
1176
|
+
MCOperand *MO3 = MCInst_getOperand(MI, Op+2);
|
|
1177
|
+
ARM_AM_AddrOpc sign = getAM3Op((unsigned int)MCOperand_getImm(MO3));
|
|
1178
|
+
unsigned ImmOffs;
|
|
1179
|
+
|
|
1180
|
+
SStream_concat0(O, "[");
|
|
1181
|
+
set_mem_access(MI, true);
|
|
1182
|
+
|
|
1183
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1184
|
+
|
|
1185
|
+
if (MI->csh->detail)
|
|
1186
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1187
|
+
|
|
1188
|
+
if (MCOperand_getReg(MO2)) {
|
|
1189
|
+
SStream_concat0(O, ", ");
|
|
1190
|
+
SStream_concat0(O, ARM_AM_getAddrOpcStr(sign));
|
|
1191
|
+
|
|
1192
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
1193
|
+
|
|
1194
|
+
if (MI->csh->detail) {
|
|
1195
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
|
|
1196
|
+
if (sign == ARM_AM_sub) {
|
|
1197
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = -1;
|
|
1198
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
SStream_concat0(O, "]");
|
|
1203
|
+
set_mem_access(MI, false);
|
|
1204
|
+
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// If the op is sub we have to print the immediate even if it is 0
|
|
1209
|
+
ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO3));
|
|
1210
|
+
|
|
1211
|
+
if (AlwaysPrintImm0 || ImmOffs || (sign == ARM_AM_sub)) {
|
|
1212
|
+
if (ImmOffs > HEX_THRESHOLD)
|
|
1213
|
+
SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(sign), ImmOffs);
|
|
1214
|
+
else
|
|
1215
|
+
SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(sign), ImmOffs);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
if (MI->csh->detail) {
|
|
1219
|
+
if (sign == ARM_AM_sub) {
|
|
1220
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = -(int)ImmOffs;
|
|
1221
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = true;
|
|
1222
|
+
} else
|
|
1223
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = (int)ImmOffs;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
SStream_concat0(O, "]");
|
|
1227
|
+
set_mem_access(MI, false);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
static void printAddrMode3Operand(MCInst *MI, unsigned Op, SStream *O,
|
|
1231
|
+
bool AlwaysPrintImm0)
|
|
1232
|
+
{
|
|
1233
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
1234
|
+
|
|
1235
|
+
if (!MCOperand_isReg(MO1)) { // For label symbolic references.
|
|
1236
|
+
printOperand(MI, Op, O);
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
printAM3PreOrOffsetIndexOp(MI, Op, O, AlwaysPrintImm0);
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1244
|
+
{
|
|
1245
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1246
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1247
|
+
ARM_AM_AddrOpc subtracted = getAM3Op((unsigned int)MCOperand_getImm(MO2));
|
|
1248
|
+
unsigned ImmOffs;
|
|
1249
|
+
|
|
1250
|
+
if (MCOperand_getReg(MO1)) {
|
|
1251
|
+
SStream_concat0(O, ARM_AM_getAddrOpcStr(subtracted));
|
|
1252
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1253
|
+
|
|
1254
|
+
if (MI->csh->detail) {
|
|
1255
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1256
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
1257
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1258
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1259
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
ImmOffs = getAM3Offset((unsigned int)MCOperand_getImm(MO2));
|
|
1266
|
+
if (ImmOffs > HEX_THRESHOLD)
|
|
1267
|
+
SStream_concat(O, "#%s0x%x", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
|
|
1268
|
+
else
|
|
1269
|
+
SStream_concat(O, "#%s%u", ARM_AM_getAddrOpcStr(subtracted), ImmOffs);
|
|
1270
|
+
|
|
1271
|
+
if (MI->csh->detail) {
|
|
1272
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1273
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = ImmOffs;
|
|
1274
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
|
1275
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
static void printPostIdxImm8Operand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1280
|
+
{
|
|
1281
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
1282
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MO);
|
|
1283
|
+
|
|
1284
|
+
if ((Imm & 0xff) > HEX_THRESHOLD)
|
|
1285
|
+
SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
|
|
1286
|
+
else
|
|
1287
|
+
SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), (Imm & 0xff));
|
|
1288
|
+
|
|
1289
|
+
if (MI->csh->detail) {
|
|
1290
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1291
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm & 0xff;
|
|
1292
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1297
|
+
{
|
|
1298
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1299
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1300
|
+
|
|
1301
|
+
SStream_concat0(O, (MCOperand_getImm(MO2) ? "" : "-"));
|
|
1302
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1303
|
+
|
|
1304
|
+
if (MI->csh->detail) {
|
|
1305
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1306
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
|
1307
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1308
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
static void printPostIdxImm8s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1313
|
+
{
|
|
1314
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
1315
|
+
int Imm = (int)MCOperand_getImm(MO);
|
|
1316
|
+
|
|
1317
|
+
if (((Imm & 0xff) << 2) > HEX_THRESHOLD) {
|
|
1318
|
+
SStream_concat(O, "#%s0x%x", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
|
|
1319
|
+
} else {
|
|
1320
|
+
SStream_concat(O, "#%s%u", ((Imm & 256) ? "" : "-"), ((Imm & 0xff) << 2));
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
if (MI->csh->detail) {
|
|
1324
|
+
int v = (Imm & 256) ? ((Imm & 0xff) << 2) : -((Imm & 0xff) << 2);
|
|
1325
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1326
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = v;
|
|
1327
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
|
|
1331
|
+
static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O,
|
|
1332
|
+
bool AlwaysPrintImm0)
|
|
1333
|
+
{
|
|
1334
|
+
unsigned ImmOffs;
|
|
1335
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1336
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1337
|
+
ARM_AM_AddrOpc Op = ARM_AM_getAM5Op((unsigned int)MCOperand_getImm(MO2));
|
|
1338
|
+
|
|
1339
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
1340
|
+
printOperand(MI, OpNum, O);
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
SStream_concat0(O, "[");
|
|
1345
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1346
|
+
|
|
1347
|
+
if (MI->csh->detail) {
|
|
1348
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
|
|
1349
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1350
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
|
1351
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
|
1352
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
|
|
1353
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
|
|
1357
|
+
if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) {
|
|
1358
|
+
if (ImmOffs * 4 > HEX_THRESHOLD)
|
|
1359
|
+
SStream_concat(O, ", #%s0x%x",
|
|
1360
|
+
ARM_AM_getAddrOpcStr(Op),
|
|
1361
|
+
ImmOffs * 4);
|
|
1362
|
+
else
|
|
1363
|
+
SStream_concat(O, ", #%s%u",
|
|
1364
|
+
ARM_AM_getAddrOpcStr(Op),
|
|
1365
|
+
ImmOffs * 4);
|
|
1366
|
+
|
|
1367
|
+
if (MI->csh->detail) {
|
|
1368
|
+
if (Op)
|
|
1369
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = ImmOffs * 4;
|
|
1370
|
+
else
|
|
1371
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = -(int)ImmOffs * 4;
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
SStream_concat0(O, "]");
|
|
1376
|
+
|
|
1377
|
+
if (MI->csh->detail) {
|
|
1378
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1379
|
+
}
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
static void printAddrMode5FP16Operand(MCInst *MI, unsigned OpNum, SStream *O,
|
|
1383
|
+
bool AlwaysPrintImm0)
|
|
1384
|
+
{
|
|
1385
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1386
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1387
|
+
unsigned ImmOffs = getAM5FP16Offset((unsigned)MCOperand_getImm(MO2));
|
|
1388
|
+
unsigned Op = getAM5FP16Op((unsigned)MCOperand_getImm(MO2));
|
|
1389
|
+
|
|
1390
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
1391
|
+
printOperand(MI, OpNum, O);
|
|
1392
|
+
return;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
SStream_concat0(O, "[");
|
|
1396
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1397
|
+
|
|
1398
|
+
if (MI->csh->detail) {
|
|
1399
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
|
|
1400
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1401
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
|
1402
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
|
1403
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
|
|
1404
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
if (AlwaysPrintImm0 || ImmOffs || Op == ARM_AM_sub) {
|
|
1408
|
+
if (ImmOffs * 2 > HEX_THRESHOLD)
|
|
1409
|
+
SStream_concat(O, ", #%s0x%x", ARM_AM_getAddrOpcStr(Op), ImmOffs * 2);
|
|
1410
|
+
else
|
|
1411
|
+
SStream_concat(O, ", #%s%u", ARM_AM_getAddrOpcStr(Op), ImmOffs * 2);
|
|
1412
|
+
|
|
1413
|
+
if (MI->csh->detail) {
|
|
1414
|
+
if (Op)
|
|
1415
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = ImmOffs * 2;
|
|
1416
|
+
else
|
|
1417
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = -(int)ImmOffs * 2;
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
SStream_concat0(O, "]");
|
|
1422
|
+
|
|
1423
|
+
if (MI->csh->detail) {
|
|
1424
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
static void printAddrMode6Operand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1429
|
+
{
|
|
1430
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1431
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
1432
|
+
unsigned tmp;
|
|
1433
|
+
|
|
1434
|
+
SStream_concat0(O, "[");
|
|
1435
|
+
set_mem_access(MI, true);
|
|
1436
|
+
|
|
1437
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1438
|
+
|
|
1439
|
+
if (MI->csh->detail)
|
|
1440
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1441
|
+
|
|
1442
|
+
tmp = (unsigned int)MCOperand_getImm(MO2);
|
|
1443
|
+
if (tmp) {
|
|
1444
|
+
if (tmp << 3 > HEX_THRESHOLD)
|
|
1445
|
+
SStream_concat(O, ":0x%x", (tmp << 3));
|
|
1446
|
+
else
|
|
1447
|
+
SStream_concat(O, ":%u", (tmp << 3));
|
|
1448
|
+
|
|
1449
|
+
if (MI->csh->detail)
|
|
1450
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp << 3;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
SStream_concat0(O, "]");
|
|
1454
|
+
set_mem_access(MI, false);
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
static void printAddrMode7Operand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1458
|
+
{
|
|
1459
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
1460
|
+
|
|
1461
|
+
SStream_concat0(O, "[");
|
|
1462
|
+
set_mem_access(MI, true);
|
|
1463
|
+
|
|
1464
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
1465
|
+
|
|
1466
|
+
if (MI->csh->detail)
|
|
1467
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
1468
|
+
|
|
1469
|
+
SStream_concat0(O, "]");
|
|
1470
|
+
set_mem_access(MI, false);
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1474
|
+
{
|
|
1475
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
1476
|
+
|
|
1477
|
+
if (MCOperand_getReg(MO) == 0) {
|
|
1478
|
+
MI->writeback = true;
|
|
1479
|
+
SStream_concat0(O, "!");
|
|
1480
|
+
} else {
|
|
1481
|
+
SStream_concat0(O, ", ");
|
|
1482
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO));
|
|
1483
|
+
|
|
1484
|
+
if (MI->csh->detail) {
|
|
1485
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1486
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO);
|
|
1487
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
1488
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1489
|
+
}
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
static void printBitfieldInvMaskImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1494
|
+
{
|
|
1495
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
1496
|
+
uint32_t v = ~(uint32_t)MCOperand_getImm(MO);
|
|
1497
|
+
int32_t lsb = CountTrailingZeros_32(v);
|
|
1498
|
+
int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
|
|
1499
|
+
|
|
1500
|
+
//assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
|
|
1501
|
+
printUInt32Bang(O, lsb);
|
|
1502
|
+
|
|
1503
|
+
if (width > HEX_THRESHOLD)
|
|
1504
|
+
SStream_concat(O, ", #0x%x", width);
|
|
1505
|
+
else
|
|
1506
|
+
SStream_concat(O, ", #%u", width);
|
|
1507
|
+
|
|
1508
|
+
if (MI->csh->detail) {
|
|
1509
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1510
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = lsb;
|
|
1511
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1512
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1513
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = width;
|
|
1514
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1515
|
+
}
|
|
1516
|
+
}
|
|
1517
|
+
|
|
1518
|
+
static void printMemBOption(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1519
|
+
{
|
|
1520
|
+
unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1521
|
+
SStream_concat0(O, ARM_MB_MemBOptToString(val,
|
|
1522
|
+
ARM_getFeatureBits(MI->csh->mode, ARM_HasV8Ops)));
|
|
1523
|
+
|
|
1524
|
+
if (MI->csh->detail) {
|
|
1525
|
+
MI->flat_insn->detail->arm.mem_barrier = (arm_mem_barrier)(val + 1);
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1530
|
+
{
|
|
1531
|
+
unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1532
|
+
SStream_concat0(O, ARM_ISB_InstSyncBOptToString(val));
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
static void printTraceSyncBOption(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1536
|
+
{
|
|
1537
|
+
unsigned val = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1538
|
+
SStream_concat0(O, ARM_TSB_TraceSyncBOptToString(val));
|
|
1539
|
+
// TODO: add to detail?
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
static void printShiftImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1543
|
+
{
|
|
1544
|
+
unsigned ShiftOp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1545
|
+
bool isASR = (ShiftOp & (1 << 5)) != 0;
|
|
1546
|
+
unsigned Amt = ShiftOp & 0x1f;
|
|
1547
|
+
|
|
1548
|
+
if (isASR) {
|
|
1549
|
+
unsigned tmp = Amt == 0 ? 32 : Amt;
|
|
1550
|
+
if (tmp > HEX_THRESHOLD)
|
|
1551
|
+
SStream_concat(O, ", asr #0x%x", tmp);
|
|
1552
|
+
else
|
|
1553
|
+
SStream_concat(O, ", asr #%u", tmp);
|
|
1554
|
+
|
|
1555
|
+
if (MI->csh->detail) {
|
|
1556
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
|
|
1557
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = tmp;
|
|
1558
|
+
}
|
|
1559
|
+
} else if (Amt) {
|
|
1560
|
+
if (Amt > HEX_THRESHOLD)
|
|
1561
|
+
SStream_concat(O, ", lsl #0x%x", Amt);
|
|
1562
|
+
else
|
|
1563
|
+
SStream_concat(O, ", lsl #%u", Amt);
|
|
1564
|
+
|
|
1565
|
+
if (MI->csh->detail) {
|
|
1566
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
|
|
1567
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Amt;
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
static void printPKHLSLShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1573
|
+
{
|
|
1574
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1575
|
+
|
|
1576
|
+
if (Imm == 0)
|
|
1577
|
+
return;
|
|
1578
|
+
|
|
1579
|
+
//assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
|
|
1580
|
+
if (Imm > HEX_THRESHOLD)
|
|
1581
|
+
SStream_concat(O, ", lsl #0x%x", Imm);
|
|
1582
|
+
else
|
|
1583
|
+
SStream_concat(O, ", lsl #%u", Imm);
|
|
1584
|
+
|
|
1585
|
+
if (MI->csh->detail) {
|
|
1586
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_LSL;
|
|
1587
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm;
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
|
|
1591
|
+
static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1592
|
+
{
|
|
1593
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1594
|
+
|
|
1595
|
+
// A shift amount of 32 is encoded as 0.
|
|
1596
|
+
if (Imm == 0)
|
|
1597
|
+
Imm = 32;
|
|
1598
|
+
|
|
1599
|
+
//assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
|
|
1600
|
+
if (Imm > HEX_THRESHOLD)
|
|
1601
|
+
SStream_concat(O, ", asr #0x%x", Imm);
|
|
1602
|
+
else
|
|
1603
|
+
SStream_concat(O, ", asr #%u", Imm);
|
|
1604
|
+
|
|
1605
|
+
if (MI->csh->detail) {
|
|
1606
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ASR;
|
|
1607
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
// FIXME: push {r1, r2, r3, ...} can exceed the number of operands in MCInst struct
|
|
1612
|
+
static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1613
|
+
{
|
|
1614
|
+
unsigned i, e;
|
|
1615
|
+
#ifndef CAPSTONE_DIET
|
|
1616
|
+
uint8_t access = 0;
|
|
1617
|
+
#endif
|
|
1618
|
+
|
|
1619
|
+
SStream_concat0(O, "{");
|
|
1620
|
+
|
|
1621
|
+
#ifndef CAPSTONE_DIET
|
|
1622
|
+
if (MI->csh->detail) {
|
|
1623
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
1624
|
+
}
|
|
1625
|
+
#endif
|
|
1626
|
+
|
|
1627
|
+
for (i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) {
|
|
1628
|
+
if (i != OpNum)
|
|
1629
|
+
SStream_concat0(O, ", ");
|
|
1630
|
+
|
|
1631
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, i)));
|
|
1632
|
+
|
|
1633
|
+
if (MI->csh->detail) {
|
|
1634
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1635
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, i));
|
|
1636
|
+
#ifndef CAPSTONE_DIET
|
|
1637
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
1638
|
+
#endif
|
|
1639
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
SStream_concat0(O, "}");
|
|
1644
|
+
|
|
1645
|
+
#ifndef CAPSTONE_DIET
|
|
1646
|
+
if (MI->csh->detail) {
|
|
1647
|
+
MI->ac_idx++;
|
|
1648
|
+
}
|
|
1649
|
+
#endif
|
|
1650
|
+
}
|
|
1651
|
+
|
|
1652
|
+
static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1653
|
+
{
|
|
1654
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
1655
|
+
|
|
1656
|
+
printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_0));
|
|
1657
|
+
|
|
1658
|
+
if (MI->csh->detail) {
|
|
1659
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1660
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_0);
|
|
1661
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
SStream_concat0(O, ", ");
|
|
1665
|
+
|
|
1666
|
+
printRegName(MI->csh, O, MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_1));
|
|
1667
|
+
|
|
1668
|
+
if (MI->csh->detail) {
|
|
1669
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
1670
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_gsub_1);
|
|
1671
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
// SETEND BE/LE
|
|
1676
|
+
static void printSetendOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1677
|
+
{
|
|
1678
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
|
1679
|
+
|
|
1680
|
+
if (MCOperand_getImm(Op)) {
|
|
1681
|
+
SStream_concat0(O, "be");
|
|
1682
|
+
|
|
1683
|
+
if (MI->csh->detail) {
|
|
1684
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
|
|
1685
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_BE;
|
|
1686
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1687
|
+
}
|
|
1688
|
+
} else {
|
|
1689
|
+
SStream_concat0(O, "le");
|
|
1690
|
+
|
|
1691
|
+
if (MI->csh->detail) {
|
|
1692
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SETEND;
|
|
1693
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].setend = ARM_SETEND_LE;
|
|
1694
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
static void printCPSIMod(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1700
|
+
{
|
|
1701
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
|
1702
|
+
unsigned int mode = (unsigned int)MCOperand_getImm(Op);
|
|
1703
|
+
|
|
1704
|
+
SStream_concat0(O, ARM_PROC_IModToString(mode));
|
|
1705
|
+
|
|
1706
|
+
if (MI->csh->detail) {
|
|
1707
|
+
MI->flat_insn->detail->arm.cps_mode = mode;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
|
|
1711
|
+
static void printCPSIFlag(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1712
|
+
{
|
|
1713
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
|
1714
|
+
unsigned IFlags = (unsigned int)MCOperand_getImm(Op);
|
|
1715
|
+
int i;
|
|
1716
|
+
|
|
1717
|
+
for (i = 2; i >= 0; --i)
|
|
1718
|
+
if (IFlags & (1 << i)) {
|
|
1719
|
+
SStream_concat0(O, ARM_PROC_IFlagsToString(1 << i));
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
if (IFlags == 0) {
|
|
1723
|
+
SStream_concat0(O, "none");
|
|
1724
|
+
IFlags = ARM_CPSFLAG_NONE;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
if (MI->csh->detail) {
|
|
1728
|
+
MI->flat_insn->detail->arm.cps_flag = IFlags;
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
static void printMSRMaskOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1733
|
+
{
|
|
1734
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
|
1735
|
+
unsigned SpecRegRBit = (unsigned)MCOperand_getImm(Op) >> 4;
|
|
1736
|
+
unsigned Mask = (unsigned)MCOperand_getImm(Op) & 0xf;
|
|
1737
|
+
unsigned reg;
|
|
1738
|
+
|
|
1739
|
+
if (ARM_getFeatureBits(MI->csh->mode, ARM_FeatureMClass)) {
|
|
1740
|
+
const MClassSysReg *TheReg;
|
|
1741
|
+
unsigned SYSm = (unsigned)MCOperand_getImm(Op) & 0xFFF; // 12-bit SYMm
|
|
1742
|
+
unsigned Opcode = MCInst_getOpcode(MI);
|
|
1743
|
+
|
|
1744
|
+
if (Opcode == ARM_t2MSR_M && ARM_getFeatureBits(MI->csh->mode, ARM_FeatureDSP)) {
|
|
1745
|
+
TheReg = lookupMClassSysRegBy12bitSYSmValue(SYSm);
|
|
1746
|
+
if (TheReg && MClassSysReg_isInRequiredFeatures(TheReg, ARM_FeatureDSP)) {
|
|
1747
|
+
SStream_concat0(O, TheReg->Name);
|
|
1748
|
+
ARM_addSysReg(MI, TheReg->sysreg);
|
|
1749
|
+
return;
|
|
1750
|
+
}
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
// Handle the basic 8-bit mask.
|
|
1754
|
+
SYSm &= 0xff;
|
|
1755
|
+
if (Opcode == ARM_t2MSR_M && ARM_getFeatureBits(MI->csh->mode, ARM_HasV7Ops)) {
|
|
1756
|
+
// ARMv7-M deprecates using MSR APSR without a _<bits> qualifier as an
|
|
1757
|
+
// alias for MSR APSR_nzcvq.
|
|
1758
|
+
TheReg = lookupMClassSysRegAPSRNonDeprecated(SYSm);
|
|
1759
|
+
if (TheReg) {
|
|
1760
|
+
SStream_concat0(O, TheReg->Name);
|
|
1761
|
+
ARM_addSysReg(MI, TheReg->sysreg);
|
|
1762
|
+
return;
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
TheReg = lookupMClassSysRegBy8bitSYSmValue(SYSm);
|
|
1767
|
+
if (TheReg) {
|
|
1768
|
+
SStream_concat0(O, TheReg->Name);
|
|
1769
|
+
ARM_addSysReg(MI, TheReg->sysreg);
|
|
1770
|
+
return;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
if (SYSm > HEX_THRESHOLD)
|
|
1774
|
+
SStream_concat(O, "%x", SYSm);
|
|
1775
|
+
else
|
|
1776
|
+
SStream_concat(O, "%u", SYSm);
|
|
1777
|
+
|
|
1778
|
+
if (MI->csh->detail)
|
|
1779
|
+
MCOperand_CreateImm0(MI, SYSm);
|
|
1780
|
+
|
|
1781
|
+
return;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
// As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
|
|
1785
|
+
// APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
|
|
1786
|
+
if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
|
|
1787
|
+
SStream_concat0(O, "apsr_");
|
|
1788
|
+
switch (Mask) {
|
|
1789
|
+
default: // llvm_unreachable("Unexpected mask value!");
|
|
1790
|
+
case 4: SStream_concat0(O, "g"); ARM_addSysReg(MI, ARM_SYSREG_APSR_G); return;
|
|
1791
|
+
case 8: SStream_concat0(O, "nzcvq"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQ); return;
|
|
1792
|
+
case 12: SStream_concat0(O, "nzcvqg"); ARM_addSysReg(MI, ARM_SYSREG_APSR_NZCVQG); return;
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
if (SpecRegRBit) {
|
|
1797
|
+
SStream_concat0(O, "spsr");
|
|
1798
|
+
} else {
|
|
1799
|
+
SStream_concat0(O, "cpsr");
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
reg = 0;
|
|
1803
|
+
if (Mask) {
|
|
1804
|
+
SStream_concat0(O, "_");
|
|
1805
|
+
|
|
1806
|
+
if (Mask & 8) {
|
|
1807
|
+
SStream_concat0(O, "f");
|
|
1808
|
+
reg += SpecRegRBit ? ARM_SYSREG_SPSR_F : ARM_SYSREG_CPSR_F;
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
if (Mask & 4) {
|
|
1812
|
+
SStream_concat0(O, "s");
|
|
1813
|
+
reg += SpecRegRBit ? ARM_SYSREG_SPSR_S : ARM_SYSREG_CPSR_S;
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
if (Mask & 2) {
|
|
1817
|
+
SStream_concat0(O, "x");
|
|
1818
|
+
reg += SpecRegRBit ? ARM_SYSREG_SPSR_X : ARM_SYSREG_CPSR_X;
|
|
1819
|
+
}
|
|
1820
|
+
|
|
1821
|
+
if (Mask & 1) {
|
|
1822
|
+
SStream_concat0(O, "c");
|
|
1823
|
+
reg += SpecRegRBit ? ARM_SYSREG_SPSR_C : ARM_SYSREG_CPSR_C;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
ARM_addSysReg(MI, reg);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
static void printBankedRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1831
|
+
{
|
|
1832
|
+
uint32_t Banked = (uint32_t)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1833
|
+
const BankedReg *TheReg = lookupBankedRegByEncoding(Banked);
|
|
1834
|
+
|
|
1835
|
+
SStream_concat0(O, TheReg->Name);
|
|
1836
|
+
ARM_addSysReg(MI, TheReg->sysreg);
|
|
1837
|
+
}
|
|
1838
|
+
|
|
1839
|
+
static void printPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1840
|
+
{
|
|
1841
|
+
ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1842
|
+
// Handle the undefined 15 CC value here for printing so we don't abort().
|
|
1843
|
+
if ((unsigned)CC == 15) {
|
|
1844
|
+
SStream_concat0(O, "<und>");
|
|
1845
|
+
|
|
1846
|
+
if (MI->csh->detail)
|
|
1847
|
+
MI->flat_insn->detail->arm.cc = ARM_CC_INVALID;
|
|
1848
|
+
} else {
|
|
1849
|
+
if (CC != ARMCC_AL) {
|
|
1850
|
+
SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
if (MI->csh->detail)
|
|
1854
|
+
MI->flat_insn->detail->arm.cc = CC + 1;
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
static void printMandatoryPredicateOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1859
|
+
{
|
|
1860
|
+
ARMCC_CondCodes CC = (ARMCC_CondCodes)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1861
|
+
SStream_concat0(O, ARMCC_ARMCondCodeToString(CC));
|
|
1862
|
+
|
|
1863
|
+
if (MI->csh->detail)
|
|
1864
|
+
MI->flat_insn->detail->arm.cc = CC + 1;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
static void printSBitModifierOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1868
|
+
{
|
|
1869
|
+
if (MCOperand_getReg(MCInst_getOperand(MI, OpNum))) {
|
|
1870
|
+
//assert(MCOperand_getReg(MCInst_getOperand(MI, OpNum)) == ARM_CPSR &&
|
|
1871
|
+
// "Expect ARM CPSR register!");
|
|
1872
|
+
SStream_concat0(O, "s");
|
|
1873
|
+
|
|
1874
|
+
if (MI->csh->detail)
|
|
1875
|
+
MI->flat_insn->detail->arm.update_flags = true;
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1880
|
+
{
|
|
1881
|
+
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1882
|
+
|
|
1883
|
+
printUInt32(O, tmp);
|
|
1884
|
+
|
|
1885
|
+
if (MI->csh->detail) {
|
|
1886
|
+
if (MI->csh->doing_mem) {
|
|
1887
|
+
MI->flat_insn->detail->arm.op_count--;
|
|
1888
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = (int8_t)tmp;
|
|
1889
|
+
MI->ac_idx--; // consecutive operands share the same access right
|
|
1890
|
+
} else {
|
|
1891
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1892
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
1893
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
static void printPImmediate(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1899
|
+
{
|
|
1900
|
+
unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1901
|
+
|
|
1902
|
+
SStream_concat(O, "p%u", imm);
|
|
1903
|
+
|
|
1904
|
+
if (MI->csh->detail) {
|
|
1905
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_PIMM;
|
|
1906
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
|
|
1907
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
static void printCImmediate(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1912
|
+
{
|
|
1913
|
+
unsigned imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1914
|
+
|
|
1915
|
+
SStream_concat(O, "c%u", imm);
|
|
1916
|
+
|
|
1917
|
+
if (MI->csh->detail) {
|
|
1918
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_CIMM;
|
|
1919
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = imm;
|
|
1920
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
static void printCoprocOptionImm(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1925
|
+
{
|
|
1926
|
+
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1927
|
+
if (tmp > HEX_THRESHOLD)
|
|
1928
|
+
SStream_concat(O, "{0x%x}", tmp);
|
|
1929
|
+
else
|
|
1930
|
+
SStream_concat(O, "{%u}", tmp);
|
|
1931
|
+
|
|
1932
|
+
if (MI->csh->detail) {
|
|
1933
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1934
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
1935
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
static void printAdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O, unsigned scale)
|
|
1940
|
+
{
|
|
1941
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
1942
|
+
|
|
1943
|
+
int32_t OffImm = (int32_t)MCOperand_getImm(MO) << scale;
|
|
1944
|
+
|
|
1945
|
+
if (OffImm == INT32_MIN) {
|
|
1946
|
+
SStream_concat0(O, "#-0");
|
|
1947
|
+
|
|
1948
|
+
if (MI->csh->detail) {
|
|
1949
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1950
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
|
|
1951
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1952
|
+
}
|
|
1953
|
+
} else {
|
|
1954
|
+
if (OffImm < 0)
|
|
1955
|
+
SStream_concat(O, "#-0x%x", -OffImm);
|
|
1956
|
+
else {
|
|
1957
|
+
if (OffImm > HEX_THRESHOLD)
|
|
1958
|
+
SStream_concat(O, "#0x%x", OffImm);
|
|
1959
|
+
else
|
|
1960
|
+
SStream_concat(O, "#%u", OffImm);
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
if (MI->csh->detail) {
|
|
1964
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1965
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
|
|
1966
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
|
|
1971
|
+
static void printThumbS4ImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1972
|
+
{
|
|
1973
|
+
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum)) * 4;
|
|
1974
|
+
|
|
1975
|
+
printUInt32Bang(O, tmp);
|
|
1976
|
+
|
|
1977
|
+
if (MI->csh->detail) {
|
|
1978
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1979
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
1980
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
static void printThumbSRImm(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1985
|
+
{
|
|
1986
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
1987
|
+
unsigned tmp = Imm == 0 ? 32 : Imm;
|
|
1988
|
+
|
|
1989
|
+
printUInt32Bang(O, tmp);
|
|
1990
|
+
|
|
1991
|
+
if (MI->csh->detail) {
|
|
1992
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
1993
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
1994
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
static void printThumbITMask(MCInst *MI, unsigned OpNum, SStream *O)
|
|
1999
|
+
{
|
|
2000
|
+
// (3 - the number of trailing zeros) is the number of then / else.
|
|
2001
|
+
unsigned Mask = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2002
|
+
unsigned Firstcond = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum - 1));
|
|
2003
|
+
unsigned CondBit0 = Firstcond & 1;
|
|
2004
|
+
unsigned NumTZ = CountTrailingZeros_32(Mask);
|
|
2005
|
+
//assert(NumTZ <= 3 && "Invalid IT mask!");
|
|
2006
|
+
unsigned Pos, e;
|
|
2007
|
+
|
|
2008
|
+
for (Pos = 3, e = NumTZ; Pos > e; --Pos) {
|
|
2009
|
+
bool T = ((Mask >> Pos) & 1) == CondBit0;
|
|
2010
|
+
if (T)
|
|
2011
|
+
SStream_concat0(O, "t");
|
|
2012
|
+
else
|
|
2013
|
+
SStream_concat0(O, "e");
|
|
2014
|
+
// TODO: detail for this t/e
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
static void printThumbAddrModeRROperand(MCInst *MI, unsigned Op, SStream *O)
|
|
2019
|
+
{
|
|
2020
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
2021
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
|
|
2022
|
+
unsigned RegNum;
|
|
2023
|
+
|
|
2024
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
2025
|
+
printOperand(MI, Op, O);
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
SStream_concat0(O, "[");
|
|
2030
|
+
set_mem_access(MI, true);
|
|
2031
|
+
|
|
2032
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2033
|
+
|
|
2034
|
+
if (MI->csh->detail)
|
|
2035
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2036
|
+
|
|
2037
|
+
RegNum = MCOperand_getReg(MO2);
|
|
2038
|
+
if (RegNum) {
|
|
2039
|
+
SStream_concat0(O, ", ");
|
|
2040
|
+
printRegName(MI->csh, O, RegNum);
|
|
2041
|
+
|
|
2042
|
+
if (MI->csh->detail)
|
|
2043
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = RegNum;
|
|
2044
|
+
}
|
|
2045
|
+
|
|
2046
|
+
SStream_concat0(O, "]");
|
|
2047
|
+
set_mem_access(MI, false);
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
static void printThumbAddrModeImm5SOperand(MCInst *MI, unsigned Op, SStream *O,
|
|
2051
|
+
unsigned Scale)
|
|
2052
|
+
{
|
|
2053
|
+
MCOperand *MO1 = MCInst_getOperand(MI, Op);
|
|
2054
|
+
MCOperand *MO2 = MCInst_getOperand(MI, Op + 1);
|
|
2055
|
+
unsigned ImmOffs, tmp;
|
|
2056
|
+
|
|
2057
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
2058
|
+
printOperand(MI, Op, O);
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
|
|
2062
|
+
SStream_concat0(O, "[");
|
|
2063
|
+
set_mem_access(MI, true);
|
|
2064
|
+
|
|
2065
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2066
|
+
|
|
2067
|
+
if (MI->csh->detail)
|
|
2068
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2069
|
+
|
|
2070
|
+
ImmOffs = (unsigned int)MCOperand_getImm(MO2);
|
|
2071
|
+
if (ImmOffs) {
|
|
2072
|
+
tmp = ImmOffs * Scale;
|
|
2073
|
+
SStream_concat0(O, ", ");
|
|
2074
|
+
printUInt32Bang(O, tmp);
|
|
2075
|
+
|
|
2076
|
+
if (MI->csh->detail)
|
|
2077
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
SStream_concat0(O, "]");
|
|
2081
|
+
set_mem_access(MI, false);
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
static void printThumbAddrModeImm5S1Operand(MCInst *MI, unsigned Op, SStream *O)
|
|
2085
|
+
{
|
|
2086
|
+
printThumbAddrModeImm5SOperand(MI, Op, O, 1);
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2089
|
+
static void printThumbAddrModeImm5S2Operand(MCInst *MI, unsigned Op, SStream *O)
|
|
2090
|
+
{
|
|
2091
|
+
printThumbAddrModeImm5SOperand(MI, Op, O, 2);
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
static void printThumbAddrModeImm5S4Operand(MCInst *MI, unsigned Op, SStream *O)
|
|
2095
|
+
{
|
|
2096
|
+
printThumbAddrModeImm5SOperand(MI, Op, O, 4);
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
static void printThumbAddrModeSPOperand(MCInst *MI, unsigned Op, SStream *O)
|
|
2100
|
+
{
|
|
2101
|
+
printThumbAddrModeImm5SOperand(MI, Op, O, 4);
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2104
|
+
// Constant shifts t2_so_reg is a 2-operand unit corresponding to the Thumb2
|
|
2105
|
+
// register with shift forms.
|
|
2106
|
+
// REG 0 0 - e.g. R5
|
|
2107
|
+
// REG IMM, SH_OPC - e.g. R5, LSL #3
|
|
2108
|
+
static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2109
|
+
{
|
|
2110
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2111
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
2112
|
+
unsigned Reg = MCOperand_getReg(MO1);
|
|
2113
|
+
|
|
2114
|
+
printRegName(MI->csh, O, Reg);
|
|
2115
|
+
|
|
2116
|
+
if (MI->csh->detail) {
|
|
2117
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2118
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
|
|
2119
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
|
2120
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
// Print the shift opc.
|
|
2124
|
+
//assert(MO2.isImm() && "Not a valid t2_so_reg value!");
|
|
2125
|
+
printRegImmShift(MI, O, ARM_AM_getSORegShOp((unsigned int)MCOperand_getImm(MO2)),
|
|
2126
|
+
getSORegOffset((unsigned int)MCOperand_getImm(MO2)));
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
static void printAddrModeImm12Operand(MCInst *MI, unsigned OpNum,
|
|
2130
|
+
SStream *O, bool AlwaysPrintImm0)
|
|
2131
|
+
{
|
|
2132
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2133
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
|
|
2134
|
+
int32_t OffImm;
|
|
2135
|
+
bool isSub;
|
|
2136
|
+
|
|
2137
|
+
if (!MCOperand_isReg(MO1)) { // FIXME: This is for CP entries, but isn't right.
|
|
2138
|
+
printOperand(MI, OpNum, O);
|
|
2139
|
+
return;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
SStream_concat0(O, "[");
|
|
2143
|
+
set_mem_access(MI, true);
|
|
2144
|
+
|
|
2145
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2146
|
+
|
|
2147
|
+
if (MI->csh->detail)
|
|
2148
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2149
|
+
|
|
2150
|
+
OffImm = (int32_t)MCOperand_getImm(MO2);
|
|
2151
|
+
isSub = OffImm < 0;
|
|
2152
|
+
|
|
2153
|
+
// Special value for #-0. All others are normal.
|
|
2154
|
+
if (OffImm == INT32_MIN)
|
|
2155
|
+
OffImm = 0;
|
|
2156
|
+
|
|
2157
|
+
if (isSub) {
|
|
2158
|
+
if (OffImm < -HEX_THRESHOLD)
|
|
2159
|
+
SStream_concat(O, ", #-0x%x", -OffImm);
|
|
2160
|
+
else
|
|
2161
|
+
SStream_concat(O, ", #-%u", -OffImm);
|
|
2162
|
+
} else if (AlwaysPrintImm0 || OffImm > 0) {
|
|
2163
|
+
if (OffImm >= 0) {
|
|
2164
|
+
if (OffImm > HEX_THRESHOLD)
|
|
2165
|
+
SStream_concat(O, ", #0x%x", OffImm);
|
|
2166
|
+
else
|
|
2167
|
+
SStream_concat(O, ", #%u", OffImm);
|
|
2168
|
+
} else {
|
|
2169
|
+
if (OffImm < -HEX_THRESHOLD)
|
|
2170
|
+
SStream_concat(O, ", #-0x%x", -OffImm);
|
|
2171
|
+
else
|
|
2172
|
+
SStream_concat(O, ", #-%u", -OffImm);
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
if (MI->csh->detail)
|
|
2177
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
|
|
2178
|
+
|
|
2179
|
+
SStream_concat0(O, "]");
|
|
2180
|
+
set_mem_access(MI, false);
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
static void printT2AddrModeImm8Operand(MCInst *MI, unsigned OpNum, SStream *O,
|
|
2184
|
+
bool AlwaysPrintImm0)
|
|
2185
|
+
{
|
|
2186
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2187
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
|
|
2188
|
+
int32_t OffImm;
|
|
2189
|
+
bool isSub;
|
|
2190
|
+
|
|
2191
|
+
SStream_concat0(O, "[");
|
|
2192
|
+
set_mem_access(MI, true);
|
|
2193
|
+
|
|
2194
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2195
|
+
|
|
2196
|
+
if (MI->csh->detail)
|
|
2197
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2198
|
+
|
|
2199
|
+
OffImm = (int32_t)MCOperand_getImm(MO2);
|
|
2200
|
+
isSub = OffImm < 0;
|
|
2201
|
+
|
|
2202
|
+
// Don't print +0.
|
|
2203
|
+
if (OffImm == INT32_MIN)
|
|
2204
|
+
OffImm = 0;
|
|
2205
|
+
|
|
2206
|
+
if (isSub)
|
|
2207
|
+
SStream_concat(O, ", #-0x%x", -OffImm);
|
|
2208
|
+
else if (AlwaysPrintImm0 || OffImm > 0) {
|
|
2209
|
+
if (OffImm > HEX_THRESHOLD)
|
|
2210
|
+
SStream_concat(O, ", #0x%x", OffImm);
|
|
2211
|
+
else
|
|
2212
|
+
SStream_concat(O, ", #%u", OffImm);
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
if (MI->csh->detail)
|
|
2216
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
|
|
2217
|
+
|
|
2218
|
+
SStream_concat0(O, "]");
|
|
2219
|
+
set_mem_access(MI, false);
|
|
2220
|
+
}
|
|
2221
|
+
|
|
2222
|
+
static void printT2AddrModeImm8s4Operand(MCInst *MI,
|
|
2223
|
+
unsigned OpNum, SStream *O, bool AlwaysPrintImm0)
|
|
2224
|
+
{
|
|
2225
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2226
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
2227
|
+
int32_t OffImm;
|
|
2228
|
+
bool isSub;
|
|
2229
|
+
|
|
2230
|
+
if (!MCOperand_isReg(MO1)) { // For label symbolic references.
|
|
2231
|
+
printOperand(MI, OpNum, O);
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
SStream_concat0(O, "[");
|
|
2236
|
+
set_mem_access(MI, true);
|
|
2237
|
+
|
|
2238
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2239
|
+
|
|
2240
|
+
if (MI->csh->detail)
|
|
2241
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2242
|
+
|
|
2243
|
+
OffImm = (int32_t)MCOperand_getImm(MO2);
|
|
2244
|
+
isSub = OffImm < 0;
|
|
2245
|
+
|
|
2246
|
+
//assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
|
|
2247
|
+
|
|
2248
|
+
// Don't print +0.
|
|
2249
|
+
if (OffImm == INT32_MIN)
|
|
2250
|
+
OffImm = 0;
|
|
2251
|
+
|
|
2252
|
+
if (isSub) {
|
|
2253
|
+
SStream_concat(O, ", #-0x%x", -OffImm);
|
|
2254
|
+
} else if (AlwaysPrintImm0 || OffImm > 0) {
|
|
2255
|
+
if (OffImm > HEX_THRESHOLD)
|
|
2256
|
+
SStream_concat(O, ", #0x%x", OffImm);
|
|
2257
|
+
else
|
|
2258
|
+
SStream_concat(O, ", #%u", OffImm);
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
if (MI->csh->detail)
|
|
2262
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
|
|
2263
|
+
|
|
2264
|
+
SStream_concat0(O, "]");
|
|
2265
|
+
set_mem_access(MI, false);
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
static void printT2AddrModeImm0_1020s4Operand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2269
|
+
{
|
|
2270
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2271
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum + 1);
|
|
2272
|
+
unsigned tmp;
|
|
2273
|
+
|
|
2274
|
+
SStream_concat0(O, "[");
|
|
2275
|
+
set_mem_access(MI, true);
|
|
2276
|
+
|
|
2277
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2278
|
+
|
|
2279
|
+
if (MI->csh->detail)
|
|
2280
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2281
|
+
|
|
2282
|
+
if (MCOperand_getImm(MO2)) {
|
|
2283
|
+
SStream_concat0(O, ", ");
|
|
2284
|
+
tmp = (unsigned int)MCOperand_getImm(MO2) * 4;
|
|
2285
|
+
printUInt32Bang(O, tmp);
|
|
2286
|
+
|
|
2287
|
+
if (MI->csh->detail)
|
|
2288
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
|
|
2289
|
+
}
|
|
2290
|
+
|
|
2291
|
+
SStream_concat0(O, "]");
|
|
2292
|
+
set_mem_access(MI, false);
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
static void printT2AddrModeImm8OffsetOperand(MCInst *MI,
|
|
2296
|
+
unsigned OpNum, SStream *O)
|
|
2297
|
+
{
|
|
2298
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2299
|
+
int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
|
|
2300
|
+
|
|
2301
|
+
SStream_concat0(O, ", ");
|
|
2302
|
+
if (OffImm == INT32_MIN) {
|
|
2303
|
+
SStream_concat0(O, "#-0");
|
|
2304
|
+
|
|
2305
|
+
if (MI->csh->detail) {
|
|
2306
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2307
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
|
|
2308
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2309
|
+
}
|
|
2310
|
+
} else {
|
|
2311
|
+
printInt32Bang(O, OffImm);
|
|
2312
|
+
|
|
2313
|
+
if (MI->csh->detail) {
|
|
2314
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2315
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
|
|
2316
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
static void printT2AddrModeImm8s4OffsetOperand(MCInst *MI,
|
|
2322
|
+
unsigned OpNum, SStream *O)
|
|
2323
|
+
{
|
|
2324
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2325
|
+
int32_t OffImm = (int32_t)MCOperand_getImm(MO1);
|
|
2326
|
+
|
|
2327
|
+
//assert(((OffImm & 0x3) == 0) && "Not a valid immediate!");
|
|
2328
|
+
|
|
2329
|
+
SStream_concat0(O, ", ");
|
|
2330
|
+
|
|
2331
|
+
if (OffImm == INT32_MIN) {
|
|
2332
|
+
SStream_concat0(O, "#-0");
|
|
2333
|
+
|
|
2334
|
+
if (MI->csh->detail) {
|
|
2335
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2336
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = 0;
|
|
2337
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2338
|
+
}
|
|
2339
|
+
} else {
|
|
2340
|
+
printInt32Bang(O, OffImm);
|
|
2341
|
+
|
|
2342
|
+
if (MI->csh->detail) {
|
|
2343
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2344
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = OffImm;
|
|
2345
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
static void printT2AddrModeSoRegOperand(MCInst *MI,
|
|
2351
|
+
unsigned OpNum, SStream *O)
|
|
2352
|
+
{
|
|
2353
|
+
MCOperand *MO1 = MCInst_getOperand(MI, OpNum);
|
|
2354
|
+
MCOperand *MO2 = MCInst_getOperand(MI, OpNum+1);
|
|
2355
|
+
MCOperand *MO3 = MCInst_getOperand(MI, OpNum+2);
|
|
2356
|
+
unsigned ShAmt;
|
|
2357
|
+
|
|
2358
|
+
SStream_concat0(O, "[");
|
|
2359
|
+
set_mem_access(MI, true);
|
|
2360
|
+
|
|
2361
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO1));
|
|
2362
|
+
|
|
2363
|
+
if (MI->csh->detail)
|
|
2364
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = MCOperand_getReg(MO1);
|
|
2365
|
+
|
|
2366
|
+
//assert(MCOperand_getReg(MO2.getReg() && "Invalid so_reg load / store address!");
|
|
2367
|
+
SStream_concat0(O, ", ");
|
|
2368
|
+
printRegName(MI->csh, O, MCOperand_getReg(MO2));
|
|
2369
|
+
|
|
2370
|
+
if (MI->csh->detail)
|
|
2371
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = MCOperand_getReg(MO2);
|
|
2372
|
+
|
|
2373
|
+
ShAmt = (unsigned int)MCOperand_getImm(MO3);
|
|
2374
|
+
if (ShAmt) {
|
|
2375
|
+
//assert(ShAmt <= 3 && "Not a valid Thumb2 addressing mode!");
|
|
2376
|
+
SStream_concat0(O, ", lsl ");
|
|
2377
|
+
SStream_concat(O, "#%u", ShAmt);
|
|
2378
|
+
|
|
2379
|
+
if (MI->csh->detail) {
|
|
2380
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = ARM_SFT_LSL;
|
|
2381
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = ShAmt;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
|
|
2385
|
+
SStream_concat0(O, "]");
|
|
2386
|
+
set_mem_access(MI, false);
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
static void printFPImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2390
|
+
{
|
|
2391
|
+
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
|
2392
|
+
|
|
2393
|
+
#if defined(_KERNEL_MODE)
|
|
2394
|
+
// Issue #681: Windows kernel does not support formatting float point
|
|
2395
|
+
SStream_concat(O, "#<float_point_unsupported>");
|
|
2396
|
+
#else
|
|
2397
|
+
SStream_concat(O, "#%e", getFPImmFloat((unsigned int)MCOperand_getImm(MO)));
|
|
2398
|
+
#endif
|
|
2399
|
+
|
|
2400
|
+
if (MI->csh->detail) {
|
|
2401
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_FP;
|
|
2402
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].fp = getFPImmFloat((unsigned int)MCOperand_getImm(MO));
|
|
2403
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
static void printNEONModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2408
|
+
{
|
|
2409
|
+
unsigned EncodedImm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2410
|
+
unsigned EltBits;
|
|
2411
|
+
uint64_t Val = ARM_AM_decodeNEONModImm(EncodedImm, &EltBits);
|
|
2412
|
+
|
|
2413
|
+
if (Val > HEX_THRESHOLD)
|
|
2414
|
+
SStream_concat(O, "#0x%"PRIx64, Val);
|
|
2415
|
+
else
|
|
2416
|
+
SStream_concat(O, "#%"PRIu64, Val);
|
|
2417
|
+
|
|
2418
|
+
if (MI->csh->detail) {
|
|
2419
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2420
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = (unsigned int)Val;
|
|
2421
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
static void printImmPlusOneOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2426
|
+
{
|
|
2427
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2428
|
+
|
|
2429
|
+
printUInt32Bang(O, Imm + 1);
|
|
2430
|
+
|
|
2431
|
+
if (MI->csh->detail) {
|
|
2432
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2433
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Imm + 1;
|
|
2434
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
static void printRotImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2439
|
+
{
|
|
2440
|
+
unsigned Imm = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2441
|
+
|
|
2442
|
+
if (Imm == 0)
|
|
2443
|
+
return;
|
|
2444
|
+
|
|
2445
|
+
SStream_concat0(O, ", ror #");
|
|
2446
|
+
|
|
2447
|
+
switch (Imm) {
|
|
2448
|
+
default: //assert (0 && "illegal ror immediate!");
|
|
2449
|
+
case 1: SStream_concat0(O, "8"); break;
|
|
2450
|
+
case 2: SStream_concat0(O, "16"); break;
|
|
2451
|
+
case 3: SStream_concat0(O, "24"); break;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
if (MI->csh->detail) {
|
|
2455
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.type = ARM_SFT_ROR;
|
|
2456
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].shift.value = Imm * 8;
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2460
|
+
static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2461
|
+
{
|
|
2462
|
+
MCOperand *Op = MCInst_getOperand(MI, OpNum);
|
|
2463
|
+
unsigned Bits = MCOperand_getImm(Op) & 0xFF;
|
|
2464
|
+
unsigned Rot = (MCOperand_getImm(Op) & 0xF00) >> 7;
|
|
2465
|
+
int32_t Rotated;
|
|
2466
|
+
bool PrintUnsigned = false;
|
|
2467
|
+
|
|
2468
|
+
switch (MCInst_getOpcode(MI)) {
|
|
2469
|
+
case ARM_MOVi:
|
|
2470
|
+
// Movs to PC should be treated unsigned
|
|
2471
|
+
PrintUnsigned = (MCOperand_getReg(MCInst_getOperand(MI, OpNum - 1)) == ARM_PC);
|
|
2472
|
+
break;
|
|
2473
|
+
case ARM_MSRi:
|
|
2474
|
+
// Movs to special registers should be treated unsigned
|
|
2475
|
+
PrintUnsigned = true;
|
|
2476
|
+
break;
|
|
2477
|
+
}
|
|
2478
|
+
|
|
2479
|
+
Rotated = rotr32(Bits, Rot);
|
|
2480
|
+
if (getSOImmVal(Rotated) == MCOperand_getImm(Op)) {
|
|
2481
|
+
// #rot has the least possible value
|
|
2482
|
+
if (PrintUnsigned) {
|
|
2483
|
+
if (Rotated > HEX_THRESHOLD || Rotated < -HEX_THRESHOLD)
|
|
2484
|
+
SStream_concat(O, "#0x%x", Rotated);
|
|
2485
|
+
else
|
|
2486
|
+
SStream_concat(O, "#%u", Rotated);
|
|
2487
|
+
} else if (Rotated >= 0) {
|
|
2488
|
+
if (Rotated > HEX_THRESHOLD)
|
|
2489
|
+
SStream_concat(O, "#0x%x", Rotated);
|
|
2490
|
+
else
|
|
2491
|
+
SStream_concat(O, "#%u", Rotated);
|
|
2492
|
+
} else {
|
|
2493
|
+
SStream_concat(O, "#0x%x", Rotated);
|
|
2494
|
+
}
|
|
2495
|
+
|
|
2496
|
+
if (MI->csh->detail) {
|
|
2497
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2498
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rotated;
|
|
2499
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
return;
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
// Explicit #bits, #rot implied
|
|
2506
|
+
SStream_concat(O, "#%u, #%u", Bits, Rot);
|
|
2507
|
+
|
|
2508
|
+
if (MI->csh->detail) {
|
|
2509
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2510
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Bits;
|
|
2511
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2512
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2513
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = Rot;
|
|
2514
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
static void printFBits16(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2519
|
+
{
|
|
2520
|
+
unsigned tmp;
|
|
2521
|
+
|
|
2522
|
+
tmp = 16 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2523
|
+
|
|
2524
|
+
printUInt32Bang(O, tmp);
|
|
2525
|
+
|
|
2526
|
+
if (MI->csh->detail) {
|
|
2527
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2528
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
2529
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
|
|
2533
|
+
static void printFBits32(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2534
|
+
{
|
|
2535
|
+
unsigned tmp;
|
|
2536
|
+
|
|
2537
|
+
tmp = 32 - (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2538
|
+
|
|
2539
|
+
printUInt32Bang(O, tmp);
|
|
2540
|
+
|
|
2541
|
+
if (MI->csh->detail) {
|
|
2542
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
2543
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
2544
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2549
|
+
{
|
|
2550
|
+
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
|
2551
|
+
|
|
2552
|
+
if (tmp > HEX_THRESHOLD)
|
|
2553
|
+
SStream_concat(O, "[0x%x]", tmp);
|
|
2554
|
+
else
|
|
2555
|
+
SStream_concat(O, "[%u]", tmp);
|
|
2556
|
+
|
|
2557
|
+
if (MI->csh->detail) {
|
|
2558
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].vector_index = tmp;
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2563
|
+
{
|
|
2564
|
+
SStream_concat0(O, "{");
|
|
2565
|
+
|
|
2566
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2567
|
+
|
|
2568
|
+
if (MI->csh->detail) {
|
|
2569
|
+
#ifndef CAPSTONE_DIET
|
|
2570
|
+
uint8_t access;
|
|
2571
|
+
|
|
2572
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2573
|
+
#endif
|
|
2574
|
+
|
|
2575
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2576
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2577
|
+
#ifndef CAPSTONE_DIET
|
|
2578
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2579
|
+
#endif
|
|
2580
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2581
|
+
|
|
2582
|
+
#ifndef CAPSTONE_DIET
|
|
2583
|
+
MI->ac_idx++;
|
|
2584
|
+
#endif
|
|
2585
|
+
}
|
|
2586
|
+
|
|
2587
|
+
SStream_concat0(O, "}");
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
static void printVectorListTwo(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2591
|
+
{
|
|
2592
|
+
#ifndef CAPSTONE_DIET
|
|
2593
|
+
uint8_t access;
|
|
2594
|
+
#endif
|
|
2595
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2596
|
+
unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0);
|
|
2597
|
+
unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_1);
|
|
2598
|
+
|
|
2599
|
+
#ifndef CAPSTONE_DIET
|
|
2600
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2601
|
+
#endif
|
|
2602
|
+
|
|
2603
|
+
SStream_concat0(O, "{");
|
|
2604
|
+
|
|
2605
|
+
printRegName(MI->csh, O, Reg0);
|
|
2606
|
+
|
|
2607
|
+
if (MI->csh->detail) {
|
|
2608
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2609
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
|
2610
|
+
#ifndef CAPSTONE_DIET
|
|
2611
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2612
|
+
#endif
|
|
2613
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
SStream_concat0(O, ", ");
|
|
2617
|
+
|
|
2618
|
+
printRegName(MI->csh, O, Reg1);
|
|
2619
|
+
|
|
2620
|
+
if (MI->csh->detail) {
|
|
2621
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2622
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
|
2623
|
+
#ifndef CAPSTONE_DIET
|
|
2624
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2625
|
+
#endif
|
|
2626
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
SStream_concat0(O, "}");
|
|
2630
|
+
|
|
2631
|
+
#ifndef CAPSTONE_DIET
|
|
2632
|
+
MI->ac_idx++;
|
|
2633
|
+
#endif
|
|
2634
|
+
}
|
|
2635
|
+
|
|
2636
|
+
static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2637
|
+
{
|
|
2638
|
+
#ifndef CAPSTONE_DIET
|
|
2639
|
+
uint8_t access;
|
|
2640
|
+
#endif
|
|
2641
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2642
|
+
unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0);
|
|
2643
|
+
unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_2);
|
|
2644
|
+
|
|
2645
|
+
#ifndef CAPSTONE_DIET
|
|
2646
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2647
|
+
#endif
|
|
2648
|
+
|
|
2649
|
+
SStream_concat0(O, "{");
|
|
2650
|
+
|
|
2651
|
+
printRegName(MI->csh, O, Reg0);
|
|
2652
|
+
|
|
2653
|
+
if (MI->csh->detail) {
|
|
2654
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2655
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
|
2656
|
+
#ifndef CAPSTONE_DIET
|
|
2657
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2658
|
+
#endif
|
|
2659
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2660
|
+
}
|
|
2661
|
+
|
|
2662
|
+
SStream_concat0(O, ", ");
|
|
2663
|
+
|
|
2664
|
+
printRegName(MI->csh, O, Reg1);
|
|
2665
|
+
|
|
2666
|
+
if (MI->csh->detail) {
|
|
2667
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2668
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
|
2669
|
+
#ifndef CAPSTONE_DIET
|
|
2670
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2671
|
+
#endif
|
|
2672
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2673
|
+
}
|
|
2674
|
+
|
|
2675
|
+
SStream_concat0(O, "}");
|
|
2676
|
+
|
|
2677
|
+
#ifndef CAPSTONE_DIET
|
|
2678
|
+
MI->ac_idx++;
|
|
2679
|
+
#endif
|
|
2680
|
+
}
|
|
2681
|
+
|
|
2682
|
+
static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2683
|
+
{
|
|
2684
|
+
#ifndef CAPSTONE_DIET
|
|
2685
|
+
uint8_t access;
|
|
2686
|
+
|
|
2687
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2688
|
+
#endif
|
|
2689
|
+
|
|
2690
|
+
// Normally, it's not safe to use register enum values directly with
|
|
2691
|
+
// addition to get the next register, but for VFP registers, the
|
|
2692
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
2693
|
+
SStream_concat0(O, "{");
|
|
2694
|
+
|
|
2695
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2696
|
+
|
|
2697
|
+
if (MI->csh->detail) {
|
|
2698
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2699
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2700
|
+
#ifndef CAPSTONE_DIET
|
|
2701
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2702
|
+
#endif
|
|
2703
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2704
|
+
}
|
|
2705
|
+
|
|
2706
|
+
SStream_concat0(O, ", ");
|
|
2707
|
+
|
|
2708
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
|
|
2709
|
+
|
|
2710
|
+
if (MI->csh->detail) {
|
|
2711
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2712
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
|
2713
|
+
#ifndef CAPSTONE_DIET
|
|
2714
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2715
|
+
#endif
|
|
2716
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
SStream_concat0(O, ", ");
|
|
2720
|
+
|
|
2721
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
2722
|
+
|
|
2723
|
+
if (MI->csh->detail) {
|
|
2724
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2725
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
2726
|
+
#ifndef CAPSTONE_DIET
|
|
2727
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2728
|
+
#endif
|
|
2729
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
SStream_concat0(O, "}");
|
|
2733
|
+
|
|
2734
|
+
#ifndef CAPSTONE_DIET
|
|
2735
|
+
MI->ac_idx++;
|
|
2736
|
+
#endif
|
|
2737
|
+
}
|
|
2738
|
+
|
|
2739
|
+
static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2740
|
+
{
|
|
2741
|
+
#ifndef CAPSTONE_DIET
|
|
2742
|
+
uint8_t access;
|
|
2743
|
+
|
|
2744
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2745
|
+
#endif
|
|
2746
|
+
|
|
2747
|
+
// Normally, it's not safe to use register enum values directly with
|
|
2748
|
+
// addition to get the next register, but for VFP registers, the
|
|
2749
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
2750
|
+
SStream_concat0(O, "{");
|
|
2751
|
+
|
|
2752
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2753
|
+
|
|
2754
|
+
if (MI->csh->detail) {
|
|
2755
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2756
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2757
|
+
#ifndef CAPSTONE_DIET
|
|
2758
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2759
|
+
#endif
|
|
2760
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2761
|
+
}
|
|
2762
|
+
|
|
2763
|
+
SStream_concat0(O, ", ");
|
|
2764
|
+
|
|
2765
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
|
|
2766
|
+
|
|
2767
|
+
if (MI->csh->detail) {
|
|
2768
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2769
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
|
2770
|
+
#ifndef CAPSTONE_DIET
|
|
2771
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2772
|
+
#endif
|
|
2773
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
SStream_concat0(O, ", ");
|
|
2777
|
+
|
|
2778
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
2779
|
+
|
|
2780
|
+
if (MI->csh->detail) {
|
|
2781
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2782
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
2783
|
+
#ifndef CAPSTONE_DIET
|
|
2784
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2785
|
+
#endif
|
|
2786
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2787
|
+
}
|
|
2788
|
+
|
|
2789
|
+
SStream_concat0(O, ", ");
|
|
2790
|
+
|
|
2791
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
|
|
2792
|
+
|
|
2793
|
+
if (MI->csh->detail) {
|
|
2794
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2795
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
|
|
2796
|
+
#ifndef CAPSTONE_DIET
|
|
2797
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2798
|
+
#endif
|
|
2799
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
SStream_concat0(O, "}");
|
|
2803
|
+
|
|
2804
|
+
#ifndef CAPSTONE_DIET
|
|
2805
|
+
MI->ac_idx++;
|
|
2806
|
+
#endif
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2810
|
+
{
|
|
2811
|
+
#ifndef CAPSTONE_DIET
|
|
2812
|
+
uint8_t access;
|
|
2813
|
+
|
|
2814
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2815
|
+
#endif
|
|
2816
|
+
|
|
2817
|
+
SStream_concat0(O, "{");
|
|
2818
|
+
|
|
2819
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2820
|
+
|
|
2821
|
+
if (MI->csh->detail) {
|
|
2822
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2823
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2824
|
+
#ifndef CAPSTONE_DIET
|
|
2825
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2826
|
+
#endif
|
|
2827
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
SStream_concat0(O, "[]}");
|
|
2831
|
+
|
|
2832
|
+
#ifndef CAPSTONE_DIET
|
|
2833
|
+
MI->ac_idx++;
|
|
2834
|
+
#endif
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2838
|
+
{
|
|
2839
|
+
#ifndef CAPSTONE_DIET
|
|
2840
|
+
uint8_t access;
|
|
2841
|
+
#endif
|
|
2842
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2843
|
+
unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0);
|
|
2844
|
+
unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_1);
|
|
2845
|
+
|
|
2846
|
+
#ifndef CAPSTONE_DIET
|
|
2847
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2848
|
+
#endif
|
|
2849
|
+
|
|
2850
|
+
SStream_concat0(O, "{");
|
|
2851
|
+
|
|
2852
|
+
printRegName(MI->csh, O, Reg0);
|
|
2853
|
+
|
|
2854
|
+
if (MI->csh->detail) {
|
|
2855
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2856
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
|
2857
|
+
#ifndef CAPSTONE_DIET
|
|
2858
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2859
|
+
#endif
|
|
2860
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
SStream_concat0(O, "[], ");
|
|
2864
|
+
|
|
2865
|
+
printRegName(MI->csh, O, Reg1);
|
|
2866
|
+
|
|
2867
|
+
if (MI->csh->detail) {
|
|
2868
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2869
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
|
2870
|
+
#ifndef CAPSTONE_DIET
|
|
2871
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2872
|
+
#endif
|
|
2873
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
SStream_concat0(O, "[]}");
|
|
2877
|
+
|
|
2878
|
+
#ifndef CAPSTONE_DIET
|
|
2879
|
+
MI->ac_idx++;
|
|
2880
|
+
#endif
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2884
|
+
{
|
|
2885
|
+
#ifndef CAPSTONE_DIET
|
|
2886
|
+
uint8_t access;
|
|
2887
|
+
|
|
2888
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2889
|
+
#endif
|
|
2890
|
+
|
|
2891
|
+
// Normally, it's not safe to use register enum values directly with
|
|
2892
|
+
// addition to get the next register, but for VFP registers, the
|
|
2893
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
2894
|
+
SStream_concat0(O, "{");
|
|
2895
|
+
|
|
2896
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2897
|
+
|
|
2898
|
+
if (MI->csh->detail) {
|
|
2899
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2900
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2901
|
+
#ifndef CAPSTONE_DIET
|
|
2902
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2903
|
+
#endif
|
|
2904
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2905
|
+
}
|
|
2906
|
+
|
|
2907
|
+
SStream_concat0(O, "[], ");
|
|
2908
|
+
|
|
2909
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
|
|
2910
|
+
|
|
2911
|
+
if (MI->csh->detail) {
|
|
2912
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2913
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
|
2914
|
+
#ifndef CAPSTONE_DIET
|
|
2915
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2916
|
+
#endif
|
|
2917
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
SStream_concat0(O, "[], ");
|
|
2921
|
+
|
|
2922
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
2923
|
+
|
|
2924
|
+
if (MI->csh->detail) {
|
|
2925
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2926
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
2927
|
+
#ifndef CAPSTONE_DIET
|
|
2928
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2929
|
+
#endif
|
|
2930
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2933
|
+
SStream_concat0(O, "[]}");
|
|
2934
|
+
|
|
2935
|
+
#ifndef CAPSTONE_DIET
|
|
2936
|
+
MI->ac_idx++;
|
|
2937
|
+
#endif
|
|
2938
|
+
}
|
|
2939
|
+
|
|
2940
|
+
static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
|
2941
|
+
{
|
|
2942
|
+
#ifndef CAPSTONE_DIET
|
|
2943
|
+
uint8_t access;
|
|
2944
|
+
|
|
2945
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
2946
|
+
#endif
|
|
2947
|
+
|
|
2948
|
+
// Normally, it's not safe to use register enum values directly with
|
|
2949
|
+
// addition to get the next register, but for VFP registers, the
|
|
2950
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
2951
|
+
SStream_concat0(O, "{");
|
|
2952
|
+
|
|
2953
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
2954
|
+
|
|
2955
|
+
if (MI->csh->detail) {
|
|
2956
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2957
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
2958
|
+
#ifndef CAPSTONE_DIET
|
|
2959
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2960
|
+
#endif
|
|
2961
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
SStream_concat0(O, "[], ");
|
|
2965
|
+
|
|
2966
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1);
|
|
2967
|
+
|
|
2968
|
+
if (MI->csh->detail) {
|
|
2969
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2970
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
|
2971
|
+
#ifndef CAPSTONE_DIET
|
|
2972
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2973
|
+
#endif
|
|
2974
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
SStream_concat0(O, "[], ");
|
|
2978
|
+
|
|
2979
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
2980
|
+
|
|
2981
|
+
if (MI->csh->detail) {
|
|
2982
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2983
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
2984
|
+
#ifndef CAPSTONE_DIET
|
|
2985
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2986
|
+
#endif
|
|
2987
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
2988
|
+
}
|
|
2989
|
+
|
|
2990
|
+
SStream_concat0(O, "[], ");
|
|
2991
|
+
|
|
2992
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3);
|
|
2993
|
+
|
|
2994
|
+
if (MI->csh->detail) {
|
|
2995
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
2996
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
|
|
2997
|
+
#ifndef CAPSTONE_DIET
|
|
2998
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
2999
|
+
#endif
|
|
3000
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
SStream_concat0(O, "[]}");
|
|
3004
|
+
|
|
3005
|
+
#ifndef CAPSTONE_DIET
|
|
3006
|
+
MI->ac_idx++;
|
|
3007
|
+
#endif
|
|
3008
|
+
}
|
|
3009
|
+
|
|
3010
|
+
static void printVectorListTwoSpacedAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
|
3011
|
+
{
|
|
3012
|
+
#ifndef CAPSTONE_DIET
|
|
3013
|
+
uint8_t access;
|
|
3014
|
+
#endif
|
|
3015
|
+
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
3016
|
+
unsigned Reg0 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_0);
|
|
3017
|
+
unsigned Reg1 = MCRegisterInfo_getSubReg(MI->MRI, Reg, ARM_dsub_2);
|
|
3018
|
+
|
|
3019
|
+
#ifndef CAPSTONE_DIET
|
|
3020
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
3021
|
+
#endif
|
|
3022
|
+
|
|
3023
|
+
SStream_concat0(O, "{");
|
|
3024
|
+
|
|
3025
|
+
printRegName(MI->csh, O, Reg0);
|
|
3026
|
+
|
|
3027
|
+
if (MI->csh->detail) {
|
|
3028
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3029
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
|
3030
|
+
#ifndef CAPSTONE_DIET
|
|
3031
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3032
|
+
#endif
|
|
3033
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3034
|
+
}
|
|
3035
|
+
|
|
3036
|
+
SStream_concat0(O, "[], ");
|
|
3037
|
+
|
|
3038
|
+
printRegName(MI->csh, O, Reg1);
|
|
3039
|
+
|
|
3040
|
+
if (MI->csh->detail) {
|
|
3041
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3042
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
|
3043
|
+
#ifndef CAPSTONE_DIET
|
|
3044
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3045
|
+
#endif
|
|
3046
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3047
|
+
}
|
|
3048
|
+
|
|
3049
|
+
SStream_concat0(O, "[]}");
|
|
3050
|
+
|
|
3051
|
+
#ifndef CAPSTONE_DIET
|
|
3052
|
+
MI->ac_idx++;
|
|
3053
|
+
#endif
|
|
3054
|
+
}
|
|
3055
|
+
|
|
3056
|
+
static void printVectorListThreeSpacedAllLanes(MCInst *MI,
|
|
3057
|
+
unsigned OpNum, SStream *O)
|
|
3058
|
+
{
|
|
3059
|
+
#ifndef CAPSTONE_DIET
|
|
3060
|
+
uint8_t access;
|
|
3061
|
+
|
|
3062
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
3063
|
+
#endif
|
|
3064
|
+
|
|
3065
|
+
// Normally, it's not safe to use register enum values directly with
|
|
3066
|
+
// addition to get the next register, but for VFP registers, the
|
|
3067
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
3068
|
+
SStream_concat0(O, "{");
|
|
3069
|
+
|
|
3070
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
3071
|
+
|
|
3072
|
+
if (MI->csh->detail) {
|
|
3073
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3074
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
3075
|
+
#ifndef CAPSTONE_DIET
|
|
3076
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3077
|
+
#endif
|
|
3078
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
SStream_concat0(O, "[], ");
|
|
3082
|
+
|
|
3083
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
3084
|
+
|
|
3085
|
+
if (MI->csh->detail) {
|
|
3086
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3087
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
3088
|
+
#ifndef CAPSTONE_DIET
|
|
3089
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3090
|
+
#endif
|
|
3091
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3092
|
+
}
|
|
3093
|
+
|
|
3094
|
+
SStream_concat0(O, "[], ");
|
|
3095
|
+
|
|
3096
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
|
|
3097
|
+
|
|
3098
|
+
if (MI->csh->detail) {
|
|
3099
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3100
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
|
3101
|
+
#ifndef CAPSTONE_DIET
|
|
3102
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3103
|
+
#endif
|
|
3104
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3107
|
+
SStream_concat0(O, "[]}");
|
|
3108
|
+
|
|
3109
|
+
#ifndef CAPSTONE_DIET
|
|
3110
|
+
MI->ac_idx++;
|
|
3111
|
+
#endif
|
|
3112
|
+
}
|
|
3113
|
+
|
|
3114
|
+
static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
|
3115
|
+
unsigned OpNum, SStream *O)
|
|
3116
|
+
{
|
|
3117
|
+
#ifndef CAPSTONE_DIET
|
|
3118
|
+
uint8_t access;
|
|
3119
|
+
|
|
3120
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
3121
|
+
#endif
|
|
3122
|
+
|
|
3123
|
+
// Normally, it's not safe to use register enum values directly with
|
|
3124
|
+
// addition to get the next register, but for VFP registers, the
|
|
3125
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
3126
|
+
SStream_concat0(O, "{");
|
|
3127
|
+
|
|
3128
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
3129
|
+
|
|
3130
|
+
if (MI->csh->detail) {
|
|
3131
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3132
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
3133
|
+
#ifndef CAPSTONE_DIET
|
|
3134
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3135
|
+
#endif
|
|
3136
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3137
|
+
}
|
|
3138
|
+
|
|
3139
|
+
SStream_concat0(O, "[], ");
|
|
3140
|
+
|
|
3141
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
3142
|
+
|
|
3143
|
+
if (MI->csh->detail) {
|
|
3144
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3145
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
3146
|
+
#ifndef CAPSTONE_DIET
|
|
3147
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3148
|
+
#endif
|
|
3149
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
SStream_concat0(O, "[], ");
|
|
3153
|
+
|
|
3154
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
|
|
3155
|
+
|
|
3156
|
+
if (MI->csh->detail) {
|
|
3157
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3158
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
|
3159
|
+
#ifndef CAPSTONE_DIET
|
|
3160
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3161
|
+
#endif
|
|
3162
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3163
|
+
}
|
|
3164
|
+
|
|
3165
|
+
SStream_concat0(O, "[], ");
|
|
3166
|
+
|
|
3167
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
|
|
3168
|
+
|
|
3169
|
+
if (MI->csh->detail) {
|
|
3170
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3171
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
|
|
3172
|
+
#ifndef CAPSTONE_DIET
|
|
3173
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3174
|
+
#endif
|
|
3175
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3176
|
+
}
|
|
3177
|
+
|
|
3178
|
+
SStream_concat0(O, "[]}");
|
|
3179
|
+
|
|
3180
|
+
#ifndef CAPSTONE_DIET
|
|
3181
|
+
MI->ac_idx++;
|
|
3182
|
+
#endif
|
|
3183
|
+
}
|
|
3184
|
+
|
|
3185
|
+
static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
|
3186
|
+
{
|
|
3187
|
+
#ifndef CAPSTONE_DIET
|
|
3188
|
+
uint8_t access;
|
|
3189
|
+
|
|
3190
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
3191
|
+
#endif
|
|
3192
|
+
|
|
3193
|
+
// Normally, it's not safe to use register enum values directly with
|
|
3194
|
+
// addition to get the next register, but for VFP registers, the
|
|
3195
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
3196
|
+
SStream_concat0(O, "{");
|
|
3197
|
+
|
|
3198
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
3199
|
+
|
|
3200
|
+
if (MI->csh->detail) {
|
|
3201
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3202
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
3203
|
+
#ifndef CAPSTONE_DIET
|
|
3204
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3205
|
+
#endif
|
|
3206
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3209
|
+
SStream_concat0(O, ", ");
|
|
3210
|
+
|
|
3211
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
3212
|
+
|
|
3213
|
+
if (MI->csh->detail) {
|
|
3214
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3215
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
3216
|
+
#ifndef CAPSTONE_DIET
|
|
3217
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3218
|
+
#endif
|
|
3219
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3220
|
+
}
|
|
3221
|
+
|
|
3222
|
+
SStream_concat0(O, ", ");
|
|
3223
|
+
|
|
3224
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
|
|
3225
|
+
|
|
3226
|
+
if (MI->csh->detail) {
|
|
3227
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3228
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
|
3229
|
+
#ifndef CAPSTONE_DIET
|
|
3230
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3231
|
+
#endif
|
|
3232
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3233
|
+
}
|
|
3234
|
+
|
|
3235
|
+
SStream_concat0(O, "}");
|
|
3236
|
+
|
|
3237
|
+
#ifndef CAPSTONE_DIET
|
|
3238
|
+
MI->ac_idx++;
|
|
3239
|
+
#endif
|
|
3240
|
+
}
|
|
3241
|
+
|
|
3242
|
+
static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
|
3243
|
+
{
|
|
3244
|
+
#ifndef CAPSTONE_DIET
|
|
3245
|
+
uint8_t access;
|
|
3246
|
+
|
|
3247
|
+
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
|
3248
|
+
#endif
|
|
3249
|
+
|
|
3250
|
+
// Normally, it's not safe to use register enum values directly with
|
|
3251
|
+
// addition to get the next register, but for VFP registers, the
|
|
3252
|
+
// sort order is guaranteed because they're all of the form D<n>.
|
|
3253
|
+
SStream_concat0(O, "{");
|
|
3254
|
+
|
|
3255
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
|
3256
|
+
|
|
3257
|
+
if (MI->csh->detail) {
|
|
3258
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3259
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
|
3260
|
+
#ifndef CAPSTONE_DIET
|
|
3261
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3262
|
+
#endif
|
|
3263
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
SStream_concat0(O, ", ");
|
|
3267
|
+
|
|
3268
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2);
|
|
3269
|
+
|
|
3270
|
+
if (MI->csh->detail) {
|
|
3271
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3272
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
|
3273
|
+
#ifndef CAPSTONE_DIET
|
|
3274
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3275
|
+
#endif
|
|
3276
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
SStream_concat0(O, ", ");
|
|
3280
|
+
|
|
3281
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4);
|
|
3282
|
+
|
|
3283
|
+
if (MI->csh->detail) {
|
|
3284
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3285
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
|
3286
|
+
#ifndef CAPSTONE_DIET
|
|
3287
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3288
|
+
#endif
|
|
3289
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3290
|
+
}
|
|
3291
|
+
|
|
3292
|
+
SStream_concat0(O, ", ");
|
|
3293
|
+
|
|
3294
|
+
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6);
|
|
3295
|
+
|
|
3296
|
+
if (MI->csh->detail) {
|
|
3297
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3298
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
|
|
3299
|
+
#ifndef CAPSTONE_DIET
|
|
3300
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
|
3301
|
+
#endif
|
|
3302
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3303
|
+
}
|
|
3304
|
+
|
|
3305
|
+
SStream_concat0(O, "}");
|
|
3306
|
+
|
|
3307
|
+
#ifndef CAPSTONE_DIET
|
|
3308
|
+
MI->ac_idx++;
|
|
3309
|
+
#endif
|
|
3310
|
+
}
|
|
3311
|
+
|
|
3312
|
+
static void printComplexRotationOp(MCInst *MI, unsigned OpNo, SStream *O, int64_t Angle, int64_t Remainder)
|
|
3313
|
+
{
|
|
3314
|
+
unsigned Val = (unsigned)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
|
|
3315
|
+
unsigned tmp = (unsigned)((Val * Angle) + Remainder);
|
|
3316
|
+
|
|
3317
|
+
printUInt32Bang(O, tmp);
|
|
3318
|
+
if (MI->csh->detail) {
|
|
3319
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
|
3320
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
|
3321
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
|
|
3325
|
+
void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)
|
|
3326
|
+
{
|
|
3327
|
+
if (MI->csh->detail) {
|
|
3328
|
+
MI->flat_insn->detail->arm.vector_data = vd;
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3331
|
+
|
|
3332
|
+
void ARM_addVectorDataSize(MCInst *MI, int size)
|
|
3333
|
+
{
|
|
3334
|
+
if (MI->csh->detail) {
|
|
3335
|
+
MI->flat_insn->detail->arm.vector_size = size;
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
|
|
3339
|
+
void ARM_addReg(MCInst *MI, int reg)
|
|
3340
|
+
{
|
|
3341
|
+
if (MI->csh->detail) {
|
|
3342
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
|
3343
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
|
|
3344
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3345
|
+
}
|
|
3346
|
+
}
|
|
3347
|
+
|
|
3348
|
+
void ARM_addUserMode(MCInst *MI)
|
|
3349
|
+
{
|
|
3350
|
+
if (MI->csh->detail) {
|
|
3351
|
+
MI->flat_insn->detail->arm.usermode = true;
|
|
3352
|
+
}
|
|
3353
|
+
}
|
|
3354
|
+
|
|
3355
|
+
void ARM_addSysReg(MCInst *MI, arm_sysreg reg)
|
|
3356
|
+
{
|
|
3357
|
+
if (MI->csh->detail) {
|
|
3358
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_SYSREG;
|
|
3359
|
+
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = reg;
|
|
3360
|
+
MI->flat_insn->detail->arm.op_count++;
|
|
3361
|
+
}
|
|
3362
|
+
}
|
|
3363
|
+
|
|
3364
|
+
#endif
|