immunio 0.15.4 → 0.16.0

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