aarch64 1.0.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 (281) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +77 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +201 -0
  5. data/README.md +77 -0
  6. data/Rakefile +168 -0
  7. data/aarch64.gemspec +21 -0
  8. data/bin/build_instructions.rb +102 -0
  9. data/lib/aarch64/instructions/adc.rb +31 -0
  10. data/lib/aarch64/instructions/adcs.rb +30 -0
  11. data/lib/aarch64/instructions/add_addsub_ext.rb +35 -0
  12. data/lib/aarch64/instructions/add_addsub_imm.rb +32 -0
  13. data/lib/aarch64/instructions/add_addsub_shift.rb +35 -0
  14. data/lib/aarch64/instructions/addg.rb +30 -0
  15. data/lib/aarch64/instructions/adds_addsub_ext.rb +35 -0
  16. data/lib/aarch64/instructions/adds_addsub_imm.rb +33 -0
  17. data/lib/aarch64/instructions/adds_addsub_shift.rb +35 -0
  18. data/lib/aarch64/instructions/adr.rb +28 -0
  19. data/lib/aarch64/instructions/adrp.rb +28 -0
  20. data/lib/aarch64/instructions/and_log_imm.rb +35 -0
  21. data/lib/aarch64/instructions/and_log_shift.rb +35 -0
  22. data/lib/aarch64/instructions/ands_log_imm.rb +35 -0
  23. data/lib/aarch64/instructions/ands_log_shift.rb +35 -0
  24. data/lib/aarch64/instructions/asrv.rb +31 -0
  25. data/lib/aarch64/instructions/autda.rb +32 -0
  26. data/lib/aarch64/instructions/autdb.rb +32 -0
  27. data/lib/aarch64/instructions/autia.rb +35 -0
  28. data/lib/aarch64/instructions/autib.rb +35 -0
  29. data/lib/aarch64/instructions/axflag.rb +18 -0
  30. data/lib/aarch64/instructions/b_cond.rb +26 -0
  31. data/lib/aarch64/instructions/b_uncond.rb +24 -0
  32. data/lib/aarch64/instructions/bc_cond.rb +26 -0
  33. data/lib/aarch64/instructions/bfm.rb +34 -0
  34. data/lib/aarch64/instructions/bic_log_shift.rb +35 -0
  35. data/lib/aarch64/instructions/bics.rb +35 -0
  36. data/lib/aarch64/instructions/bl.rb +24 -0
  37. data/lib/aarch64/instructions/blr.rb +24 -0
  38. data/lib/aarch64/instructions/blra.rb +33 -0
  39. data/lib/aarch64/instructions/br.rb +24 -0
  40. data/lib/aarch64/instructions/bra.rb +33 -0
  41. data/lib/aarch64/instructions/brk.rb +24 -0
  42. data/lib/aarch64/instructions/bti.rb +24 -0
  43. data/lib/aarch64/instructions/cas.rb +41 -0
  44. data/lib/aarch64/instructions/casb.rb +35 -0
  45. data/lib/aarch64/instructions/cash.rb +35 -0
  46. data/lib/aarch64/instructions/casp.rb +41 -0
  47. data/lib/aarch64/instructions/cbnz.rb +29 -0
  48. data/lib/aarch64/instructions/cbz.rb +29 -0
  49. data/lib/aarch64/instructions/ccmn_imm.rb +33 -0
  50. data/lib/aarch64/instructions/ccmn_reg.rb +33 -0
  51. data/lib/aarch64/instructions/ccmp_imm.rb +33 -0
  52. data/lib/aarch64/instructions/ccmp_reg.rb +33 -0
  53. data/lib/aarch64/instructions/cfinv.rb +19 -0
  54. data/lib/aarch64/instructions/clrex.rb +24 -0
  55. data/lib/aarch64/instructions/cls_int.rb +29 -0
  56. data/lib/aarch64/instructions/clz_int.rb +29 -0
  57. data/lib/aarch64/instructions/crc32.rb +35 -0
  58. data/lib/aarch64/instructions/crc32c.rb +35 -0
  59. data/lib/aarch64/instructions/csdb.rb +19 -0
  60. data/lib/aarch64/instructions/csel.rb +33 -0
  61. data/lib/aarch64/instructions/csinc.rb +33 -0
  62. data/lib/aarch64/instructions/csinv.rb +33 -0
  63. data/lib/aarch64/instructions/csneg.rb +33 -0
  64. data/lib/aarch64/instructions/dcps.rb +26 -0
  65. data/lib/aarch64/instructions/dgh.rb +19 -0
  66. data/lib/aarch64/instructions/dmb.rb +24 -0
  67. data/lib/aarch64/instructions/drps.rb +19 -0
  68. data/lib/aarch64/instructions/dsb.rb +25 -0
  69. data/lib/aarch64/instructions/eon.rb +35 -0
  70. data/lib/aarch64/instructions/eor_log_imm.rb +35 -0
  71. data/lib/aarch64/instructions/eor_log_shift.rb +35 -0
  72. data/lib/aarch64/instructions/eret.rb +19 -0
  73. data/lib/aarch64/instructions/ereta.rb +25 -0
  74. data/lib/aarch64/instructions/esb.rb +19 -0
  75. data/lib/aarch64/instructions/extr.rb +34 -0
  76. data/lib/aarch64/instructions/gmi.rb +28 -0
  77. data/lib/aarch64/instructions/hint.rb +26 -0
  78. data/lib/aarch64/instructions/hlt.rb +24 -0
  79. data/lib/aarch64/instructions/hvc.rb +24 -0
  80. data/lib/aarch64/instructions/irg.rb +28 -0
  81. data/lib/aarch64/instructions/isb.rb +24 -0
  82. data/lib/aarch64/instructions/ld64b.rb +26 -0
  83. data/lib/aarch64/instructions/ldadd.rb +41 -0
  84. data/lib/aarch64/instructions/ldaddb.rb +35 -0
  85. data/lib/aarch64/instructions/ldaddh.rb +35 -0
  86. data/lib/aarch64/instructions/ldapr.rb +29 -0
  87. data/lib/aarch64/instructions/ldaprb.rb +26 -0
  88. data/lib/aarch64/instructions/ldaprh.rb +26 -0
  89. data/lib/aarch64/instructions/ldapur_gen.rb +33 -0
  90. data/lib/aarch64/instructions/ldar.rb +29 -0
  91. data/lib/aarch64/instructions/ldaxp.rb +31 -0
  92. data/lib/aarch64/instructions/ldaxr.rb +29 -0
  93. data/lib/aarch64/instructions/ldclr.rb +41 -0
  94. data/lib/aarch64/instructions/ldclrb.rb +37 -0
  95. data/lib/aarch64/instructions/ldeor.rb +41 -0
  96. data/lib/aarch64/instructions/ldg.rb +28 -0
  97. data/lib/aarch64/instructions/ldgm.rb +26 -0
  98. data/lib/aarch64/instructions/ldlar.rb +29 -0
  99. data/lib/aarch64/instructions/ldnp_gen.rb +33 -0
  100. data/lib/aarch64/instructions/ldp_gen.rb +39 -0
  101. data/lib/aarch64/instructions/ldpsw.rb +34 -0
  102. data/lib/aarch64/instructions/ldr_imm_gen.rb +35 -0
  103. data/lib/aarch64/instructions/ldr_imm_unsigned.rb +31 -0
  104. data/lib/aarch64/instructions/ldr_lit_gen.rb +29 -0
  105. data/lib/aarch64/instructions/ldr_reg_gen.rb +35 -0
  106. data/lib/aarch64/instructions/ldra.rb +37 -0
  107. data/lib/aarch64/instructions/ldrb_imm.rb +32 -0
  108. data/lib/aarch64/instructions/ldrb_reg.rb +33 -0
  109. data/lib/aarch64/instructions/ldrb_unsigned.rb +28 -0
  110. data/lib/aarch64/instructions/ldrh_imm.rb +32 -0
  111. data/lib/aarch64/instructions/ldrh_reg.rb +32 -0
  112. data/lib/aarch64/instructions/ldrh_unsigned.rb +28 -0
  113. data/lib/aarch64/instructions/ldrsb_imm.rb +37 -0
  114. data/lib/aarch64/instructions/ldrsb_reg.rb +37 -0
  115. data/lib/aarch64/instructions/ldrsb_unsigned.rb +35 -0
  116. data/lib/aarch64/instructions/ldrsh_imm.rb +37 -0
  117. data/lib/aarch64/instructions/ldrsh_reg.rb +35 -0
  118. data/lib/aarch64/instructions/ldrsh_unsigned.rb +31 -0
  119. data/lib/aarch64/instructions/ldrsw_imm.rb +32 -0
  120. data/lib/aarch64/instructions/ldrsw_lit.rb +26 -0
  121. data/lib/aarch64/instructions/ldrsw_reg.rb +32 -0
  122. data/lib/aarch64/instructions/ldrsw_unsigned.rb +30 -0
  123. data/lib/aarch64/instructions/ldset.rb +41 -0
  124. data/lib/aarch64/instructions/ldsetb.rb +35 -0
  125. data/lib/aarch64/instructions/ldseth.rb +35 -0
  126. data/lib/aarch64/instructions/ldsmax.rb +41 -0
  127. data/lib/aarch64/instructions/ldsmaxb.rb +35 -0
  128. data/lib/aarch64/instructions/ldsmaxh.rb +35 -0
  129. data/lib/aarch64/instructions/ldsmin.rb +41 -0
  130. data/lib/aarch64/instructions/ldsminb.rb +35 -0
  131. data/lib/aarch64/instructions/ldsminh.rb +35 -0
  132. data/lib/aarch64/instructions/ldtr.rb +31 -0
  133. data/lib/aarch64/instructions/ldtrb.rb +28 -0
  134. data/lib/aarch64/instructions/ldtrh.rb +28 -0
  135. data/lib/aarch64/instructions/ldtrsb.rb +31 -0
  136. data/lib/aarch64/instructions/ldtrsh.rb +31 -0
  137. data/lib/aarch64/instructions/ldtrsw.rb +28 -0
  138. data/lib/aarch64/instructions/ldumax.rb +41 -0
  139. data/lib/aarch64/instructions/ldumaxb.rb +35 -0
  140. data/lib/aarch64/instructions/ldumaxh.rb +35 -0
  141. data/lib/aarch64/instructions/ldumin.rb +41 -0
  142. data/lib/aarch64/instructions/lduminb.rb +35 -0
  143. data/lib/aarch64/instructions/lduminh.rb +35 -0
  144. data/lib/aarch64/instructions/ldur_gen.rb +31 -0
  145. data/lib/aarch64/instructions/ldursb.rb +31 -0
  146. data/lib/aarch64/instructions/ldursh.rb +31 -0
  147. data/lib/aarch64/instructions/ldursw.rb +28 -0
  148. data/lib/aarch64/instructions/ldxp.rb +31 -0
  149. data/lib/aarch64/instructions/ldxr.rb +29 -0
  150. data/lib/aarch64/instructions/lslv.rb +31 -0
  151. data/lib/aarch64/instructions/lsrv.rb +31 -0
  152. data/lib/aarch64/instructions/madd.rb +33 -0
  153. data/lib/aarch64/instructions/movk.rb +31 -0
  154. data/lib/aarch64/instructions/movn.rb +31 -0
  155. data/lib/aarch64/instructions/movz.rb +31 -0
  156. data/lib/aarch64/instructions/mrs.rb +34 -0
  157. data/lib/aarch64/instructions/msr_imm.rb +28 -0
  158. data/lib/aarch64/instructions/msr_reg.rb +34 -0
  159. data/lib/aarch64/instructions/msub.rb +33 -0
  160. data/lib/aarch64/instructions/nop.rb +19 -0
  161. data/lib/aarch64/instructions/orn_log_shift.rb +35 -0
  162. data/lib/aarch64/instructions/orr_log_imm.rb +35 -0
  163. data/lib/aarch64/instructions/orr_log_shift.rb +35 -0
  164. data/lib/aarch64/instructions/pacda.rb +29 -0
  165. data/lib/aarch64/instructions/pacdb.rb +29 -0
  166. data/lib/aarch64/instructions/pacga.rb +28 -0
  167. data/lib/aarch64/instructions/pacia.rb +32 -0
  168. data/lib/aarch64/instructions/pacia2.rb +28 -0
  169. data/lib/aarch64/instructions/pacib.rb +32 -0
  170. data/lib/aarch64/instructions/prfm_imm.rb +28 -0
  171. data/lib/aarch64/instructions/prfm_lit.rb +26 -0
  172. data/lib/aarch64/instructions/prfm_reg.rb +32 -0
  173. data/lib/aarch64/instructions/prfum.rb +28 -0
  174. data/lib/aarch64/instructions/psb.rb +19 -0
  175. data/lib/aarch64/instructions/rbit_int.rb +29 -0
  176. data/lib/aarch64/instructions/ret.rb +24 -0
  177. data/lib/aarch64/instructions/reta.rb +25 -0
  178. data/lib/aarch64/instructions/rev.rb +31 -0
  179. data/lib/aarch64/instructions/rmif.rb +28 -0
  180. data/lib/aarch64/instructions/rorv.rb +31 -0
  181. data/lib/aarch64/instructions/sb.rb +19 -0
  182. data/lib/aarch64/instructions/sbc.rb +31 -0
  183. data/lib/aarch64/instructions/sbcs.rb +31 -0
  184. data/lib/aarch64/instructions/sbfm.rb +34 -0
  185. data/lib/aarch64/instructions/sdiv.rb +31 -0
  186. data/lib/aarch64/instructions/setf.rb +27 -0
  187. data/lib/aarch64/instructions/setgp.rb +25 -0
  188. data/lib/aarch64/instructions/setgpn.rb +25 -0
  189. data/lib/aarch64/instructions/setgpt.rb +25 -0
  190. data/lib/aarch64/instructions/setgptn.rb +25 -0
  191. data/lib/aarch64/instructions/setp.rb +25 -0
  192. data/lib/aarch64/instructions/setpn.rb +25 -0
  193. data/lib/aarch64/instructions/setpt.rb +25 -0
  194. data/lib/aarch64/instructions/setptn.rb +25 -0
  195. data/lib/aarch64/instructions/sev.rb +18 -0
  196. data/lib/aarch64/instructions/sevl.rb +18 -0
  197. data/lib/aarch64/instructions/smaddl.rb +30 -0
  198. data/lib/aarch64/instructions/smc.rb +24 -0
  199. data/lib/aarch64/instructions/smsubl.rb +30 -0
  200. data/lib/aarch64/instructions/smulh.rb +28 -0
  201. data/lib/aarch64/instructions/st2g.rb +32 -0
  202. data/lib/aarch64/instructions/st64b.rb +26 -0
  203. data/lib/aarch64/instructions/st64bv.rb +28 -0
  204. data/lib/aarch64/instructions/st64bv0.rb +28 -0
  205. data/lib/aarch64/instructions/stg.rb +32 -0
  206. data/lib/aarch64/instructions/stgm.rb +26 -0
  207. data/lib/aarch64/instructions/stgp.rb +34 -0
  208. data/lib/aarch64/instructions/stllr.rb +29 -0
  209. data/lib/aarch64/instructions/stllrb.rb +26 -0
  210. data/lib/aarch64/instructions/stllrh.rb +26 -0
  211. data/lib/aarch64/instructions/stlr.rb +29 -0
  212. data/lib/aarch64/instructions/stlrb.rb +26 -0
  213. data/lib/aarch64/instructions/stlrh.rb +26 -0
  214. data/lib/aarch64/instructions/stlur_gen.rb +31 -0
  215. data/lib/aarch64/instructions/stlxp.rb +33 -0
  216. data/lib/aarch64/instructions/stlxr.rb +31 -0
  217. data/lib/aarch64/instructions/stlxrb.rb +28 -0
  218. data/lib/aarch64/instructions/stlxrh.rb +28 -0
  219. data/lib/aarch64/instructions/stnp_gen.rb +33 -0
  220. data/lib/aarch64/instructions/stp_gen.rb +39 -0
  221. data/lib/aarch64/instructions/str_imm_gen.rb +37 -0
  222. data/lib/aarch64/instructions/str_imm_unsigned.rb +31 -0
  223. data/lib/aarch64/instructions/str_reg_gen.rb +35 -0
  224. data/lib/aarch64/instructions/strb_imm.rb +32 -0
  225. data/lib/aarch64/instructions/strb_imm_unsigned.rb +28 -0
  226. data/lib/aarch64/instructions/strb_reg.rb +33 -0
  227. data/lib/aarch64/instructions/strh_imm.rb +32 -0
  228. data/lib/aarch64/instructions/strh_imm_unsigned.rb +28 -0
  229. data/lib/aarch64/instructions/strh_reg.rb +32 -0
  230. data/lib/aarch64/instructions/sttr.rb +31 -0
  231. data/lib/aarch64/instructions/stur_gen.rb +31 -0
  232. data/lib/aarch64/instructions/stxp.rb +33 -0
  233. data/lib/aarch64/instructions/stxr.rb +31 -0
  234. data/lib/aarch64/instructions/stxrb.rb +28 -0
  235. data/lib/aarch64/instructions/stxrh.rb +28 -0
  236. data/lib/aarch64/instructions/stz2g.rb +32 -0
  237. data/lib/aarch64/instructions/stzg.rb +32 -0
  238. data/lib/aarch64/instructions/stzgm.rb +26 -0
  239. data/lib/aarch64/instructions/sub_addsub_ext.rb +35 -0
  240. data/lib/aarch64/instructions/sub_addsub_imm.rb +33 -0
  241. data/lib/aarch64/instructions/sub_addsub_shift.rb +35 -0
  242. data/lib/aarch64/instructions/subg.rb +30 -0
  243. data/lib/aarch64/instructions/subp.rb +28 -0
  244. data/lib/aarch64/instructions/subps.rb +28 -0
  245. data/lib/aarch64/instructions/subs_addsub_ext.rb +35 -0
  246. data/lib/aarch64/instructions/subs_addsub_imm.rb +33 -0
  247. data/lib/aarch64/instructions/subs_addsub_shift.rb +35 -0
  248. data/lib/aarch64/instructions/svc.rb +24 -0
  249. data/lib/aarch64/instructions/swp.rb +41 -0
  250. data/lib/aarch64/instructions/swpb.rb +35 -0
  251. data/lib/aarch64/instructions/swph.rb +35 -0
  252. data/lib/aarch64/instructions/sys.rb +32 -0
  253. data/lib/aarch64/instructions/sysl.rb +32 -0
  254. data/lib/aarch64/instructions/tbnz.rb +30 -0
  255. data/lib/aarch64/instructions/tbz.rb +30 -0
  256. data/lib/aarch64/instructions/tsb.rb +18 -0
  257. data/lib/aarch64/instructions/ubfm.rb +34 -0
  258. data/lib/aarch64/instructions/udf_perm_undef.rb +24 -0
  259. data/lib/aarch64/instructions/udiv.rb +31 -0
  260. data/lib/aarch64/instructions/umaddl.rb +30 -0
  261. data/lib/aarch64/instructions/umsubl.rb +30 -0
  262. data/lib/aarch64/instructions/umulh.rb +28 -0
  263. data/lib/aarch64/instructions/wfe.rb +19 -0
  264. data/lib/aarch64/instructions/wfet.rb +24 -0
  265. data/lib/aarch64/instructions/wfi.rb +19 -0
  266. data/lib/aarch64/instructions/wfit.rb +24 -0
  267. data/lib/aarch64/instructions/xaflag.rb +19 -0
  268. data/lib/aarch64/instructions/xpac.rb +28 -0
  269. data/lib/aarch64/instructions/xpaclri.rb +18 -0
  270. data/lib/aarch64/instructions/yield.rb +19 -0
  271. data/lib/aarch64/instructions.rb +266 -0
  272. data/lib/aarch64/system_registers/mrs_msr_64.rb +395 -0
  273. data/lib/aarch64/utils.rb +325 -0
  274. data/lib/aarch64/version.rb +3 -0
  275. data/lib/aarch64.rb +2857 -0
  276. data/test/all_adds_test.rb +129 -0
  277. data/test/base_instructions_test.rb +9263 -0
  278. data/test/dsl_test.rb +11 -0
  279. data/test/helper.rb +51 -0
  280. data/test/not_supported_yet_test.rb +55 -0
  281. metadata +382 -0
data/lib/aarch64.rb ADDED
@@ -0,0 +1,2857 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aarch64/instructions"
4
+ require "aarch64/system_registers/mrs_msr_64"
5
+ require "aarch64/utils"
6
+
7
+ module AArch64
8
+ module Registers
9
+ class Register < Struct.new(:to_i, :sp?, :zr?)
10
+ def integer?; false; end
11
+ end
12
+
13
+ class XRegister < Register
14
+ def x?; true; end
15
+ def zr; XZR; end
16
+ def size; 64; end
17
+ def sf; 1; end
18
+ def sizeb; 0b11; end
19
+ def opc; 0b10; end
20
+ def opc2; 0b11; end
21
+ def opc3; 0b10; end
22
+ end
23
+
24
+ class WRegister < Register
25
+ def x?; false; end
26
+ def zr; WZR; end
27
+ def size; 32; end
28
+ def sf; 0; end
29
+ def sizeb; 0b10; end
30
+ def opc; 0b11; end
31
+ def opc2; 0b10; end
32
+ def opc3; 0b00; end
33
+ end
34
+
35
+ 31.times { |i|
36
+ const_set(:"X#{i}", XRegister.new(i, false, false))
37
+ const_set(:"W#{i}", WRegister.new(i, false, false))
38
+ }
39
+
40
+ SP = XRegister.new(31, true, false)
41
+ WSP = WRegister.new(31, true, false)
42
+ XZR = XRegister.new(31, false, true)
43
+ WZR = WRegister.new(31, false, true)
44
+
45
+ module Methods
46
+ str = 31.times.map { |i|
47
+ "def x#{i}; ::AArch64::Registers::X#{i}; end; " +
48
+ "def w#{i}; ::AArch64::Registers::W#{i}; end"
49
+ }.join("; ")
50
+
51
+ module_eval str, __FILE__, __LINE__
52
+
53
+ def sp; SP; end
54
+ def wsp; WSP; end
55
+ def xzr; XZR; end
56
+ def wzr; WZR; end
57
+ end
58
+ end
59
+
60
+ module Conditions
61
+ module Methods
62
+ module_eval Utils::COND_TABLE.keys.map { |key|
63
+ "def #{key.downcase}; #{key.dump}; end"
64
+ }.join("\n")
65
+ end
66
+ end
67
+
68
+ module Names
69
+ 0x10.times.map { |i| const_set(:"C#{i}", i) }
70
+
71
+ module Methods
72
+ module_eval 0x10.times.map { |i|
73
+ "def c#{i}; #{i}; end"
74
+ }.join("\n")
75
+ end
76
+ end
77
+
78
+ module Extends
79
+ class Extend < Struct.new(:amount, :type, :name)
80
+ def extend?; true; end
81
+ def shift?; false; end
82
+ end
83
+
84
+ module Methods
85
+ module_eval [
86
+ :uxtb,
87
+ :uxth,
88
+ :uxtw,
89
+ :uxtx,
90
+ :sxtb,
91
+ :sxth,
92
+ :sxtw,
93
+ :sxtx ].map.with_index { |n, i|
94
+ "def #{n}(amount = 0); Extend.new(amount, #{i}, :#{n}); end"
95
+ }.join("\n")
96
+ end
97
+ end
98
+
99
+ module Shifts
100
+ class Shift < Struct.new(:amount, :type, :name)
101
+ def extend?; false; end
102
+ def shift?; true; end
103
+ end
104
+
105
+ module Methods
106
+ module_eval [:lsl, :lsr, :asr, :ror].map.with_index { |n, i|
107
+ "def #{n}(amount = 0); Shift.new(amount, #{i}, :#{n}); end"
108
+ }.join("\n")
109
+ end
110
+ end
111
+
112
+ class DSL
113
+ include AArch64::Registers
114
+ include AArch64::Registers::Methods
115
+ include AArch64::Conditions::Methods
116
+ include AArch64::Extends::Methods
117
+ include AArch64::Shifts::Methods
118
+ include AArch64::Names::Methods
119
+ include AArch64::SystemRegisters
120
+ end
121
+
122
+ class Assembler
123
+ include Instructions
124
+ include Registers
125
+
126
+ class Label
127
+ def initialize name
128
+ @name = name
129
+ @offset = nil
130
+ end
131
+
132
+ def set_offset offset
133
+ @offset = offset
134
+ freeze
135
+ end
136
+
137
+ def to_i
138
+ @offset * 4
139
+ end
140
+ end
141
+
142
+ def initialize
143
+ @insns = []
144
+ end
145
+
146
+ # Creates a DSL object so you can write prettier assembly. For example:
147
+ #
148
+ # asm = AArch64::Assembler.new
149
+ # asm.pretty do
150
+ # asm.movz x0, 42
151
+ # asm.ret
152
+ # end
153
+ def pretty &block
154
+ DSL.new.instance_eval(&block)
155
+ end
156
+
157
+ # Makes a new label with +name+. Place the label using the +put_label+
158
+ # method.
159
+ def make_label name
160
+ Label.new name
161
+ end
162
+
163
+ # Puts the label at the current position. Labels can only be placed once.
164
+ def put_label label
165
+ label.set_offset @insns.length
166
+ end
167
+
168
+ def adc d, n, m
169
+ a ADC.new(d, n, m, d.sf)
170
+ end
171
+
172
+ def adcs d, n, m
173
+ a ADCS.new(d, n, m, d.sf)
174
+ end
175
+
176
+ def add d, n, m, extend: nil, amount: 0, lsl: 0, shift: :lsl
177
+ if extend
178
+ extend = case extend
179
+ when :uxtb then 0b000
180
+ when :uxth then 0b001
181
+ when :uxtw then 0b010
182
+ when :uxtx then 0b011
183
+ when :sxtb then 0b100
184
+ when :sxth then 0b101
185
+ when :sxtw then 0b110
186
+ when :sxtx then 0b111
187
+ else
188
+ raise "Unknown extend #{extend}"
189
+ end
190
+
191
+ if m.x?
192
+ if (extend & 0x3 != 0x3)
193
+ raise "Wrong extend"
194
+ end
195
+ else
196
+ if (extend & 0x3 == 0x3)
197
+ raise "Wrong extend"
198
+ end
199
+ end
200
+
201
+ a ADD_addsub_ext.new(d, n, m, extend, amount, d.sf)
202
+ else
203
+ if m.integer?
204
+ # add immediate
205
+ a ADD_addsub_imm.new(d, n, m, lsl / 12, d.sf)
206
+ else
207
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
208
+ a ADD_addsub_shift.new(d, n, m, shift, amount, d.sf)
209
+ end
210
+ end
211
+ end
212
+
213
+ def addg xd, xn, imm6, imm4
214
+ a ADDG.new(xd, xn, imm6, imm4)
215
+ end
216
+
217
+ def adds d, n, m, option = nil, extend: nil, amount: 0, lsl: 0, shift: :lsl
218
+ if n.sp? && !m.integer?
219
+ if n.x?
220
+ extend ||= :uxtx
221
+ else
222
+ extend ||= :uxtw
223
+ end
224
+ end
225
+
226
+ if option
227
+ if option.extend?
228
+ extend = option.name
229
+ amount = option.amount
230
+ else
231
+ if m.integer?
232
+ lsl = option.amount
233
+ else
234
+ shift = option.name
235
+ amount = option.amount
236
+ end
237
+ end
238
+ end
239
+
240
+ if extend
241
+ extend = case extend
242
+ when :uxtb then 0b000
243
+ when :uxth then 0b001
244
+ when :uxtw then 0b010
245
+ when :uxtx then 0b011
246
+ when :sxtb then 0b100
247
+ when :sxth then 0b101
248
+ when :sxtw then 0b110
249
+ when :sxtx then 0b111
250
+ else
251
+ raise "Unknown extend #{extend}"
252
+ end
253
+ a ADDS_addsub_ext.new(d, n, m, extend, amount, d.sf)
254
+ else
255
+ if m.integer?
256
+ a ADDS_addsub_imm.new(d, n, m, lsl / 12, d.sf)
257
+ else
258
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
259
+ a ADDS_addsub_shift.new(d, n, m, shift, amount, d.sf)
260
+ end
261
+ end
262
+ end
263
+
264
+ def adr xd, label
265
+ a ADR.new(xd, label)
266
+ end
267
+
268
+ def adrp xd, label
269
+ a ADRP.new(xd, label)
270
+ end
271
+
272
+ def and d, n, m, shift: :lsl, amount: 0
273
+ if m.integer?
274
+ enc = Utils.encode_mask(m, d.size) || raise("Can't encode mask #{m}")
275
+ a AND_log_imm.new(d, n, enc.immr, enc.imms, enc.n, d.sf)
276
+ else
277
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
278
+ a AND_log_shift.new(d, n, m, shift, amount, d.sf)
279
+ end
280
+ end
281
+
282
+ def ands d, n, m, shift: :lsl, amount: 0
283
+ if m.integer?
284
+ enc = Utils.encode_mask(m, d.size) || raise("Can't encode mask #{m}")
285
+ a ANDS_log_imm.new(d, n, enc.immr, enc.imms, enc.n, d.sf)
286
+ else
287
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
288
+ a ANDS_log_shift.new(d, n, m, shift, amount, d.sf)
289
+ end
290
+ end
291
+
292
+ def asr d, n, m
293
+ if m.integer?
294
+ if d.x?
295
+ sbfm d, n, m, 63
296
+ else
297
+ sbfm d, n, m, 31
298
+ end
299
+ else
300
+ asrv d, n, m
301
+ end
302
+ end
303
+
304
+ def asrv d, n, m
305
+ a ASRV.new(d, n, m, d.sf)
306
+ end
307
+
308
+ def at at_op, t
309
+ op = Utils.at_op(at_op)
310
+ sys op[:op1], Names::C7, op[:crm], op[:op2], t
311
+ end
312
+
313
+ def autda d, n
314
+ a AUTDA.new(d, n)
315
+ end
316
+
317
+ def autdza d
318
+ a AUTDA.new(d, 0b11111)
319
+ end
320
+
321
+ def autdb d, n
322
+ a AUTDB.new(d, n)
323
+ end
324
+
325
+ def autdzb d
326
+ a AUTDB.new(d, 0b11111)
327
+ end
328
+
329
+ def autia d, n
330
+ a AUTIA.new(d, n)
331
+ end
332
+
333
+ def autiza d
334
+ a AUTIA.new(d, 0b11111)
335
+ end
336
+
337
+ def autia1716
338
+ a HINT.new(0b0001, 0b100)
339
+ end
340
+
341
+ def autiasp
342
+ a HINT.new(0b0011, 0b101)
343
+ end
344
+
345
+ def autiaz
346
+ a HINT.new(0b0011, 0b100)
347
+ end
348
+
349
+ def autib d, n
350
+ a AUTIB.new(d, n)
351
+ end
352
+
353
+ def autizb d
354
+ a AUTIB.new(d, 0b11111)
355
+ end
356
+
357
+ def autib1716
358
+ a HINT.new(0b0001, 0b110)
359
+ end
360
+
361
+ def autibsp
362
+ a HINT.new(0b0011, 0b111)
363
+ end
364
+
365
+ def autibz
366
+ a HINT.new(0b0011, 0b110)
367
+ end
368
+
369
+ def axflag
370
+ a AXFLAG.new
371
+ end
372
+
373
+ def b label, cond: nil
374
+ if cond
375
+ a B_cond.new(cond, label)
376
+ else
377
+ a B_uncond.new(label)
378
+ end
379
+ end
380
+
381
+ def bc label, cond:
382
+ a BC_cond.new(cond, label)
383
+ end
384
+
385
+ def bfc rd, lsb, width
386
+ div = rd.x? ? 64 : 32
387
+ rn = rd.x? ? XZR : WZR
388
+ bfm(rd, rn, -lsb % div, width - 1)
389
+ end
390
+
391
+ def bfi rd, rn, lsb, width
392
+ div = rd.x? ? 64 : 32
393
+ bfm(rd, rn, -lsb % div, width - 1)
394
+ end
395
+
396
+ def bfm d, n, immr, imms
397
+ a BFM.new(d, n, immr, imms, d.sf)
398
+ end
399
+
400
+ def bfxil d, n, lsb, width
401
+ bfm d, n, lsb, lsb + width - 1
402
+ end
403
+
404
+ def bic d, n, m, option = nil, shift: :lsl, amount: 0
405
+ if option
406
+ shift = option.name
407
+ amount = option.amount
408
+ end
409
+
410
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
411
+ a BIC_log_shift.new(d, n, m, shift, amount, d.sf)
412
+ end
413
+
414
+ def bics d, n, m, option = nil, shift: :lsl, amount: 0
415
+ if option
416
+ shift = option.name
417
+ amount = option.amount
418
+ end
419
+
420
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
421
+ a BICS.new(d, n, m, shift, amount, d.sf)
422
+ end
423
+
424
+ def bl label
425
+ a BL.new(label)
426
+ end
427
+
428
+ def blr n
429
+ a BLR.new(n)
430
+ end
431
+
432
+ def blraaz rn
433
+ a BLRA.new(rn, 0b11111, 0, 0)
434
+ end
435
+
436
+ def blraa rn, rm
437
+ a BLRA.new(rn, rm, 1, 0)
438
+ end
439
+
440
+ def blrabz rn
441
+ a BLRA.new(rn, 0b11111, 0, 1)
442
+ end
443
+
444
+ def blrab rn, rm
445
+ a BLRA.new(rn, rm, 1, 1)
446
+ end
447
+
448
+ def br rn
449
+ a BR.new(rn)
450
+ end
451
+
452
+ def braaz rn
453
+ a BRA.new(rn, 0b11111, 0, 0)
454
+ end
455
+
456
+ def braa rn, rm
457
+ a BRA.new(rn, rm, 1, 0)
458
+ end
459
+
460
+ def brabz rn
461
+ a BRA.new(rn, 0b11111, 0, 1)
462
+ end
463
+
464
+ def brab rn, rm
465
+ a BRA.new(rn, rm, 1, 1)
466
+ end
467
+
468
+ def brk imm
469
+ a BRK.new(imm)
470
+ end
471
+
472
+ def bti target
473
+ target = [:c, :j, :jc].index(target) || raise(NotImplementedError)
474
+ a BTI.new(target)
475
+ end
476
+
477
+ def cas s, t, n_list
478
+ a CAS.new(s, t, n_list[0], 0, 0, s.sf)
479
+ end
480
+
481
+ def casa s, t, n_list
482
+ a CAS.new(s, t, n_list[0], 1, 0, s.sf)
483
+ end
484
+
485
+ def casl s, t, n_list
486
+ a CAS.new(s, t, n_list[0], 0, 1, s.sf)
487
+ end
488
+
489
+ def casal s, t, n_list
490
+ a CAS.new(s, t, n_list[0], 1, 1, s.sf)
491
+ end
492
+
493
+ def casb rs, rt, rn_list
494
+ a CASB.new(rs, rt, rn_list[0], 0, 0)
495
+ end
496
+
497
+ def casalb rs, rt, rn_list
498
+ a CASB.new(rs, rt, rn_list[0], 1, 1)
499
+ end
500
+
501
+ def caslb rs, rt, rn_list
502
+ a CASB.new(rs, rt, rn_list[0], 0, 1)
503
+ end
504
+
505
+ def casah rs, rt, rn_list
506
+ a CASH.new(rs, rt, rn_list[0], 1, 0)
507
+ end
508
+
509
+ def casalh rs, rt, rn_list
510
+ a CASH.new(rs, rt, rn_list[0], 1, 1)
511
+ end
512
+
513
+ def cash rs, rt, rn_list
514
+ a CASH.new(rs, rt, rn_list[0], 0, 0)
515
+ end
516
+
517
+ def caslh rs, rt, rn_list
518
+ a CASH.new(rs, rt, rn_list[0], 0, 1)
519
+ end
520
+
521
+ def casp rs, rs1, rt, rt1, rn_list
522
+ a CASP.new(rs, rt, rn_list[0], 0, 0, rs.sf)
523
+ end
524
+
525
+ def caspa rs, rs1, rt, rt1, rn_list
526
+ a CASP.new(rs, rt, rn_list[0], 1, 0, rs.sf)
527
+ end
528
+
529
+ def caspl rs, rs1, rt, rt1, rn_list
530
+ a CASP.new(rs, rt, rn_list[0], 0, 1, rs.sf)
531
+ end
532
+
533
+ def caspal rs, rs1, rt, rt1, rn_list
534
+ a CASP.new(rs, rt, rn_list[0], 1, 1, rs.sf)
535
+ end
536
+
537
+ def cbnz rt, label
538
+ a CBNZ.new(rt, label, rt.sf)
539
+ end
540
+
541
+ def cbz rt, label
542
+ a CBZ.new(rt, label, rt.sf)
543
+ end
544
+
545
+ def ccmn rn, rm, nzcv, cond
546
+ cond = Utils.cond2bin(cond)
547
+
548
+ if rm.integer?
549
+ a CCMN_imm.new(rn, rm, nzcv, cond, rn.sf)
550
+ else
551
+ a CCMN_reg.new(rn, rm, nzcv, cond, rn.sf)
552
+ end
553
+ end
554
+
555
+ def ccmp rn, rm, nzcv, cond
556
+ cond = Utils.cond2bin(cond)
557
+
558
+ if rm.integer?
559
+ a CCMP_imm.new(rn, rm, nzcv, cond, rn.sf)
560
+ else
561
+ a CCMP_reg.new(rn, rm, nzcv, cond, rn.sf)
562
+ end
563
+ end
564
+
565
+ def cfinv
566
+ a CFINV.new
567
+ end
568
+
569
+ def cfp_rcfx rt
570
+ sys 3, Names::C7, Names::C3, 4, rt
571
+ end
572
+
573
+ def cinc rd, rn, cond
574
+ a CSINC.new(rd, rn, rn, Utils.cond2bin(cond) ^ 1, rd.sf)
575
+ end
576
+
577
+ def cset rd, cond
578
+ a CSINC.new(rd, WZR, WZR, Utils.cond2bin(cond) ^ 1, rd.sf)
579
+ end
580
+
581
+ def csetm rd, cond
582
+ reg = rd.x? ? XZR : WZR
583
+ a CSINV.new(rd, reg, reg, Utils.cond2bin(cond) ^ 1, rd.sf)
584
+ end
585
+
586
+ def csinc rd, rn, rm, cond
587
+ a CSINC.new(rd, rn, rm, Utils.cond2bin(cond), rd.sf)
588
+ end
589
+
590
+ def cinv rd, rn, cond
591
+ a CSINV.new(rd, rn, rn, Utils.cond2bin(cond) ^ 1, rd.sf)
592
+ end
593
+
594
+ def csinv rd, rn, rm, cond
595
+ a CSINV.new(rd, rn, rm, Utils.cond2bin(cond), rd.sf)
596
+ end
597
+
598
+ def clrex imm = 15
599
+ a CLREX.new(imm)
600
+ end
601
+
602
+ def cls rd, rn
603
+ a CLS_int.new(rd, rn, rd.sf)
604
+ end
605
+
606
+ def clz rd, rn
607
+ a CLZ_int.new(rd, rn, rd.sf)
608
+ end
609
+
610
+ def cmn rn, rm, option = nil, extend: nil, amount: 0, shift: :lsl, lsl: 0
611
+ adds(rn.zr, rn, rm, option, extend: extend, amount: amount, shift: shift, lsl: lsl)
612
+ end
613
+
614
+ def cmp rn, rm, option = nil, extend: nil, amount: 0, shift: :lsl, lsl: 0
615
+ subs(rn.zr, rn, rm, option, extend: extend, amount: amount, shift: shift, lsl: lsl)
616
+ end
617
+
618
+ def cmpp xn, xm
619
+ subps XZR, xn, xm
620
+ end
621
+
622
+ def cneg rd, rn, cond
623
+ a CSNEG.new(rd, rn, rn, Utils.cond2bin(cond) ^ 1, rd.sf)
624
+ end
625
+
626
+ def cpp _, xn
627
+ sys 3, Names::C7, Names::C3, 7, xn
628
+ end
629
+
630
+ def crc32b rd, rn, rm
631
+ a CRC32.new(rd, rn, rm, 0x00, 0b0)
632
+ end
633
+
634
+ def crc32h rd, rn, rm
635
+ a CRC32.new(rd, rn, rm, 0x01, 0b0)
636
+ end
637
+
638
+ def crc32w rd, rn, rm
639
+ a CRC32.new(rd, rn, rm, 0x02, 0b0)
640
+ end
641
+
642
+ def crc32x rd, rn, rm
643
+ a CRC32.new(rd, rn, rm, 0x03, 0b1)
644
+ end
645
+
646
+ def crc32cb rd, rn, rm
647
+ a CRC32C.new(rd, rn, rm, 0x00, 0b0)
648
+ end
649
+
650
+ def crc32ch rd, rn, rm
651
+ a CRC32C.new(rd, rn, rm, 0x01, 0b0)
652
+ end
653
+
654
+ def crc32cw rd, rn, rm
655
+ a CRC32C.new(rd, rn, rm, 0x02, 0b0)
656
+ end
657
+
658
+ def crc32cx rd, rn, rm
659
+ a CRC32C.new(rd, rn, rm, 0x03, 0b1)
660
+ end
661
+
662
+ def csdb
663
+ a CSDB.new
664
+ end
665
+
666
+ def csel rd, rn, rm, cond
667
+ a CSEL.new(rd, rn, rm, Utils.cond2bin(cond), rd.sf)
668
+ end
669
+
670
+ def csneg rd, rn, rm, cond
671
+ a CSNEG.new(rd, rn, rm, Utils.cond2bin(cond), rd.sf)
672
+ end
673
+
674
+ def dc dc_op, xt
675
+ op1, cm, op2 = Utils.dc_op(dc_op)
676
+ sys op1, Names::C7, cm, op2, xt
677
+ end
678
+
679
+ def dcps1 imm = 0
680
+ a DCPS.new(imm, 0x1)
681
+ end
682
+
683
+ def dcps2 imm = 0
684
+ a DCPS.new(imm, 0x2)
685
+ end
686
+
687
+ def dcps3 imm = 0
688
+ a DCPS.new(imm, 0x3)
689
+ end
690
+
691
+ def dgh
692
+ a DGH.new
693
+ end
694
+
695
+ def dmb option
696
+ if Numeric === option
697
+ a DMB.new(option)
698
+ else
699
+ a DMB.new(Utils.dmb2imm(option))
700
+ end
701
+ end
702
+
703
+ def drps
704
+ a DRPS.new
705
+ end
706
+
707
+ def dsb option
708
+ if Numeric === option
709
+ a DSB.new(option)
710
+ else
711
+ a DSB.new(Utils.dmb2imm(option))
712
+ end
713
+ end
714
+
715
+ def dvp _, xt
716
+ sys 3, Names::C7, Names::C3, 5, xt
717
+ end
718
+
719
+ def eon d, n, m, option = nil, amount: 0, shift: :lsl
720
+ if option
721
+ shift = option.name
722
+ amount = option.amount
723
+ end
724
+
725
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
726
+ a EON.new(d, n, m, shift, amount, d.sf)
727
+ end
728
+
729
+ def eor rd, rn, rm, options = nil, shift: :lsl, amount: 0
730
+ if options
731
+ shift = options.name
732
+ amount = options.amount
733
+ end
734
+
735
+ if rm.integer?
736
+ encoding = Utils.encode_mask(rm, rd.size)
737
+ n = rd.x? ? encoding.n : 0
738
+ a EOR_log_imm.new(rd, rn, n, encoding.immr, encoding.imms, rd.sf)
739
+ else
740
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
741
+ a EOR_log_shift.new(rd, rn, rm, shift, amount, rd.sf)
742
+ end
743
+ end
744
+
745
+ def eret
746
+ a ERET.new
747
+ end
748
+
749
+ def eretaa
750
+ a ERETA.new(0)
751
+ end
752
+
753
+ def eretab
754
+ a ERETA.new(1)
755
+ end
756
+
757
+ def esb
758
+ a ESB.new
759
+ end
760
+
761
+ def extr rd, rn, rm, lsb
762
+ a EXTR.new(rd, rn, rm, lsb, rd.sf)
763
+ end
764
+
765
+ def gmi rd, rn, rm
766
+ a GMI.new(rd, rn, rm)
767
+ end
768
+
769
+ def hint imm
770
+ a HINT.new(31, imm)
771
+ end
772
+
773
+ def hlt imm
774
+ a HLT.new(imm)
775
+ end
776
+
777
+ def hvc imm
778
+ a HVC.new(imm)
779
+ end
780
+
781
+ def ic op, xt = SP
782
+ op1, crm, op2 = Utils.ic_op(op)
783
+ sys op1, Names::C7, crm, op2, xt
784
+ end
785
+
786
+ def irg rd, rn, rm = XZR
787
+ a IRG.new(rd, rn, rm)
788
+ end
789
+
790
+ def isb option = 0b1111
791
+ a ISB.new(option)
792
+ end
793
+
794
+ def ld64b rt, rn
795
+ a LD64B.new(rt, rn.first)
796
+ end
797
+
798
+ def ldadd rs, rt, rn
799
+ if rs.x?
800
+ a LDADD.new(rs, rt, rn.first, 0b11, 0, 0)
801
+ else
802
+ a LDADD.new(rs, rt, rn.first, 0b10, 0, 0)
803
+ end
804
+ end
805
+
806
+ def ldadda rs, rt, rn
807
+ if rs.x?
808
+ a LDADD.new(rs, rt, rn.first, 0b11, 1, 0)
809
+ else
810
+ a LDADD.new(rs, rt, rn.first, 0b10, 1, 0)
811
+ end
812
+ end
813
+
814
+ def ldaddal rs, rt, rn
815
+ if rs.x?
816
+ a LDADD.new(rs, rt, rn.first, 0b11, 1, 1)
817
+ else
818
+ a LDADD.new(rs, rt, rn.first, 0b10, 1, 1)
819
+ end
820
+ end
821
+
822
+ def ldaddl rs, rt, rn
823
+ if rs.x?
824
+ a LDADD.new(rs, rt, rn.first, 0b11, 0, 1)
825
+ else
826
+ a LDADD.new(rs, rt, rn.first, 0b10, 0, 1)
827
+ end
828
+ end
829
+
830
+ def ldaddab rs, rt, rn
831
+ a LDADDB.new(rs, rt, rn.first, 1, 0)
832
+ end
833
+
834
+ def ldaddalb rs, rt, rn
835
+ a LDADDB.new(rs, rt, rn.first, 1, 1)
836
+ end
837
+
838
+ def ldaddb rs, rt, rn
839
+ a LDADDB.new(rs, rt, rn.first, 0, 0)
840
+ end
841
+
842
+ def ldaddlb rs, rt, rn
843
+ a LDADDB.new(rs, rt, rn.first, 0, 1)
844
+ end
845
+
846
+ def ldaddah rs, rt, rn
847
+ a LDADDH.new(rs, rt, rn.first, 1, 0)
848
+ end
849
+
850
+ def ldaddalh rs, rt, rn
851
+ a LDADDH.new(rs, rt, rn.first, 1, 1)
852
+ end
853
+
854
+ def ldaddh rs, rt, rn
855
+ a LDADDH.new(rs, rt, rn.first, 0, 0)
856
+ end
857
+
858
+ def ldaddlh rs, rt, rn
859
+ a LDADDH.new(rs, rt, rn.first, 0, 1)
860
+ end
861
+
862
+ def ldapr rt, rn
863
+ if rt.x?
864
+ a LDAPR.new(rt, rn.first, 0b11)
865
+ else
866
+ a LDAPR.new(rt, rn.first, 0b10)
867
+ end
868
+ end
869
+
870
+ def ldaprb rt, rn
871
+ a LDAPRB.new(rt, rn.first)
872
+ end
873
+
874
+ def ldaprh rt, rn
875
+ a LDAPRH.new(rt, rn.first)
876
+ end
877
+
878
+ def ldapur rt, rn
879
+ if rt.x?
880
+ a LDAPUR_gen.new(0b11, 0b01, rt, rn.first, rn[1] || 0)
881
+ else
882
+ a LDAPUR_gen.new(0b10, 0b01, rt, rn.first, rn[1] || 0)
883
+ end
884
+ end
885
+
886
+ def ldapurb rt, rn
887
+ a LDAPUR_gen.new(0b00, 0b01, rt, rn.first, rn[1] || 0)
888
+ end
889
+
890
+ def ldapurh rt, rn
891
+ a LDAPUR_gen.new(0b01, 0b01, rt, rn.first, rn[1] || 0)
892
+ end
893
+
894
+ def ldapursb rt, rn
895
+ if rt.x?
896
+ a LDAPUR_gen.new(0b00, 0b10, rt, rn.first, rn[1] || 0)
897
+ else
898
+ a LDAPUR_gen.new(0b00, 0b11, rt, rn.first, rn[1] || 0)
899
+ end
900
+ end
901
+
902
+ def ldapursh rt, rn
903
+ if rt.x?
904
+ a LDAPUR_gen.new(0b01, 0b10, rt, rn.first, rn[1] || 0)
905
+ else
906
+ a LDAPUR_gen.new(0b01, 0b11, rt, rn.first, rn[1] || 0)
907
+ end
908
+ end
909
+
910
+ def ldapursw rt, rn
911
+ a LDAPUR_gen.new(0b10, 0b10, rt, rn.first, rn[1] || 0)
912
+ end
913
+
914
+ def ldar rt, rn
915
+ size = rt.x? ? 0b11 : 0b10
916
+ a LDAR.new(rt, rn.first, size)
917
+ end
918
+
919
+ def ldarb rt, rn
920
+ a LDAR.new(rt, rn.first, 0x00)
921
+ end
922
+
923
+ def ldarh rt, rn
924
+ a LDAR.new(rt, rn.first, 0x01)
925
+ end
926
+
927
+ def ldaxp rt1, rt2, xn
928
+ a LDAXP.new(rt1, rt2, xn.first, rt1.sf)
929
+ end
930
+
931
+ def ldaxr rt1, xn
932
+ size = rt1.x? ? 0b11 : 0b10
933
+ a LDAXR.new(rt1, xn.first, size)
934
+ end
935
+
936
+ def ldaxrb rt1, xn
937
+ a LDAXR.new(rt1, xn.first, 0b00)
938
+ end
939
+
940
+ def ldaxrh rt1, xn
941
+ a LDAXR.new(rt1, xn.first, 0b01)
942
+ end
943
+
944
+ def ldclr rs, rt, rn
945
+ size = rs.x? ? 0b11 : 0b10
946
+ a LDCLR.new(rs, rt, rn.first, 0, 0, size)
947
+ end
948
+
949
+ def ldclra rs, rt, rn
950
+ size = rs.x? ? 0b11 : 0b10
951
+ a LDCLR.new(rs, rt, rn.first, 1, 0, size)
952
+ end
953
+
954
+ def ldclral rs, rt, rn
955
+ size = rs.x? ? 0b11 : 0b10
956
+ a LDCLR.new(rs, rt, rn.first, 1, 1, size)
957
+ end
958
+
959
+ def ldclrl rs, rt, rn
960
+ size = rs.x? ? 0b11 : 0b10
961
+ a LDCLR.new(rs, rt, rn.first, 0, 1, size)
962
+ end
963
+
964
+ def ldclrab rs, rt, rn
965
+ a LDCLRB.new(rs, rt, rn.first, 1, 0, 0b00)
966
+ end
967
+
968
+ def ldclralb rs, rt, rn
969
+ a LDCLRB.new(rs, rt, rn.first, 1, 1, 0b00)
970
+ end
971
+
972
+ def ldclrb rs, rt, rn
973
+ a LDCLRB.new(rs, rt, rn.first, 0, 0, 0b00)
974
+ end
975
+
976
+ def ldclrlb rs, rt, rn
977
+ a LDCLRB.new(rs, rt, rn.first, 0, 1, 0b00)
978
+ end
979
+
980
+ def ldclrah rs, rt, rn
981
+ a LDCLRB.new(rs, rt, rn.first, 1, 0, 0b01)
982
+ end
983
+
984
+ def ldclralh rs, rt, rn
985
+ a LDCLRB.new(rs, rt, rn.first, 1, 1, 0b01)
986
+ end
987
+
988
+ def ldclrh rs, rt, rn
989
+ a LDCLRB.new(rs, rt, rn.first, 0, 0, 0b01)
990
+ end
991
+
992
+ def ldclrlh rs, rt, rn
993
+ a LDCLRB.new(rs, rt, rn.first, 0, 1, 0b01)
994
+ end
995
+
996
+ def ldeor rs, rt, rn
997
+ size = rs.x? ? 0b11 : 0b10
998
+ a LDEOR.new(rs, rt, rn.first, 0, 0, size)
999
+ end
1000
+
1001
+ def ldeora rs, rt, rn
1002
+ size = rs.x? ? 0b11 : 0b10
1003
+ a LDEOR.new(rs, rt, rn.first, 1, 0, size)
1004
+ end
1005
+
1006
+ def ldeoral rs, rt, rn
1007
+ size = rs.x? ? 0b11 : 0b10
1008
+ a LDEOR.new(rs, rt, rn.first, 1, 1, size)
1009
+ end
1010
+
1011
+ def ldeorl rs, rt, rn
1012
+ size = rs.x? ? 0b11 : 0b10
1013
+ a LDEOR.new(rs, rt, rn.first, 0, 1, size)
1014
+ end
1015
+
1016
+ def ldeorab rs, rt, rn
1017
+ a LDEOR.new(rs, rt, rn.first, 1, 0, 0b00)
1018
+ end
1019
+
1020
+ def ldeoralb rs, rt, rn
1021
+ a LDEOR.new(rs, rt, rn.first, 1, 1, 0b00)
1022
+ end
1023
+
1024
+ def ldeorb rs, rt, rn
1025
+ a LDEOR.new(rs, rt, rn.first, 0, 0, 0b00)
1026
+ end
1027
+
1028
+ def ldeorlb rs, rt, rn
1029
+ a LDEOR.new(rs, rt, rn.first, 0, 1, 0b00)
1030
+ end
1031
+
1032
+ def ldeorah rs, rt, rn
1033
+ a LDEOR.new(rs, rt, rn.first, 1, 0, 0b01)
1034
+ end
1035
+
1036
+ def ldeoralh rs, rt, rn
1037
+ a LDEOR.new(rs, rt, rn.first, 1, 1, 0b01)
1038
+ end
1039
+
1040
+ def ldeorh rs, rt, rn
1041
+ a LDEOR.new(rs, rt, rn.first, 0, 0, 0b01)
1042
+ end
1043
+
1044
+ def ldeorlh rs, rt, rn
1045
+ a LDEOR.new(rs, rt, rn.first, 0, 1, 0b01)
1046
+ end
1047
+
1048
+ def ldg xt, xn
1049
+ a LDG.new(xt, xn.first, xn[1] || 0)
1050
+ end
1051
+
1052
+ def ldgm xt, xn
1053
+ a LDGM.new(xt, xn.first)
1054
+ end
1055
+
1056
+ def ldlar rt, rn
1057
+ size = rt.x? ? 0b11 : 0b10
1058
+ a LDLAR.new(rt, rn.first, size)
1059
+ end
1060
+
1061
+ def ldlarb rt, rn
1062
+ a LDLAR.new(rt, rn.first, 0b00)
1063
+ end
1064
+
1065
+ def ldlarh rt, rn
1066
+ a LDLAR.new(rt, rn.first, 0b01)
1067
+ end
1068
+
1069
+ def ldnp rt1, rt2, rn
1070
+ opc = rt1.x? ? 0b10 : 0b00
1071
+ div = rt1.x? ? 8 : 4
1072
+ a LDNP_gen.new(rt1, rt2, rn.first, (rn[1] || 0) / div, opc)
1073
+ end
1074
+
1075
+ def ldp rt1, rt2, rn, imm = nil
1076
+ opc = rt1.x? ? 0b10 : 0b00
1077
+ div = rt1.x? ? 8 : 4
1078
+
1079
+ if imm
1080
+ if imm == :!
1081
+ # pre-index
1082
+ a LDP_gen.new(rt1, rt2, rn.first, (rn[1] || 0) / div, 0b011, opc)
1083
+ else
1084
+ # post-index
1085
+ a LDP_gen.new(rt1, rt2, rn.first, (imm || 0) / div, 0b001, opc)
1086
+ end
1087
+ else
1088
+ # signed offset
1089
+ a LDP_gen.new(rt1, rt2, rn.first, (rn[1] || 0) / div, 0b010, opc)
1090
+ end
1091
+ end
1092
+
1093
+ def ldpsw rt, rt2, rn, imm = nil
1094
+ div = 4
1095
+
1096
+ if imm
1097
+ if imm == :!
1098
+ # pre-index
1099
+ a LDPSW.new(rt, rt2, rn.first, (rn[1] || 0) / div, 0b011)
1100
+ else
1101
+ # post-index
1102
+ a LDPSW.new(rt, rt2, rn.first, (imm || 0) / div, 0b001)
1103
+ end
1104
+ else
1105
+ # signed offset
1106
+ a LDPSW.new(rt, rt2, rn.first, (rn[1] || 0) / div, 0b010)
1107
+ end
1108
+ end
1109
+
1110
+ def ldr rt, rn, simm = nil
1111
+ size = rt.x? ? 0b11 : 0b10
1112
+
1113
+ if simm
1114
+ if simm == :!
1115
+ a LDR_imm_gen.new(rt, rn.first, (rn[1] || 0), size, 0b11)
1116
+ else
1117
+ if simm.integer?
1118
+ a LDR_imm_gen.new(rt, rn.first, simm, size, 0b01)
1119
+ else
1120
+ raise
1121
+ end
1122
+ end
1123
+ else
1124
+ if rn.is_a?(Array)
1125
+ simm = rn[1] || 0
1126
+ if simm.integer?
1127
+ div = rt.x? ? 8 : 4
1128
+ a LDR_imm_unsigned.new(rt, rn.first, simm / div, size)
1129
+ else
1130
+ rn, rm, option = *rn
1131
+ option ||= Shifts::Shift.new(0, 0, :lsl)
1132
+ extend = case option.name
1133
+ when :uxtw then 0b010
1134
+ when :lsl then 0b011
1135
+ when :sxtw then 0b110
1136
+ when :sxtx then 0b111
1137
+ else
1138
+ raise
1139
+ end
1140
+
1141
+ amount = if rt.x?
1142
+ if option.amount == 3
1143
+ 1
1144
+ else
1145
+ 0
1146
+ end
1147
+ else
1148
+ if option.amount == 2
1149
+ 1
1150
+ else
1151
+ 0
1152
+ end
1153
+ end
1154
+
1155
+ a LDR_reg_gen.new(rt, rn, rm, size, extend, amount)
1156
+ end
1157
+ else
1158
+ size = rt.x? ? 0b01 : 0b00
1159
+ a LDR_lit_gen.new(rt, rn, size)
1160
+ end
1161
+ end
1162
+ end
1163
+
1164
+ def ldraa xt, xn, option = nil
1165
+ imm = xn[1] || 0
1166
+ s = imm < 0 ? 1 : 0
1167
+ a LDRA.new(xt, xn.first, imm / 8, 0, option == :! ? 1 : 0, s)
1168
+ end
1169
+
1170
+ def ldrab xt, xn, option = nil
1171
+ imm = xn[1] || 0
1172
+ s = imm < 0 ? 1 : 0
1173
+ a LDRA.new(xt, xn.first, imm / 8, 1, option == :! ? 1 : 0, s)
1174
+ end
1175
+
1176
+ def ldrb wt, xn, imm = nil
1177
+ if imm
1178
+ if imm == :!
1179
+ a LDRB_imm.new(wt, xn.first, xn[1], 0b11)
1180
+ else
1181
+ # Post index
1182
+ a LDRB_imm.new(wt, xn.first, imm, 0b01)
1183
+ end
1184
+ else
1185
+ xn, imm, option = *xn
1186
+ imm ||= 0
1187
+ if imm.integer?
1188
+ a LDRB_unsigned.new(wt, xn, imm)
1189
+ else
1190
+ if option
1191
+ option_name = option ? option.name : :lsl
1192
+
1193
+ val = case option_name
1194
+ when :lsl then 0b011
1195
+ when :uxtw then 0b010
1196
+ when :sxtw then 0b110
1197
+ when :sxtx then 0b111
1198
+ end
1199
+
1200
+ a LDRB_reg.new(wt, xn, imm, option.shift? ? 1 : 0, val)
1201
+ else
1202
+ a LDRB_reg.new(wt, xn, imm, 0, 0b11)
1203
+ end
1204
+ end
1205
+ end
1206
+ end
1207
+
1208
+ def ldrh wt, xn, imm = nil
1209
+ if imm
1210
+ if imm == :!
1211
+ a LDRH_imm.new(wt, xn.first, xn[1], 0b11)
1212
+ else
1213
+ # Post index
1214
+ a LDRH_imm.new(wt, xn.first, imm, 0b01)
1215
+ end
1216
+ else
1217
+ xn, imm, option = *xn
1218
+ imm ||= 0
1219
+ if imm.integer?
1220
+ a LDRH_unsigned.new(wt, xn, imm)
1221
+ else
1222
+ if option
1223
+ option_name = option ? option.name : :lsl
1224
+
1225
+ val = case option_name
1226
+ when :lsl then 0b011
1227
+ when :uxtw then 0b010
1228
+ when :sxtw then 0b110
1229
+ when :sxtx then 0b111
1230
+ end
1231
+
1232
+ a LDRH_reg.new(wt, xn, imm, option.shift? ? 1 : 0, val)
1233
+ else
1234
+ a LDRH_reg.new(wt, xn, imm, 0, 0b11)
1235
+ end
1236
+ end
1237
+ end
1238
+ end
1239
+
1240
+ def ldrsb wt, xn, imm = nil
1241
+ opc = wt.x? ? 0b10 : 0b11
1242
+
1243
+ if imm
1244
+ if imm == :!
1245
+ a LDRSB_imm.new(wt, xn.first, xn[1], 0b11, opc)
1246
+ else
1247
+ # Post index
1248
+ a LDRSB_imm.new(wt, xn.first, imm, 0b01, opc)
1249
+ end
1250
+ else
1251
+ xn, imm, option = *xn
1252
+ imm ||= 0
1253
+ if imm.integer?
1254
+ a LDRSB_unsigned.new(wt, xn, imm, opc)
1255
+ else
1256
+ if option
1257
+ option_name = option ? option.name : :lsl
1258
+
1259
+ val = case option_name
1260
+ when :uxtw then 0b010
1261
+ when :sxtw then 0b110
1262
+ when :sxtx then 0b111
1263
+ end
1264
+
1265
+ a LDRSB_reg.new(wt, xn, imm, 1, val, opc)
1266
+ else
1267
+ a LDRSB_reg.new(wt, xn, imm, 0, 0b11, opc)
1268
+ end
1269
+ end
1270
+ end
1271
+ end
1272
+
1273
+ def ldrsh wt, xn, imm = nil
1274
+ opc = wt.x? ? 0b10 : 0b11
1275
+
1276
+ if imm
1277
+ if imm == :!
1278
+ a LDRSH_imm.new(wt, xn.first, xn[1] || 0, 0b11, opc)
1279
+ else
1280
+ a LDRSH_imm.new(wt, xn.first, imm, 0b01, opc)
1281
+ end
1282
+ else
1283
+ xn, imm, option = *xn
1284
+ imm ||= 0
1285
+ if imm.integer?
1286
+ a LDRSH_unsigned.new(wt, xn, imm / 2, opc)
1287
+ else
1288
+ if option
1289
+ option_name = option ? option.name : :lsl
1290
+
1291
+ val = case option_name
1292
+ when :uxtw then 0b010
1293
+ when :sxtw then 0b110
1294
+ when :sxtx then 0b111
1295
+ end
1296
+
1297
+ a LDRSH_reg.new(wt, xn, imm, 1, val, opc)
1298
+ else
1299
+ a LDRSH_reg.new(wt, xn, imm, 0, 0b11, opc)
1300
+ end
1301
+ end
1302
+ end
1303
+ end
1304
+
1305
+ def ldrsw xt, xn, imm = nil
1306
+ if imm
1307
+ if imm == :!
1308
+ a LDRSW_imm.new(xt, xn.first, xn[1] || 0, 0b11)
1309
+ else
1310
+ a LDRSW_imm.new(xt, xn.first, imm, 0b01)
1311
+ end
1312
+ else
1313
+ if xn.is_a?(Array)
1314
+ xn, imm, option = *xn
1315
+ imm ||= 0
1316
+ if imm.integer?
1317
+ a LDRSW_unsigned.new(xt, xn, imm / 4)
1318
+ else
1319
+ if option
1320
+ option_name = option ? option.name : :lsl
1321
+
1322
+ val = case option_name
1323
+ when :uxtw then 0b010
1324
+ when :lsl then 0b011
1325
+ when :sxtw then 0b110
1326
+ when :sxtx then 0b111
1327
+ end
1328
+
1329
+ a LDRSW_reg.new(xt, xn, imm, option.amount / 2, val)
1330
+ else
1331
+ a LDRSW_reg.new(xt, xn, imm, 0, 0b11)
1332
+ end
1333
+ end
1334
+ else
1335
+ a LDRSW_lit.new(xt, xn)
1336
+ end
1337
+ end
1338
+ end
1339
+
1340
+ def ldset rs, rt, rn
1341
+ size = rs.x? ? 0b11 : 0b10
1342
+ a LDSET.new(rs, rt, rn.first, size, 0, 0)
1343
+ end
1344
+
1345
+ def ldseta rs, rt, rn
1346
+ size = rs.x? ? 0b11 : 0b10
1347
+ a LDSET.new(rs, rt, rn.first, size, 1, 0)
1348
+ end
1349
+
1350
+ def ldsetal rs, rt, rn
1351
+ size = rs.x? ? 0b11 : 0b10
1352
+ a LDSET.new(rs, rt, rn.first, size, 1, 1)
1353
+ end
1354
+
1355
+ def ldsetl rs, rt, rn
1356
+ size = rs.x? ? 0b11 : 0b10
1357
+ a LDSET.new(rs, rt, rn.first, size, 0, 1)
1358
+ end
1359
+
1360
+ def ldsetb rs, rt, rn
1361
+ a LDSETB.new(rs, rt, rn.first, 0, 0)
1362
+ end
1363
+
1364
+ def ldsetab rs, rt, rn
1365
+ a LDSETB.new(rs, rt, rn.first, 1, 0)
1366
+ end
1367
+
1368
+ def ldsetalb rs, rt, rn
1369
+ a LDSETB.new(rs, rt, rn.first, 1, 1)
1370
+ end
1371
+
1372
+ def ldsetlb rs, rt, rn
1373
+ a LDSETB.new(rs, rt, rn.first, 0, 1)
1374
+ end
1375
+
1376
+ def ldseth rs, rt, rn
1377
+ a LDSETH.new(rs, rt, rn.first, 0, 0)
1378
+ end
1379
+
1380
+ def ldsetah rs, rt, rn
1381
+ a LDSETH.new(rs, rt, rn.first, 1, 0)
1382
+ end
1383
+
1384
+ def ldsetalh rs, rt, rn
1385
+ a LDSETH.new(rs, rt, rn.first, 1, 1)
1386
+ end
1387
+
1388
+ def ldsetlh rs, rt, rn
1389
+ a LDSETH.new(rs, rt, rn.first, 0, 1)
1390
+ end
1391
+
1392
+ def ldsmax rs, rt, rn
1393
+ size = rs.x? ? 0b11 : 0b10
1394
+ a LDSMAX.new(rs, rt, rn.first, size, 0, 0)
1395
+ end
1396
+
1397
+ def ldsmaxa rs, rt, rn
1398
+ size = rs.x? ? 0b11 : 0b10
1399
+ a LDSMAX.new(rs, rt, rn.first, size, 1, 0)
1400
+ end
1401
+
1402
+ def ldsmaxal rs, rt, rn
1403
+ size = rs.x? ? 0b11 : 0b10
1404
+ a LDSMAX.new(rs, rt, rn.first, size, 1, 1)
1405
+ end
1406
+
1407
+ def ldsmaxl rs, rt, rn
1408
+ size = rs.x? ? 0b11 : 0b10
1409
+ a LDSMAX.new(rs, rt, rn.first, size, 0, 1)
1410
+ end
1411
+
1412
+ def ldsmaxab rs, rt, rn
1413
+ a LDSMAXB.new(rs, rt, rn.first, 1, 0)
1414
+ end
1415
+
1416
+ def ldsmaxalb rs, rt, rn
1417
+ a LDSMAXB.new(rs, rt, rn.first, 1, 1)
1418
+ end
1419
+
1420
+ def ldsmaxb rs, rt, rn
1421
+ a LDSMAXB.new(rs, rt, rn.first, 0, 0)
1422
+ end
1423
+
1424
+ def ldsmaxlb rs, rt, rn
1425
+ a LDSMAXB.new(rs, rt, rn.first, 0, 1)
1426
+ end
1427
+
1428
+ def ldsmaxah rs, rt, rn
1429
+ a LDSMAXH.new(rs, rt, rn.first, 1, 0)
1430
+ end
1431
+
1432
+ def ldsmaxalh rs, rt, rn
1433
+ a LDSMAXH.new(rs, rt, rn.first, 1, 1)
1434
+ end
1435
+
1436
+ def ldsmaxh rs, rt, rn
1437
+ a LDSMAXH.new(rs, rt, rn.first, 0, 0)
1438
+ end
1439
+
1440
+ def ldsmaxlh rs, rt, rn
1441
+ a LDSMAXH.new(rs, rt, rn.first, 0, 1)
1442
+ end
1443
+
1444
+ def ldsmin rs, rt, rn
1445
+ size = rs.x? ? 0b11 : 0b10
1446
+ a LDSMIN.new(rs, rt, rn.first, size, 0, 0)
1447
+ end
1448
+
1449
+ def ldsmina rs, rt, rn
1450
+ size = rs.x? ? 0b11 : 0b10
1451
+ a LDSMIN.new(rs, rt, rn.first, size, 1, 0)
1452
+ end
1453
+
1454
+ def ldsminal rs, rt, rn
1455
+ size = rs.x? ? 0b11 : 0b10
1456
+ a LDSMIN.new(rs, rt, rn.first, size, 1, 1)
1457
+ end
1458
+
1459
+ def ldsminl rs, rt, rn
1460
+ size = rs.x? ? 0b11 : 0b10
1461
+ a LDSMIN.new(rs, rt, rn.first, size, 0, 1)
1462
+ end
1463
+
1464
+ def ldsminb rs, rt, rn
1465
+ a LDSMINB.new(rs, rt, rn.first, 0, 0)
1466
+ end
1467
+
1468
+ def ldsminab rs, rt, rn
1469
+ a LDSMINB.new(rs, rt, rn.first, 1, 0)
1470
+ end
1471
+
1472
+ def ldsminalb rs, rt, rn
1473
+ a LDSMINB.new(rs, rt, rn.first, 1, 1)
1474
+ end
1475
+
1476
+ def ldsminlb rs, rt, rn
1477
+ a LDSMINB.new(rs, rt, rn.first, 0, 1)
1478
+ end
1479
+
1480
+ def ldsminh rs, rt, rn
1481
+ a LDSMINH.new(rs, rt, rn.first, 0, 0)
1482
+ end
1483
+
1484
+ def ldsminah rs, rt, rn
1485
+ a LDSMINH.new(rs, rt, rn.first, 1, 0)
1486
+ end
1487
+
1488
+ def ldsminalh rs, rt, rn
1489
+ a LDSMINH.new(rs, rt, rn.first, 1, 1)
1490
+ end
1491
+
1492
+ def ldsminlh rs, rt, rn
1493
+ a LDSMINH.new(rs, rt, rn.first, 0, 1)
1494
+ end
1495
+
1496
+ def ldtr rt, rn
1497
+ size = rt.x? ? 0b11 : 0b10
1498
+ a LDTR.new(rt, rn.first, rn[1] || 0, size)
1499
+ end
1500
+
1501
+ def ldtrb rt, rn
1502
+ a LDTRB.new(rt, rn.first, rn[1] || 0)
1503
+ end
1504
+
1505
+ def ldtrh rt, rn
1506
+ a LDTRH.new(rt, rn.first, rn[1] || 0)
1507
+ end
1508
+
1509
+ def ldtrsb rt, rn
1510
+ opc = rt.x? ? 0b10 : 0b11
1511
+ a LDTRSB.new(rt, rn.first, rn[1] || 0, opc)
1512
+ end
1513
+
1514
+ def ldtrsh rt, rn
1515
+ opc = rt.x? ? 0b10 : 0b11
1516
+ a LDTRSH.new(rt, rn.first, rn[1] || 0, opc)
1517
+ end
1518
+
1519
+ def ldtrsw rt, rn
1520
+ a LDTRSW.new(rt, rn.first, rn[1] || 0)
1521
+ end
1522
+
1523
+ def ldumax rs, rt, rn
1524
+ size = rt.x? ? 0b11 : 0b10
1525
+ a LDUMAX.new(rs, rt, rn.first, size, 0, 0)
1526
+ end
1527
+
1528
+ def ldumaxa rs, rt, rn
1529
+ size = rt.x? ? 0b11 : 0b10
1530
+ a LDUMAX.new(rs, rt, rn.first, size, 1, 0)
1531
+ end
1532
+
1533
+ def ldumaxal rs, rt, rn
1534
+ size = rt.x? ? 0b11 : 0b10
1535
+ a LDUMAX.new(rs, rt, rn.first, size, 1, 1)
1536
+ end
1537
+
1538
+ def ldumaxl rs, rt, rn
1539
+ size = rt.x? ? 0b11 : 0b10
1540
+ a LDUMAX.new(rs, rt, rn.first, size, 0, 1)
1541
+ end
1542
+
1543
+ def ldumaxab rs, rt, rn
1544
+ a LDUMAXB.new(rs, rt, rn.first, 1, 0)
1545
+ end
1546
+
1547
+ def ldumaxalb rs, rt, rn
1548
+ a LDUMAXB.new(rs, rt, rn.first, 1, 1)
1549
+ end
1550
+
1551
+ def ldumaxb rs, rt, rn
1552
+ a LDUMAXB.new(rs, rt, rn.first, 0, 0)
1553
+ end
1554
+
1555
+ def ldumaxlb rs, rt, rn
1556
+ a LDUMAXB.new(rs, rt, rn.first, 0, 1)
1557
+ end
1558
+
1559
+ def ldumaxah rs, rt, rn
1560
+ a LDUMAXH.new(rs, rt, rn.first, 1, 0)
1561
+ end
1562
+
1563
+ def ldumaxalh rs, rt, rn
1564
+ a LDUMAXH.new(rs, rt, rn.first, 1, 1)
1565
+ end
1566
+
1567
+ def ldumaxh rs, rt, rn
1568
+ a LDUMAXH.new(rs, rt, rn.first, 0, 0)
1569
+ end
1570
+
1571
+ def ldumaxlh rs, rt, rn
1572
+ a LDUMAXH.new(rs, rt, rn.first, 0, 1)
1573
+ end
1574
+
1575
+ def ldumin rs, rt, rn
1576
+ a LDUMIN.new(rs, rt, rn.first, rs.sizeb, 0, 0)
1577
+ end
1578
+
1579
+ def ldumina rs, rt, rn
1580
+ a LDUMIN.new(rs, rt, rn.first, rs.sizeb, 1, 0)
1581
+ end
1582
+
1583
+ def lduminal rs, rt, rn
1584
+ a LDUMIN.new(rs, rt, rn.first, rs.sizeb, 1, 1)
1585
+ end
1586
+
1587
+ def lduminl rs, rt, rn
1588
+ a LDUMIN.new(rs, rt, rn.first, rs.sizeb, 0, 1)
1589
+ end
1590
+
1591
+ def lduminab rs, rt, rn
1592
+ a LDUMINB.new(rs, rt, rn.first, 1, 0)
1593
+ end
1594
+
1595
+ def lduminalb rs, rt, rn
1596
+ a LDUMINB.new(rs, rt, rn.first, 1, 1)
1597
+ end
1598
+
1599
+ def lduminb rs, rt, rn
1600
+ a LDUMINB.new(rs, rt, rn.first, 0, 0)
1601
+ end
1602
+
1603
+ def lduminlb rs, rt, rn
1604
+ a LDUMINB.new(rs, rt, rn.first, 0, 1)
1605
+ end
1606
+
1607
+ def lduminah rs, rt, rn
1608
+ a LDUMINH.new(rs, rt, rn.first, 1, 0)
1609
+ end
1610
+
1611
+ def lduminalh rs, rt, rn
1612
+ a LDUMINH.new(rs, rt, rn.first, 1, 1)
1613
+ end
1614
+
1615
+ def lduminh rs, rt, rn
1616
+ a LDUMINH.new(rs, rt, rn.first, 0, 0)
1617
+ end
1618
+
1619
+ def lduminlh rs, rt, rn
1620
+ a LDUMINH.new(rs, rt, rn.first, 0, 1)
1621
+ end
1622
+
1623
+ def ldursb rt, rn
1624
+ a LDURSB.new(rt, rn.first, rn[1] || 0, rt.opc)
1625
+ end
1626
+
1627
+ def ldursh rt, rn
1628
+ a LDURSH.new(rt, rn.first, rn[1] || 0, rt.opc)
1629
+ end
1630
+
1631
+ def ldursw rt, rn
1632
+ a LDURSW.new(rt, rn.first, rn[1] || 0)
1633
+ end
1634
+
1635
+ def ldxp rt, rt2, rn
1636
+ a LDXP.new(rt, rt2, rn.first, rt.sf)
1637
+ end
1638
+
1639
+ def ldur rt, rn
1640
+ if rt.x?
1641
+ a LDUR_gen.new(rt, rn.first, rn[1] || 0, 0b11)
1642
+ else
1643
+ a LDUR_gen.new(rt, rn.first, rn[1] || 0, 0b10)
1644
+ end
1645
+ end
1646
+
1647
+ def ldurb rt, rn
1648
+ a LDUR_gen.new(rt, rn.first, rn[1] || 0, 0b00)
1649
+ end
1650
+
1651
+ def ldurh rt, rn
1652
+ a LDUR_gen.new(rt, rn.first, rn[1] || 0, 0b01)
1653
+ end
1654
+
1655
+ def ldxr rt, rn
1656
+ if rt.x?
1657
+ a LDXR.new(rt, rn.first, 0b11)
1658
+ else
1659
+ a LDXR.new(rt, rn.first, 0b10)
1660
+ end
1661
+ end
1662
+
1663
+ def ldxrb rt, rn
1664
+ a LDXR.new(rt, rn.first, 0b00)
1665
+ end
1666
+
1667
+ def ldxrh rt, rn
1668
+ a LDXR.new(rt, rn.first, 0b01)
1669
+ end
1670
+
1671
+ def lsl rd, rn, rm
1672
+ if rm.integer?
1673
+ if rd.x?
1674
+ ubfm rd, rn, -rm % 64, 63 - rm
1675
+ else
1676
+ ubfm rd, rn, -rm % 32, 31 - rm
1677
+ end
1678
+ else
1679
+ lslv rd, rn, rm
1680
+ end
1681
+ end
1682
+
1683
+ def lslv rd, rn, rm
1684
+ a LSLV.new(rd, rn, rm, rd.sf)
1685
+ end
1686
+
1687
+ def lsr rd, rn, rm
1688
+ if rm.integer?
1689
+ if rd.x?
1690
+ ubfm rd, rn, rm, 63
1691
+ else
1692
+ ubfm rd, rn, rm, 31
1693
+ end
1694
+ else
1695
+ lsrv rd, rn, rm
1696
+ end
1697
+ end
1698
+
1699
+ def lsrv rd, rn, rm
1700
+ a LSRV.new(rd, rn, rm, rd.sf)
1701
+ end
1702
+
1703
+ def madd rd, rn, rm, ra
1704
+ a MADD.new(rd, rn, rm, ra, rd.sf)
1705
+ end
1706
+
1707
+ def mneg rd, rn, rm
1708
+ msub rd, rn, rm, rd.zr
1709
+ end
1710
+
1711
+ def mov rd, rm
1712
+ if rm.integer?
1713
+ if rm < 0
1714
+ rm = ~rm
1715
+ if rm < 65536 || rm % 65536 == 0
1716
+ movn(rd, rm)
1717
+ else
1718
+ orr(rd, rd.x? ? XZR : WZR, ~rm)
1719
+ end
1720
+ else
1721
+ if rm < 65536 || rm % 65536 == 0
1722
+ movz(rd, rm)
1723
+ else
1724
+ orr(rd, rd.x? ? XZR : WZR, rm)
1725
+ end
1726
+ end
1727
+ else
1728
+ if rd.sp? || rm.sp?
1729
+ add rd, rm, 0
1730
+ else
1731
+ orr(rd, rd.x? ? XZR : WZR, rm)
1732
+ end
1733
+ end
1734
+ end
1735
+
1736
+ def movn rd, imm, option = nil, lsl: 0
1737
+ lsl = option.amount if option
1738
+
1739
+ lsl /= 16
1740
+ while imm > 65535
1741
+ lsl += 1
1742
+ imm >>= 16
1743
+ end
1744
+ a MOVN.new(rd, imm, lsl, rd.sf)
1745
+ end
1746
+
1747
+ def movz reg, imm, option = nil, lsl: 0
1748
+ lsl = option.amount if option
1749
+
1750
+ lsl /= 16
1751
+ while imm > 65535
1752
+ lsl += 1
1753
+ imm >>= 16
1754
+ end
1755
+ a MOVZ.new(reg, imm, lsl, reg.sf)
1756
+ end
1757
+
1758
+ def movk reg, imm, option = nil, lsl: 0
1759
+ lsl = option.amount if option
1760
+ a MOVK.new(reg, imm, lsl / 16, reg.sf)
1761
+ end
1762
+
1763
+ def mrs rt, reg
1764
+ a MRS.new(reg.op0, reg.op1, reg.CRn, reg.CRm, reg.op2, rt)
1765
+ end
1766
+
1767
+ def msr reg, rt
1768
+ if rt.integer?
1769
+ raise NotImplementedError
1770
+ else
1771
+ a MSR_reg.new(reg.op0, reg.op1, reg.CRn, reg.CRm, reg.op2, rt)
1772
+ end
1773
+ end
1774
+
1775
+ def msub rd, rn, rm, ra
1776
+ a MSUB.new(rd, rn, rm, ra, rd.sf)
1777
+ end
1778
+
1779
+ def mul rd, rn, rm
1780
+ madd rd, rn, rm, rd.zr
1781
+ end
1782
+
1783
+ def mvn rd, rm, option = nil, shift: :lsl, amount: 0
1784
+ orn rd, rd.zr, rm, option, shift: shift, amount: amount
1785
+ end
1786
+
1787
+ def neg rd, rm, option = nil, extend: nil, amount: 0, lsl: 0, shift: :lsl
1788
+ sub rd, rd.zr, rm, option, extend: extend, amount: amount, lsl: lsl, shift: shift
1789
+ end
1790
+
1791
+ def negs rd, rm, option = nil, shift: :lsl, amount: 0
1792
+ subs rd, rd.zr, rm, option, shift: shift, amount: amount
1793
+ end
1794
+
1795
+ def ngc rd, rm
1796
+ sbc rd, rd.zr, rm
1797
+ end
1798
+
1799
+ def ngcs rd, rm
1800
+ sbcs rd, rd.zr, rm
1801
+ end
1802
+
1803
+ def nop
1804
+ a NOP.new
1805
+ end
1806
+
1807
+ def orn rd, rn, rm, option = nil, shift: :lsl, amount: 0
1808
+ if option
1809
+ shift = option.name
1810
+ amount = option.amount
1811
+ end
1812
+
1813
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
1814
+
1815
+ a ORN_log_shift.new(rd, rn, rm, shift, amount, rd.sf)
1816
+ end
1817
+
1818
+ def orr rd, rn, rm, option = nil, shift: :lsl, amount: 0
1819
+ if rm.integer?
1820
+ encoding = Utils.encode_mask(rm, rd.size)
1821
+ a ORR_log_imm.new(rd, rn, encoding.n, encoding.immr, encoding.imms, rd.sf)
1822
+ else
1823
+ if option
1824
+ shift = option.name
1825
+ amount = option.amount
1826
+ end
1827
+
1828
+ shift = [:lsl, :lsr, :asr, :ror].index(shift) || raise(NotImplementedError)
1829
+
1830
+ a ORR_log_shift.new(rd, rn, rm, shift, amount, rd.sf)
1831
+ end
1832
+ end
1833
+
1834
+ def pacda xd, xn
1835
+ a PACDA.new(xd, xn, 0)
1836
+ end
1837
+
1838
+ def pacdza xd
1839
+ a PACDA.new(xd, xd.zr, 1)
1840
+ end
1841
+
1842
+ def pacdb xd, xn
1843
+ a PACDB.new(xd, xn, 0)
1844
+ end
1845
+
1846
+ def pacdzb xd
1847
+ a PACDB.new(xd, xd.zr, 1)
1848
+ end
1849
+
1850
+ def pacga xd, xn, xm
1851
+ a PACGA.new(xd, xn, xm)
1852
+ end
1853
+
1854
+ def pacia xd, xn
1855
+ a PACIA.new(xd, xn, 0)
1856
+ end
1857
+
1858
+ def paciza xd
1859
+ a PACIA.new(xd, xd.zr, 1)
1860
+ end
1861
+
1862
+ def pacia1716
1863
+ a PACIA2.new(0b0001, 0b000)
1864
+ end
1865
+
1866
+ def paciasp
1867
+ a PACIA2.new(0b0011, 0b001)
1868
+ end
1869
+
1870
+ def paciaz
1871
+ a PACIA2.new(0b0011, 0b000)
1872
+ end
1873
+
1874
+ def pacib xd, xn
1875
+ a PACIB.new(xd, xn, 0)
1876
+ end
1877
+
1878
+ def pacizb xd
1879
+ a PACIB.new(xd, xd.zr, 1)
1880
+ end
1881
+
1882
+ def pacib1716
1883
+ a PACIA2.new(0b0001, 0b010)
1884
+ end
1885
+
1886
+ def pacibsp
1887
+ a PACIA2.new(0b0011, 0b011)
1888
+ end
1889
+
1890
+ def pacibz
1891
+ a PACIA2.new(0b0011, 0b010)
1892
+ end
1893
+
1894
+ def prfm rt, xn
1895
+ if rt.is_a?(Symbol)
1896
+ rt = Utils.prfop(rt)
1897
+ end
1898
+
1899
+ if xn.is_a?(Array)
1900
+ xn, rm, option = *xn
1901
+ rm ||= 0
1902
+ if rm.integer?
1903
+ a PRFM_imm.new(rt, xn, rm / 8)
1904
+ else
1905
+ shift = case option.name
1906
+ when :uxtw then 0b010
1907
+ when :lsl then 0b011
1908
+ when :sxtw then 0b110
1909
+ when :sxtx then 0b111
1910
+ else
1911
+ raise
1912
+ end
1913
+ a PRFM_reg.new(rt, xn, rm, shift, option.amount / 3)
1914
+ end
1915
+ else
1916
+ a PRFM_lit.new(rt, xn)
1917
+ end
1918
+ end
1919
+
1920
+ def prfum rt, rn
1921
+ if rt.is_a?(Symbol)
1922
+ rt = Utils.prfop(rt)
1923
+ end
1924
+ a PRFUM.new(rt, rn.first, rn[1] || 0)
1925
+ end
1926
+
1927
+ def psb _
1928
+ a PSB.new
1929
+ end
1930
+
1931
+ def pssbb
1932
+ dsb 4
1933
+ end
1934
+
1935
+ def rbit rd, rn
1936
+ a RBIT_int.new(rd, rn, rd.sf)
1937
+ end
1938
+
1939
+ def ret reg = X30
1940
+ a RET.new(reg)
1941
+ end
1942
+
1943
+ def retaa
1944
+ a RETA.new(0)
1945
+ end
1946
+
1947
+ def retab
1948
+ a RETA.new(1)
1949
+ end
1950
+
1951
+ def rev rd, rn
1952
+ a REV.new(rd, rn, rd.sf, rd.opc2)
1953
+ end
1954
+
1955
+ def rev16 rd, rn
1956
+ a REV.new(rd, rn, rd.sf, 0b01)
1957
+ end
1958
+
1959
+ def rev32 rd, rn
1960
+ a REV.new(rd, rn, rd.sf, 0b10)
1961
+ end
1962
+
1963
+ alias :rev64 :rev
1964
+
1965
+ def rmif rn, shift, mask
1966
+ a RMIF.new(rn, shift, mask)
1967
+ end
1968
+
1969
+ def ror rd, rs, shift
1970
+ if shift.integer?
1971
+ extr rd, rs, rs, shift
1972
+ else
1973
+ rorv rd, rs, shift
1974
+ end
1975
+ end
1976
+
1977
+ def rorv rd, rn, rm
1978
+ a RORV.new(rd, rn, rm, rd.sf)
1979
+ end
1980
+
1981
+ def sb
1982
+ a SB.new
1983
+ end
1984
+
1985
+ def sbc rd, rn, rm
1986
+ a SBC.new(rd, rn, rm, rd.sf)
1987
+ end
1988
+
1989
+ def sbcs rd, rn, rm
1990
+ a SBCS.new(rd, rn, rm, rd.sf)
1991
+ end
1992
+
1993
+ def sbfiz rd, rn, lsb, width
1994
+ sbfm rd, rn, -lsb % rd.size, width - 1
1995
+ end
1996
+
1997
+ def sbfm d, n, immr, imms
1998
+ a SBFM.new(d, n, immr, imms, d.sf)
1999
+ end
2000
+
2001
+ def sbfx rd, rn, lsb, width
2002
+ sbfm rd, rn, lsb, lsb + width - 1
2003
+ end
2004
+
2005
+ def sdiv rd, rn, rm
2006
+ a SDIV.new(rd, rn, rm, rd.sf)
2007
+ end
2008
+
2009
+ def setf8 rn
2010
+ a SETF.new(rn, 0)
2011
+ end
2012
+
2013
+ def setf16 rn
2014
+ a SETF.new(rn, 1)
2015
+ end
2016
+
2017
+ def sev
2018
+ a SEV.new
2019
+ end
2020
+
2021
+ def sevl
2022
+ a SEVL.new
2023
+ end
2024
+
2025
+ def smaddl xd, wn, wm, xa
2026
+ a SMADDL.new(xd, wn, wm, xa)
2027
+ end
2028
+
2029
+ def smc imm
2030
+ a SMC.new(imm)
2031
+ end
2032
+
2033
+ def smnegl rd, rn, rm
2034
+ smsubl rd, rn, rm, XZR
2035
+ end
2036
+
2037
+ def smsubl rd, rn, rm, ra
2038
+ a SMSUBL.new(rd, rn, rm, ra)
2039
+ end
2040
+
2041
+ def smulh rd, rn, rm
2042
+ a SMULH.new(rd, rn, rm)
2043
+ end
2044
+
2045
+ def smull rd, rn, rm
2046
+ smaddl rd, rn, rm, XZR
2047
+ end
2048
+
2049
+ def ssbb
2050
+ dsb 0
2051
+ end
2052
+
2053
+ def st2g rt, rn, imm = nil
2054
+ if imm
2055
+ if imm == :!
2056
+ # Pre index
2057
+ a ST2G.new(rt, rn.first, (rn[1] || 0) / 16, 0b11)
2058
+ else
2059
+ # Post index
2060
+ a ST2G.new(rt, rn.first, (imm || 0) / 16, 0b01)
2061
+ end
2062
+ else
2063
+ # Signed offset
2064
+ a ST2G.new(rt, rn.first, (rn[1] || 0) / 16, 0b10)
2065
+ end
2066
+ end
2067
+
2068
+ def st64b rt, rn
2069
+ a ST64B.new(rt, rn.first)
2070
+ end
2071
+
2072
+ def st64bv rs, rt, rn
2073
+ a ST64BV.new(rs, rt, rn.first)
2074
+ end
2075
+
2076
+ def st64bv0 rs, rt, rn
2077
+ a ST64BV0.new(rs, rt, rn.first)
2078
+ end
2079
+
2080
+ def stadd rs, rn
2081
+ ldadd rs, rs.zr, rn
2082
+ end
2083
+
2084
+ def staddl rs, rn
2085
+ ldaddl rs, rs.zr, rn
2086
+ end
2087
+
2088
+ def staddb rs, rn
2089
+ ldaddb rs, rs.zr, rn
2090
+ end
2091
+
2092
+ def staddlb rs, rn
2093
+ ldaddlb rs, rs.zr, rn
2094
+ end
2095
+
2096
+ def staddh rs, rn
2097
+ ldaddh rs, rs.zr, rn
2098
+ end
2099
+
2100
+ def staddlh rs, rn
2101
+ ldaddlh rs, rs.zr, rn
2102
+ end
2103
+
2104
+ def stclr rs, rn
2105
+ ldclr rs, rs.zr, rn
2106
+ end
2107
+
2108
+ def stclrl rs, rn
2109
+ ldclrl rs, rs.zr, rn
2110
+ end
2111
+
2112
+ def stclrb rs, rn
2113
+ ldclrb rs, rs.zr, rn
2114
+ end
2115
+
2116
+ def stclrlb rs, rn
2117
+ ldclrlb rs, rs.zr, rn
2118
+ end
2119
+
2120
+ def stclrh rs, rn
2121
+ ldclrh rs, rs.zr, rn
2122
+ end
2123
+
2124
+ def stclrlh rs, rn
2125
+ ldclrlh rs, rs.zr, rn
2126
+ end
2127
+
2128
+ def steor rs, rn
2129
+ ldeor rs, rs.zr, rn
2130
+ end
2131
+
2132
+ def steorl rs, rn
2133
+ ldeorl rs, rs.zr, rn
2134
+ end
2135
+
2136
+ def steorb rs, rn
2137
+ ldeorb rs, rs.zr, rn
2138
+ end
2139
+
2140
+ def steorlb rs, rn
2141
+ ldeorlb rs, rs.zr, rn
2142
+ end
2143
+
2144
+ def steorh rs, rn
2145
+ ldeorh rs, rs.zr, rn
2146
+ end
2147
+
2148
+ def steorlh rs, rn
2149
+ ldeorlh rs, rs.zr, rn
2150
+ end
2151
+
2152
+ def stg rt, rn, imm = nil
2153
+ if imm
2154
+ if imm == :!
2155
+ # Pre index
2156
+ a STG.new(rt, rn.first, (rn[1] || 0) / 16, 0b11)
2157
+ else
2158
+ # Post index
2159
+ a STG.new(rt, rn.first, (imm || 0) / 16, 0b01)
2160
+ end
2161
+ else
2162
+ # Signed offset
2163
+ a STG.new(rt, rn.first, (rn[1] || 0) / 16, 0b10)
2164
+ end
2165
+ end
2166
+
2167
+ def stgm rt, rn
2168
+ a STGM.new(rt, rn.first)
2169
+ end
2170
+
2171
+ def stgp xt1, xt2, xn, imm = nil
2172
+ if imm
2173
+ if imm == :!
2174
+ # Pre index
2175
+ a STGP.new(xt1, xt2, xn.first, (xn[1] || 0) / 16, 0b011)
2176
+ else
2177
+ # Post index
2178
+ a STGP.new(xt1, xt2, xn.first, imm / 16, 0b001)
2179
+ end
2180
+ else
2181
+ # Signed offset
2182
+ a STGP.new(xt1, xt2, xn.first, (xn[1] || 0) / 16, 0b010)
2183
+ end
2184
+ end
2185
+
2186
+ def stllr rt, rn
2187
+ a STLLR.new(rt, rn.first, rt.sizeb)
2188
+ end
2189
+
2190
+ def stllrb rt, rn
2191
+ a STLLRB.new(rt, rn.first)
2192
+ end
2193
+
2194
+ def stllrh rt, rn
2195
+ a STLLRH.new(rt, rn.first)
2196
+ end
2197
+
2198
+ def stlr rt, rn
2199
+ a STLR.new(rt, rn.first, rt.sizeb)
2200
+ end
2201
+
2202
+ def stlrb rt, rn
2203
+ a STLRB.new(rt, rn.first)
2204
+ end
2205
+
2206
+ def stlrh rt, rn
2207
+ a STLRH.new(rt, rn.first)
2208
+ end
2209
+
2210
+ def stlur rt, rn
2211
+ a STLUR_gen.new(rt, rn.first, rn[1] || 0, rt.sizeb)
2212
+ end
2213
+
2214
+ def stlurb rt, rn
2215
+ a STLUR_gen.new(rt, rn.first, rn[1] || 0, 0b00)
2216
+ end
2217
+
2218
+ def stlurh rt, rn
2219
+ a STLUR_gen.new(rt, rn.first, rn[1] || 0, 0b01)
2220
+ end
2221
+
2222
+ def stlxp rs, rt, rt2, rn
2223
+ a STLXP.new(rs, rt, rt2, rn.first, rt.sizeb)
2224
+ end
2225
+
2226
+ def stlxr rs, rt, rn
2227
+ a STLXR.new(rs, rt, rn.first, rt.sizeb)
2228
+ end
2229
+
2230
+ def stlxrb rs, rt, rn
2231
+ a STLXRB.new(rs, rt, rn.first)
2232
+ end
2233
+
2234
+ def stlxrh rs, rt, rn
2235
+ a STLXRH.new(rs, rt, rn.first)
2236
+ end
2237
+
2238
+ def stnp rt, rt2, rn
2239
+ a STNP_gen.new(rt, rt2, rn.first, (rn[1] || 0) / (rt.x? ? 8 : 4), rt.opc3)
2240
+ end
2241
+
2242
+ def stp rt, rt2, rn, imm = nil
2243
+ div = rt.x? ? 8 : 4
2244
+
2245
+ if imm
2246
+ if imm == :!
2247
+ # Pre index
2248
+ a STP_gen.new(rt, rt2, rn.first, (rn[1] || 0) / div, rt.opc3, 0b011)
2249
+ else
2250
+ # Post index
2251
+ a STP_gen.new(rt, rt2, rn.first, imm / div, rt.opc3, 0b001)
2252
+ end
2253
+ else
2254
+ # Signed offset
2255
+ a STP_gen.new(rt, rt2, rn.first, (rn[1] || 0) / div, rt.opc3, 0b010)
2256
+ end
2257
+ end
2258
+
2259
+ def str rt, rn, imm = nil
2260
+ if imm
2261
+ if imm == :!
2262
+ # Post index
2263
+ a STR_imm_gen.new(rt, rn.first, rn[1] || 0, 0b11, rt.sizeb)
2264
+ else
2265
+ # Pre index
2266
+ a STR_imm_gen.new(rt, rn.first, imm || 0, 0b01, rt.sizeb)
2267
+ end
2268
+ else
2269
+ imm = rn[1] || 0
2270
+ if imm.integer?
2271
+ # Unsigned
2272
+ div = rt.x? ? 8 : 4
2273
+ a STR_imm_unsigned.new(rt, rn.first, imm / div, rt.sizeb)
2274
+ else
2275
+ rn, rm, opt = *rn
2276
+ opt ||= Extends::Extend.new(0, 0, :lsl)
2277
+ extend = case opt.name
2278
+ when :uxtw then 0b010
2279
+ when :lsl then 0b011
2280
+ when :sxtw then 0b110
2281
+ when :sxtx then 0b111
2282
+ else
2283
+ raise "Unknown type #{opt.name}"
2284
+ end
2285
+
2286
+ amount = opt.amount / (rt.x? ? 3 : 2)
2287
+ a STR_reg_gen.new(rt, rn, rm, extend, amount, rt.sizeb)
2288
+ end
2289
+ end
2290
+ end
2291
+
2292
+ def strb rt, rn, imm = nil
2293
+ if imm
2294
+ if imm == :!
2295
+ # Post index
2296
+ a STRB_imm.new(rt, rn.first, rn[1] || 0, 0b11)
2297
+ else
2298
+ # Pre index
2299
+ a STRB_imm.new(rt, rn.first, imm, 0b01)
2300
+ end
2301
+ else
2302
+ imm = rn[1] || 0
2303
+ if imm.integer?
2304
+ # Unsigned
2305
+ a STRB_imm_unsigned.new(rt, rn.first, imm)
2306
+ else
2307
+ amount = rn[2] ? 1 : 0
2308
+
2309
+ rn, rm, opt = *rn
2310
+ opt ||= Extends::Extend.new(0, 0, :lsl)
2311
+ extend = case opt.name
2312
+ when :uxtw then 0b010
2313
+ when :lsl then 0b011
2314
+ when :sxtw then 0b110
2315
+ when :sxtx then 0b111
2316
+ else
2317
+ raise "Unknown type #{opt.name}"
2318
+ end
2319
+
2320
+ a STRB_reg.new(rt, rn, rm, extend, amount)
2321
+ end
2322
+ end
2323
+ end
2324
+
2325
+ def strh rt, rn, imm = nil
2326
+ if imm
2327
+ if imm == :!
2328
+ # Pre index
2329
+ a STRH_imm.new(rt, rn.first, rn[1] || 0, 0b11)
2330
+ else
2331
+ # Post index
2332
+ a STRH_imm.new(rt, rn.first, imm, 0b01)
2333
+ end
2334
+ else
2335
+ imm = rn[1] || 0
2336
+ if imm.integer?
2337
+ # Unsigned
2338
+ a STRH_imm_unsigned.new(rt, rn.first, imm >> 1)
2339
+ else
2340
+ rn, rm, opt = *rn
2341
+ opt ||= Extends::Extend.new(0, 0, :lsl)
2342
+ extend = case opt.name
2343
+ when :uxtw then 0b010
2344
+ when :lsl then 0b011
2345
+ when :sxtw then 0b110
2346
+ when :sxtx then 0b111
2347
+ else
2348
+ raise "Unknown type #{opt.name}"
2349
+ end
2350
+
2351
+ amount = opt.amount > 0 ? 1 : 0
2352
+
2353
+ a STRH_reg.new(rt, rn, rm, extend, amount)
2354
+ end
2355
+ end
2356
+ end
2357
+
2358
+ def stset rs, rn
2359
+ ldset rs, rs.zr, rn
2360
+ end
2361
+
2362
+ def stsetl rs, rn
2363
+ ldsetl rs, rs.zr, rn
2364
+ end
2365
+
2366
+ def stsetb rs, rn
2367
+ ldsetb rs, rs.zr, rn
2368
+ end
2369
+
2370
+ def stsetlb rs, rn
2371
+ ldsetlb rs, rs.zr, rn
2372
+ end
2373
+
2374
+ def stseth rs, rn
2375
+ ldseth rs, rs.zr, rn
2376
+ end
2377
+
2378
+ def stsetlh rs, rn
2379
+ ldsetlh rs, rs.zr, rn
2380
+ end
2381
+
2382
+ def stsmax rs, rn
2383
+ ldsmax rs, rs.zr, rn
2384
+ end
2385
+
2386
+ def stsmaxl rs, rn
2387
+ ldsmaxl rs, rs.zr, rn
2388
+ end
2389
+
2390
+ def stsmaxb rs, rn
2391
+ ldsmaxb rs, rs.zr, rn
2392
+ end
2393
+
2394
+ def stsmaxlb rs, rn
2395
+ ldsmaxlb rs, rs.zr, rn
2396
+ end
2397
+
2398
+ def stsmaxh rs, rn
2399
+ ldsmaxh rs, rs.zr, rn
2400
+ end
2401
+
2402
+ def stsmaxlh rs, rn
2403
+ ldsmaxlh rs, rs.zr, rn
2404
+ end
2405
+
2406
+ def stsmin rs, rn
2407
+ ldsmin rs, rs.zr, rn
2408
+ end
2409
+
2410
+ def stsminl rs, rn
2411
+ ldsminl rs, rs.zr, rn
2412
+ end
2413
+
2414
+ def stsminb rs, rn
2415
+ ldsminb rs, rs.zr, rn
2416
+ end
2417
+
2418
+ def stsminlb rs, rn
2419
+ ldsminlb rs, rs.zr, rn
2420
+ end
2421
+
2422
+ def stsminh rs, rn
2423
+ ldsminh rs, rs.zr, rn
2424
+ end
2425
+
2426
+ def stsminlh rs, rn
2427
+ ldsminlh rs, rs.zr, rn
2428
+ end
2429
+
2430
+ def sttr rt, rn
2431
+ a STTR.new(rt, rn.first, rn[1] || 0, rt.sizeb)
2432
+ end
2433
+
2434
+ def sttrb rt, rn
2435
+ a STTR.new(rt, rn.first, rn[1] || 0, 0b00)
2436
+ end
2437
+
2438
+ def sttrh rt, rn
2439
+ a STTR.new(rt, rn.first, rn[1] || 0, 0b01)
2440
+ end
2441
+
2442
+ def stumax rs, rn
2443
+ ldumax rs, rs.zr, rn
2444
+ end
2445
+
2446
+ def stumaxl rs, rn
2447
+ ldumaxl rs, rs.zr, rn
2448
+ end
2449
+
2450
+ def stumaxb rs, rn
2451
+ ldumaxb rs, rs.zr, rn
2452
+ end
2453
+
2454
+ def stumaxlb rs, rn
2455
+ ldumaxlb rs, rs.zr, rn
2456
+ end
2457
+
2458
+ def stumaxh rs, rn
2459
+ ldumaxh rs, rs.zr, rn
2460
+ end
2461
+
2462
+ def stumaxlh rs, rn
2463
+ ldumaxlh rs, rs.zr, rn
2464
+ end
2465
+
2466
+ def stumin rs, rn
2467
+ ldumin rs, rs.zr, rn
2468
+ end
2469
+
2470
+ def stuminl rs, rn
2471
+ lduminl rs, rs.zr, rn
2472
+ end
2473
+
2474
+ def stuminb rs, rn
2475
+ lduminb rs, rs.zr, rn
2476
+ end
2477
+
2478
+ def stuminlb rs, rn
2479
+ lduminlb rs, rs.zr, rn
2480
+ end
2481
+
2482
+ def stuminh rs, rn
2483
+ lduminh rs, rs.zr, rn
2484
+ end
2485
+
2486
+ def stuminlh rs, rn
2487
+ lduminlh rs, rs.zr, rn
2488
+ end
2489
+
2490
+ def stur rt, rn
2491
+ a STUR_gen.new(rt, rn.first, rn[1] || 0, rt.sizeb)
2492
+ end
2493
+
2494
+ def sturb rt, rn
2495
+ a STUR_gen.new(rt, rn.first, rn[1] || 0, 0b00)
2496
+ end
2497
+
2498
+ def sturh rt, rn
2499
+ a STUR_gen.new(rt, rn.first, rn[1] || 0, 0b01)
2500
+ end
2501
+
2502
+ def stxp rs, rt1, rt2, rn
2503
+ a STXP.new(rs, rt1, rt2, rn.first, rt1.sf)
2504
+ end
2505
+
2506
+ def stxr rs, rt, rn
2507
+ size = rt.x? ? 0b11 : 0b10
2508
+ a STXR.new(rs, rt, rn.first, size)
2509
+ end
2510
+
2511
+ def stxrb rs, rt, rn
2512
+ a STXRB.new(rs, rt, rn.first)
2513
+ end
2514
+
2515
+ def stxrh rs, rt, rn
2516
+ a STXRH.new(rs, rt, rn.first)
2517
+ end
2518
+
2519
+ def stz2g rt, rn, imm = nil
2520
+ if imm
2521
+ if imm == :!
2522
+ # Pre index
2523
+ a STZ2G.new(rt, rn.first, (rn[1] || 0) / 16, 0b11)
2524
+ else
2525
+ a STZ2G.new(rt, rn.first, imm / 16, 0b01)
2526
+ end
2527
+ else
2528
+ # Signed offset
2529
+ a STZ2G.new(rt, rn.first, (rn[1] || 0) / 16, 0b10)
2530
+ end
2531
+ end
2532
+
2533
+ def stzg rt, rn, imm = nil
2534
+ if imm
2535
+ if imm == :!
2536
+ # Pre index
2537
+ a STZG.new(rt, rn.first, (rn[1] || 0) / 16, 0b11)
2538
+ else
2539
+ a STZG.new(rt, rn.first, imm / 16, 0b01)
2540
+ end
2541
+ else
2542
+ # Signed offset
2543
+ a STZG.new(rt, rn.first, (rn[1] || 0) / 16, 0b10)
2544
+ end
2545
+ end
2546
+
2547
+ def stzgm rt, rn
2548
+ a STZGM.new(rt, rn.first)
2549
+ end
2550
+
2551
+ def subs d, n, m, option = nil, extend: nil, amount: 0, lsl: 0, shift: :lsl
2552
+ if n.sp? && !m.integer?
2553
+ if n.x?
2554
+ extend ||= :uxtx
2555
+ else
2556
+ extend ||= :uxtw
2557
+ end
2558
+ end
2559
+
2560
+ if option
2561
+ if option.extend?
2562
+ extend = option.name
2563
+ amount = option.amount
2564
+ else
2565
+ if m.integer?
2566
+ lsl = option.amount
2567
+ else
2568
+ shift = option.name
2569
+ amount = option.amount
2570
+ end
2571
+ end
2572
+ end
2573
+
2574
+ if extend
2575
+ extend = case extend
2576
+ when :uxtb then 0b000
2577
+ when :uxth then 0b001
2578
+ when :uxtw then 0b010
2579
+ when :uxtx then 0b011
2580
+ when :sxtb then 0b100
2581
+ when :sxth then 0b101
2582
+ when :sxtw then 0b110
2583
+ when :sxtx then 0b111
2584
+ else
2585
+ raise "Unknown extend #{extend}"
2586
+ end
2587
+ a SUBS_addsub_ext.new(d, n, m, extend, amount, d.sf)
2588
+ else
2589
+ if m.integer?
2590
+ a SUBS_addsub_imm.new(d, n, m, lsl / 12, d.sf)
2591
+ else
2592
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
2593
+ a SUBS_addsub_shift.new(d, n, m, shift, amount, d.sf)
2594
+ end
2595
+ end
2596
+ end
2597
+
2598
+ def sub d, n, m, option = nil, extend: nil, amount: 0, lsl: 0, shift: :lsl
2599
+ if (d.sp? || n.sp?) && !m.integer?
2600
+ if n.x?
2601
+ extend ||= :uxtx
2602
+ else
2603
+ extend ||= :uxtw
2604
+ end
2605
+ end
2606
+
2607
+ if option
2608
+ if option.extend?
2609
+ extend = option.name
2610
+ amount = option.amount
2611
+ else
2612
+ if m.integer?
2613
+ lsl = option.amount
2614
+ else
2615
+ shift = option.name
2616
+ amount = option.amount
2617
+ end
2618
+ end
2619
+ end
2620
+
2621
+ if extend
2622
+ extend = case extend
2623
+ when :uxtb then 0b000
2624
+ when :uxth then 0b001
2625
+ when :uxtw then 0b010
2626
+ when :uxtx then 0b011
2627
+ when :sxtb then 0b100
2628
+ when :sxth then 0b101
2629
+ when :sxtw then 0b110
2630
+ when :sxtx then 0b111
2631
+ else
2632
+ raise "Unknown extend #{extend}"
2633
+ end
2634
+ a SUB_addsub_ext.new(d, n, m, extend, amount, d.sf)
2635
+ else
2636
+ if m.integer?
2637
+ a SUB_addsub_imm.new(d, n, m, lsl / 12, d.sf)
2638
+ else
2639
+ shift = [:lsl, :lsr, :asr].index(shift) || raise(NotImplementedError)
2640
+ a SUB_addsub_shift.new(d, n, m, shift, amount, d.sf)
2641
+ end
2642
+ end
2643
+ end
2644
+
2645
+ def subg xd, xn, uimm6, uimm4
2646
+ raise NotImplementedError unless xd.x?
2647
+ a SUBG.new(xd, xn, uimm6, uimm4)
2648
+ end
2649
+
2650
+ def subp xd, xn, xm
2651
+ raise NotImplementedError unless xd.x?
2652
+ a SUBP.new(xd, xn, xm)
2653
+ end
2654
+
2655
+ def subps xd, xn, xm
2656
+ raise NotImplementedError unless xd.x?
2657
+ a SUBPS.new(xd, xn, xm)
2658
+ end
2659
+
2660
+ def svc imm
2661
+ a SVC.new(imm)
2662
+ end
2663
+
2664
+ def swp rs, rt, rn
2665
+ size = rs.x? ? 0b11 : 0b10
2666
+ a SWP.new(rs, rt, rn.first, size, 0, 0)
2667
+ end
2668
+
2669
+ def swpal rs, rt, rn
2670
+ size = rs.x? ? 0b11 : 0b10
2671
+ a SWP.new(rs, rt, rn.first, size, 1, 1)
2672
+ end
2673
+
2674
+ def swpl rs, rt, rn
2675
+ size = rs.x? ? 0b11 : 0b10
2676
+ a SWP.new(rs, rt, rn.first, size, 0, 1)
2677
+ end
2678
+
2679
+ def swpa rs, rt, rn
2680
+ size = rs.x? ? 0b11 : 0b10
2681
+ a SWP.new(rs, rt, rn.first, size, 1, 0)
2682
+ end
2683
+
2684
+ def swpab rs, rt, rn
2685
+ a SWPB.new(rs, rt, rn.first, 1, 0)
2686
+ end
2687
+
2688
+ def swpalb rs, rt, rn
2689
+ a SWPB.new(rs, rt, rn.first, 1, 1)
2690
+ end
2691
+
2692
+ def swpb rs, rt, rn
2693
+ a SWPB.new(rs, rt, rn.first, 0, 0)
2694
+ end
2695
+
2696
+ def swplb rs, rt, rn
2697
+ a SWPB.new(rs, rt, rn.first, 0, 1)
2698
+ end
2699
+
2700
+ def swpah rs, rt, rn
2701
+ a SWPH.new(rs, rt, rn.first, 1, 0)
2702
+ end
2703
+
2704
+ def swpalh rs, rt, rn
2705
+ a SWPH.new(rs, rt, rn.first, 1, 1)
2706
+ end
2707
+
2708
+ def swph rs, rt, rn
2709
+ a SWPH.new(rs, rt, rn.first, 0, 0)
2710
+ end
2711
+
2712
+ def swplh rs, rt, rn
2713
+ a SWPH.new(rs, rt, rn.first, 0, 1)
2714
+ end
2715
+
2716
+ def sxtb rd, rn
2717
+ sbfm rd, rn, 0, 7
2718
+ end
2719
+
2720
+ def sxth rd, rn
2721
+ sbfm rd, rn, 0, 15
2722
+ end
2723
+
2724
+ def sxtw rd, rn
2725
+ sbfm rd, rn, 0, 31
2726
+ end
2727
+
2728
+ def sys op1, cn, cm, op2, xt = XZR
2729
+ a SYS.new(op1, cn, cm, op2, xt)
2730
+ end
2731
+
2732
+ def sysl xt, op1, cn, cm, op2
2733
+ a SYSL.new(xt, op1, cn, cm, op2)
2734
+ end
2735
+
2736
+ def tbnz rt, imm, label
2737
+ a TBNZ.new(rt, imm, label, rt.sf)
2738
+ end
2739
+
2740
+ def tbz rt, imm, label
2741
+ a TBZ.new(rt, imm, label, rt.sf)
2742
+ end
2743
+
2744
+ def tlbi tlbi_op, xt = XZR
2745
+ op1, crm, op2 = Utils.tlbi_op(tlbi_op)
2746
+ sys op1, Names::C8, crm, op2, xt
2747
+ end
2748
+
2749
+ def tsb _
2750
+ a TSB.new
2751
+ end
2752
+
2753
+ def tst rn, rm, option = nil, shift: :lsl, amount: 0
2754
+ if option
2755
+ shift = option.name
2756
+ amount = option.amount
2757
+ end
2758
+
2759
+ ands rn.zr, rn, rm, shift: shift, amount: amount
2760
+ end
2761
+
2762
+ def ubfm rd, rn, immr, imms
2763
+ a UBFM.new(rd, rn, immr, imms, rd.sf)
2764
+ end
2765
+
2766
+ def ubfiz rd, rn, lsb, width
2767
+ ubfm rd, rn, (-lsb) % rd.size, width - 1
2768
+ end
2769
+
2770
+ def ubfx rd, rn, lsb, width
2771
+ ubfm rd, rn, lsb, lsb + width - 1
2772
+ end
2773
+
2774
+ def udf imm
2775
+ a UDF_perm_undef.new(imm)
2776
+ end
2777
+
2778
+ def udiv rd, rn, rm
2779
+ a UDIV.new(rd, rn, rm, rd.sf)
2780
+ end
2781
+
2782
+ def umaddl xd, wn, wm, xa
2783
+ a UMADDL.new(xd, wn, wm, xa)
2784
+ end
2785
+
2786
+ def umnegl xd, wn, wm
2787
+ umsubl xd, wn, wm, XZR
2788
+ end
2789
+
2790
+ def umsubl xd, wn, wm, xa
2791
+ a UMSUBL.new(xd, wn, wm, xa)
2792
+ end
2793
+
2794
+ def umulh rd, rn, rm
2795
+ a UMULH.new(rd, rn, rm)
2796
+ end
2797
+
2798
+ def umull xd, wn, wm
2799
+ umaddl xd, wn, wm, XZR
2800
+ end
2801
+
2802
+ def uxtb rd, rn
2803
+ ubfm rd, rn, 0, 7
2804
+ end
2805
+
2806
+ def uxth rd, rn
2807
+ ubfm rd, rn, 0, 15
2808
+ end
2809
+
2810
+ def wfe
2811
+ a WFE.new
2812
+ end
2813
+
2814
+ def wfet rd
2815
+ a WFET.new(rd)
2816
+ end
2817
+
2818
+ def wfi
2819
+ a WFI.new
2820
+ end
2821
+
2822
+ def wfit rd
2823
+ a WFIT.new(rd)
2824
+ end
2825
+
2826
+ def xaflag
2827
+ a XAFLAG.new
2828
+ end
2829
+
2830
+ def xpacd rd
2831
+ a XPAC.new(rd, 1)
2832
+ end
2833
+
2834
+ def xpaci rd
2835
+ a XPAC.new(rd, 0)
2836
+ end
2837
+
2838
+ def xpaclri
2839
+ a XPACLRI.new
2840
+ end
2841
+
2842
+ def yield
2843
+ a YIELD.new
2844
+ end
2845
+
2846
+ def write_to io
2847
+ io.write @insns.map(&:encode).pack("L<*")
2848
+ end
2849
+
2850
+ private
2851
+
2852
+ def a insn
2853
+ @insns = @insns << insn
2854
+ self
2855
+ end
2856
+ end
2857
+ end