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.
Files changed (332) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +191 -0
  3. package/binding.gyp +168 -0
  4. package/deps/capstone/LEB128.h +38 -0
  5. package/deps/capstone/MCDisassembler.h +14 -0
  6. package/deps/capstone/MCFixedLenDisassembler.h +32 -0
  7. package/deps/capstone/MCInst.c +270 -0
  8. package/deps/capstone/MCInst.h +165 -0
  9. package/deps/capstone/MCInstrDesc.c +41 -0
  10. package/deps/capstone/MCInstrDesc.h +167 -0
  11. package/deps/capstone/MCRegisterInfo.c +151 -0
  12. package/deps/capstone/MCRegisterInfo.h +116 -0
  13. package/deps/capstone/Mapping.c +254 -0
  14. package/deps/capstone/Mapping.h +174 -0
  15. package/deps/capstone/MathExtras.h +442 -0
  16. package/deps/capstone/SStream.c +181 -0
  17. package/deps/capstone/SStream.h +40 -0
  18. package/deps/capstone/arch/AArch64/AArch64AddressingModes.h +945 -0
  19. package/deps/capstone/arch/AArch64/AArch64BaseInfo.c +77 -0
  20. package/deps/capstone/arch/AArch64/AArch64BaseInfo.h +585 -0
  21. package/deps/capstone/arch/AArch64/AArch64Disassembler.c +2280 -0
  22. package/deps/capstone/arch/AArch64/AArch64Disassembler.h +18 -0
  23. package/deps/capstone/arch/AArch64/AArch64GenAsmWriter.inc +26589 -0
  24. package/deps/capstone/arch/AArch64/AArch64GenDisassemblerTables.inc +27322 -0
  25. package/deps/capstone/arch/AArch64/AArch64GenInstrInfo.inc +13194 -0
  26. package/deps/capstone/arch/AArch64/AArch64GenRegisterInfo.inc +3814 -0
  27. package/deps/capstone/arch/AArch64/AArch64GenRegisterName.inc +714 -0
  28. package/deps/capstone/arch/AArch64/AArch64GenRegisterV.inc +673 -0
  29. package/deps/capstone/arch/AArch64/AArch64GenSubtargetInfo.inc +229 -0
  30. package/deps/capstone/arch/AArch64/AArch64GenSystemOperands.inc +2863 -0
  31. package/deps/capstone/arch/AArch64/AArch64GenSystemOperands_enum.inc +21 -0
  32. package/deps/capstone/arch/AArch64/AArch64InstPrinter.c +3029 -0
  33. package/deps/capstone/arch/AArch64/AArch64InstPrinter.h +28 -0
  34. package/deps/capstone/arch/AArch64/AArch64Mapping.c +883 -0
  35. package/deps/capstone/arch/AArch64/AArch64Mapping.h +43 -0
  36. package/deps/capstone/arch/AArch64/AArch64MappingInsn.inc +37790 -0
  37. package/deps/capstone/arch/AArch64/AArch64MappingInsnName.inc +1282 -0
  38. package/deps/capstone/arch/AArch64/AArch64MappingInsnOp.inc +26994 -0
  39. package/deps/capstone/arch/AArch64/AArch64Module.c +44 -0
  40. package/deps/capstone/arch/AArch64/AArch64Module.h +12 -0
  41. package/deps/capstone/arch/ARM/ARMAddressingModes.h +698 -0
  42. package/deps/capstone/arch/ARM/ARMBaseInfo.h +486 -0
  43. package/deps/capstone/arch/ARM/ARMDisassembler.c +5763 -0
  44. package/deps/capstone/arch/ARM/ARMDisassembler.h +18 -0
  45. package/deps/capstone/arch/ARM/ARMGenAsmWriter.inc +9545 -0
  46. package/deps/capstone/arch/ARM/ARMGenDisassemblerTables.inc +15185 -0
  47. package/deps/capstone/arch/ARM/ARMGenInstrInfo.inc +6632 -0
  48. package/deps/capstone/arch/ARM/ARMGenRegisterInfo.inc +2102 -0
  49. package/deps/capstone/arch/ARM/ARMGenRegisterName.inc +231 -0
  50. package/deps/capstone/arch/ARM/ARMGenRegisterName_digit.inc +231 -0
  51. package/deps/capstone/arch/ARM/ARMGenSubtargetInfo.inc +162 -0
  52. package/deps/capstone/arch/ARM/ARMGenSystemRegister.inc +270 -0
  53. package/deps/capstone/arch/ARM/ARMInstPrinter.c +3364 -0
  54. package/deps/capstone/arch/ARM/ARMInstPrinter.h +43 -0
  55. package/deps/capstone/arch/ARM/ARMMapping.c +551 -0
  56. package/deps/capstone/arch/ARM/ARMMapping.h +40 -0
  57. package/deps/capstone/arch/ARM/ARMMappingInsn.inc +18772 -0
  58. package/deps/capstone/arch/ARM/ARMMappingInsnName.inc +475 -0
  59. package/deps/capstone/arch/ARM/ARMMappingInsnOp.inc +10729 -0
  60. package/deps/capstone/arch/ARM/ARMModule.c +63 -0
  61. package/deps/capstone/arch/ARM/ARMModule.h +12 -0
  62. package/deps/capstone/arch/BPF/BPFConstants.h +88 -0
  63. package/deps/capstone/arch/BPF/BPFDisassembler.c +464 -0
  64. package/deps/capstone/arch/BPF/BPFDisassembler.h +27 -0
  65. package/deps/capstone/arch/BPF/BPFInstPrinter.c +285 -0
  66. package/deps/capstone/arch/BPF/BPFInstPrinter.h +16 -0
  67. package/deps/capstone/arch/BPF/BPFMapping.c +513 -0
  68. package/deps/capstone/arch/BPF/BPFMapping.h +21 -0
  69. package/deps/capstone/arch/BPF/BPFModule.c +34 -0
  70. package/deps/capstone/arch/BPF/BPFModule.h +12 -0
  71. package/deps/capstone/arch/EVM/EVMDisassembler.c +379 -0
  72. package/deps/capstone/arch/EVM/EVMDisassembler.h +12 -0
  73. package/deps/capstone/arch/EVM/EVMInstPrinter.c +20 -0
  74. package/deps/capstone/arch/EVM/EVMInstPrinter.h +17 -0
  75. package/deps/capstone/arch/EVM/EVMMapping.c +344 -0
  76. package/deps/capstone/arch/EVM/EVMMapping.h +8 -0
  77. package/deps/capstone/arch/EVM/EVMMappingInsn.inc +259 -0
  78. package/deps/capstone/arch/EVM/EVMModule.c +33 -0
  79. package/deps/capstone/arch/EVM/EVMModule.h +12 -0
  80. package/deps/capstone/arch/M680X/M680XDisassembler.c +2307 -0
  81. package/deps/capstone/arch/M680X/M680XDisassembler.h +17 -0
  82. package/deps/capstone/arch/M680X/M680XDisassemblerInternals.h +57 -0
  83. package/deps/capstone/arch/M680X/M680XInstPrinter.c +360 -0
  84. package/deps/capstone/arch/M680X/M680XInstPrinter.h +25 -0
  85. package/deps/capstone/arch/M680X/M680XModule.c +77 -0
  86. package/deps/capstone/arch/M680X/M680XModule.h +12 -0
  87. package/deps/capstone/arch/M680X/cpu12.inc +335 -0
  88. package/deps/capstone/arch/M680X/hcs08.inc +60 -0
  89. package/deps/capstone/arch/M680X/hd6301.inc +15 -0
  90. package/deps/capstone/arch/M680X/hd6309.inc +259 -0
  91. package/deps/capstone/arch/M680X/insn_props.inc +367 -0
  92. package/deps/capstone/arch/M680X/m6800.inc +277 -0
  93. package/deps/capstone/arch/M680X/m6801.inc +39 -0
  94. package/deps/capstone/arch/M680X/m6805.inc +277 -0
  95. package/deps/capstone/arch/M680X/m6808.inc +91 -0
  96. package/deps/capstone/arch/M680X/m6809.inc +352 -0
  97. package/deps/capstone/arch/M680X/m6811.inc +105 -0
  98. package/deps/capstone/arch/M68K/M68KDisassembler.c +3668 -0
  99. package/deps/capstone/arch/M68K/M68KDisassembler.h +30 -0
  100. package/deps/capstone/arch/M68K/M68KInstPrinter.c +387 -0
  101. package/deps/capstone/arch/M68K/M68KInstPrinter.h +21 -0
  102. package/deps/capstone/arch/M68K/M68KInstructionTable.inc +65540 -0
  103. package/deps/capstone/arch/M68K/M68KModule.c +42 -0
  104. package/deps/capstone/arch/M68K/M68KModule.h +12 -0
  105. package/deps/capstone/arch/MOS65XX/MOS65XXDisassembler.c +544 -0
  106. package/deps/capstone/arch/MOS65XX/MOS65XXDisassembler.h +22 -0
  107. package/deps/capstone/arch/MOS65XX/MOS65XXDisassemblerInternals.h +23 -0
  108. package/deps/capstone/arch/MOS65XX/MOS65XXModule.c +79 -0
  109. package/deps/capstone/arch/MOS65XX/MOS65XXModule.h +12 -0
  110. package/deps/capstone/arch/MOS65XX/instruction_info.inc +106 -0
  111. package/deps/capstone/arch/MOS65XX/m6502.inc +256 -0
  112. package/deps/capstone/arch/MOS65XX/m65816.inc +256 -0
  113. package/deps/capstone/arch/MOS65XX/m65c02.inc +256 -0
  114. package/deps/capstone/arch/MOS65XX/mw65c02.inc +256 -0
  115. package/deps/capstone/arch/Mips/MipsDisassembler.c +1794 -0
  116. package/deps/capstone/arch/Mips/MipsDisassembler.h +16 -0
  117. package/deps/capstone/arch/Mips/MipsGenAsmWriter.inc +5725 -0
  118. package/deps/capstone/arch/Mips/MipsGenDisassemblerTables.inc +6942 -0
  119. package/deps/capstone/arch/Mips/MipsGenInstrInfo.inc +1805 -0
  120. package/deps/capstone/arch/Mips/MipsGenRegisterInfo.inc +1679 -0
  121. package/deps/capstone/arch/Mips/MipsGenSubtargetInfo.inc +52 -0
  122. package/deps/capstone/arch/Mips/MipsInstPrinter.c +424 -0
  123. package/deps/capstone/arch/Mips/MipsInstPrinter.h +25 -0
  124. package/deps/capstone/arch/Mips/MipsMapping.c +1070 -0
  125. package/deps/capstone/arch/Mips/MipsMapping.h +25 -0
  126. package/deps/capstone/arch/Mips/MipsMappingInsn.inc +9315 -0
  127. package/deps/capstone/arch/Mips/MipsModule.c +52 -0
  128. package/deps/capstone/arch/Mips/MipsModule.h +12 -0
  129. package/deps/capstone/arch/PowerPC/PPCDisassembler.c +627 -0
  130. package/deps/capstone/arch/PowerPC/PPCDisassembler.h +17 -0
  131. package/deps/capstone/arch/PowerPC/PPCGenAsmWriter.inc +11451 -0
  132. package/deps/capstone/arch/PowerPC/PPCGenDisassemblerTables.inc +6886 -0
  133. package/deps/capstone/arch/PowerPC/PPCGenInstrInfo.inc +4772 -0
  134. package/deps/capstone/arch/PowerPC/PPCGenRegisterInfo.inc +1122 -0
  135. package/deps/capstone/arch/PowerPC/PPCGenRegisterName.inc +278 -0
  136. package/deps/capstone/arch/PowerPC/PPCGenSubtargetInfo.inc +90 -0
  137. package/deps/capstone/arch/PowerPC/PPCInstPrinter.c +1238 -0
  138. package/deps/capstone/arch/PowerPC/PPCInstPrinter.h +15 -0
  139. package/deps/capstone/arch/PowerPC/PPCMapping.c +570 -0
  140. package/deps/capstone/arch/PowerPC/PPCMapping.h +40 -0
  141. package/deps/capstone/arch/PowerPC/PPCMappingInsn.inc +13220 -0
  142. package/deps/capstone/arch/PowerPC/PPCMappingInsnName.inc +1731 -0
  143. package/deps/capstone/arch/PowerPC/PPCModule.c +45 -0
  144. package/deps/capstone/arch/PowerPC/PPCModule.h +12 -0
  145. package/deps/capstone/arch/PowerPC/PPCPredicates.h +62 -0
  146. package/deps/capstone/arch/RISCV/RISCVBaseInfo.h +106 -0
  147. package/deps/capstone/arch/RISCV/RISCVDisassembler.c +433 -0
  148. package/deps/capstone/arch/RISCV/RISCVDisassembler.h +18 -0
  149. package/deps/capstone/arch/RISCV/RISCVGenAsmWriter.inc +2651 -0
  150. package/deps/capstone/arch/RISCV/RISCVGenDisassemblerTables.inc +1776 -0
  151. package/deps/capstone/arch/RISCV/RISCVGenInsnNameMaps.inc +275 -0
  152. package/deps/capstone/arch/RISCV/RISCVGenInstrInfo.inc +470 -0
  153. package/deps/capstone/arch/RISCV/RISCVGenRegisterInfo.inc +426 -0
  154. package/deps/capstone/arch/RISCV/RISCVGenSubtargetInfo.inc +33 -0
  155. package/deps/capstone/arch/RISCV/RISCVInstPrinter.c +447 -0
  156. package/deps/capstone/arch/RISCV/RISCVInstPrinter.h +24 -0
  157. package/deps/capstone/arch/RISCV/RISCVMapping.c +366 -0
  158. package/deps/capstone/arch/RISCV/RISCVMapping.h +22 -0
  159. package/deps/capstone/arch/RISCV/RISCVMappingInsn.inc +1635 -0
  160. package/deps/capstone/arch/RISCV/RISCVModule.c +42 -0
  161. package/deps/capstone/arch/RISCV/RISCVModule.h +12 -0
  162. package/deps/capstone/arch/SH/SHDisassembler.c +2221 -0
  163. package/deps/capstone/arch/SH/SHDisassembler.h +19 -0
  164. package/deps/capstone/arch/SH/SHInsnTable.inc +66 -0
  165. package/deps/capstone/arch/SH/SHInstPrinter.c +438 -0
  166. package/deps/capstone/arch/SH/SHInstPrinter.h +23 -0
  167. package/deps/capstone/arch/SH/SHModule.c +39 -0
  168. package/deps/capstone/arch/SH/SHModule.h +12 -0
  169. package/deps/capstone/arch/SH/mktable.rb +390 -0
  170. package/deps/capstone/arch/Sparc/Sparc.h +63 -0
  171. package/deps/capstone/arch/Sparc/SparcDisassembler.c +500 -0
  172. package/deps/capstone/arch/Sparc/SparcDisassembler.h +17 -0
  173. package/deps/capstone/arch/Sparc/SparcGenAsmWriter.inc +5709 -0
  174. package/deps/capstone/arch/Sparc/SparcGenDisassemblerTables.inc +2028 -0
  175. package/deps/capstone/arch/Sparc/SparcGenInstrInfo.inc +514 -0
  176. package/deps/capstone/arch/Sparc/SparcGenRegisterInfo.inc +451 -0
  177. package/deps/capstone/arch/Sparc/SparcGenSubtargetInfo.inc +27 -0
  178. package/deps/capstone/arch/Sparc/SparcInstPrinter.c +446 -0
  179. package/deps/capstone/arch/Sparc/SparcInstPrinter.h +17 -0
  180. package/deps/capstone/arch/Sparc/SparcMapping.c +665 -0
  181. package/deps/capstone/arch/Sparc/SparcMapping.h +34 -0
  182. package/deps/capstone/arch/Sparc/SparcMappingInsn.inc +2643 -0
  183. package/deps/capstone/arch/Sparc/SparcModule.c +45 -0
  184. package/deps/capstone/arch/Sparc/SparcModule.h +12 -0
  185. package/deps/capstone/arch/SystemZ/SystemZDisassembler.c +484 -0
  186. package/deps/capstone/arch/SystemZ/SystemZDisassembler.h +17 -0
  187. package/deps/capstone/arch/SystemZ/SystemZGenAsmWriter.inc +11575 -0
  188. package/deps/capstone/arch/SystemZ/SystemZGenDisassemblerTables.inc +10262 -0
  189. package/deps/capstone/arch/SystemZ/SystemZGenInsnNameMaps.inc +2348 -0
  190. package/deps/capstone/arch/SystemZ/SystemZGenInstrInfo.inc +2820 -0
  191. package/deps/capstone/arch/SystemZ/SystemZGenRegisterInfo.inc +741 -0
  192. package/deps/capstone/arch/SystemZ/SystemZGenSubtargetInfo.inc +49 -0
  193. package/deps/capstone/arch/SystemZ/SystemZInstPrinter.c +433 -0
  194. package/deps/capstone/arch/SystemZ/SystemZInstPrinter.h +15 -0
  195. package/deps/capstone/arch/SystemZ/SystemZMCTargetDesc.c +195 -0
  196. package/deps/capstone/arch/SystemZ/SystemZMCTargetDesc.h +51 -0
  197. package/deps/capstone/arch/SystemZ/SystemZMapping.c +479 -0
  198. package/deps/capstone/arch/SystemZ/SystemZMapping.h +23 -0
  199. package/deps/capstone/arch/SystemZ/SystemZMappingInsn.inc +14175 -0
  200. package/deps/capstone/arch/SystemZ/SystemZModule.c +44 -0
  201. package/deps/capstone/arch/SystemZ/SystemZModule.h +12 -0
  202. package/deps/capstone/arch/TMS320C64x/TMS320C64xDisassembler.c +628 -0
  203. package/deps/capstone/arch/TMS320C64x/TMS320C64xDisassembler.h +19 -0
  204. package/deps/capstone/arch/TMS320C64x/TMS320C64xGenAsmWriter.inc +684 -0
  205. package/deps/capstone/arch/TMS320C64x/TMS320C64xGenDisassemblerTables.inc +1352 -0
  206. package/deps/capstone/arch/TMS320C64x/TMS320C64xGenInstrInfo.inc +298 -0
  207. package/deps/capstone/arch/TMS320C64x/TMS320C64xGenRegisterInfo.inc +277 -0
  208. package/deps/capstone/arch/TMS320C64x/TMS320C64xInstPrinter.c +572 -0
  209. package/deps/capstone/arch/TMS320C64x/TMS320C64xInstPrinter.h +15 -0
  210. package/deps/capstone/arch/TMS320C64x/TMS320C64xMapping.c +1926 -0
  211. package/deps/capstone/arch/TMS320C64x/TMS320C64xMapping.h +26 -0
  212. package/deps/capstone/arch/TMS320C64x/TMS320C64xModule.c +39 -0
  213. package/deps/capstone/arch/TMS320C64x/TMS320C64xModule.h +12 -0
  214. package/deps/capstone/arch/TriCore/TriCore.td +134 -0
  215. package/deps/capstone/arch/TriCore/TriCoreCallingConv.td +61 -0
  216. package/deps/capstone/arch/TriCore/TriCoreDisassembler.c +1655 -0
  217. package/deps/capstone/arch/TriCore/TriCoreDisassembler.h +18 -0
  218. package/deps/capstone/arch/TriCore/TriCoreGenAsmWriter.inc +3691 -0
  219. package/deps/capstone/arch/TriCore/TriCoreGenCSFeatureName.inc +22 -0
  220. package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsn.inc +8938 -0
  221. package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsnName.inc +404 -0
  222. package/deps/capstone/arch/TriCore/TriCoreGenCSMappingInsnOp.inc +7994 -0
  223. package/deps/capstone/arch/TriCore/TriCoreGenCSOpGroup.inc +32 -0
  224. package/deps/capstone/arch/TriCore/TriCoreGenDisassemblerTables.inc +4044 -0
  225. package/deps/capstone/arch/TriCore/TriCoreGenInstrInfo.inc +2693 -0
  226. package/deps/capstone/arch/TriCore/TriCoreGenRegisterInfo.inc +295 -0
  227. package/deps/capstone/arch/TriCore/TriCoreGenSubtargetInfo.inc +40 -0
  228. package/deps/capstone/arch/TriCore/TriCoreInstPrinter.c +488 -0
  229. package/deps/capstone/arch/TriCore/TriCoreInstrFormats.td +773 -0
  230. package/deps/capstone/arch/TriCore/TriCoreInstrInfo.td +1873 -0
  231. package/deps/capstone/arch/TriCore/TriCoreLinkage.h +21 -0
  232. package/deps/capstone/arch/TriCore/TriCoreMapping.c +241 -0
  233. package/deps/capstone/arch/TriCore/TriCoreMapping.h +32 -0
  234. package/deps/capstone/arch/TriCore/TriCoreModule.c +44 -0
  235. package/deps/capstone/arch/TriCore/TriCoreModule.h +11 -0
  236. package/deps/capstone/arch/TriCore/TriCoreRegisterInfo.td +153 -0
  237. package/deps/capstone/arch/WASM/WASMDisassembler.c +1009 -0
  238. package/deps/capstone/arch/WASM/WASMDisassembler.h +12 -0
  239. package/deps/capstone/arch/WASM/WASMInstPrinter.c +47 -0
  240. package/deps/capstone/arch/WASM/WASMInstPrinter.h +18 -0
  241. package/deps/capstone/arch/WASM/WASMMapping.c +333 -0
  242. package/deps/capstone/arch/WASM/WASMMapping.h +9 -0
  243. package/deps/capstone/arch/WASM/WASMModule.c +33 -0
  244. package/deps/capstone/arch/WASM/WASMModule.h +12 -0
  245. package/deps/capstone/arch/X86/X86ATTInstPrinter.c +997 -0
  246. package/deps/capstone/arch/X86/X86BaseInfo.h +50 -0
  247. package/deps/capstone/arch/X86/X86Disassembler.c +1033 -0
  248. package/deps/capstone/arch/X86/X86Disassembler.h +28 -0
  249. package/deps/capstone/arch/X86/X86DisassemblerDecoder.c +2358 -0
  250. package/deps/capstone/arch/X86/X86DisassemblerDecoder.h +725 -0
  251. package/deps/capstone/arch/X86/X86DisassemblerDecoderCommon.h +483 -0
  252. package/deps/capstone/arch/X86/X86GenAsmWriter.inc +49199 -0
  253. package/deps/capstone/arch/X86/X86GenAsmWriter1.inc +33196 -0
  254. package/deps/capstone/arch/X86/X86GenAsmWriter1_reduce.inc +2531 -0
  255. package/deps/capstone/arch/X86/X86GenAsmWriter_reduce.inc +2855 -0
  256. package/deps/capstone/arch/X86/X86GenDisassemblerTables.inc +112961 -0
  257. package/deps/capstone/arch/X86/X86GenDisassemblerTables2.inc +102151 -0
  258. package/deps/capstone/arch/X86/X86GenDisassemblerTables_reduce.inc +28047 -0
  259. package/deps/capstone/arch/X86/X86GenDisassemblerTables_reduce2.inc +18827 -0
  260. package/deps/capstone/arch/X86/X86GenInstrInfo.inc +15158 -0
  261. package/deps/capstone/arch/X86/X86GenInstrInfo_reduce.inc +1564 -0
  262. package/deps/capstone/arch/X86/X86GenRegisterInfo.inc +1549 -0
  263. package/deps/capstone/arch/X86/X86GenRegisterName.inc +292 -0
  264. package/deps/capstone/arch/X86/X86GenRegisterName1.inc +291 -0
  265. package/deps/capstone/arch/X86/X86ImmSize.inc +335 -0
  266. package/deps/capstone/arch/X86/X86InstPrinter.h +26 -0
  267. package/deps/capstone/arch/X86/X86InstPrinterCommon.c +116 -0
  268. package/deps/capstone/arch/X86/X86InstPrinterCommon.h +16 -0
  269. package/deps/capstone/arch/X86/X86IntelInstPrinter.c +1061 -0
  270. package/deps/capstone/arch/X86/X86Lookup16.inc +16874 -0
  271. package/deps/capstone/arch/X86/X86Lookup16_reduce.inc +2308 -0
  272. package/deps/capstone/arch/X86/X86Mapping.c +2266 -0
  273. package/deps/capstone/arch/X86/X86Mapping.h +96 -0
  274. package/deps/capstone/arch/X86/X86MappingInsn.inc +105977 -0
  275. package/deps/capstone/arch/X86/X86MappingInsnName.inc +1527 -0
  276. package/deps/capstone/arch/X86/X86MappingInsnName_reduce.inc +348 -0
  277. package/deps/capstone/arch/X86/X86MappingInsnOp.inc +75700 -0
  278. package/deps/capstone/arch/X86/X86MappingInsnOp_reduce.inc +7729 -0
  279. package/deps/capstone/arch/X86/X86MappingInsn_reduce.inc +10819 -0
  280. package/deps/capstone/arch/X86/X86MappingReg.inc +280 -0
  281. package/deps/capstone/arch/X86/X86Module.c +94 -0
  282. package/deps/capstone/arch/X86/X86Module.h +12 -0
  283. package/deps/capstone/arch/XCore/XCoreDisassembler.c +794 -0
  284. package/deps/capstone/arch/XCore/XCoreDisassembler.h +17 -0
  285. package/deps/capstone/arch/XCore/XCoreGenAsmWriter.inc +772 -0
  286. package/deps/capstone/arch/XCore/XCoreGenDisassemblerTables.inc +853 -0
  287. package/deps/capstone/arch/XCore/XCoreGenInstrInfo.inc +267 -0
  288. package/deps/capstone/arch/XCore/XCoreGenRegisterInfo.inc +110 -0
  289. package/deps/capstone/arch/XCore/XCoreInstPrinter.c +250 -0
  290. package/deps/capstone/arch/XCore/XCoreInstPrinter.h +18 -0
  291. package/deps/capstone/arch/XCore/XCoreMapping.c +297 -0
  292. package/deps/capstone/arch/XCore/XCoreMapping.h +26 -0
  293. package/deps/capstone/arch/XCore/XCoreMappingInsn.inc +1287 -0
  294. package/deps/capstone/arch/XCore/XCoreModule.c +41 -0
  295. package/deps/capstone/arch/XCore/XCoreModule.h +12 -0
  296. package/deps/capstone/cs.c +1664 -0
  297. package/deps/capstone/cs_priv.h +101 -0
  298. package/deps/capstone/cs_simple_types.h +886 -0
  299. package/deps/capstone/include/capstone/arm.h +991 -0
  300. package/deps/capstone/include/capstone/arm64.h +3159 -0
  301. package/deps/capstone/include/capstone/bpf.h +209 -0
  302. package/deps/capstone/include/capstone/capstone.h +875 -0
  303. package/deps/capstone/include/capstone/evm.h +188 -0
  304. package/deps/capstone/include/capstone/m680x.h +537 -0
  305. package/deps/capstone/include/capstone/m68k.h +613 -0
  306. package/deps/capstone/include/capstone/mips.h +956 -0
  307. package/deps/capstone/include/capstone/mos65xx.h +204 -0
  308. package/deps/capstone/include/capstone/platform.h +122 -0
  309. package/deps/capstone/include/capstone/ppc.h +2108 -0
  310. package/deps/capstone/include/capstone/riscv.h +531 -0
  311. package/deps/capstone/include/capstone/sh.h +465 -0
  312. package/deps/capstone/include/capstone/sparc.h +520 -0
  313. package/deps/capstone/include/capstone/systemz.h +2601 -0
  314. package/deps/capstone/include/capstone/tms320c64x.h +359 -0
  315. package/deps/capstone/include/capstone/tricore.h +567 -0
  316. package/deps/capstone/include/capstone/wasm.h +250 -0
  317. package/deps/capstone/include/capstone/x86.h +1986 -0
  318. package/deps/capstone/include/capstone/xcore.h +235 -0
  319. package/deps/capstone/include/platform.h +110 -0
  320. package/deps/capstone/include/windowsce/intrin.h +12 -0
  321. package/deps/capstone/include/windowsce/stdint.h +133 -0
  322. package/deps/capstone/utils.c +140 -0
  323. package/deps/capstone/utils.h +54 -0
  324. package/index.d.ts +448 -0
  325. package/index.js +64 -0
  326. package/index.mjs +25 -0
  327. package/package.json +82 -0
  328. package/prebuilds/win32-x64/hexcore-capstone.node +0 -0
  329. package/src/capstone_wrapper.cpp +910 -0
  330. package/src/capstone_wrapper.h +147 -0
  331. package/src/disasm_async_worker.h +215 -0
  332. 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