immunio 0.15.4 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|