immunio 0.15.4 → 0.16.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 (454) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -27
  3. data/ext/immunio/Rakefile +9 -0
  4. data/lib/immunio/plugins/active_record.rb +1 -1
  5. data/lib/immunio/plugins/active_record_relation.rb +1 -1
  6. data/lib/immunio/plugins/environment_reporter.rb +20 -0
  7. data/lib/immunio/rufus_lua_ext/ref.rb +1 -3
  8. data/lib/immunio/version.rb +1 -1
  9. data/lib/immunio/vm.rb +1 -2
  10. data/lua-hooks/Makefile +97 -0
  11. data/lua-hooks/ext/all.c +41 -52
  12. data/lua-hooks/ext/all.o +0 -0
  13. data/lua-hooks/ext/libinjection/libinjection_html5.o +0 -0
  14. data/lua-hooks/ext/libinjection/libinjection_sqli.o +0 -0
  15. data/lua-hooks/ext/libinjection/libinjection_xss.o +0 -0
  16. data/lua-hooks/ext/libinjection/lualib.c +2 -2
  17. data/lua-hooks/ext/lpeg/lpcap.c +2 -2
  18. data/lua-hooks/ext/lpeg/lpcap.o +0 -0
  19. data/lua-hooks/ext/lpeg/lpcode.c +2 -2
  20. data/lua-hooks/ext/lpeg/lpcode.h +1 -1
  21. data/lua-hooks/ext/lpeg/lpcode.o +0 -0
  22. data/lua-hooks/ext/lpeg/lpprint.o +0 -0
  23. data/lua-hooks/ext/lpeg/lptree.c +2 -2
  24. data/lua-hooks/ext/lpeg/lptypes.h +1 -1
  25. data/lua-hooks/ext/lpeg/lpvm.c +2 -2
  26. data/lua-hooks/ext/lpeg/lpvm.o +0 -0
  27. data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +16 -3
  28. data/lua-hooks/ext/lua-snapshot/snapshot.c +14 -7
  29. data/lua-hooks/ext/luajit/COPYRIGHT +56 -0
  30. data/lua-hooks/ext/luajit/Makefile +159 -0
  31. data/lua-hooks/ext/luajit/README +16 -0
  32. data/lua-hooks/ext/luajit/doc/bluequad-print.css +166 -0
  33. data/lua-hooks/ext/luajit/doc/bluequad.css +325 -0
  34. data/lua-hooks/ext/luajit/doc/changes.html +804 -0
  35. data/lua-hooks/ext/luajit/doc/contact.html +104 -0
  36. data/lua-hooks/ext/luajit/doc/ext_c_api.html +189 -0
  37. data/lua-hooks/ext/luajit/doc/ext_ffi.html +332 -0
  38. data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +570 -0
  39. data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +1261 -0
  40. data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +603 -0
  41. data/lua-hooks/ext/luajit/doc/ext_jit.html +201 -0
  42. data/lua-hooks/ext/luajit/doc/ext_profiler.html +365 -0
  43. data/lua-hooks/ext/luajit/doc/extensions.html +448 -0
  44. data/lua-hooks/ext/luajit/doc/faq.html +186 -0
  45. data/lua-hooks/ext/luajit/doc/img/contact.png +0 -0
  46. data/lua-hooks/ext/luajit/doc/install.html +659 -0
  47. data/lua-hooks/ext/luajit/doc/luajit.html +236 -0
  48. data/lua-hooks/ext/luajit/doc/running.html +309 -0
  49. data/lua-hooks/ext/luajit/doc/status.html +118 -0
  50. data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +456 -0
  51. data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1125 -0
  52. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +518 -0
  53. data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1166 -0
  54. data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +416 -0
  55. data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +953 -0
  56. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +419 -0
  57. data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1919 -0
  58. data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +83 -0
  59. data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +12 -0
  60. data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +471 -0
  61. data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +1945 -0
  62. data/lua-hooks/ext/luajit/dynasm/dynasm.lua +1094 -0
  63. data/lua-hooks/ext/luajit/etc/luajit.1 +88 -0
  64. data/lua-hooks/ext/luajit/etc/luajit.pc +25 -0
  65. data/lua-hooks/ext/luajit/src/Makefile +697 -0
  66. data/lua-hooks/ext/luajit/src/Makefile.dep +244 -0
  67. data/lua-hooks/ext/luajit/src/host/README +4 -0
  68. data/lua-hooks/ext/luajit/src/host/buildvm +0 -0
  69. data/lua-hooks/ext/luajit/src/host/buildvm.c +518 -0
  70. data/lua-hooks/ext/luajit/src/host/buildvm.h +105 -0
  71. data/lua-hooks/ext/luajit/src/host/buildvm.o +0 -0
  72. data/lua-hooks/ext/luajit/src/host/buildvm_arch.h +7449 -0
  73. data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +345 -0
  74. data/lua-hooks/ext/luajit/src/host/buildvm_asm.o +0 -0
  75. data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +229 -0
  76. data/lua-hooks/ext/luajit/src/host/buildvm_fold.o +0 -0
  77. data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +457 -0
  78. data/lua-hooks/ext/luajit/src/host/buildvm_lib.o +0 -0
  79. data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +45 -0
  80. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +368 -0
  81. data/lua-hooks/ext/luajit/src/host/buildvm_peobj.o +0 -0
  82. data/lua-hooks/ext/luajit/src/host/genlibbc.lua +197 -0
  83. data/lua-hooks/ext/luajit/src/host/genminilua.lua +428 -0
  84. data/lua-hooks/ext/luajit/src/host/minilua +0 -0
  85. data/lua-hooks/ext/luajit/src/host/minilua.c +7770 -0
  86. data/lua-hooks/ext/luajit/src/host/minilua.o +0 -0
  87. data/lua-hooks/ext/luajit/src/jit/bc.lua +190 -0
  88. data/lua-hooks/ext/luajit/src/jit/bcsave.lua +661 -0
  89. data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +689 -0
  90. data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +428 -0
  91. data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +17 -0
  92. data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +591 -0
  93. data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +17 -0
  94. data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +838 -0
  95. data/lua-hooks/ext/luajit/src/jit/dump.lua +706 -0
  96. data/lua-hooks/ext/luajit/src/jit/p.lua +310 -0
  97. data/lua-hooks/ext/luajit/src/jit/v.lua +170 -0
  98. data/lua-hooks/ext/luajit/src/jit/vmdef.lua +362 -0
  99. data/lua-hooks/ext/luajit/src/jit/zone.lua +45 -0
  100. data/lua-hooks/ext/{lua → luajit/src}/lauxlib.h +10 -17
  101. data/lua-hooks/ext/luajit/src/lib_aux.c +356 -0
  102. data/lua-hooks/ext/luajit/src/lib_aux.o +0 -0
  103. data/lua-hooks/ext/luajit/src/lib_aux_dyn.o +0 -0
  104. data/lua-hooks/ext/luajit/src/lib_base.c +664 -0
  105. data/lua-hooks/ext/luajit/src/lib_base.o +0 -0
  106. data/lua-hooks/ext/luajit/src/lib_base_dyn.o +0 -0
  107. data/lua-hooks/ext/luajit/src/lib_bit.c +180 -0
  108. data/lua-hooks/ext/luajit/src/lib_bit.o +0 -0
  109. data/lua-hooks/ext/luajit/src/lib_bit_dyn.o +0 -0
  110. data/lua-hooks/ext/luajit/src/lib_debug.c +405 -0
  111. data/lua-hooks/ext/luajit/src/lib_debug.o +0 -0
  112. data/lua-hooks/ext/luajit/src/lib_debug_dyn.o +0 -0
  113. data/lua-hooks/ext/luajit/src/lib_ffi.c +872 -0
  114. data/lua-hooks/ext/luajit/src/lib_ffi.o +0 -0
  115. data/lua-hooks/ext/luajit/src/lib_ffi_dyn.o +0 -0
  116. data/lua-hooks/ext/luajit/src/lib_init.c +55 -0
  117. data/lua-hooks/ext/luajit/src/lib_init.o +0 -0
  118. data/lua-hooks/ext/luajit/src/lib_init_dyn.o +0 -0
  119. data/lua-hooks/ext/luajit/src/lib_io.c +541 -0
  120. data/lua-hooks/ext/luajit/src/lib_io.o +0 -0
  121. data/lua-hooks/ext/luajit/src/lib_io_dyn.o +0 -0
  122. data/lua-hooks/ext/luajit/src/lib_jit.c +767 -0
  123. data/lua-hooks/ext/luajit/src/lib_jit.o +0 -0
  124. data/lua-hooks/ext/luajit/src/lib_jit_dyn.o +0 -0
  125. data/lua-hooks/ext/luajit/src/lib_math.c +230 -0
  126. data/lua-hooks/ext/luajit/src/lib_math.o +0 -0
  127. data/lua-hooks/ext/luajit/src/lib_math_dyn.o +0 -0
  128. data/lua-hooks/ext/luajit/src/lib_os.c +292 -0
  129. data/lua-hooks/ext/luajit/src/lib_os.o +0 -0
  130. data/lua-hooks/ext/luajit/src/lib_os_dyn.o +0 -0
  131. data/lua-hooks/ext/luajit/src/lib_package.c +610 -0
  132. data/lua-hooks/ext/luajit/src/lib_package.o +0 -0
  133. data/lua-hooks/ext/luajit/src/lib_package_dyn.o +0 -0
  134. data/lua-hooks/ext/luajit/src/lib_string.c +752 -0
  135. data/lua-hooks/ext/luajit/src/lib_string.o +0 -0
  136. data/lua-hooks/ext/luajit/src/lib_string_dyn.o +0 -0
  137. data/lua-hooks/ext/luajit/src/lib_table.c +307 -0
  138. data/lua-hooks/ext/luajit/src/lib_table.o +0 -0
  139. data/lua-hooks/ext/luajit/src/lib_table_dyn.o +0 -0
  140. data/lua-hooks/ext/luajit/src/libluajit.a +0 -0
  141. data/lua-hooks/ext/luajit/src/libluajit.so +0 -0
  142. data/lua-hooks/ext/luajit/src/lj.supp +26 -0
  143. data/lua-hooks/ext/luajit/src/lj_alloc.c +1398 -0
  144. data/lua-hooks/ext/luajit/src/lj_alloc.h +17 -0
  145. data/lua-hooks/ext/luajit/src/lj_alloc.o +0 -0
  146. data/lua-hooks/ext/luajit/src/lj_alloc_dyn.o +0 -0
  147. data/lua-hooks/ext/luajit/src/lj_api.c +1210 -0
  148. data/lua-hooks/ext/luajit/src/lj_api.o +0 -0
  149. data/lua-hooks/ext/luajit/src/lj_api_dyn.o +0 -0
  150. data/lua-hooks/ext/luajit/src/lj_arch.h +509 -0
  151. data/lua-hooks/ext/luajit/src/lj_asm.c +2278 -0
  152. data/lua-hooks/ext/luajit/src/lj_asm.h +17 -0
  153. data/lua-hooks/ext/luajit/src/lj_asm.o +0 -0
  154. data/lua-hooks/ext/luajit/src/lj_asm_arm.h +2217 -0
  155. data/lua-hooks/ext/luajit/src/lj_asm_dyn.o +0 -0
  156. data/lua-hooks/ext/luajit/src/lj_asm_mips.h +1833 -0
  157. data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2015 -0
  158. data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2634 -0
  159. data/lua-hooks/ext/luajit/src/lj_bc.c +14 -0
  160. data/lua-hooks/ext/luajit/src/lj_bc.h +265 -0
  161. data/lua-hooks/ext/luajit/src/lj_bc.o +0 -0
  162. data/lua-hooks/ext/luajit/src/lj_bc_dyn.o +0 -0
  163. data/lua-hooks/ext/luajit/src/lj_bcdef.h +220 -0
  164. data/lua-hooks/ext/luajit/src/lj_bcdump.h +68 -0
  165. data/lua-hooks/ext/luajit/src/lj_bcread.c +457 -0
  166. data/lua-hooks/ext/luajit/src/lj_bcread.o +0 -0
  167. data/lua-hooks/ext/luajit/src/lj_bcread_dyn.o +0 -0
  168. data/lua-hooks/ext/luajit/src/lj_bcwrite.c +361 -0
  169. data/lua-hooks/ext/luajit/src/lj_bcwrite.o +0 -0
  170. data/lua-hooks/ext/luajit/src/lj_bcwrite_dyn.o +0 -0
  171. data/lua-hooks/ext/luajit/src/lj_buf.c +234 -0
  172. data/lua-hooks/ext/luajit/src/lj_buf.h +105 -0
  173. data/lua-hooks/ext/luajit/src/lj_buf.o +0 -0
  174. data/lua-hooks/ext/luajit/src/lj_buf_dyn.o +0 -0
  175. data/lua-hooks/ext/luajit/src/lj_carith.c +429 -0
  176. data/lua-hooks/ext/luajit/src/lj_carith.h +37 -0
  177. data/lua-hooks/ext/luajit/src/lj_carith.o +0 -0
  178. data/lua-hooks/ext/luajit/src/lj_carith_dyn.o +0 -0
  179. data/lua-hooks/ext/luajit/src/lj_ccall.c +984 -0
  180. data/lua-hooks/ext/luajit/src/lj_ccall.h +178 -0
  181. data/lua-hooks/ext/luajit/src/lj_ccall.o +0 -0
  182. data/lua-hooks/ext/luajit/src/lj_ccall_dyn.o +0 -0
  183. data/lua-hooks/ext/luajit/src/lj_ccallback.c +712 -0
  184. data/lua-hooks/ext/luajit/src/lj_ccallback.h +25 -0
  185. data/lua-hooks/ext/luajit/src/lj_ccallback.o +0 -0
  186. data/lua-hooks/ext/luajit/src/lj_ccallback_dyn.o +0 -0
  187. data/lua-hooks/ext/luajit/src/lj_cconv.c +752 -0
  188. data/lua-hooks/ext/luajit/src/lj_cconv.h +70 -0
  189. data/lua-hooks/ext/luajit/src/lj_cconv.o +0 -0
  190. data/lua-hooks/ext/luajit/src/lj_cconv_dyn.o +0 -0
  191. data/lua-hooks/ext/luajit/src/lj_cdata.c +288 -0
  192. data/lua-hooks/ext/luajit/src/lj_cdata.h +76 -0
  193. data/lua-hooks/ext/luajit/src/lj_cdata.o +0 -0
  194. data/lua-hooks/ext/luajit/src/lj_cdata_dyn.o +0 -0
  195. data/lua-hooks/ext/luajit/src/lj_char.c +43 -0
  196. data/lua-hooks/ext/luajit/src/lj_char.h +42 -0
  197. data/lua-hooks/ext/luajit/src/lj_char.o +0 -0
  198. data/lua-hooks/ext/luajit/src/lj_char_dyn.o +0 -0
  199. data/lua-hooks/ext/luajit/src/lj_clib.c +418 -0
  200. data/lua-hooks/ext/luajit/src/lj_clib.h +29 -0
  201. data/lua-hooks/ext/luajit/src/lj_clib.o +0 -0
  202. data/lua-hooks/ext/luajit/src/lj_clib_dyn.o +0 -0
  203. data/lua-hooks/ext/luajit/src/lj_cparse.c +1862 -0
  204. data/lua-hooks/ext/luajit/src/lj_cparse.h +65 -0
  205. data/lua-hooks/ext/luajit/src/lj_cparse.o +0 -0
  206. data/lua-hooks/ext/luajit/src/lj_cparse_dyn.o +0 -0
  207. data/lua-hooks/ext/luajit/src/lj_crecord.c +1834 -0
  208. data/lua-hooks/ext/luajit/src/lj_crecord.h +38 -0
  209. data/lua-hooks/ext/luajit/src/lj_crecord.o +0 -0
  210. data/lua-hooks/ext/luajit/src/lj_crecord_dyn.o +0 -0
  211. data/lua-hooks/ext/luajit/src/lj_ctype.c +635 -0
  212. data/lua-hooks/ext/luajit/src/lj_ctype.h +461 -0
  213. data/lua-hooks/ext/luajit/src/lj_ctype.o +0 -0
  214. data/lua-hooks/ext/luajit/src/lj_ctype_dyn.o +0 -0
  215. data/lua-hooks/ext/luajit/src/lj_debug.c +699 -0
  216. data/lua-hooks/ext/luajit/src/lj_debug.h +65 -0
  217. data/lua-hooks/ext/luajit/src/lj_debug.o +0 -0
  218. data/lua-hooks/ext/luajit/src/lj_debug_dyn.o +0 -0
  219. data/lua-hooks/ext/luajit/src/lj_def.h +365 -0
  220. data/lua-hooks/ext/luajit/src/lj_dispatch.c +557 -0
  221. data/lua-hooks/ext/luajit/src/lj_dispatch.h +138 -0
  222. data/lua-hooks/ext/luajit/src/lj_dispatch.o +0 -0
  223. data/lua-hooks/ext/luajit/src/lj_dispatch_dyn.o +0 -0
  224. data/lua-hooks/ext/luajit/src/lj_emit_arm.h +356 -0
  225. data/lua-hooks/ext/luajit/src/lj_emit_mips.h +211 -0
  226. data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +238 -0
  227. data/lua-hooks/ext/luajit/src/lj_emit_x86.h +462 -0
  228. data/lua-hooks/ext/luajit/src/lj_err.c +794 -0
  229. data/lua-hooks/ext/luajit/src/lj_err.h +41 -0
  230. data/lua-hooks/ext/luajit/src/lj_err.o +0 -0
  231. data/lua-hooks/ext/luajit/src/lj_err_dyn.o +0 -0
  232. data/lua-hooks/ext/luajit/src/lj_errmsg.h +190 -0
  233. data/lua-hooks/ext/luajit/src/lj_ff.h +18 -0
  234. data/lua-hooks/ext/luajit/src/lj_ffdef.h +209 -0
  235. data/lua-hooks/ext/luajit/src/lj_ffrecord.c +1247 -0
  236. data/lua-hooks/ext/luajit/src/lj_ffrecord.h +24 -0
  237. data/lua-hooks/ext/luajit/src/lj_ffrecord.o +0 -0
  238. data/lua-hooks/ext/luajit/src/lj_ffrecord_dyn.o +0 -0
  239. data/lua-hooks/ext/luajit/src/lj_folddef.h +1138 -0
  240. data/lua-hooks/ext/luajit/src/lj_frame.h +259 -0
  241. data/lua-hooks/ext/luajit/src/lj_func.c +185 -0
  242. data/lua-hooks/ext/luajit/src/lj_func.h +24 -0
  243. data/lua-hooks/ext/luajit/src/lj_func.o +0 -0
  244. data/lua-hooks/ext/luajit/src/lj_func_dyn.o +0 -0
  245. data/lua-hooks/ext/luajit/src/lj_gc.c +845 -0
  246. data/lua-hooks/ext/luajit/src/lj_gc.h +134 -0
  247. data/lua-hooks/ext/luajit/src/lj_gc.o +0 -0
  248. data/lua-hooks/ext/luajit/src/lj_gc_dyn.o +0 -0
  249. data/lua-hooks/ext/luajit/src/lj_gdbjit.c +787 -0
  250. data/lua-hooks/ext/luajit/src/lj_gdbjit.h +22 -0
  251. data/lua-hooks/ext/luajit/src/lj_gdbjit.o +0 -0
  252. data/lua-hooks/ext/luajit/src/lj_gdbjit_dyn.o +0 -0
  253. data/lua-hooks/ext/luajit/src/lj_ir.c +505 -0
  254. data/lua-hooks/ext/luajit/src/lj_ir.h +577 -0
  255. data/lua-hooks/ext/luajit/src/lj_ir.o +0 -0
  256. data/lua-hooks/ext/luajit/src/lj_ir_dyn.o +0 -0
  257. data/lua-hooks/ext/luajit/src/lj_ircall.h +321 -0
  258. data/lua-hooks/ext/luajit/src/lj_iropt.h +161 -0
  259. data/lua-hooks/ext/luajit/src/lj_jit.h +440 -0
  260. data/lua-hooks/ext/luajit/src/lj_lex.c +482 -0
  261. data/lua-hooks/ext/luajit/src/lj_lex.h +86 -0
  262. data/lua-hooks/ext/luajit/src/lj_lex.o +0 -0
  263. data/lua-hooks/ext/luajit/src/lj_lex_dyn.o +0 -0
  264. data/lua-hooks/ext/luajit/src/lj_lib.c +303 -0
  265. data/lua-hooks/ext/luajit/src/lj_lib.h +115 -0
  266. data/lua-hooks/ext/luajit/src/lj_lib.o +0 -0
  267. data/lua-hooks/ext/luajit/src/lj_lib_dyn.o +0 -0
  268. data/lua-hooks/ext/luajit/src/lj_libdef.h +414 -0
  269. data/lua-hooks/ext/luajit/src/lj_load.c +168 -0
  270. data/lua-hooks/ext/luajit/src/lj_load.o +0 -0
  271. data/lua-hooks/ext/luajit/src/lj_load_dyn.o +0 -0
  272. data/lua-hooks/ext/luajit/src/lj_mcode.c +386 -0
  273. data/lua-hooks/ext/luajit/src/lj_mcode.h +30 -0
  274. data/lua-hooks/ext/luajit/src/lj_mcode.o +0 -0
  275. data/lua-hooks/ext/luajit/src/lj_mcode_dyn.o +0 -0
  276. data/lua-hooks/ext/luajit/src/lj_meta.c +477 -0
  277. data/lua-hooks/ext/luajit/src/lj_meta.h +38 -0
  278. data/lua-hooks/ext/luajit/src/lj_meta.o +0 -0
  279. data/lua-hooks/ext/luajit/src/lj_meta_dyn.o +0 -0
  280. data/lua-hooks/ext/luajit/src/lj_obj.c +50 -0
  281. data/lua-hooks/ext/luajit/src/lj_obj.h +976 -0
  282. data/lua-hooks/ext/luajit/src/lj_obj.o +0 -0
  283. data/lua-hooks/ext/luajit/src/lj_obj_dyn.o +0 -0
  284. data/lua-hooks/ext/luajit/src/lj_opt_dce.c +78 -0
  285. data/lua-hooks/ext/luajit/src/lj_opt_dce.o +0 -0
  286. data/lua-hooks/ext/luajit/src/lj_opt_dce_dyn.o +0 -0
  287. data/lua-hooks/ext/luajit/src/lj_opt_fold.c +2488 -0
  288. data/lua-hooks/ext/luajit/src/lj_opt_fold.o +0 -0
  289. data/lua-hooks/ext/luajit/src/lj_opt_fold_dyn.o +0 -0
  290. data/lua-hooks/ext/luajit/src/lj_opt_loop.c +449 -0
  291. data/lua-hooks/ext/luajit/src/lj_opt_loop.o +0 -0
  292. data/lua-hooks/ext/luajit/src/lj_opt_loop_dyn.o +0 -0
  293. data/lua-hooks/ext/luajit/src/lj_opt_mem.c +935 -0
  294. data/lua-hooks/ext/luajit/src/lj_opt_mem.o +0 -0
  295. data/lua-hooks/ext/luajit/src/lj_opt_mem_dyn.o +0 -0
  296. data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +652 -0
  297. data/lua-hooks/ext/luajit/src/lj_opt_narrow.o +0 -0
  298. data/lua-hooks/ext/luajit/src/lj_opt_narrow_dyn.o +0 -0
  299. data/lua-hooks/ext/luajit/src/lj_opt_sink.c +245 -0
  300. data/lua-hooks/ext/luajit/src/lj_opt_sink.o +0 -0
  301. data/lua-hooks/ext/luajit/src/lj_opt_sink_dyn.o +0 -0
  302. data/lua-hooks/ext/luajit/src/lj_opt_split.c +856 -0
  303. data/lua-hooks/ext/luajit/src/lj_opt_split.o +0 -0
  304. data/lua-hooks/ext/luajit/src/lj_opt_split_dyn.o +0 -0
  305. data/lua-hooks/ext/luajit/src/lj_parse.c +2725 -0
  306. data/lua-hooks/ext/luajit/src/lj_parse.h +18 -0
  307. data/lua-hooks/ext/luajit/src/lj_parse.o +0 -0
  308. data/lua-hooks/ext/luajit/src/lj_parse_dyn.o +0 -0
  309. data/lua-hooks/ext/luajit/src/lj_profile.c +368 -0
  310. data/lua-hooks/ext/luajit/src/lj_profile.h +21 -0
  311. data/lua-hooks/ext/luajit/src/lj_profile.o +0 -0
  312. data/lua-hooks/ext/luajit/src/lj_profile_dyn.o +0 -0
  313. data/lua-hooks/ext/luajit/src/lj_recdef.h +270 -0
  314. data/lua-hooks/ext/luajit/src/lj_record.c +2554 -0
  315. data/lua-hooks/ext/luajit/src/lj_record.h +45 -0
  316. data/lua-hooks/ext/luajit/src/lj_record.o +0 -0
  317. data/lua-hooks/ext/luajit/src/lj_record_dyn.o +0 -0
  318. data/lua-hooks/ext/luajit/src/lj_snap.c +870 -0
  319. data/lua-hooks/ext/luajit/src/lj_snap.h +34 -0
  320. data/lua-hooks/ext/luajit/src/lj_snap.o +0 -0
  321. data/lua-hooks/ext/luajit/src/lj_snap_dyn.o +0 -0
  322. data/lua-hooks/ext/luajit/src/lj_state.c +300 -0
  323. data/lua-hooks/ext/luajit/src/lj_state.h +35 -0
  324. data/lua-hooks/ext/luajit/src/lj_state.o +0 -0
  325. data/lua-hooks/ext/luajit/src/lj_state_dyn.o +0 -0
  326. data/lua-hooks/ext/luajit/src/lj_str.c +197 -0
  327. data/lua-hooks/ext/luajit/src/lj_str.h +27 -0
  328. data/lua-hooks/ext/luajit/src/lj_str.o +0 -0
  329. data/lua-hooks/ext/luajit/src/lj_str_dyn.o +0 -0
  330. data/lua-hooks/ext/luajit/src/lj_strfmt.c +554 -0
  331. data/lua-hooks/ext/luajit/src/lj_strfmt.h +125 -0
  332. data/lua-hooks/ext/luajit/src/lj_strfmt.o +0 -0
  333. data/lua-hooks/ext/luajit/src/lj_strfmt_dyn.o +0 -0
  334. data/lua-hooks/ext/luajit/src/lj_strscan.c +547 -0
  335. data/lua-hooks/ext/luajit/src/lj_strscan.h +39 -0
  336. data/lua-hooks/ext/luajit/src/lj_strscan.o +0 -0
  337. data/lua-hooks/ext/luajit/src/lj_strscan_dyn.o +0 -0
  338. data/lua-hooks/ext/luajit/src/lj_tab.c +666 -0
  339. data/lua-hooks/ext/luajit/src/lj_tab.h +73 -0
  340. data/lua-hooks/ext/luajit/src/lj_tab.o +0 -0
  341. data/lua-hooks/ext/luajit/src/lj_tab_dyn.o +0 -0
  342. data/lua-hooks/ext/luajit/src/lj_target.h +164 -0
  343. data/lua-hooks/ext/luajit/src/lj_target_arm.h +270 -0
  344. data/lua-hooks/ext/luajit/src/lj_target_arm64.h +97 -0
  345. data/lua-hooks/ext/luajit/src/lj_target_mips.h +260 -0
  346. data/lua-hooks/ext/luajit/src/lj_target_ppc.h +280 -0
  347. data/lua-hooks/ext/luajit/src/lj_target_x86.h +345 -0
  348. data/lua-hooks/ext/luajit/src/lj_trace.c +859 -0
  349. data/lua-hooks/ext/luajit/src/lj_trace.h +54 -0
  350. data/lua-hooks/ext/luajit/src/lj_trace.o +0 -0
  351. data/lua-hooks/ext/luajit/src/lj_trace_dyn.o +0 -0
  352. data/lua-hooks/ext/luajit/src/lj_traceerr.h +63 -0
  353. data/lua-hooks/ext/luajit/src/lj_udata.c +34 -0
  354. data/lua-hooks/ext/luajit/src/lj_udata.h +14 -0
  355. data/lua-hooks/ext/luajit/src/lj_udata.o +0 -0
  356. data/lua-hooks/ext/luajit/src/lj_udata_dyn.o +0 -0
  357. data/lua-hooks/ext/luajit/src/lj_vm.S +2730 -0
  358. data/lua-hooks/ext/luajit/src/lj_vm.h +114 -0
  359. data/lua-hooks/ext/luajit/src/lj_vm.o +0 -0
  360. data/lua-hooks/ext/luajit/src/lj_vm_dyn.o +0 -0
  361. data/lua-hooks/ext/luajit/src/lj_vmevent.c +58 -0
  362. data/lua-hooks/ext/luajit/src/lj_vmevent.h +59 -0
  363. data/lua-hooks/ext/luajit/src/lj_vmevent.o +0 -0
  364. data/lua-hooks/ext/luajit/src/lj_vmevent_dyn.o +0 -0
  365. data/lua-hooks/ext/luajit/src/lj_vmmath.c +152 -0
  366. data/lua-hooks/ext/luajit/src/lj_vmmath.o +0 -0
  367. data/lua-hooks/ext/luajit/src/lj_vmmath_dyn.o +0 -0
  368. data/lua-hooks/ext/luajit/src/ljamalg.c +96 -0
  369. data/lua-hooks/ext/{lua → luajit/src}/lua.h +12 -7
  370. data/lua-hooks/ext/luajit/src/lua.hpp +9 -0
  371. data/lua-hooks/ext/luajit/src/luaconf.h +156 -0
  372. data/lua-hooks/ext/luajit/src/luajit +0 -0
  373. data/lua-hooks/ext/luajit/src/luajit.c +570 -0
  374. data/lua-hooks/ext/luajit/src/luajit.h +79 -0
  375. data/lua-hooks/ext/luajit/src/luajit.o +0 -0
  376. data/lua-hooks/ext/luajit/src/lualib.h +43 -0
  377. data/lua-hooks/ext/luajit/src/msvcbuild.bat +114 -0
  378. data/lua-hooks/ext/luajit/src/ps4build.bat +103 -0
  379. data/lua-hooks/ext/luajit/src/psvitabuild.bat +93 -0
  380. data/lua-hooks/ext/luajit/src/vm_arm.dasc +4585 -0
  381. data/lua-hooks/ext/luajit/src/vm_arm64.dasc +3764 -0
  382. data/lua-hooks/ext/luajit/src/vm_mips.dasc +4355 -0
  383. data/lua-hooks/ext/luajit/src/vm_ppc.dasc +5252 -0
  384. data/lua-hooks/ext/luajit/src/vm_x64.dasc +4902 -0
  385. data/lua-hooks/ext/luajit/src/vm_x86.dasc +5710 -0
  386. data/lua-hooks/ext/luajit/src/xb1build.bat +101 -0
  387. data/lua-hooks/ext/luajit/src/xedkbuild.bat +92 -0
  388. data/lua-hooks/ext/luautf8/lutf8lib.c +3 -3
  389. data/lua-hooks/lib/boot.lua +37 -2
  390. metadata +372 -69
  391. data/lua-hooks/ext/bitop/README +0 -22
  392. data/lua-hooks/ext/bitop/bit.c +0 -189
  393. data/lua-hooks/ext/extconf.rb +0 -38
  394. data/lua-hooks/ext/lua/COPYRIGHT +0 -34
  395. data/lua-hooks/ext/lua/lapi.c +0 -1087
  396. data/lua-hooks/ext/lua/lapi.h +0 -16
  397. data/lua-hooks/ext/lua/lauxlib.c +0 -652
  398. data/lua-hooks/ext/lua/lbaselib.c +0 -659
  399. data/lua-hooks/ext/lua/lcode.c +0 -831
  400. data/lua-hooks/ext/lua/lcode.h +0 -76
  401. data/lua-hooks/ext/lua/ldblib.c +0 -398
  402. data/lua-hooks/ext/lua/ldebug.c +0 -638
  403. data/lua-hooks/ext/lua/ldebug.h +0 -33
  404. data/lua-hooks/ext/lua/ldo.c +0 -519
  405. data/lua-hooks/ext/lua/ldo.h +0 -57
  406. data/lua-hooks/ext/lua/ldump.c +0 -164
  407. data/lua-hooks/ext/lua/lfunc.c +0 -174
  408. data/lua-hooks/ext/lua/lfunc.h +0 -34
  409. data/lua-hooks/ext/lua/lgc.c +0 -710
  410. data/lua-hooks/ext/lua/lgc.h +0 -110
  411. data/lua-hooks/ext/lua/linit.c +0 -38
  412. data/lua-hooks/ext/lua/liolib.c +0 -556
  413. data/lua-hooks/ext/lua/llex.c +0 -463
  414. data/lua-hooks/ext/lua/llex.h +0 -81
  415. data/lua-hooks/ext/lua/llimits.h +0 -128
  416. data/lua-hooks/ext/lua/lmathlib.c +0 -263
  417. data/lua-hooks/ext/lua/lmem.c +0 -86
  418. data/lua-hooks/ext/lua/lmem.h +0 -49
  419. data/lua-hooks/ext/lua/loadlib.c +0 -705
  420. data/lua-hooks/ext/lua/loadlib_rel.c +0 -760
  421. data/lua-hooks/ext/lua/lobject.c +0 -214
  422. data/lua-hooks/ext/lua/lobject.h +0 -381
  423. data/lua-hooks/ext/lua/lopcodes.c +0 -102
  424. data/lua-hooks/ext/lua/lopcodes.h +0 -268
  425. data/lua-hooks/ext/lua/loslib.c +0 -243
  426. data/lua-hooks/ext/lua/lparser.c +0 -1339
  427. data/lua-hooks/ext/lua/lparser.h +0 -82
  428. data/lua-hooks/ext/lua/lstate.c +0 -214
  429. data/lua-hooks/ext/lua/lstate.h +0 -169
  430. data/lua-hooks/ext/lua/lstring.c +0 -111
  431. data/lua-hooks/ext/lua/lstring.h +0 -31
  432. data/lua-hooks/ext/lua/lstrlib.c +0 -871
  433. data/lua-hooks/ext/lua/ltable.c +0 -588
  434. data/lua-hooks/ext/lua/ltable.h +0 -40
  435. data/lua-hooks/ext/lua/ltablib.c +0 -287
  436. data/lua-hooks/ext/lua/ltm.c +0 -75
  437. data/lua-hooks/ext/lua/ltm.h +0 -54
  438. data/lua-hooks/ext/lua/lua.c +0 -392
  439. data/lua-hooks/ext/lua/lua.def +0 -131
  440. data/lua-hooks/ext/lua/lua.rc +0 -28
  441. data/lua-hooks/ext/lua/lua_dll.rc +0 -26
  442. data/lua-hooks/ext/lua/luac.c +0 -200
  443. data/lua-hooks/ext/lua/luac.rc +0 -1
  444. data/lua-hooks/ext/lua/luaconf.h +0 -763
  445. data/lua-hooks/ext/lua/luaconf.h.in +0 -724
  446. data/lua-hooks/ext/lua/luaconf.h.orig +0 -763
  447. data/lua-hooks/ext/lua/lualib.h +0 -53
  448. data/lua-hooks/ext/lua/lundump.c +0 -227
  449. data/lua-hooks/ext/lua/lundump.h +0 -36
  450. data/lua-hooks/ext/lua/lvm.c +0 -767
  451. data/lua-hooks/ext/lua/lvm.h +0 -36
  452. data/lua-hooks/ext/lua/lzio.c +0 -82
  453. data/lua-hooks/ext/lua/lzio.h +0 -67
  454. data/lua-hooks/ext/lua/print.c +0 -227
@@ -0,0 +1,1945 @@
1
+ ------------------------------------------------------------------------------
2
+ -- DynASM x86/x64 module.
3
+ --
4
+ -- Copyright (C) 2005-2015 Mike Pall. All rights reserved.
5
+ -- See dynasm.lua for full copyright notice.
6
+ ------------------------------------------------------------------------------
7
+
8
+ local x64 = x64
9
+
10
+ -- Module information:
11
+ local _info = {
12
+ arch = x64 and "x64" or "x86",
13
+ description = "DynASM x86/x64 module",
14
+ version = "1.3.0",
15
+ vernum = 10300,
16
+ release = "2011-05-05",
17
+ author = "Mike Pall",
18
+ license = "MIT",
19
+ }
20
+
21
+ -- Exported glue functions for the arch-specific module.
22
+ local _M = { _info = _info }
23
+
24
+ -- Cache library functions.
25
+ local type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs
26
+ local assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatable
27
+ local _s = string
28
+ local sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char
29
+ local find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub
30
+ local concat, sort = table.concat, table.sort
31
+ local bit = bit or require("bit")
32
+ local band, shl, shr = bit.band, bit.lshift, bit.rshift
33
+
34
+ -- Inherited tables and callbacks.
35
+ local g_opt, g_arch
36
+ local wline, werror, wfatal, wwarn
37
+
38
+ -- Action name list.
39
+ -- CHECK: Keep this in sync with the C code!
40
+ local action_names = {
41
+ -- int arg, 1 buffer pos:
42
+ "DISP", "IMM_S", "IMM_B", "IMM_W", "IMM_D", "IMM_WB", "IMM_DB",
43
+ -- action arg (1 byte), int arg, 1 buffer pos (reg/num):
44
+ "VREG", "SPACE", -- !x64: VREG support NYI.
45
+ -- ptrdiff_t arg, 1 buffer pos (address): !x64
46
+ "SETLABEL", "REL_A",
47
+ -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):
48
+ "REL_LG", "REL_PC",
49
+ -- action arg (1 byte) or int arg, 1 buffer pos (link):
50
+ "IMM_LG", "IMM_PC",
51
+ -- action arg (1 byte) or int arg, 1 buffer pos (offset):
52
+ "LABEL_LG", "LABEL_PC",
53
+ -- action arg (1 byte), 1 buffer pos (offset):
54
+ "ALIGN",
55
+ -- action args (2 bytes), no buffer pos.
56
+ "EXTERN",
57
+ -- action arg (1 byte), no buffer pos.
58
+ "ESC",
59
+ -- no action arg, no buffer pos.
60
+ "MARK",
61
+ -- action arg (1 byte), no buffer pos, terminal action:
62
+ "SECTION",
63
+ -- no args, no buffer pos, terminal action:
64
+ "STOP"
65
+ }
66
+
67
+ -- Maximum number of section buffer positions for dasm_put().
68
+ -- CHECK: Keep this in sync with the C code!
69
+ local maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.
70
+
71
+ -- Action name -> action number (dynamically generated below).
72
+ local map_action = {}
73
+ -- First action number. Everything below does not need to be escaped.
74
+ local actfirst = 256-#action_names
75
+
76
+ -- Action list buffer and string (only used to remove dupes).
77
+ local actlist = {}
78
+ local actstr = ""
79
+
80
+ -- Argument list for next dasm_put(). Start with offset 0 into action list.
81
+ local actargs = { 0 }
82
+
83
+ -- Current number of section buffer positions for dasm_put().
84
+ local secpos = 1
85
+
86
+ ------------------------------------------------------------------------------
87
+
88
+ -- Compute action numbers for action names.
89
+ for n,name in ipairs(action_names) do
90
+ local num = actfirst + n - 1
91
+ map_action[name] = num
92
+ end
93
+
94
+ -- Dump action names and numbers.
95
+ local function dumpactions(out)
96
+ out:write("DynASM encoding engine action codes:\n")
97
+ for n,name in ipairs(action_names) do
98
+ local num = map_action[name]
99
+ out:write(format(" %-10s %02X %d\n", name, num, num))
100
+ end
101
+ out:write("\n")
102
+ end
103
+
104
+ -- Write action list buffer as a huge static C array.
105
+ local function writeactions(out, name)
106
+ local nn = #actlist
107
+ local last = actlist[nn] or 255
108
+ actlist[nn] = nil -- Remove last byte.
109
+ if nn == 0 then nn = 1 end
110
+ out:write("static const unsigned char ", name, "[", nn, "] = {\n")
111
+ local s = " "
112
+ for n,b in ipairs(actlist) do
113
+ s = s..b..","
114
+ if #s >= 75 then
115
+ assert(out:write(s, "\n"))
116
+ s = " "
117
+ end
118
+ end
119
+ out:write(s, last, "\n};\n\n") -- Add last byte back.
120
+ end
121
+
122
+ ------------------------------------------------------------------------------
123
+
124
+ -- Add byte to action list.
125
+ local function wputxb(n)
126
+ assert(n >= 0 and n <= 255 and n % 1 == 0, "byte out of range")
127
+ actlist[#actlist+1] = n
128
+ end
129
+
130
+ -- Add action to list with optional arg. Advance buffer pos, too.
131
+ local function waction(action, a, num)
132
+ wputxb(assert(map_action[action], "bad action name `"..action.."'"))
133
+ if a then actargs[#actargs+1] = a end
134
+ if a or num then secpos = secpos + (num or 1) end
135
+ end
136
+
137
+ -- Add call to embedded DynASM C code.
138
+ local function wcall(func, args)
139
+ wline(format("dasm_%s(Dst, %s);", func, concat(args, ", ")), true)
140
+ end
141
+
142
+ -- Delete duplicate action list chunks. A tad slow, but so what.
143
+ local function dedupechunk(offset)
144
+ local al, as = actlist, actstr
145
+ local chunk = char(unpack(al, offset+1, #al))
146
+ local orig = find(as, chunk, 1, true)
147
+ if orig then
148
+ actargs[1] = orig-1 -- Replace with original offset.
149
+ for i=offset+1,#al do al[i] = nil end -- Kill dupe.
150
+ else
151
+ actstr = as..chunk
152
+ end
153
+ end
154
+
155
+ -- Flush action list (intervening C code or buffer pos overflow).
156
+ local function wflush(term)
157
+ local offset = actargs[1]
158
+ if #actlist == offset then return end -- Nothing to flush.
159
+ if not term then waction("STOP") end -- Terminate action list.
160
+ dedupechunk(offset)
161
+ wcall("put", actargs) -- Add call to dasm_put().
162
+ actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().
163
+ secpos = 1 -- The actionlist offset occupies a buffer position, too.
164
+ end
165
+
166
+ -- Put escaped byte.
167
+ local function wputb(n)
168
+ if n >= actfirst then waction("ESC") end -- Need to escape byte.
169
+ wputxb(n)
170
+ end
171
+
172
+ ------------------------------------------------------------------------------
173
+
174
+ -- Global label name -> global label number. With auto assignment on 1st use.
175
+ local next_global = 10
176
+ local map_global = setmetatable({}, { __index = function(t, name)
177
+ if not match(name, "^[%a_][%w_@]*$") then werror("bad global label") end
178
+ local n = next_global
179
+ if n > 246 then werror("too many global labels") end
180
+ next_global = n + 1
181
+ t[name] = n
182
+ return n
183
+ end})
184
+
185
+ -- Dump global labels.
186
+ local function dumpglobals(out, lvl)
187
+ local t = {}
188
+ for name, n in pairs(map_global) do t[n] = name end
189
+ out:write("Global labels:\n")
190
+ for i=10,next_global-1 do
191
+ out:write(format(" %s\n", t[i]))
192
+ end
193
+ out:write("\n")
194
+ end
195
+
196
+ -- Write global label enum.
197
+ local function writeglobals(out, prefix)
198
+ local t = {}
199
+ for name, n in pairs(map_global) do t[n] = name end
200
+ out:write("enum {\n")
201
+ for i=10,next_global-1 do
202
+ out:write(" ", prefix, gsub(t[i], "@.*", ""), ",\n")
203
+ end
204
+ out:write(" ", prefix, "_MAX\n};\n")
205
+ end
206
+
207
+ -- Write global label names.
208
+ local function writeglobalnames(out, name)
209
+ local t = {}
210
+ for name, n in pairs(map_global) do t[n] = name end
211
+ out:write("static const char *const ", name, "[] = {\n")
212
+ for i=10,next_global-1 do
213
+ out:write(" \"", t[i], "\",\n")
214
+ end
215
+ out:write(" (const char *)0\n};\n")
216
+ end
217
+
218
+ ------------------------------------------------------------------------------
219
+
220
+ -- Extern label name -> extern label number. With auto assignment on 1st use.
221
+ local next_extern = -1
222
+ local map_extern = setmetatable({}, { __index = function(t, name)
223
+ -- No restrictions on the name for now.
224
+ local n = next_extern
225
+ if n < -256 then werror("too many extern labels") end
226
+ next_extern = n - 1
227
+ t[name] = n
228
+ return n
229
+ end})
230
+
231
+ -- Dump extern labels.
232
+ local function dumpexterns(out, lvl)
233
+ local t = {}
234
+ for name, n in pairs(map_extern) do t[-n] = name end
235
+ out:write("Extern labels:\n")
236
+ for i=1,-next_extern-1 do
237
+ out:write(format(" %s\n", t[i]))
238
+ end
239
+ out:write("\n")
240
+ end
241
+
242
+ -- Write extern label names.
243
+ local function writeexternnames(out, name)
244
+ local t = {}
245
+ for name, n in pairs(map_extern) do t[-n] = name end
246
+ out:write("static const char *const ", name, "[] = {\n")
247
+ for i=1,-next_extern-1 do
248
+ out:write(" \"", t[i], "\",\n")
249
+ end
250
+ out:write(" (const char *)0\n};\n")
251
+ end
252
+
253
+ ------------------------------------------------------------------------------
254
+
255
+ -- Arch-specific maps.
256
+ local map_archdef = {} -- Ext. register name -> int. name.
257
+ local map_reg_rev = {} -- Int. register name -> ext. name.
258
+ local map_reg_num = {} -- Int. register name -> register number.
259
+ local map_reg_opsize = {} -- Int. register name -> operand size.
260
+ local map_reg_valid_base = {} -- Int. register name -> valid base register?
261
+ local map_reg_valid_index = {} -- Int. register name -> valid index register?
262
+ local map_reg_needrex = {} -- Int. register name -> need rex vs. no rex.
263
+ local reg_list = {} -- Canonical list of int. register names.
264
+
265
+ local map_type = {} -- Type name -> { ctype, reg }
266
+ local ctypenum = 0 -- Type number (for _PTx macros).
267
+
268
+ local addrsize = x64 and "q" or "d" -- Size for address operands.
269
+
270
+ -- Helper functions to fill register maps.
271
+ local function mkrmap(sz, cl, names)
272
+ local cname = format("@%s", sz)
273
+ reg_list[#reg_list+1] = cname
274
+ map_archdef[cl] = cname
275
+ map_reg_rev[cname] = cl
276
+ map_reg_num[cname] = -1
277
+ map_reg_opsize[cname] = sz
278
+ if sz == addrsize or sz == "d" then
279
+ map_reg_valid_base[cname] = true
280
+ map_reg_valid_index[cname] = true
281
+ end
282
+ if names then
283
+ for n,name in ipairs(names) do
284
+ local iname = format("@%s%x", sz, n-1)
285
+ reg_list[#reg_list+1] = iname
286
+ map_archdef[name] = iname
287
+ map_reg_rev[iname] = name
288
+ map_reg_num[iname] = n-1
289
+ map_reg_opsize[iname] = sz
290
+ if sz == "b" and n > 4 then map_reg_needrex[iname] = false end
291
+ if sz == addrsize or sz == "d" then
292
+ map_reg_valid_base[iname] = true
293
+ map_reg_valid_index[iname] = true
294
+ end
295
+ end
296
+ end
297
+ for i=0,(x64 and sz ~= "f") and 15 or 7 do
298
+ local needrex = sz == "b" and i > 3
299
+ local iname = format("@%s%x%s", sz, i, needrex and "R" or "")
300
+ if needrex then map_reg_needrex[iname] = true end
301
+ local name
302
+ if sz == "o" then name = format("xmm%d", i)
303
+ elseif sz == "f" then name = format("st%d", i)
304
+ else name = format("r%d%s", i, sz == addrsize and "" or sz) end
305
+ map_archdef[name] = iname
306
+ if not map_reg_rev[iname] then
307
+ reg_list[#reg_list+1] = iname
308
+ map_reg_rev[iname] = name
309
+ map_reg_num[iname] = i
310
+ map_reg_opsize[iname] = sz
311
+ if sz == addrsize or sz == "d" then
312
+ map_reg_valid_base[iname] = true
313
+ map_reg_valid_index[iname] = true
314
+ end
315
+ end
316
+ end
317
+ reg_list[#reg_list+1] = ""
318
+ end
319
+
320
+ -- Integer registers (qword, dword, word and byte sized).
321
+ if x64 then
322
+ mkrmap("q", "Rq", {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"})
323
+ end
324
+ mkrmap("d", "Rd", {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"})
325
+ mkrmap("w", "Rw", {"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"})
326
+ mkrmap("b", "Rb", {"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"})
327
+ map_reg_valid_index[map_archdef.esp] = false
328
+ if x64 then map_reg_valid_index[map_archdef.rsp] = false end
329
+ map_archdef["Ra"] = "@"..addrsize
330
+
331
+ -- FP registers (internally tword sized, but use "f" as operand size).
332
+ mkrmap("f", "Rf")
333
+
334
+ -- SSE registers (oword sized, but qword and dword accessible).
335
+ mkrmap("o", "xmm")
336
+
337
+ -- Operand size prefixes to codes.
338
+ local map_opsize = {
339
+ byte = "b", word = "w", dword = "d", qword = "q", oword = "o", tword = "t",
340
+ aword = addrsize,
341
+ }
342
+
343
+ -- Operand size code to number.
344
+ local map_opsizenum = {
345
+ b = 1, w = 2, d = 4, q = 8, o = 16, t = 10,
346
+ }
347
+
348
+ -- Operand size code to name.
349
+ local map_opsizename = {
350
+ b = "byte", w = "word", d = "dword", q = "qword", o = "oword", t = "tword",
351
+ f = "fpword",
352
+ }
353
+
354
+ -- Valid index register scale factors.
355
+ local map_xsc = {
356
+ ["1"] = 0, ["2"] = 1, ["4"] = 2, ["8"] = 3,
357
+ }
358
+
359
+ -- Condition codes.
360
+ local map_cc = {
361
+ o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,
362
+ s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,
363
+ c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,
364
+ pe = 10, po = 11, nge = 12, ge = 13, ng = 14, g = 15,
365
+ }
366
+
367
+
368
+ -- Reverse defines for registers.
369
+ function _M.revdef(s)
370
+ return gsub(s, "@%w+", map_reg_rev)
371
+ end
372
+
373
+ -- Dump register names and numbers
374
+ local function dumpregs(out)
375
+ out:write("Register names, sizes and internal numbers:\n")
376
+ for _,reg in ipairs(reg_list) do
377
+ if reg == "" then
378
+ out:write("\n")
379
+ else
380
+ local name = map_reg_rev[reg]
381
+ local num = map_reg_num[reg]
382
+ local opsize = map_opsizename[map_reg_opsize[reg]]
383
+ out:write(format(" %-5s %-8s %s\n", name, opsize,
384
+ num < 0 and "(variable)" or num))
385
+ end
386
+ end
387
+ end
388
+
389
+ ------------------------------------------------------------------------------
390
+
391
+ -- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).
392
+ local function wputlabel(aprefix, imm, num)
393
+ if type(imm) == "number" then
394
+ if imm < 0 then
395
+ waction("EXTERN")
396
+ wputxb(aprefix == "IMM_" and 0 or 1)
397
+ imm = -imm-1
398
+ else
399
+ waction(aprefix.."LG", nil, num);
400
+ end
401
+ wputxb(imm)
402
+ else
403
+ waction(aprefix.."PC", imm, num)
404
+ end
405
+ end
406
+
407
+ -- Put signed byte or arg.
408
+ local function wputsbarg(n)
409
+ if type(n) == "number" then
410
+ if n < -128 or n > 127 then
411
+ werror("signed immediate byte out of range")
412
+ end
413
+ if n < 0 then n = n + 256 end
414
+ wputb(n)
415
+ else waction("IMM_S", n) end
416
+ end
417
+
418
+ -- Put unsigned byte or arg.
419
+ local function wputbarg(n)
420
+ if type(n) == "number" then
421
+ if n < 0 or n > 255 then
422
+ werror("unsigned immediate byte out of range")
423
+ end
424
+ wputb(n)
425
+ else waction("IMM_B", n) end
426
+ end
427
+
428
+ -- Put unsigned word or arg.
429
+ local function wputwarg(n)
430
+ if type(n) == "number" then
431
+ if shr(n, 16) ~= 0 then
432
+ werror("unsigned immediate word out of range")
433
+ end
434
+ wputb(band(n, 255)); wputb(shr(n, 8));
435
+ else waction("IMM_W", n) end
436
+ end
437
+
438
+ -- Put signed or unsigned dword or arg.
439
+ local function wputdarg(n)
440
+ local tn = type(n)
441
+ if tn == "number" then
442
+ wputb(band(n, 255))
443
+ wputb(band(shr(n, 8), 255))
444
+ wputb(band(shr(n, 16), 255))
445
+ wputb(shr(n, 24))
446
+ elseif tn == "table" then
447
+ wputlabel("IMM_", n[1], 1)
448
+ else
449
+ waction("IMM_D", n)
450
+ end
451
+ end
452
+
453
+ -- Put operand-size dependent number or arg (defaults to dword).
454
+ local function wputszarg(sz, n)
455
+ if not sz or sz == "d" or sz == "q" then wputdarg(n)
456
+ elseif sz == "w" then wputwarg(n)
457
+ elseif sz == "b" then wputbarg(n)
458
+ elseif sz == "s" then wputsbarg(n)
459
+ else werror("bad operand size") end
460
+ end
461
+
462
+ -- Put multi-byte opcode with operand-size dependent modifications.
463
+ local function wputop(sz, op, rex)
464
+ local r
465
+ if rex ~= 0 and not x64 then werror("bad operand size") end
466
+ if sz == "w" then wputb(102) end
467
+ -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]
468
+ if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end
469
+ if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end
470
+ if op >= 65536 then
471
+ if rex ~= 0 then
472
+ local opc3 = band(op, 0xffff00)
473
+ if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then
474
+ wputb(64 + band(rex, 15)); rex = 0
475
+ end
476
+ end
477
+ wputb(shr(op, 16)); op = band(op, 0xffff)
478
+ end
479
+ if op >= 256 then
480
+ local b = shr(op, 8)
481
+ if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0 end
482
+ wputb(b)
483
+ op = band(op, 255)
484
+ end
485
+ if rex ~= 0 then wputb(64 + band(rex, 15)) end
486
+ if sz == "b" then op = op - 1 end
487
+ wputb(op)
488
+ end
489
+
490
+ -- Put ModRM or SIB formatted byte.
491
+ local function wputmodrm(m, s, rm, vs, vrm)
492
+ assert(m < 4 and s < 16 and rm < 16, "bad modrm operands")
493
+ wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))
494
+ end
495
+
496
+ -- Put ModRM/SIB plus optional displacement.
497
+ local function wputmrmsib(t, imark, s, vsreg)
498
+ local vreg, vxreg
499
+ local reg, xreg = t.reg, t.xreg
500
+ if reg and reg < 0 then reg = 0; vreg = t.vreg end
501
+ if xreg and xreg < 0 then xreg = 0; vxreg = t.vxreg end
502
+ if s < 0 then s = 0 end
503
+
504
+ -- Register mode.
505
+ if sub(t.mode, 1, 1) == "r" then
506
+ wputmodrm(3, s, reg)
507
+ if vsreg then waction("VREG", vsreg); wputxb(2) end
508
+ if vreg then waction("VREG", vreg); wputxb(0) end
509
+ return
510
+ end
511
+
512
+ local disp = t.disp
513
+ local tdisp = type(disp)
514
+ -- No base register?
515
+ if not reg then
516
+ local riprel = false
517
+ if xreg then
518
+ -- Indexed mode with index register only.
519
+ -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)
520
+ wputmodrm(0, s, 4)
521
+ if imark == "I" then waction("MARK") end
522
+ if vsreg then waction("VREG", vsreg); wputxb(2) end
523
+ wputmodrm(t.xsc, xreg, 5)
524
+ if vxreg then waction("VREG", vxreg); wputxb(3) end
525
+ else
526
+ -- Pure 32 bit displacement.
527
+ if x64 and tdisp ~= "table" then
528
+ wputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)
529
+ if imark == "I" then waction("MARK") end
530
+ wputmodrm(0, 4, 5)
531
+ else
532
+ riprel = x64
533
+ wputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)
534
+ if imark == "I" then waction("MARK") end
535
+ end
536
+ if vsreg then waction("VREG", vsreg); wputxb(2) end
537
+ end
538
+ if riprel then -- Emit rip-relative displacement.
539
+ if match("UWSiI", imark) then
540
+ werror("NYI: rip-relative displacement followed by immediate")
541
+ end
542
+ -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.
543
+ wputlabel("REL_", disp[1], 2)
544
+ else
545
+ wputdarg(disp)
546
+ end
547
+ return
548
+ end
549
+
550
+ local m
551
+ if tdisp == "number" then -- Check displacement size at assembly time.
552
+ if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)
553
+ if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]
554
+ elseif disp >= -128 and disp <= 127 then m = 1
555
+ else m = 2 end
556
+ elseif tdisp == "table" then
557
+ m = 2
558
+ end
559
+
560
+ -- Index register present or esp as base register: need SIB encoding.
561
+ if xreg or band(reg, 7) == 4 then
562
+ wputmodrm(m or 2, s, 4) -- ModRM.
563
+ if m == nil or imark == "I" then waction("MARK") end
564
+ if vsreg then waction("VREG", vsreg); wputxb(2) end
565
+ wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.
566
+ if vxreg then waction("VREG", vxreg); wputxb(3) end
567
+ if vreg then waction("VREG", vreg); wputxb(1) end
568
+ else
569
+ wputmodrm(m or 2, s, reg) -- ModRM.
570
+ if (imark == "I" and (m == 1 or m == 2)) or
571
+ (m == nil and (vsreg or vreg)) then waction("MARK") end
572
+ if vsreg then waction("VREG", vsreg); wputxb(2) end
573
+ if vreg then waction("VREG", vreg); wputxb(1) end
574
+ end
575
+
576
+ -- Put displacement.
577
+ if m == 1 then wputsbarg(disp)
578
+ elseif m == 2 then wputdarg(disp)
579
+ elseif m == nil then waction("DISP", disp) end
580
+ end
581
+
582
+ ------------------------------------------------------------------------------
583
+
584
+ -- Return human-readable operand mode string.
585
+ local function opmodestr(op, args)
586
+ local m = {}
587
+ for i=1,#args do
588
+ local a = args[i]
589
+ m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or "?")
590
+ end
591
+ return op.." "..concat(m, ",")
592
+ end
593
+
594
+ -- Convert number to valid integer or nil.
595
+ local function toint(expr)
596
+ local n = tonumber(expr)
597
+ if n then
598
+ if n % 1 ~= 0 or n < -2147483648 or n > 4294967295 then
599
+ werror("bad integer number `"..expr.."'")
600
+ end
601
+ return n
602
+ end
603
+ end
604
+
605
+ -- Parse immediate expression.
606
+ local function immexpr(expr)
607
+ -- &expr (pointer)
608
+ if sub(expr, 1, 1) == "&" then
609
+ return "iPJ", format("(ptrdiff_t)(%s)", sub(expr,2))
610
+ end
611
+
612
+ local prefix = sub(expr, 1, 2)
613
+ -- =>expr (pc label reference)
614
+ if prefix == "=>" then
615
+ return "iJ", sub(expr, 3)
616
+ end
617
+ -- ->name (global label reference)
618
+ if prefix == "->" then
619
+ return "iJ", map_global[sub(expr, 3)]
620
+ end
621
+
622
+ -- [<>][1-9] (local label reference)
623
+ local dir, lnum = match(expr, "^([<>])([1-9])$")
624
+ if dir then -- Fwd: 247-255, Bkwd: 1-9.
625
+ return "iJ", lnum + (dir == ">" and 246 or 0)
626
+ end
627
+
628
+ local extname = match(expr, "^extern%s+(%S+)$")
629
+ if extname then
630
+ return "iJ", map_extern[extname]
631
+ end
632
+
633
+ -- expr (interpreted as immediate)
634
+ return "iI", expr
635
+ end
636
+
637
+ -- Parse displacement expression: +-num, +-expr, +-opsize*num
638
+ local function dispexpr(expr)
639
+ local disp = expr == "" and 0 or toint(expr)
640
+ if disp then return disp end
641
+ local c, dispt = match(expr, "^([+-])%s*(.+)$")
642
+ if c == "+" then
643
+ expr = dispt
644
+ elseif not c then
645
+ werror("bad displacement expression `"..expr.."'")
646
+ end
647
+ local opsize, tailops = match(dispt, "^(%w+)%s*%*%s*(.+)$")
648
+ local ops, imm = map_opsize[opsize], toint(tailops)
649
+ if ops and imm then
650
+ if c == "-" then imm = -imm end
651
+ return imm*map_opsizenum[ops]
652
+ end
653
+ local mode, iexpr = immexpr(dispt)
654
+ if mode == "iJ" then
655
+ if c == "-" then werror("cannot invert label reference") end
656
+ return { iexpr }
657
+ end
658
+ return expr -- Need to return original signed expression.
659
+ end
660
+
661
+ -- Parse register or type expression.
662
+ local function rtexpr(expr)
663
+ if not expr then return end
664
+ local tname, ovreg = match(expr, "^([%w_]+):(@[%w_]+)$")
665
+ local tp = map_type[tname or expr]
666
+ if tp then
667
+ local reg = ovreg or tp.reg
668
+ local rnum = map_reg_num[reg]
669
+ if not rnum then
670
+ werror("type `"..(tname or expr).."' needs a register override")
671
+ end
672
+ if not map_reg_valid_base[reg] then
673
+ werror("bad base register override `"..(map_reg_rev[reg] or reg).."'")
674
+ end
675
+ return reg, rnum, tp
676
+ end
677
+ return expr, map_reg_num[expr]
678
+ end
679
+
680
+ -- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.
681
+ local function parseoperand(param)
682
+ local t = {}
683
+
684
+ local expr = param
685
+ local opsize, tailops = match(param, "^(%w+)%s*(.+)$")
686
+ if opsize then
687
+ t.opsize = map_opsize[opsize]
688
+ if t.opsize then expr = tailops end
689
+ end
690
+
691
+ local br = match(expr, "^%[%s*(.-)%s*%]$")
692
+ repeat
693
+ if br then
694
+ t.mode = "xm"
695
+
696
+ -- [disp]
697
+ t.disp = toint(br)
698
+ if t.disp then
699
+ t.mode = x64 and "xm" or "xmO"
700
+ break
701
+ end
702
+
703
+ -- [reg...]
704
+ local tp
705
+ local reg, tailr = match(br, "^([@%w_:]+)%s*(.*)$")
706
+ reg, t.reg, tp = rtexpr(reg)
707
+ if not t.reg then
708
+ -- [expr]
709
+ t.mode = x64 and "xm" or "xmO"
710
+ t.disp = dispexpr("+"..br)
711
+ break
712
+ end
713
+
714
+ if t.reg == -1 then
715
+ t.vreg, tailr = match(tailr, "^(%b())(.*)$")
716
+ if not t.vreg then werror("bad variable register expression") end
717
+ end
718
+
719
+ -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]
720
+ local xsc, tailsc = match(tailr, "^%*%s*([1248])%s*(.*)$")
721
+ if xsc then
722
+ if not map_reg_valid_index[reg] then
723
+ werror("bad index register `"..map_reg_rev[reg].."'")
724
+ end
725
+ t.xsc = map_xsc[xsc]
726
+ t.xreg = t.reg
727
+ t.vxreg = t.vreg
728
+ t.reg = nil
729
+ t.vreg = nil
730
+ t.disp = dispexpr(tailsc)
731
+ break
732
+ end
733
+ if not map_reg_valid_base[reg] then
734
+ werror("bad base register `"..map_reg_rev[reg].."'")
735
+ end
736
+
737
+ -- [reg] or [reg+-disp]
738
+ t.disp = toint(tailr) or (tailr == "" and 0)
739
+ if t.disp then break end
740
+
741
+ -- [reg+xreg...]
742
+ local xreg, tailx = match(tailr, "^+%s*([@%w_:]+)%s*(.*)$")
743
+ xreg, t.xreg, tp = rtexpr(xreg)
744
+ if not t.xreg then
745
+ -- [reg+-expr]
746
+ t.disp = dispexpr(tailr)
747
+ break
748
+ end
749
+ if not map_reg_valid_index[xreg] then
750
+ werror("bad index register `"..map_reg_rev[xreg].."'")
751
+ end
752
+
753
+ if t.xreg == -1 then
754
+ t.vxreg, tailx = match(tailx, "^(%b())(.*)$")
755
+ if not t.vxreg then werror("bad variable register expression") end
756
+ end
757
+
758
+ -- [reg+xreg*xsc...]
759
+ local xsc, tailsc = match(tailx, "^%*%s*([1248])%s*(.*)$")
760
+ if xsc then
761
+ t.xsc = map_xsc[xsc]
762
+ tailx = tailsc
763
+ end
764
+
765
+ -- [...] or [...+-disp] or [...+-expr]
766
+ t.disp = dispexpr(tailx)
767
+ else
768
+ -- imm or opsize*imm
769
+ local imm = toint(expr)
770
+ if not imm and sub(expr, 1, 1) == "*" and t.opsize then
771
+ imm = toint(sub(expr, 2))
772
+ if imm then
773
+ imm = imm * map_opsizenum[t.opsize]
774
+ t.opsize = nil
775
+ end
776
+ end
777
+ if imm then
778
+ if t.opsize then werror("bad operand size override") end
779
+ local m = "i"
780
+ if imm == 1 then m = m.."1" end
781
+ if imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end
782
+ if imm >= -128 and imm <= 127 then m = m.."S" end
783
+ t.imm = imm
784
+ t.mode = m
785
+ break
786
+ end
787
+
788
+ local tp
789
+ local reg, tailr = match(expr, "^([@%w_:]+)%s*(.*)$")
790
+ reg, t.reg, tp = rtexpr(reg)
791
+ if t.reg then
792
+ if t.reg == -1 then
793
+ t.vreg, tailr = match(tailr, "^(%b())(.*)$")
794
+ if not t.vreg then werror("bad variable register expression") end
795
+ end
796
+ -- reg
797
+ if tailr == "" then
798
+ if t.opsize then werror("bad operand size override") end
799
+ t.opsize = map_reg_opsize[reg]
800
+ if t.opsize == "f" then
801
+ t.mode = t.reg == 0 and "fF" or "f"
802
+ else
803
+ if reg == "@w4" or (x64 and reg == "@d4") then
804
+ wwarn("bad idea, try again with `"..(x64 and "rsp'" or "esp'"))
805
+ end
806
+ t.mode = t.reg == 0 and "rmR" or (reg == "@b1" and "rmC" or "rm")
807
+ end
808
+ t.needrex = map_reg_needrex[reg]
809
+ break
810
+ end
811
+
812
+ -- type[idx], type[idx].field, type->field -> [reg+offset_expr]
813
+ if not tp then werror("bad operand `"..param.."'") end
814
+ t.mode = "xm"
815
+ t.disp = format(tp.ctypefmt, tailr)
816
+ else
817
+ t.mode, t.imm = immexpr(expr)
818
+ if sub(t.mode, -1) == "J" then
819
+ if t.opsize and t.opsize ~= addrsize then
820
+ werror("bad operand size override")
821
+ end
822
+ t.opsize = addrsize
823
+ end
824
+ end
825
+ end
826
+ until true
827
+ return t
828
+ end
829
+
830
+ ------------------------------------------------------------------------------
831
+ -- x86 Template String Description
832
+ -- ===============================
833
+ --
834
+ -- Each template string is a list of [match:]pattern pairs,
835
+ -- separated by "|". The first match wins. No match means a
836
+ -- bad or unsupported combination of operand modes or sizes.
837
+ --
838
+ -- The match part and the ":" is omitted if the operation has
839
+ -- no operands. Otherwise the first N characters are matched
840
+ -- against the mode strings of each of the N operands.
841
+ --
842
+ -- The mode string for each operand type is (see parseoperand()):
843
+ -- Integer register: "rm", +"R" for eax, ax, al, +"C" for cl
844
+ -- FP register: "f", +"F" for st0
845
+ -- Index operand: "xm", +"O" for [disp] (pure offset)
846
+ -- Immediate: "i", +"S" for signed 8 bit, +"1" for 1,
847
+ -- +"I" for arg, +"P" for pointer
848
+ -- Any: +"J" for valid jump targets
849
+ --
850
+ -- So a match character "m" (mixed) matches both an integer register
851
+ -- and an index operand (to be encoded with the ModRM/SIB scheme).
852
+ -- But "r" matches only a register and "x" only an index operand
853
+ -- (e.g. for FP memory access operations).
854
+ --
855
+ -- The operand size match string starts right after the mode match
856
+ -- characters and ends before the ":". "dwb" or "qdwb" is assumed, if empty.
857
+ -- The effective data size of the operation is matched against this list.
858
+ --
859
+ -- If only the regular "b", "w", "d", "q", "t" operand sizes are
860
+ -- present, then all operands must be the same size. Unspecified sizes
861
+ -- are ignored, but at least one operand must have a size or the pattern
862
+ -- won't match (use the "byte", "word", "dword", "qword", "tword"
863
+ -- operand size overrides. E.g.: mov dword [eax], 1).
864
+ --
865
+ -- If the list has a "1" or "2" prefix, the operand size is taken
866
+ -- from the respective operand and any other operand sizes are ignored.
867
+ -- If the list contains only ".", all operand sizes are ignored.
868
+ -- If the list has a "/" prefix, the concatenated (mixed) operand sizes
869
+ -- are compared to the match.
870
+ --
871
+ -- E.g. "rrdw" matches for either two dword registers or two word
872
+ -- registers. "Fx2dq" matches an st0 operand plus an index operand
873
+ -- pointing to a dword (float) or qword (double).
874
+ --
875
+ -- Every character after the ":" is part of the pattern string:
876
+ -- Hex chars are accumulated to form the opcode (left to right).
877
+ -- "n" disables the standard opcode mods
878
+ -- (otherwise: -1 for "b", o16 prefix for "w", rex.w for "q")
879
+ -- "X" Force REX.W.
880
+ -- "r"/"R" adds the reg. number from the 1st/2nd operand to the opcode.
881
+ -- "m"/"M" generates ModRM/SIB from the 1st/2nd operand.
882
+ -- The spare 3 bits are either filled with the last hex digit or
883
+ -- the result from a previous "r"/"R". The opcode is restored.
884
+ --
885
+ -- All of the following characters force a flush of the opcode:
886
+ -- "o"/"O" stores a pure 32 bit disp (offset) from the 1st/2nd operand.
887
+ -- "S" stores a signed 8 bit immediate from the last operand.
888
+ -- "U" stores an unsigned 8 bit immediate from the last operand.
889
+ -- "W" stores an unsigned 16 bit immediate from the last operand.
890
+ -- "i" stores an operand sized immediate from the last operand.
891
+ -- "I" dito, but generates an action code to optionally modify
892
+ -- the opcode (+2) for a signed 8 bit immediate.
893
+ -- "J" generates one of the REL action codes from the last operand.
894
+ --
895
+ ------------------------------------------------------------------------------
896
+
897
+ -- Template strings for x86 instructions. Ordered by first opcode byte.
898
+ -- Unimplemented opcodes (deliberate omissions) are marked with *.
899
+ local map_op = {
900
+ -- 00-05: add...
901
+ -- 06: *push es
902
+ -- 07: *pop es
903
+ -- 08-0D: or...
904
+ -- 0E: *push cs
905
+ -- 0F: two byte opcode prefix
906
+ -- 10-15: adc...
907
+ -- 16: *push ss
908
+ -- 17: *pop ss
909
+ -- 18-1D: sbb...
910
+ -- 1E: *push ds
911
+ -- 1F: *pop ds
912
+ -- 20-25: and...
913
+ es_0 = "26",
914
+ -- 27: *daa
915
+ -- 28-2D: sub...
916
+ cs_0 = "2E",
917
+ -- 2F: *das
918
+ -- 30-35: xor...
919
+ ss_0 = "36",
920
+ -- 37: *aaa
921
+ -- 38-3D: cmp...
922
+ ds_0 = "3E",
923
+ -- 3F: *aas
924
+ inc_1 = x64 and "m:FF0m" or "rdw:40r|m:FF0m",
925
+ dec_1 = x64 and "m:FF1m" or "rdw:48r|m:FF1m",
926
+ push_1 = (x64 and "rq:n50r|rw:50r|mq:nFF6m|mw:FF6m" or
927
+ "rdw:50r|mdw:FF6m").."|S.:6AS|ib:n6Ai|i.:68i",
928
+ pop_1 = x64 and "rq:n58r|rw:58r|mq:n8F0m|mw:8F0m" or "rdw:58r|mdw:8F0m",
929
+ -- 60: *pusha, *pushad, *pushaw
930
+ -- 61: *popa, *popad, *popaw
931
+ -- 62: *bound rdw,x
932
+ -- 63: x86: *arpl mw,rw
933
+ movsxd_2 = x64 and "rm/qd:63rM",
934
+ fs_0 = "64",
935
+ gs_0 = "65",
936
+ o16_0 = "66",
937
+ a16_0 = not x64 and "67" or nil,
938
+ a32_0 = x64 and "67",
939
+ -- 68: push idw
940
+ -- 69: imul rdw,mdw,idw
941
+ -- 6A: push ib
942
+ -- 6B: imul rdw,mdw,S
943
+ -- 6C: *insb
944
+ -- 6D: *insd, *insw
945
+ -- 6E: *outsb
946
+ -- 6F: *outsd, *outsw
947
+ -- 70-7F: jcc lb
948
+ -- 80: add... mb,i
949
+ -- 81: add... mdw,i
950
+ -- 82: *undefined
951
+ -- 83: add... mdw,S
952
+ test_2 = "mr:85Rm|rm:85rM|Ri:A9ri|mi:F70mi",
953
+ -- 86: xchg rb,mb
954
+ -- 87: xchg rdw,mdw
955
+ -- 88: mov mb,r
956
+ -- 89: mov mdw,r
957
+ -- 8A: mov r,mb
958
+ -- 8B: mov r,mdw
959
+ -- 8C: *mov mdw,seg
960
+ lea_2 = "rx1dq:8DrM",
961
+ -- 8E: *mov seg,mdw
962
+ -- 8F: pop mdw
963
+ nop_0 = "90",
964
+ xchg_2 = "Rrqdw:90R|rRqdw:90r|rm:87rM|mr:87Rm",
965
+ cbw_0 = "6698",
966
+ cwde_0 = "98",
967
+ cdqe_0 = "4898",
968
+ cwd_0 = "6699",
969
+ cdq_0 = "99",
970
+ cqo_0 = "4899",
971
+ -- 9A: *call iw:idw
972
+ wait_0 = "9B",
973
+ fwait_0 = "9B",
974
+ pushf_0 = "9C",
975
+ pushfd_0 = not x64 and "9C",
976
+ pushfq_0 = x64 and "9C",
977
+ popf_0 = "9D",
978
+ popfd_0 = not x64 and "9D",
979
+ popfq_0 = x64 and "9D",
980
+ sahf_0 = "9E",
981
+ lahf_0 = "9F",
982
+ mov_2 = "OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi",
983
+ movsb_0 = "A4",
984
+ movsw_0 = "66A5",
985
+ movsd_0 = "A5",
986
+ cmpsb_0 = "A6",
987
+ cmpsw_0 = "66A7",
988
+ cmpsd_0 = "A7",
989
+ -- A8: test Rb,i
990
+ -- A9: test Rdw,i
991
+ stosb_0 = "AA",
992
+ stosw_0 = "66AB",
993
+ stosd_0 = "AB",
994
+ lodsb_0 = "AC",
995
+ lodsw_0 = "66AD",
996
+ lodsd_0 = "AD",
997
+ scasb_0 = "AE",
998
+ scasw_0 = "66AF",
999
+ scasd_0 = "AF",
1000
+ -- B0-B7: mov rb,i
1001
+ -- B8-BF: mov rdw,i
1002
+ -- C0: rol... mb,i
1003
+ -- C1: rol... mdw,i
1004
+ ret_1 = "i.:nC2W",
1005
+ ret_0 = "C3",
1006
+ -- C4: *les rdw,mq
1007
+ -- C5: *lds rdw,mq
1008
+ -- C6: mov mb,i
1009
+ -- C7: mov mdw,i
1010
+ -- C8: *enter iw,ib
1011
+ leave_0 = "C9",
1012
+ -- CA: *retf iw
1013
+ -- CB: *retf
1014
+ int3_0 = "CC",
1015
+ int_1 = "i.:nCDU",
1016
+ into_0 = "CE",
1017
+ -- CF: *iret
1018
+ -- D0: rol... mb,1
1019
+ -- D1: rol... mdw,1
1020
+ -- D2: rol... mb,cl
1021
+ -- D3: rol... mb,cl
1022
+ -- D4: *aam ib
1023
+ -- D5: *aad ib
1024
+ -- D6: *salc
1025
+ -- D7: *xlat
1026
+ -- D8-DF: floating point ops
1027
+ -- E0: *loopne
1028
+ -- E1: *loope
1029
+ -- E2: *loop
1030
+ -- E3: *jcxz, *jecxz
1031
+ -- E4: *in Rb,ib
1032
+ -- E5: *in Rdw,ib
1033
+ -- E6: *out ib,Rb
1034
+ -- E7: *out ib,Rdw
1035
+ call_1 = x64 and "mq:nFF2m|J.:E8nJ" or "md:FF2m|J.:E8J",
1036
+ jmp_1 = x64 and "mq:nFF4m|J.:E9nJ" or "md:FF4m|J.:E9J", -- short: EB
1037
+ -- EA: *jmp iw:idw
1038
+ -- EB: jmp ib
1039
+ -- EC: *in Rb,dx
1040
+ -- ED: *in Rdw,dx
1041
+ -- EE: *out dx,Rb
1042
+ -- EF: *out dx,Rdw
1043
+ lock_0 = "F0",
1044
+ int1_0 = "F1",
1045
+ repne_0 = "F2",
1046
+ repnz_0 = "F2",
1047
+ rep_0 = "F3",
1048
+ repe_0 = "F3",
1049
+ repz_0 = "F3",
1050
+ -- F4: *hlt
1051
+ cmc_0 = "F5",
1052
+ -- F6: test... mb,i; div... mb
1053
+ -- F7: test... mdw,i; div... mdw
1054
+ clc_0 = "F8",
1055
+ stc_0 = "F9",
1056
+ -- FA: *cli
1057
+ cld_0 = "FC",
1058
+ std_0 = "FD",
1059
+ -- FE: inc... mb
1060
+ -- FF: inc... mdw
1061
+
1062
+ -- misc ops
1063
+ not_1 = "m:F72m",
1064
+ neg_1 = "m:F73m",
1065
+ mul_1 = "m:F74m",
1066
+ imul_1 = "m:F75m",
1067
+ div_1 = "m:F76m",
1068
+ idiv_1 = "m:F77m",
1069
+
1070
+ imul_2 = "rmqdw:0FAFrM|rIqdw:69rmI|rSqdw:6BrmS|riqdw:69rmi",
1071
+ imul_3 = "rmIqdw:69rMI|rmSqdw:6BrMS|rmiqdw:69rMi",
1072
+
1073
+ movzx_2 = "rm/db:0FB6rM|rm/qb:|rm/wb:0FB6rM|rm/dw:0FB7rM|rm/qw:",
1074
+ movsx_2 = "rm/db:0FBErM|rm/qb:|rm/wb:0FBErM|rm/dw:0FBFrM|rm/qw:",
1075
+
1076
+ bswap_1 = "rqd:0FC8r",
1077
+ bsf_2 = "rmqdw:0FBCrM",
1078
+ bsr_2 = "rmqdw:0FBDrM",
1079
+ bt_2 = "mrqdw:0FA3Rm|miqdw:0FBA4mU",
1080
+ btc_2 = "mrqdw:0FBBRm|miqdw:0FBA7mU",
1081
+ btr_2 = "mrqdw:0FB3Rm|miqdw:0FBA6mU",
1082
+ bts_2 = "mrqdw:0FABRm|miqdw:0FBA5mU",
1083
+
1084
+ shld_3 = "mriqdw:0FA4RmU|mrCqdw:0FA5Rm",
1085
+ shrd_3 = "mriqdw:0FACRmU|mrCqdw:0FADRm",
1086
+
1087
+ rdtsc_0 = "0F31", -- P1+
1088
+ cpuid_0 = "0FA2", -- P1+
1089
+
1090
+ -- floating point ops
1091
+ fst_1 = "ff:DDD0r|xd:D92m|xq:nDD2m",
1092
+ fstp_1 = "ff:DDD8r|xd:D93m|xq:nDD3m|xt:DB7m",
1093
+ fld_1 = "ff:D9C0r|xd:D90m|xq:nDD0m|xt:DB5m",
1094
+
1095
+ fpop_0 = "DDD8", -- Alias for fstp st0.
1096
+
1097
+ fist_1 = "xw:nDF2m|xd:DB2m",
1098
+ fistp_1 = "xw:nDF3m|xd:DB3m|xq:nDF7m",
1099
+ fild_1 = "xw:nDF0m|xd:DB0m|xq:nDF5m",
1100
+
1101
+ fxch_0 = "D9C9",
1102
+ fxch_1 = "ff:D9C8r",
1103
+ fxch_2 = "fFf:D9C8r|Fff:D9C8R",
1104
+
1105
+ fucom_1 = "ff:DDE0r",
1106
+ fucom_2 = "Fff:DDE0R",
1107
+ fucomp_1 = "ff:DDE8r",
1108
+ fucomp_2 = "Fff:DDE8R",
1109
+ fucomi_1 = "ff:DBE8r", -- P6+
1110
+ fucomi_2 = "Fff:DBE8R", -- P6+
1111
+ fucomip_1 = "ff:DFE8r", -- P6+
1112
+ fucomip_2 = "Fff:DFE8R", -- P6+
1113
+ fcomi_1 = "ff:DBF0r", -- P6+
1114
+ fcomi_2 = "Fff:DBF0R", -- P6+
1115
+ fcomip_1 = "ff:DFF0r", -- P6+
1116
+ fcomip_2 = "Fff:DFF0R", -- P6+
1117
+ fucompp_0 = "DAE9",
1118
+ fcompp_0 = "DED9",
1119
+
1120
+ fldenv_1 = "x.:D94m",
1121
+ fnstenv_1 = "x.:D96m",
1122
+ fstenv_1 = "x.:9BD96m",
1123
+ fldcw_1 = "xw:nD95m",
1124
+ fstcw_1 = "xw:n9BD97m",
1125
+ fnstcw_1 = "xw:nD97m",
1126
+ fstsw_1 = "Rw:n9BDFE0|xw:n9BDD7m",
1127
+ fnstsw_1 = "Rw:nDFE0|xw:nDD7m",
1128
+ fclex_0 = "9BDBE2",
1129
+ fnclex_0 = "DBE2",
1130
+
1131
+ fnop_0 = "D9D0",
1132
+ -- D9D1-D9DF: unassigned
1133
+
1134
+ fchs_0 = "D9E0",
1135
+ fabs_0 = "D9E1",
1136
+ -- D9E2: unassigned
1137
+ -- D9E3: unassigned
1138
+ ftst_0 = "D9E4",
1139
+ fxam_0 = "D9E5",
1140
+ -- D9E6: unassigned
1141
+ -- D9E7: unassigned
1142
+ fld1_0 = "D9E8",
1143
+ fldl2t_0 = "D9E9",
1144
+ fldl2e_0 = "D9EA",
1145
+ fldpi_0 = "D9EB",
1146
+ fldlg2_0 = "D9EC",
1147
+ fldln2_0 = "D9ED",
1148
+ fldz_0 = "D9EE",
1149
+ -- D9EF: unassigned
1150
+
1151
+ f2xm1_0 = "D9F0",
1152
+ fyl2x_0 = "D9F1",
1153
+ fptan_0 = "D9F2",
1154
+ fpatan_0 = "D9F3",
1155
+ fxtract_0 = "D9F4",
1156
+ fprem1_0 = "D9F5",
1157
+ fdecstp_0 = "D9F6",
1158
+ fincstp_0 = "D9F7",
1159
+ fprem_0 = "D9F8",
1160
+ fyl2xp1_0 = "D9F9",
1161
+ fsqrt_0 = "D9FA",
1162
+ fsincos_0 = "D9FB",
1163
+ frndint_0 = "D9FC",
1164
+ fscale_0 = "D9FD",
1165
+ fsin_0 = "D9FE",
1166
+ fcos_0 = "D9FF",
1167
+
1168
+ -- SSE, SSE2
1169
+ andnpd_2 = "rmo:660F55rM",
1170
+ andnps_2 = "rmo:0F55rM",
1171
+ andpd_2 = "rmo:660F54rM",
1172
+ andps_2 = "rmo:0F54rM",
1173
+ clflush_1 = "x.:0FAE7m",
1174
+ cmppd_3 = "rmio:660FC2rMU",
1175
+ cmpps_3 = "rmio:0FC2rMU",
1176
+ cmpsd_3 = "rrio:F20FC2rMU|rxi/oq:",
1177
+ cmpss_3 = "rrio:F30FC2rMU|rxi/od:",
1178
+ comisd_2 = "rro:660F2FrM|rx/oq:",
1179
+ comiss_2 = "rro:0F2FrM|rx/od:",
1180
+ cvtdq2pd_2 = "rro:F30FE6rM|rx/oq:",
1181
+ cvtdq2ps_2 = "rmo:0F5BrM",
1182
+ cvtpd2dq_2 = "rmo:F20FE6rM",
1183
+ cvtpd2ps_2 = "rmo:660F5ArM",
1184
+ cvtpi2pd_2 = "rx/oq:660F2ArM",
1185
+ cvtpi2ps_2 = "rx/oq:0F2ArM",
1186
+ cvtps2dq_2 = "rmo:660F5BrM",
1187
+ cvtps2pd_2 = "rro:0F5ArM|rx/oq:",
1188
+ cvtsd2si_2 = "rr/do:F20F2DrM|rr/qo:|rx/dq:|rxq:",
1189
+ cvtsd2ss_2 = "rro:F20F5ArM|rx/oq:",
1190
+ cvtsi2sd_2 = "rm/od:F20F2ArM|rm/oq:F20F2ArXM",
1191
+ cvtsi2ss_2 = "rm/od:F30F2ArM|rm/oq:F30F2ArXM",
1192
+ cvtss2sd_2 = "rro:F30F5ArM|rx/od:",
1193
+ cvtss2si_2 = "rr/do:F20F2CrM|rr/qo:|rxd:|rx/qd:",
1194
+ cvttpd2dq_2 = "rmo:660FE6rM",
1195
+ cvttps2dq_2 = "rmo:F30F5BrM",
1196
+ cvttsd2si_2 = "rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:",
1197
+ cvttss2si_2 = "rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:",
1198
+ fxsave_1 = "x.:0FAE0m",
1199
+ fxrstor_1 = "x.:0FAE1m",
1200
+ ldmxcsr_1 = "xd:0FAE2m",
1201
+ lfence_0 = "0FAEE8",
1202
+ maskmovdqu_2 = "rro:660FF7rM",
1203
+ mfence_0 = "0FAEF0",
1204
+ movapd_2 = "rmo:660F28rM|mro:660F29Rm",
1205
+ movaps_2 = "rmo:0F28rM|mro:0F29Rm",
1206
+ movd_2 = "rm/od:660F6ErM|rm/oq:660F6ErXM|mr/do:660F7ERm|mr/qo:",
1207
+ movdqa_2 = "rmo:660F6FrM|mro:660F7FRm",
1208
+ movdqu_2 = "rmo:F30F6FrM|mro:F30F7FRm",
1209
+ movhlps_2 = "rro:0F12rM",
1210
+ movhpd_2 = "rx/oq:660F16rM|xr/qo:n660F17Rm",
1211
+ movhps_2 = "rx/oq:0F16rM|xr/qo:n0F17Rm",
1212
+ movlhps_2 = "rro:0F16rM",
1213
+ movlpd_2 = "rx/oq:660F12rM|xr/qo:n660F13Rm",
1214
+ movlps_2 = "rx/oq:0F12rM|xr/qo:n0F13Rm",
1215
+ movmskpd_2 = "rr/do:660F50rM",
1216
+ movmskps_2 = "rr/do:0F50rM",
1217
+ movntdq_2 = "xro:660FE7Rm",
1218
+ movnti_2 = "xrqd:0FC3Rm",
1219
+ movntpd_2 = "xro:660F2BRm",
1220
+ movntps_2 = "xro:0F2BRm",
1221
+ movq_2 = "rro:F30F7ErM|rx/oq:|xr/qo:n660FD6Rm",
1222
+ movsd_2 = "rro:F20F10rM|rx/oq:|xr/qo:nF20F11Rm",
1223
+ movss_2 = "rro:F30F10rM|rx/od:|xr/do:F30F11Rm",
1224
+ movupd_2 = "rmo:660F10rM|mro:660F11Rm",
1225
+ movups_2 = "rmo:0F10rM|mro:0F11Rm",
1226
+ orpd_2 = "rmo:660F56rM",
1227
+ orps_2 = "rmo:0F56rM",
1228
+ packssdw_2 = "rmo:660F6BrM",
1229
+ packsswb_2 = "rmo:660F63rM",
1230
+ packuswb_2 = "rmo:660F67rM",
1231
+ paddb_2 = "rmo:660FFCrM",
1232
+ paddd_2 = "rmo:660FFErM",
1233
+ paddq_2 = "rmo:660FD4rM",
1234
+ paddsb_2 = "rmo:660FECrM",
1235
+ paddsw_2 = "rmo:660FEDrM",
1236
+ paddusb_2 = "rmo:660FDCrM",
1237
+ paddusw_2 = "rmo:660FDDrM",
1238
+ paddw_2 = "rmo:660FFDrM",
1239
+ pand_2 = "rmo:660FDBrM",
1240
+ pandn_2 = "rmo:660FDFrM",
1241
+ pause_0 = "F390",
1242
+ pavgb_2 = "rmo:660FE0rM",
1243
+ pavgw_2 = "rmo:660FE3rM",
1244
+ pcmpeqb_2 = "rmo:660F74rM",
1245
+ pcmpeqd_2 = "rmo:660F76rM",
1246
+ pcmpeqw_2 = "rmo:660F75rM",
1247
+ pcmpgtb_2 = "rmo:660F64rM",
1248
+ pcmpgtd_2 = "rmo:660F66rM",
1249
+ pcmpgtw_2 = "rmo:660F65rM",
1250
+ pextrw_3 = "rri/do:660FC5rMU|xri/wo:660F3A15nrMU", -- Mem op: SSE4.1 only.
1251
+ pinsrw_3 = "rri/od:660FC4rMU|rxi/ow:",
1252
+ pmaddwd_2 = "rmo:660FF5rM",
1253
+ pmaxsw_2 = "rmo:660FEErM",
1254
+ pmaxub_2 = "rmo:660FDErM",
1255
+ pminsw_2 = "rmo:660FEArM",
1256
+ pminub_2 = "rmo:660FDArM",
1257
+ pmovmskb_2 = "rr/do:660FD7rM",
1258
+ pmulhuw_2 = "rmo:660FE4rM",
1259
+ pmulhw_2 = "rmo:660FE5rM",
1260
+ pmullw_2 = "rmo:660FD5rM",
1261
+ pmuludq_2 = "rmo:660FF4rM",
1262
+ por_2 = "rmo:660FEBrM",
1263
+ prefetchnta_1 = "xb:n0F180m",
1264
+ prefetcht0_1 = "xb:n0F181m",
1265
+ prefetcht1_1 = "xb:n0F182m",
1266
+ prefetcht2_1 = "xb:n0F183m",
1267
+ psadbw_2 = "rmo:660FF6rM",
1268
+ pshufd_3 = "rmio:660F70rMU",
1269
+ pshufhw_3 = "rmio:F30F70rMU",
1270
+ pshuflw_3 = "rmio:F20F70rMU",
1271
+ pslld_2 = "rmo:660FF2rM|rio:660F726mU",
1272
+ pslldq_2 = "rio:660F737mU",
1273
+ psllq_2 = "rmo:660FF3rM|rio:660F736mU",
1274
+ psllw_2 = "rmo:660FF1rM|rio:660F716mU",
1275
+ psrad_2 = "rmo:660FE2rM|rio:660F724mU",
1276
+ psraw_2 = "rmo:660FE1rM|rio:660F714mU",
1277
+ psrld_2 = "rmo:660FD2rM|rio:660F722mU",
1278
+ psrldq_2 = "rio:660F733mU",
1279
+ psrlq_2 = "rmo:660FD3rM|rio:660F732mU",
1280
+ psrlw_2 = "rmo:660FD1rM|rio:660F712mU",
1281
+ psubb_2 = "rmo:660FF8rM",
1282
+ psubd_2 = "rmo:660FFArM",
1283
+ psubq_2 = "rmo:660FFBrM",
1284
+ psubsb_2 = "rmo:660FE8rM",
1285
+ psubsw_2 = "rmo:660FE9rM",
1286
+ psubusb_2 = "rmo:660FD8rM",
1287
+ psubusw_2 = "rmo:660FD9rM",
1288
+ psubw_2 = "rmo:660FF9rM",
1289
+ punpckhbw_2 = "rmo:660F68rM",
1290
+ punpckhdq_2 = "rmo:660F6ArM",
1291
+ punpckhqdq_2 = "rmo:660F6DrM",
1292
+ punpckhwd_2 = "rmo:660F69rM",
1293
+ punpcklbw_2 = "rmo:660F60rM",
1294
+ punpckldq_2 = "rmo:660F62rM",
1295
+ punpcklqdq_2 = "rmo:660F6CrM",
1296
+ punpcklwd_2 = "rmo:660F61rM",
1297
+ pxor_2 = "rmo:660FEFrM",
1298
+ rcpps_2 = "rmo:0F53rM",
1299
+ rcpss_2 = "rro:F30F53rM|rx/od:",
1300
+ rsqrtps_2 = "rmo:0F52rM",
1301
+ rsqrtss_2 = "rmo:F30F52rM",
1302
+ sfence_0 = "0FAEF8",
1303
+ shufpd_3 = "rmio:660FC6rMU",
1304
+ shufps_3 = "rmio:0FC6rMU",
1305
+ stmxcsr_1 = "xd:0FAE3m",
1306
+ ucomisd_2 = "rro:660F2ErM|rx/oq:",
1307
+ ucomiss_2 = "rro:0F2ErM|rx/od:",
1308
+ unpckhpd_2 = "rmo:660F15rM",
1309
+ unpckhps_2 = "rmo:0F15rM",
1310
+ unpcklpd_2 = "rmo:660F14rM",
1311
+ unpcklps_2 = "rmo:0F14rM",
1312
+ xorpd_2 = "rmo:660F57rM",
1313
+ xorps_2 = "rmo:0F57rM",
1314
+
1315
+ -- SSE3 ops
1316
+ fisttp_1 = "xw:nDF1m|xd:DB1m|xq:nDD1m",
1317
+ addsubpd_2 = "rmo:660FD0rM",
1318
+ addsubps_2 = "rmo:F20FD0rM",
1319
+ haddpd_2 = "rmo:660F7CrM",
1320
+ haddps_2 = "rmo:F20F7CrM",
1321
+ hsubpd_2 = "rmo:660F7DrM",
1322
+ hsubps_2 = "rmo:F20F7DrM",
1323
+ lddqu_2 = "rxo:F20FF0rM",
1324
+ movddup_2 = "rmo:F20F12rM",
1325
+ movshdup_2 = "rmo:F30F16rM",
1326
+ movsldup_2 = "rmo:F30F12rM",
1327
+
1328
+ -- SSSE3 ops
1329
+ pabsb_2 = "rmo:660F381CrM",
1330
+ pabsd_2 = "rmo:660F381ErM",
1331
+ pabsw_2 = "rmo:660F381DrM",
1332
+ palignr_3 = "rmio:660F3A0FrMU",
1333
+ phaddd_2 = "rmo:660F3802rM",
1334
+ phaddsw_2 = "rmo:660F3803rM",
1335
+ phaddw_2 = "rmo:660F3801rM",
1336
+ phsubd_2 = "rmo:660F3806rM",
1337
+ phsubsw_2 = "rmo:660F3807rM",
1338
+ phsubw_2 = "rmo:660F3805rM",
1339
+ pmaddubsw_2 = "rmo:660F3804rM",
1340
+ pmulhrsw_2 = "rmo:660F380BrM",
1341
+ pshufb_2 = "rmo:660F3800rM",
1342
+ psignb_2 = "rmo:660F3808rM",
1343
+ psignd_2 = "rmo:660F380ArM",
1344
+ psignw_2 = "rmo:660F3809rM",
1345
+
1346
+ -- SSE4.1 ops
1347
+ blendpd_3 = "rmio:660F3A0DrMU",
1348
+ blendps_3 = "rmio:660F3A0CrMU",
1349
+ blendvpd_3 = "rmRo:660F3815rM",
1350
+ blendvps_3 = "rmRo:660F3814rM",
1351
+ dppd_3 = "rmio:660F3A41rMU",
1352
+ dpps_3 = "rmio:660F3A40rMU",
1353
+ extractps_3 = "mri/do:660F3A17RmU|rri/qo:660F3A17RXmU",
1354
+ insertps_3 = "rrio:660F3A41rMU|rxi/od:",
1355
+ movntdqa_2 = "rmo:660F382ArM",
1356
+ mpsadbw_3 = "rmio:660F3A42rMU",
1357
+ packusdw_2 = "rmo:660F382BrM",
1358
+ pblendvb_3 = "rmRo:660F3810rM",
1359
+ pblendw_3 = "rmio:660F3A0ErMU",
1360
+ pcmpeqq_2 = "rmo:660F3829rM",
1361
+ pextrb_3 = "rri/do:660F3A14nRmU|rri/qo:|xri/bo:",
1362
+ pextrd_3 = "mri/do:660F3A16RmU",
1363
+ pextrq_3 = "mri/qo:660F3A16RmU",
1364
+ -- pextrw is SSE2, mem operand is SSE4.1 only
1365
+ phminposuw_2 = "rmo:660F3841rM",
1366
+ pinsrb_3 = "rri/od:660F3A20nrMU|rxi/ob:",
1367
+ pinsrd_3 = "rmi/od:660F3A22rMU",
1368
+ pinsrq_3 = "rmi/oq:660F3A22rXMU",
1369
+ pmaxsb_2 = "rmo:660F383CrM",
1370
+ pmaxsd_2 = "rmo:660F383DrM",
1371
+ pmaxud_2 = "rmo:660F383FrM",
1372
+ pmaxuw_2 = "rmo:660F383ErM",
1373
+ pminsb_2 = "rmo:660F3838rM",
1374
+ pminsd_2 = "rmo:660F3839rM",
1375
+ pminud_2 = "rmo:660F383BrM",
1376
+ pminuw_2 = "rmo:660F383ArM",
1377
+ pmovsxbd_2 = "rro:660F3821rM|rx/od:",
1378
+ pmovsxbq_2 = "rro:660F3822rM|rx/ow:",
1379
+ pmovsxbw_2 = "rro:660F3820rM|rx/oq:",
1380
+ pmovsxdq_2 = "rro:660F3825rM|rx/oq:",
1381
+ pmovsxwd_2 = "rro:660F3823rM|rx/oq:",
1382
+ pmovsxwq_2 = "rro:660F3824rM|rx/od:",
1383
+ pmovzxbd_2 = "rro:660F3831rM|rx/od:",
1384
+ pmovzxbq_2 = "rro:660F3832rM|rx/ow:",
1385
+ pmovzxbw_2 = "rro:660F3830rM|rx/oq:",
1386
+ pmovzxdq_2 = "rro:660F3835rM|rx/oq:",
1387
+ pmovzxwd_2 = "rro:660F3833rM|rx/oq:",
1388
+ pmovzxwq_2 = "rro:660F3834rM|rx/od:",
1389
+ pmuldq_2 = "rmo:660F3828rM",
1390
+ pmulld_2 = "rmo:660F3840rM",
1391
+ ptest_2 = "rmo:660F3817rM",
1392
+ roundpd_3 = "rmio:660F3A09rMU",
1393
+ roundps_3 = "rmio:660F3A08rMU",
1394
+ roundsd_3 = "rrio:660F3A0BrMU|rxi/oq:",
1395
+ roundss_3 = "rrio:660F3A0ArMU|rxi/od:",
1396
+
1397
+ -- SSE4.2 ops
1398
+ crc32_2 = "rmqd:F20F38F1rM|rm/dw:66F20F38F1rM|rm/db:F20F38F0rM|rm/qb:",
1399
+ pcmpestri_3 = "rmio:660F3A61rMU",
1400
+ pcmpestrm_3 = "rmio:660F3A60rMU",
1401
+ pcmpgtq_2 = "rmo:660F3837rM",
1402
+ pcmpistri_3 = "rmio:660F3A63rMU",
1403
+ pcmpistrm_3 = "rmio:660F3A62rMU",
1404
+ popcnt_2 = "rmqdw:F30FB8rM",
1405
+
1406
+ -- SSE4a
1407
+ extrq_2 = "rro:660F79rM",
1408
+ extrq_3 = "riio:660F780mUU",
1409
+ insertq_2 = "rro:F20F79rM",
1410
+ insertq_4 = "rriio:F20F78rMUU",
1411
+ lzcnt_2 = "rmqdw:F30FBDrM",
1412
+ movntsd_2 = "xr/qo:nF20F2BRm",
1413
+ movntss_2 = "xr/do:F30F2BRm",
1414
+ -- popcnt is also in SSE4.2
1415
+ }
1416
+
1417
+ ------------------------------------------------------------------------------
1418
+
1419
+ -- Arithmetic ops.
1420
+ for name,n in pairs{ add = 0, ["or"] = 1, adc = 2, sbb = 3,
1421
+ ["and"] = 4, sub = 5, xor = 6, cmp = 7 } do
1422
+ local n8 = shl(n, 3)
1423
+ map_op[name.."_2"] = format(
1424
+ "mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi",
1425
+ 1+n8, 3+n8, n, n, 5+n8, n)
1426
+ end
1427
+
1428
+ -- Shift ops.
1429
+ for name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,
1430
+ shl = 4, shr = 5, sar = 7, sal = 4 } do
1431
+ map_op[name.."_2"] = format("m1:D1%Xm|mC1qdwb:D3%Xm|mi:C1%XmU", n, n, n)
1432
+ end
1433
+
1434
+ -- Conditional ops.
1435
+ for cc,n in pairs(map_cc) do
1436
+ map_op["j"..cc.."_1"] = format("J.:n0F8%XJ", n) -- short: 7%X
1437
+ map_op["set"..cc.."_1"] = format("mb:n0F9%X2m", n)
1438
+ map_op["cmov"..cc.."_2"] = format("rmqdw:0F4%XrM", n) -- P6+
1439
+ end
1440
+
1441
+ -- FP arithmetic ops.
1442
+ for name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,
1443
+ sub = 4, subr = 5, div = 6, divr = 7 } do
1444
+ local nc = 0xc0 + shl(n, 3)
1445
+ local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))
1446
+ local fn = "f"..name
1447
+ map_op[fn.."_1"] = format("ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm", nc, n, n)
1448
+ if n == 2 or n == 3 then
1449
+ map_op[fn.."_2"] = format("Fff:D8%02XR|Fx2d:D8%XM|Fx2q:nDC%XM", nc, n, n)
1450
+ else
1451
+ map_op[fn.."_2"] = format("Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:nDC%XM", nc, nr, n, n)
1452
+ map_op[fn.."p_1"] = format("ff:DE%02Xr", nr)
1453
+ map_op[fn.."p_2"] = format("fFf:DE%02Xr", nr)
1454
+ end
1455
+ map_op["fi"..name.."_1"] = format("xd:DA%Xm|xw:nDE%Xm", n, n)
1456
+ end
1457
+
1458
+ -- FP conditional moves.
1459
+ for cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do
1460
+ local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)
1461
+ map_op["fcmov"..cc.."_1"] = format("ff:%04Xr", nc) -- P6+
1462
+ map_op["fcmov"..cc.."_2"] = format("Fff:%04XR", nc) -- P6+
1463
+ end
1464
+
1465
+ -- SSE FP arithmetic ops.
1466
+ for name,n in pairs{ sqrt = 1, add = 8, mul = 9,
1467
+ sub = 12, min = 13, div = 14, max = 15 } do
1468
+ map_op[name.."ps_2"] = format("rmo:0F5%XrM", n)
1469
+ map_op[name.."ss_2"] = format("rro:F30F5%XrM|rx/od:", n)
1470
+ map_op[name.."pd_2"] = format("rmo:660F5%XrM", n)
1471
+ map_op[name.."sd_2"] = format("rro:F20F5%XrM|rx/oq:", n)
1472
+ end
1473
+
1474
+ ------------------------------------------------------------------------------
1475
+
1476
+ -- Process pattern string.
1477
+ local function dopattern(pat, args, sz, op, needrex)
1478
+ local digit, addin
1479
+ local opcode = 0
1480
+ local szov = sz
1481
+ local narg = 1
1482
+ local rex = 0
1483
+
1484
+ -- Limit number of section buffer positions used by a single dasm_put().
1485
+ -- A single opcode needs a maximum of 5 positions.
1486
+ if secpos+5 > maxsecpos then wflush() end
1487
+
1488
+ -- Process each character.
1489
+ for c in gmatch(pat.."|", ".") do
1490
+ if match(c, "%x") then -- Hex digit.
1491
+ digit = byte(c) - 48
1492
+ if digit > 48 then digit = digit - 39
1493
+ elseif digit > 16 then digit = digit - 7 end
1494
+ opcode = opcode*16 + digit
1495
+ addin = nil
1496
+ elseif c == "n" then -- Disable operand size mods for opcode.
1497
+ szov = nil
1498
+ elseif c == "X" then -- Force REX.W.
1499
+ rex = 8
1500
+ elseif c == "r" then -- Merge 1st operand regno. into opcode.
1501
+ addin = args[1]; opcode = opcode + (addin.reg % 8)
1502
+ if narg < 2 then narg = 2 end
1503
+ elseif c == "R" then -- Merge 2nd operand regno. into opcode.
1504
+ addin = args[2]; opcode = opcode + (addin.reg % 8)
1505
+ narg = 3
1506
+ elseif c == "m" or c == "M" then -- Encode ModRM/SIB.
1507
+ local s
1508
+ if addin then
1509
+ s = addin.reg
1510
+ opcode = opcode - band(s, 7) -- Undo regno opcode merge.
1511
+ else
1512
+ s = band(opcode, 15) -- Undo last digit.
1513
+ opcode = shr(opcode, 4)
1514
+ end
1515
+ local nn = c == "m" and 1 or 2
1516
+ local t = args[nn]
1517
+ if narg <= nn then narg = nn + 1 end
1518
+ if szov == "q" and rex == 0 then rex = rex + 8 end
1519
+ if t.reg and t.reg > 7 then rex = rex + 1 end
1520
+ if t.xreg and t.xreg > 7 then rex = rex + 2 end
1521
+ if s > 7 then rex = rex + 4 end
1522
+ if needrex then rex = rex + 16 end
1523
+ wputop(szov, opcode, rex); opcode = nil
1524
+ local imark = sub(pat, -1) -- Force a mark (ugly).
1525
+ -- Put ModRM/SIB with regno/last digit as spare.
1526
+ wputmrmsib(t, imark, s, addin and addin.vreg)
1527
+ addin = nil
1528
+ else
1529
+ if opcode then -- Flush opcode.
1530
+ if szov == "q" and rex == 0 then rex = rex + 8 end
1531
+ if needrex then rex = rex + 16 end
1532
+ if addin and addin.reg == -1 then
1533
+ wputop(szov, opcode - 7, rex)
1534
+ waction("VREG", addin.vreg); wputxb(0)
1535
+ else
1536
+ if addin and addin.reg > 7 then rex = rex + 1 end
1537
+ wputop(szov, opcode, rex)
1538
+ end
1539
+ opcode = nil
1540
+ end
1541
+ if c == "|" then break end
1542
+ if c == "o" then -- Offset (pure 32 bit displacement).
1543
+ wputdarg(args[1].disp); if narg < 2 then narg = 2 end
1544
+ elseif c == "O" then
1545
+ wputdarg(args[2].disp); narg = 3
1546
+ else
1547
+ -- Anything else is an immediate operand.
1548
+ local a = args[narg]
1549
+ narg = narg + 1
1550
+ local mode, imm = a.mode, a.imm
1551
+ if mode == "iJ" and not match("iIJ", c) then
1552
+ werror("bad operand size for label")
1553
+ end
1554
+ if c == "S" then
1555
+ wputsbarg(imm)
1556
+ elseif c == "U" then
1557
+ wputbarg(imm)
1558
+ elseif c == "W" then
1559
+ wputwarg(imm)
1560
+ elseif c == "i" or c == "I" then
1561
+ if mode == "iJ" then
1562
+ wputlabel("IMM_", imm, 1)
1563
+ elseif mode == "iI" and c == "I" then
1564
+ waction(sz == "w" and "IMM_WB" or "IMM_DB", imm)
1565
+ else
1566
+ wputszarg(sz, imm)
1567
+ end
1568
+ elseif c == "J" then
1569
+ if mode == "iPJ" then
1570
+ waction("REL_A", imm) -- !x64 (secpos)
1571
+ else
1572
+ wputlabel("REL_", imm, 2)
1573
+ end
1574
+ else
1575
+ werror("bad char `"..c.."' in pattern `"..pat.."' for `"..op.."'")
1576
+ end
1577
+ end
1578
+ end
1579
+ end
1580
+ end
1581
+
1582
+ ------------------------------------------------------------------------------
1583
+
1584
+ -- Mapping of operand modes to short names. Suppress output with '#'.
1585
+ local map_modename = {
1586
+ r = "reg", R = "eax", C = "cl", x = "mem", m = "mrm", i = "imm",
1587
+ f = "stx", F = "st0", J = "lbl", ["1"] = "1",
1588
+ I = "#", S = "#", O = "#",
1589
+ }
1590
+
1591
+ -- Return a table/string showing all possible operand modes.
1592
+ local function templatehelp(template, nparams)
1593
+ if nparams == 0 then return "" end
1594
+ local t = {}
1595
+ for tm in gmatch(template, "[^%|]+") do
1596
+ local s = map_modename[sub(tm, 1, 1)]
1597
+ s = s..gsub(sub(tm, 2, nparams), ".", function(c)
1598
+ return ", "..map_modename[c]
1599
+ end)
1600
+ if not match(s, "#") then t[#t+1] = s end
1601
+ end
1602
+ return t
1603
+ end
1604
+
1605
+ -- Match operand modes against mode match part of template.
1606
+ local function matchtm(tm, args)
1607
+ for i=1,#args do
1608
+ if not match(args[i].mode, sub(tm, i, i)) then return end
1609
+ end
1610
+ return true
1611
+ end
1612
+
1613
+ -- Handle opcodes defined with template strings.
1614
+ map_op[".template__"] = function(params, template, nparams)
1615
+ if not params then return templatehelp(template, nparams) end
1616
+ local args = {}
1617
+
1618
+ -- Zero-operand opcodes have no match part.
1619
+ if #params == 0 then
1620
+ dopattern(template, args, "d", params.op, nil)
1621
+ return
1622
+ end
1623
+
1624
+ -- Determine common operand size (coerce undefined size) or flag as mixed.
1625
+ local sz, szmix, needrex
1626
+ for i,p in ipairs(params) do
1627
+ args[i] = parseoperand(p)
1628
+ local nsz = args[i].opsize
1629
+ if nsz then
1630
+ if sz and sz ~= nsz then szmix = true else sz = nsz end
1631
+ end
1632
+ local nrex = args[i].needrex
1633
+ if nrex ~= nil then
1634
+ if needrex == nil then
1635
+ needrex = nrex
1636
+ elseif needrex ~= nrex then
1637
+ werror("bad mix of byte-addressable registers")
1638
+ end
1639
+ end
1640
+ end
1641
+
1642
+ -- Try all match:pattern pairs (separated by '|').
1643
+ local gotmatch, lastpat
1644
+ for tm in gmatch(template, "[^%|]+") do
1645
+ -- Split off size match (starts after mode match) and pattern string.
1646
+ local szm, pat = match(tm, "^(.-):(.*)$", #args+1)
1647
+ if pat == "" then pat = lastpat else lastpat = pat end
1648
+ if matchtm(tm, args) then
1649
+ local prefix = sub(szm, 1, 1)
1650
+ if prefix == "/" then -- Match both operand sizes.
1651
+ if args[1].opsize == sub(szm, 2, 2) and
1652
+ args[2].opsize == sub(szm, 3, 3) then
1653
+ dopattern(pat, args, sz, params.op, needrex) -- Process pattern.
1654
+ return
1655
+ end
1656
+ else -- Match common operand size.
1657
+ local szp = sz
1658
+ if szm == "" then szm = x64 and "qdwb" or "dwb" end -- Default sizes.
1659
+ if prefix == "1" then szp = args[1].opsize; szmix = nil
1660
+ elseif prefix == "2" then szp = args[2].opsize; szmix = nil end
1661
+ if not szmix and (prefix == "." or match(szm, szp or "#")) then
1662
+ dopattern(pat, args, szp, params.op, needrex) -- Process pattern.
1663
+ return
1664
+ end
1665
+ end
1666
+ gotmatch = true
1667
+ end
1668
+ end
1669
+
1670
+ local msg = "bad operand mode"
1671
+ if gotmatch then
1672
+ if szmix then
1673
+ msg = "mixed operand size"
1674
+ else
1675
+ msg = sz and "bad operand size" or "missing operand size"
1676
+ end
1677
+ end
1678
+
1679
+ werror(msg.." in `"..opmodestr(params.op, args).."'")
1680
+ end
1681
+
1682
+ ------------------------------------------------------------------------------
1683
+
1684
+ -- x64-specific opcode for 64 bit immediates and displacements.
1685
+ if x64 then
1686
+ function map_op.mov64_2(params)
1687
+ if not params then return { "reg, imm", "reg, [disp]", "[disp], reg" } end
1688
+ if secpos+2 > maxsecpos then wflush() end
1689
+ local opcode, op64, sz, rex, vreg
1690
+ local op64 = match(params[1], "^%[%s*(.-)%s*%]$")
1691
+ if op64 then
1692
+ local a = parseoperand(params[2])
1693
+ if a.mode ~= "rmR" then werror("bad operand mode") end
1694
+ sz = a.opsize
1695
+ rex = sz == "q" and 8 or 0
1696
+ opcode = 0xa3
1697
+ else
1698
+ op64 = match(params[2], "^%[%s*(.-)%s*%]$")
1699
+ local a = parseoperand(params[1])
1700
+ if op64 then
1701
+ if a.mode ~= "rmR" then werror("bad operand mode") end
1702
+ sz = a.opsize
1703
+ rex = sz == "q" and 8 or 0
1704
+ opcode = 0xa1
1705
+ else
1706
+ if sub(a.mode, 1, 1) ~= "r" or a.opsize ~= "q" then
1707
+ werror("bad operand mode")
1708
+ end
1709
+ op64 = params[2]
1710
+ if a.reg == -1 then
1711
+ vreg = a.vreg
1712
+ opcode = 0xb8
1713
+ else
1714
+ opcode = 0xb8 + band(a.reg, 7)
1715
+ end
1716
+ rex = a.reg > 7 and 9 or 8
1717
+ end
1718
+ end
1719
+ wputop(sz, opcode, rex)
1720
+ if vreg then waction("VREG", vreg); wputxb(0) end
1721
+ waction("IMM_D", format("(unsigned int)(%s)", op64))
1722
+ waction("IMM_D", format("(unsigned int)((%s)>>32)", op64))
1723
+ end
1724
+ end
1725
+
1726
+ ------------------------------------------------------------------------------
1727
+
1728
+ -- Pseudo-opcodes for data storage.
1729
+ local function op_data(params)
1730
+ if not params then return "imm..." end
1731
+ local sz = sub(params.op, 2, 2)
1732
+ if sz == "a" then sz = addrsize end
1733
+ for _,p in ipairs(params) do
1734
+ local a = parseoperand(p)
1735
+ if sub(a.mode, 1, 1) ~= "i" or (a.opsize and a.opsize ~= sz) then
1736
+ werror("bad mode or size in `"..p.."'")
1737
+ end
1738
+ if a.mode == "iJ" then
1739
+ wputlabel("IMM_", a.imm, 1)
1740
+ else
1741
+ wputszarg(sz, a.imm)
1742
+ end
1743
+ if secpos+2 > maxsecpos then wflush() end
1744
+ end
1745
+ end
1746
+
1747
+ map_op[".byte_*"] = op_data
1748
+ map_op[".sbyte_*"] = op_data
1749
+ map_op[".word_*"] = op_data
1750
+ map_op[".dword_*"] = op_data
1751
+ map_op[".aword_*"] = op_data
1752
+
1753
+ ------------------------------------------------------------------------------
1754
+
1755
+ -- Pseudo-opcode to mark the position where the action list is to be emitted.
1756
+ map_op[".actionlist_1"] = function(params)
1757
+ if not params then return "cvar" end
1758
+ local name = params[1] -- No syntax check. You get to keep the pieces.
1759
+ wline(function(out) writeactions(out, name) end)
1760
+ end
1761
+
1762
+ -- Pseudo-opcode to mark the position where the global enum is to be emitted.
1763
+ map_op[".globals_1"] = function(params)
1764
+ if not params then return "prefix" end
1765
+ local prefix = params[1] -- No syntax check. You get to keep the pieces.
1766
+ wline(function(out) writeglobals(out, prefix) end)
1767
+ end
1768
+
1769
+ -- Pseudo-opcode to mark the position where the global names are to be emitted.
1770
+ map_op[".globalnames_1"] = function(params)
1771
+ if not params then return "cvar" end
1772
+ local name = params[1] -- No syntax check. You get to keep the pieces.
1773
+ wline(function(out) writeglobalnames(out, name) end)
1774
+ end
1775
+
1776
+ -- Pseudo-opcode to mark the position where the extern names are to be emitted.
1777
+ map_op[".externnames_1"] = function(params)
1778
+ if not params then return "cvar" end
1779
+ local name = params[1] -- No syntax check. You get to keep the pieces.
1780
+ wline(function(out) writeexternnames(out, name) end)
1781
+ end
1782
+
1783
+ ------------------------------------------------------------------------------
1784
+
1785
+ -- Label pseudo-opcode (converted from trailing colon form).
1786
+ map_op[".label_2"] = function(params)
1787
+ if not params then return "[1-9] | ->global | =>pcexpr [, addr]" end
1788
+ if secpos+2 > maxsecpos then wflush() end
1789
+ local a = parseoperand(params[1])
1790
+ local mode, imm = a.mode, a.imm
1791
+ if type(imm) == "number" and (mode == "iJ" or (imm >= 1 and imm <= 9)) then
1792
+ -- Local label (1: ... 9:) or global label (->global:).
1793
+ waction("LABEL_LG", nil, 1)
1794
+ wputxb(imm)
1795
+ elseif mode == "iJ" then
1796
+ -- PC label (=>pcexpr:).
1797
+ waction("LABEL_PC", imm)
1798
+ else
1799
+ werror("bad label definition")
1800
+ end
1801
+ -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.
1802
+ local addr = params[2]
1803
+ if addr then
1804
+ local a = parseoperand(addr)
1805
+ if a.mode == "iPJ" then
1806
+ waction("SETLABEL", a.imm)
1807
+ else
1808
+ werror("bad label assignment")
1809
+ end
1810
+ end
1811
+ end
1812
+ map_op[".label_1"] = map_op[".label_2"]
1813
+
1814
+ ------------------------------------------------------------------------------
1815
+
1816
+ -- Alignment pseudo-opcode.
1817
+ map_op[".align_1"] = function(params)
1818
+ if not params then return "numpow2" end
1819
+ if secpos+1 > maxsecpos then wflush() end
1820
+ local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]
1821
+ if align then
1822
+ local x = align
1823
+ -- Must be a power of 2 in the range (2 ... 256).
1824
+ for i=1,8 do
1825
+ x = x / 2
1826
+ if x == 1 then
1827
+ waction("ALIGN", nil, 1)
1828
+ wputxb(align-1) -- Action byte is 2**n-1.
1829
+ return
1830
+ end
1831
+ end
1832
+ end
1833
+ werror("bad alignment")
1834
+ end
1835
+
1836
+ -- Spacing pseudo-opcode.
1837
+ map_op[".space_2"] = function(params)
1838
+ if not params then return "num [, filler]" end
1839
+ if secpos+1 > maxsecpos then wflush() end
1840
+ waction("SPACE", params[1])
1841
+ local fill = params[2]
1842
+ if fill then
1843
+ fill = tonumber(fill)
1844
+ if not fill or fill < 0 or fill > 255 then werror("bad filler") end
1845
+ end
1846
+ wputxb(fill or 0)
1847
+ end
1848
+ map_op[".space_1"] = map_op[".space_2"]
1849
+
1850
+ ------------------------------------------------------------------------------
1851
+
1852
+ -- Pseudo-opcode for (primitive) type definitions (map to C types).
1853
+ map_op[".type_3"] = function(params, nparams)
1854
+ if not params then
1855
+ return nparams == 2 and "name, ctype" or "name, ctype, reg"
1856
+ end
1857
+ local name, ctype, reg = params[1], params[2], params[3]
1858
+ if not match(name, "^[%a_][%w_]*$") then
1859
+ werror("bad type name `"..name.."'")
1860
+ end
1861
+ local tp = map_type[name]
1862
+ if tp then
1863
+ werror("duplicate type `"..name.."'")
1864
+ end
1865
+ if reg and not map_reg_valid_base[reg] then
1866
+ werror("bad base register `"..(map_reg_rev[reg] or reg).."'")
1867
+ end
1868
+ -- Add #type to defines. A bit unclean to put it in map_archdef.
1869
+ map_archdef["#"..name] = "sizeof("..ctype..")"
1870
+ -- Add new type and emit shortcut define.
1871
+ local num = ctypenum + 1
1872
+ map_type[name] = {
1873
+ ctype = ctype,
1874
+ ctypefmt = format("Dt%X(%%s)", num),
1875
+ reg = reg,
1876
+ }
1877
+ wline(format("#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)", num, ctype))
1878
+ ctypenum = num
1879
+ end
1880
+ map_op[".type_2"] = map_op[".type_3"]
1881
+
1882
+ -- Dump type definitions.
1883
+ local function dumptypes(out, lvl)
1884
+ local t = {}
1885
+ for name in pairs(map_type) do t[#t+1] = name end
1886
+ sort(t)
1887
+ out:write("Type definitions:\n")
1888
+ for _,name in ipairs(t) do
1889
+ local tp = map_type[name]
1890
+ local reg = tp.reg and map_reg_rev[tp.reg] or ""
1891
+ out:write(format(" %-20s %-20s %s\n", name, tp.ctype, reg))
1892
+ end
1893
+ out:write("\n")
1894
+ end
1895
+
1896
+ ------------------------------------------------------------------------------
1897
+
1898
+ -- Set the current section.
1899
+ function _M.section(num)
1900
+ waction("SECTION")
1901
+ wputxb(num)
1902
+ wflush(true) -- SECTION is a terminal action.
1903
+ end
1904
+
1905
+ ------------------------------------------------------------------------------
1906
+
1907
+ -- Dump architecture description.
1908
+ function _M.dumparch(out)
1909
+ out:write(format("DynASM %s version %s, released %s\n\n",
1910
+ _info.arch, _info.version, _info.release))
1911
+ dumpregs(out)
1912
+ dumpactions(out)
1913
+ end
1914
+
1915
+ -- Dump all user defined elements.
1916
+ function _M.dumpdef(out, lvl)
1917
+ dumptypes(out, lvl)
1918
+ dumpglobals(out, lvl)
1919
+ dumpexterns(out, lvl)
1920
+ end
1921
+
1922
+ ------------------------------------------------------------------------------
1923
+
1924
+ -- Pass callbacks from/to the DynASM core.
1925
+ function _M.passcb(wl, we, wf, ww)
1926
+ wline, werror, wfatal, wwarn = wl, we, wf, ww
1927
+ return wflush
1928
+ end
1929
+
1930
+ -- Setup the arch-specific module.
1931
+ function _M.setup(arch, opt)
1932
+ g_arch, g_opt = arch, opt
1933
+ end
1934
+
1935
+ -- Merge the core maps and the arch-specific maps.
1936
+ function _M.mergemaps(map_coreop, map_def)
1937
+ setmetatable(map_op, { __index = map_coreop })
1938
+ setmetatable(map_def, { __index = map_archdef })
1939
+ return map_op, map_def
1940
+ end
1941
+
1942
+ return _M
1943
+
1944
+ ------------------------------------------------------------------------------
1945
+