aarch64 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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