immunio 0.15.4 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +0 -27
- data/ext/immunio/Rakefile +9 -0
- data/lib/immunio/plugins/active_record.rb +1 -1
- data/lib/immunio/plugins/active_record_relation.rb +1 -1
- data/lib/immunio/plugins/environment_reporter.rb +20 -0
- data/lib/immunio/rufus_lua_ext/ref.rb +1 -3
- data/lib/immunio/version.rb +1 -1
- data/lib/immunio/vm.rb +1 -2
- data/lua-hooks/Makefile +97 -0
- data/lua-hooks/ext/all.c +41 -52
- data/lua-hooks/ext/all.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_html5.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_sqli.o +0 -0
- data/lua-hooks/ext/libinjection/libinjection_xss.o +0 -0
- data/lua-hooks/ext/libinjection/lualib.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.c +2 -2
- data/lua-hooks/ext/lpeg/lpcap.o +0 -0
- data/lua-hooks/ext/lpeg/lpcode.c +2 -2
- data/lua-hooks/ext/lpeg/lpcode.h +1 -1
- data/lua-hooks/ext/lpeg/lpcode.o +0 -0
- data/lua-hooks/ext/lpeg/lpprint.o +0 -0
- data/lua-hooks/ext/lpeg/lptree.c +2 -2
- data/lua-hooks/ext/lpeg/lptypes.h +1 -1
- data/lua-hooks/ext/lpeg/lpvm.c +2 -2
- data/lua-hooks/ext/lpeg/lpvm.o +0 -0
- data/lua-hooks/ext/lua-cmsgpack/lua_cmsgpack.c +16 -3
- data/lua-hooks/ext/lua-snapshot/snapshot.c +14 -7
- data/lua-hooks/ext/luajit/COPYRIGHT +56 -0
- data/lua-hooks/ext/luajit/Makefile +159 -0
- data/lua-hooks/ext/luajit/README +16 -0
- data/lua-hooks/ext/luajit/doc/bluequad-print.css +166 -0
- data/lua-hooks/ext/luajit/doc/bluequad.css +325 -0
- data/lua-hooks/ext/luajit/doc/changes.html +804 -0
- data/lua-hooks/ext/luajit/doc/contact.html +104 -0
- data/lua-hooks/ext/luajit/doc/ext_c_api.html +189 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi.html +332 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_api.html +570 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_semantics.html +1261 -0
- data/lua-hooks/ext/luajit/doc/ext_ffi_tutorial.html +603 -0
- data/lua-hooks/ext/luajit/doc/ext_jit.html +201 -0
- data/lua-hooks/ext/luajit/doc/ext_profiler.html +365 -0
- data/lua-hooks/ext/luajit/doc/extensions.html +448 -0
- data/lua-hooks/ext/luajit/doc/faq.html +186 -0
- data/lua-hooks/ext/luajit/doc/img/contact.png +0 -0
- data/lua-hooks/ext/luajit/doc/install.html +659 -0
- data/lua-hooks/ext/luajit/doc/luajit.html +236 -0
- data/lua-hooks/ext/luajit/doc/running.html +309 -0
- data/lua-hooks/ext/luajit/doc/status.html +118 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.h +456 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm.lua +1125 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.h +518 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_arm64.lua +1166 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.h +416 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_mips.lua +953 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.h +419 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_ppc.lua +1919 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_proto.h +83 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x64.lua +12 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.h +471 -0
- data/lua-hooks/ext/luajit/dynasm/dasm_x86.lua +1945 -0
- data/lua-hooks/ext/luajit/dynasm/dynasm.lua +1094 -0
- data/lua-hooks/ext/luajit/etc/luajit.1 +88 -0
- data/lua-hooks/ext/luajit/etc/luajit.pc +25 -0
- data/lua-hooks/ext/luajit/src/Makefile +697 -0
- data/lua-hooks/ext/luajit/src/Makefile.dep +244 -0
- data/lua-hooks/ext/luajit/src/host/README +4 -0
- data/lua-hooks/ext/luajit/src/host/buildvm +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.c +518 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.h +105 -0
- data/lua-hooks/ext/luajit/src/host/buildvm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_arch.h +7449 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.c +345 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.c +229 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.c +457 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_libbc.h +45 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.c +368 -0
- data/lua-hooks/ext/luajit/src/host/buildvm_peobj.o +0 -0
- data/lua-hooks/ext/luajit/src/host/genlibbc.lua +197 -0
- data/lua-hooks/ext/luajit/src/host/genminilua.lua +428 -0
- data/lua-hooks/ext/luajit/src/host/minilua +0 -0
- data/lua-hooks/ext/luajit/src/host/minilua.c +7770 -0
- data/lua-hooks/ext/luajit/src/host/minilua.o +0 -0
- data/lua-hooks/ext/luajit/src/jit/bc.lua +190 -0
- data/lua-hooks/ext/luajit/src/jit/bcsave.lua +661 -0
- data/lua-hooks/ext/luajit/src/jit/dis_arm.lua +689 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mips.lua +428 -0
- data/lua-hooks/ext/luajit/src/jit/dis_mipsel.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_ppc.lua +591 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x64.lua +17 -0
- data/lua-hooks/ext/luajit/src/jit/dis_x86.lua +838 -0
- data/lua-hooks/ext/luajit/src/jit/dump.lua +706 -0
- data/lua-hooks/ext/luajit/src/jit/p.lua +310 -0
- data/lua-hooks/ext/luajit/src/jit/v.lua +170 -0
- data/lua-hooks/ext/luajit/src/jit/vmdef.lua +362 -0
- data/lua-hooks/ext/luajit/src/jit/zone.lua +45 -0
- data/lua-hooks/ext/{lua → luajit/src}/lauxlib.h +10 -17
- data/lua-hooks/ext/luajit/src/lib_aux.c +356 -0
- data/lua-hooks/ext/luajit/src/lib_aux.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_aux_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base.c +664 -0
- data/lua-hooks/ext/luajit/src/lib_base.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_base_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit.c +180 -0
- data/lua-hooks/ext/luajit/src/lib_bit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_bit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug.c +405 -0
- data/lua-hooks/ext/luajit/src/lib_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.c +872 -0
- data/lua-hooks/ext/luajit/src/lib_ffi.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_ffi_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init.c +55 -0
- data/lua-hooks/ext/luajit/src/lib_init.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_init_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io.c +541 -0
- data/lua-hooks/ext/luajit/src/lib_io.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_io_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit.c +767 -0
- data/lua-hooks/ext/luajit/src/lib_jit.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_jit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math.c +230 -0
- data/lua-hooks/ext/luajit/src/lib_math.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_math_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os.c +292 -0
- data/lua-hooks/ext/luajit/src/lib_os.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_os_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package.c +610 -0
- data/lua-hooks/ext/luajit/src/lib_package.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_package_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string.c +752 -0
- data/lua-hooks/ext/luajit/src/lib_string.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_string_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table.c +307 -0
- data/lua-hooks/ext/luajit/src/lib_table.o +0 -0
- data/lua-hooks/ext/luajit/src/lib_table_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.a +0 -0
- data/lua-hooks/ext/luajit/src/libluajit.so +0 -0
- data/lua-hooks/ext/luajit/src/lj.supp +26 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.c +1398 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_alloc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_alloc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api.c +1210 -0
- data/lua-hooks/ext/luajit/src/lj_api.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_api_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_arch.h +509 -0
- data/lua-hooks/ext/luajit/src/lj_asm.c +2278 -0
- data/lua-hooks/ext/luajit/src/lj_asm.h +17 -0
- data/lua-hooks/ext/luajit/src/lj_asm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_arm.h +2217 -0
- data/lua-hooks/ext/luajit/src/lj_asm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_asm_mips.h +1833 -0
- data/lua-hooks/ext/luajit/src/lj_asm_ppc.h +2015 -0
- data/lua-hooks/ext/luajit/src/lj_asm_x86.h +2634 -0
- data/lua-hooks/ext/luajit/src/lj_bc.c +14 -0
- data/lua-hooks/ext/luajit/src/lj_bc.h +265 -0
- data/lua-hooks/ext/luajit/src/lj_bc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcdef.h +220 -0
- data/lua-hooks/ext/luajit/src/lj_bcdump.h +68 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.c +457 -0
- data/lua-hooks/ext/luajit/src/lj_bcread.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcread_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.c +361 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_bcwrite_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf.c +234 -0
- data/lua-hooks/ext/luajit/src/lj_buf.h +105 -0
- data/lua-hooks/ext/luajit/src/lj_buf.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_buf_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith.c +429 -0
- data/lua-hooks/ext/luajit/src/lj_carith.h +37 -0
- data/lua-hooks/ext/luajit/src/lj_carith.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_carith_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.c +984 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.h +178 -0
- data/lua-hooks/ext/luajit/src/lj_ccall.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccall_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.c +712 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.h +25 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ccallback_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.c +752 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.h +70 -0
- data/lua-hooks/ext/luajit/src/lj_cconv.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cconv_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.c +288 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.h +76 -0
- data/lua-hooks/ext/luajit/src/lj_cdata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cdata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char.c +43 -0
- data/lua-hooks/ext/luajit/src/lj_char.h +42 -0
- data/lua-hooks/ext/luajit/src/lj_char.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_char_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib.c +418 -0
- data/lua-hooks/ext/luajit/src/lj_clib.h +29 -0
- data/lua-hooks/ext/luajit/src/lj_clib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_clib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.c +1862 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_cparse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_cparse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.c +1834 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_crecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_crecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.c +635 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.h +461 -0
- data/lua-hooks/ext/luajit/src/lj_ctype.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ctype_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug.c +699 -0
- data/lua-hooks/ext/luajit/src/lj_debug.h +65 -0
- data/lua-hooks/ext/luajit/src/lj_debug.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_debug_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_def.h +365 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.c +557 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.h +138 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_dispatch_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_emit_arm.h +356 -0
- data/lua-hooks/ext/luajit/src/lj_emit_mips.h +211 -0
- data/lua-hooks/ext/luajit/src/lj_emit_ppc.h +238 -0
- data/lua-hooks/ext/luajit/src/lj_emit_x86.h +462 -0
- data/lua-hooks/ext/luajit/src/lj_err.c +794 -0
- data/lua-hooks/ext/luajit/src/lj_err.h +41 -0
- data/lua-hooks/ext/luajit/src/lj_err.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_err_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_errmsg.h +190 -0
- data/lua-hooks/ext/luajit/src/lj_ff.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_ffdef.h +209 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.c +1247 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ffrecord_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_folddef.h +1138 -0
- data/lua-hooks/ext/luajit/src/lj_frame.h +259 -0
- data/lua-hooks/ext/luajit/src/lj_func.c +185 -0
- data/lua-hooks/ext/luajit/src/lj_func.h +24 -0
- data/lua-hooks/ext/luajit/src/lj_func.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_func_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc.c +845 -0
- data/lua-hooks/ext/luajit/src/lj_gc.h +134 -0
- data/lua-hooks/ext/luajit/src/lj_gc.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gc_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.c +787 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.h +22 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_gdbjit_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir.c +505 -0
- data/lua-hooks/ext/luajit/src/lj_ir.h +577 -0
- data/lua-hooks/ext/luajit/src/lj_ir.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ir_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_ircall.h +321 -0
- data/lua-hooks/ext/luajit/src/lj_iropt.h +161 -0
- data/lua-hooks/ext/luajit/src/lj_jit.h +440 -0
- data/lua-hooks/ext/luajit/src/lj_lex.c +482 -0
- data/lua-hooks/ext/luajit/src/lj_lex.h +86 -0
- data/lua-hooks/ext/luajit/src/lj_lex.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lex_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib.c +303 -0
- data/lua-hooks/ext/luajit/src/lj_lib.h +115 -0
- data/lua-hooks/ext/luajit/src/lj_lib.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_lib_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_libdef.h +414 -0
- data/lua-hooks/ext/luajit/src/lj_load.c +168 -0
- data/lua-hooks/ext/luajit/src/lj_load.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_load_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.c +386 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.h +30 -0
- data/lua-hooks/ext/luajit/src/lj_mcode.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_mcode_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta.c +477 -0
- data/lua-hooks/ext/luajit/src/lj_meta.h +38 -0
- data/lua-hooks/ext/luajit/src/lj_meta.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_meta_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj.c +50 -0
- data/lua-hooks/ext/luajit/src/lj_obj.h +976 -0
- data/lua-hooks/ext/luajit/src/lj_obj.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_obj_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.c +78 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_dce_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.c +2488 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_fold_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.c +449 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_loop_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.c +935 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_mem_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.c +652 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_narrow_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.c +245 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_sink_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.c +856 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_opt_split_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse.c +2725 -0
- data/lua-hooks/ext/luajit/src/lj_parse.h +18 -0
- data/lua-hooks/ext/luajit/src/lj_parse.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_parse_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile.c +368 -0
- data/lua-hooks/ext/luajit/src/lj_profile.h +21 -0
- data/lua-hooks/ext/luajit/src/lj_profile.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_profile_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_recdef.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_record.c +2554 -0
- data/lua-hooks/ext/luajit/src/lj_record.h +45 -0
- data/lua-hooks/ext/luajit/src/lj_record.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_record_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap.c +870 -0
- data/lua-hooks/ext/luajit/src/lj_snap.h +34 -0
- data/lua-hooks/ext/luajit/src/lj_snap.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_snap_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state.c +300 -0
- data/lua-hooks/ext/luajit/src/lj_state.h +35 -0
- data/lua-hooks/ext/luajit/src/lj_state.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_state_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str.c +197 -0
- data/lua-hooks/ext/luajit/src/lj_str.h +27 -0
- data/lua-hooks/ext/luajit/src/lj_str.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_str_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.c +554 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.h +125 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strfmt_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.c +547 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.h +39 -0
- data/lua-hooks/ext/luajit/src/lj_strscan.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_strscan_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab.c +666 -0
- data/lua-hooks/ext/luajit/src/lj_tab.h +73 -0
- data/lua-hooks/ext/luajit/src/lj_tab.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_tab_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_target.h +164 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm.h +270 -0
- data/lua-hooks/ext/luajit/src/lj_target_arm64.h +97 -0
- data/lua-hooks/ext/luajit/src/lj_target_mips.h +260 -0
- data/lua-hooks/ext/luajit/src/lj_target_ppc.h +280 -0
- data/lua-hooks/ext/luajit/src/lj_target_x86.h +345 -0
- data/lua-hooks/ext/luajit/src/lj_trace.c +859 -0
- data/lua-hooks/ext/luajit/src/lj_trace.h +54 -0
- data/lua-hooks/ext/luajit/src/lj_trace.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_trace_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_traceerr.h +63 -0
- data/lua-hooks/ext/luajit/src/lj_udata.c +34 -0
- data/lua-hooks/ext/luajit/src/lj_udata.h +14 -0
- data/lua-hooks/ext/luajit/src/lj_udata.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_udata_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm.S +2730 -0
- data/lua-hooks/ext/luajit/src/lj_vm.h +114 -0
- data/lua-hooks/ext/luajit/src/lj_vm.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vm_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.c +58 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.h +59 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmevent_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.c +152 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath.o +0 -0
- data/lua-hooks/ext/luajit/src/lj_vmmath_dyn.o +0 -0
- data/lua-hooks/ext/luajit/src/ljamalg.c +96 -0
- data/lua-hooks/ext/{lua → luajit/src}/lua.h +12 -7
- data/lua-hooks/ext/luajit/src/lua.hpp +9 -0
- data/lua-hooks/ext/luajit/src/luaconf.h +156 -0
- data/lua-hooks/ext/luajit/src/luajit +0 -0
- data/lua-hooks/ext/luajit/src/luajit.c +570 -0
- data/lua-hooks/ext/luajit/src/luajit.h +79 -0
- data/lua-hooks/ext/luajit/src/luajit.o +0 -0
- data/lua-hooks/ext/luajit/src/lualib.h +43 -0
- data/lua-hooks/ext/luajit/src/msvcbuild.bat +114 -0
- data/lua-hooks/ext/luajit/src/ps4build.bat +103 -0
- data/lua-hooks/ext/luajit/src/psvitabuild.bat +93 -0
- data/lua-hooks/ext/luajit/src/vm_arm.dasc +4585 -0
- data/lua-hooks/ext/luajit/src/vm_arm64.dasc +3764 -0
- data/lua-hooks/ext/luajit/src/vm_mips.dasc +4355 -0
- data/lua-hooks/ext/luajit/src/vm_ppc.dasc +5252 -0
- data/lua-hooks/ext/luajit/src/vm_x64.dasc +4902 -0
- data/lua-hooks/ext/luajit/src/vm_x86.dasc +5710 -0
- data/lua-hooks/ext/luajit/src/xb1build.bat +101 -0
- data/lua-hooks/ext/luajit/src/xedkbuild.bat +92 -0
- data/lua-hooks/ext/luautf8/lutf8lib.c +3 -3
- data/lua-hooks/lib/boot.lua +37 -2
- metadata +372 -69
- data/lua-hooks/ext/bitop/README +0 -22
- data/lua-hooks/ext/bitop/bit.c +0 -189
- data/lua-hooks/ext/extconf.rb +0 -38
- data/lua-hooks/ext/lua/COPYRIGHT +0 -34
- data/lua-hooks/ext/lua/lapi.c +0 -1087
- data/lua-hooks/ext/lua/lapi.h +0 -16
- data/lua-hooks/ext/lua/lauxlib.c +0 -652
- data/lua-hooks/ext/lua/lbaselib.c +0 -659
- data/lua-hooks/ext/lua/lcode.c +0 -831
- data/lua-hooks/ext/lua/lcode.h +0 -76
- data/lua-hooks/ext/lua/ldblib.c +0 -398
- data/lua-hooks/ext/lua/ldebug.c +0 -638
- data/lua-hooks/ext/lua/ldebug.h +0 -33
- data/lua-hooks/ext/lua/ldo.c +0 -519
- data/lua-hooks/ext/lua/ldo.h +0 -57
- data/lua-hooks/ext/lua/ldump.c +0 -164
- data/lua-hooks/ext/lua/lfunc.c +0 -174
- data/lua-hooks/ext/lua/lfunc.h +0 -34
- data/lua-hooks/ext/lua/lgc.c +0 -710
- data/lua-hooks/ext/lua/lgc.h +0 -110
- data/lua-hooks/ext/lua/linit.c +0 -38
- data/lua-hooks/ext/lua/liolib.c +0 -556
- data/lua-hooks/ext/lua/llex.c +0 -463
- data/lua-hooks/ext/lua/llex.h +0 -81
- data/lua-hooks/ext/lua/llimits.h +0 -128
- data/lua-hooks/ext/lua/lmathlib.c +0 -263
- data/lua-hooks/ext/lua/lmem.c +0 -86
- data/lua-hooks/ext/lua/lmem.h +0 -49
- data/lua-hooks/ext/lua/loadlib.c +0 -705
- data/lua-hooks/ext/lua/loadlib_rel.c +0 -760
- data/lua-hooks/ext/lua/lobject.c +0 -214
- data/lua-hooks/ext/lua/lobject.h +0 -381
- data/lua-hooks/ext/lua/lopcodes.c +0 -102
- data/lua-hooks/ext/lua/lopcodes.h +0 -268
- data/lua-hooks/ext/lua/loslib.c +0 -243
- data/lua-hooks/ext/lua/lparser.c +0 -1339
- data/lua-hooks/ext/lua/lparser.h +0 -82
- data/lua-hooks/ext/lua/lstate.c +0 -214
- data/lua-hooks/ext/lua/lstate.h +0 -169
- data/lua-hooks/ext/lua/lstring.c +0 -111
- data/lua-hooks/ext/lua/lstring.h +0 -31
- data/lua-hooks/ext/lua/lstrlib.c +0 -871
- data/lua-hooks/ext/lua/ltable.c +0 -588
- data/lua-hooks/ext/lua/ltable.h +0 -40
- data/lua-hooks/ext/lua/ltablib.c +0 -287
- data/lua-hooks/ext/lua/ltm.c +0 -75
- data/lua-hooks/ext/lua/ltm.h +0 -54
- data/lua-hooks/ext/lua/lua.c +0 -392
- data/lua-hooks/ext/lua/lua.def +0 -131
- data/lua-hooks/ext/lua/lua.rc +0 -28
- data/lua-hooks/ext/lua/lua_dll.rc +0 -26
- data/lua-hooks/ext/lua/luac.c +0 -200
- data/lua-hooks/ext/lua/luac.rc +0 -1
- data/lua-hooks/ext/lua/luaconf.h +0 -763
- data/lua-hooks/ext/lua/luaconf.h.in +0 -724
- data/lua-hooks/ext/lua/luaconf.h.orig +0 -763
- data/lua-hooks/ext/lua/lualib.h +0 -53
- data/lua-hooks/ext/lua/lundump.c +0 -227
- data/lua-hooks/ext/lua/lundump.h +0 -36
- data/lua-hooks/ext/lua/lvm.c +0 -767
- data/lua-hooks/ext/lua/lvm.h +0 -36
- data/lua-hooks/ext/lua/lzio.c +0 -82
- data/lua-hooks/ext/lua/lzio.h +0 -67
- 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
|
+
|