diff options
author | 2011-01-17 03:43:54 +0000 | |
---|---|---|
committer | 2011-01-17 03:43:54 +0000 | |
commit | f5c03d12e27df20e704ae6e1af233aefabfaeaec (patch) | |
tree | f57c5ae3e0d618903b702363e06f5a2b0014e23d | |
parent | 51d7c644e0a53fe7b2c6a59360b155b5d4699b08 (diff) |
Redo most of the DRC/backend support as C++
Yes, it is intentional that the x86/x64 backends compile everywhere.
Backends are now derived from drcbe_interface and implement several
required overrides.
x86emit.h now uses namespaces so that the x86/x64 emitters can co-exist.
New file uml.h/uml.c actually describes the UML language, separating
out several concepts from drcuml.c.
Lots of other changes/fixes.
-rw-r--r-- | .gitattributes | 5 | ||||
-rw-r--r-- | src/emu/cpu/cpu.mak | 35 | ||||
-rw-r--r-- | src/emu/cpu/drcbec.c | 1790 | ||||
-rw-r--r-- | src/emu/cpu/drcbec.h | 87 | ||||
-rw-r--r-- | src/emu/cpu/drcbeut.c | 54 | ||||
-rw-r--r-- | src/emu/cpu/drcbeut.h | 12 | ||||
-rw-r--r-- | src/emu/cpu/drcbex64.c | 8248 | ||||
-rw-r--r-- | src/emu/cpu/drcbex64.h | 370 | ||||
-rw-r--r-- | src/emu/cpu/drcbex86.c | 8021 | ||||
-rw-r--r-- | src/emu/cpu/drcbex86.h | 371 | ||||
-rw-r--r-- | src/emu/cpu/drccache.h | 14 | ||||
-rw-r--r-- | src/emu/cpu/drcuml.c | 2395 | ||||
-rw-r--r-- | src/emu/cpu/drcuml.h | 680 | ||||
-rw-r--r-- | src/emu/cpu/drcumlsh.h | 333 | ||||
-rw-r--r-- | src/emu/cpu/mips/mips3drc.c | 930 | ||||
-rw-r--r-- | src/emu/cpu/powerpc/ppcdrc.c | 1021 | ||||
-rw-r--r-- | src/emu/cpu/rsp/rspdrc.c | 364 | ||||
-rw-r--r-- | src/emu/cpu/sh2/sh2comn.h | 26 | ||||
-rw-r--r-- | src/emu/cpu/sh2/sh2drc.c | 570 | ||||
-rw-r--r-- | src/emu/cpu/uml.c | 1059 | ||||
-rw-r--r-- | src/emu/cpu/uml.h | 687 | ||||
-rw-r--r-- | src/emu/cpu/x86emit.h | 4913 | ||||
-rw-r--r-- | src/lib/util/astring.h | 1 | ||||
-rw-r--r-- | src/osd/windows/windows.mak | 2 |
24 files changed, 15981 insertions, 16007 deletions
diff --git a/.gitattributes b/.gitattributes index 03ea06fcb97..6fdb510e0e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -73,10 +73,13 @@ src/emu/cpu/cubeqcpu/cubedasm.c svneol=native#text/plain src/emu/cpu/cubeqcpu/cubeqcpu.c svneol=native#text/plain src/emu/cpu/cubeqcpu/cubeqcpu.h svneol=native#text/plain src/emu/cpu/drcbec.c svneol=native#text/plain +src/emu/cpu/drcbec.h svneol=native#text/plain src/emu/cpu/drcbeut.c svneol=native#text/plain src/emu/cpu/drcbeut.h svneol=native#text/plain src/emu/cpu/drcbex64.c svneol=native#text/plain +src/emu/cpu/drcbex64.h svneol=native#text/plain src/emu/cpu/drcbex86.c svneol=native#text/plain +src/emu/cpu/drcbex86.h svneol=native#text/plain src/emu/cpu/drccache.c svneol=native#text/plain src/emu/cpu/drccache.h svneol=native#text/plain src/emu/cpu/drcfe.c svneol=native#text/plain @@ -495,6 +498,8 @@ src/emu/cpu/tms9900/tms9900.c svneol=native#text/plain src/emu/cpu/tms9900/tms9900.h svneol=native#text/plain src/emu/cpu/tms9900/tms9980a.c svneol=native#text/plain src/emu/cpu/tms9900/tms9995.c svneol=native#text/plain +src/emu/cpu/uml.c svneol=native#text/plain +src/emu/cpu/uml.h svneol=native#text/plain src/emu/cpu/unsp/unsp.c svneol=native#text/plain src/emu/cpu/unsp/unsp.h svneol=native#text/plain src/emu/cpu/unsp/unspdasm.c svneol=native#text/plain diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 80afdb6d1a7..aac1d1930e8 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -33,39 +33,31 @@ DRCOBJ = \ $(CPUOBJ)/drccache.o \ $(CPUOBJ)/drcfe.o \ $(CPUOBJ)/drcuml.o \ + $(CPUOBJ)/uml.o \ + $(CPUOBJ)/i386/i386dasm.o \ + $(CPUOBJ)/x86log.o \ + $(CPUOBJ)/drcbex86.o \ + $(CPUOBJ)/drcbex64.o \ DRCDEPS = \ + $(CPUSRC)/drcbec.h \ $(CPUSRC)/drcbeut.h \ $(CPUSRC)/drccache.h \ $(CPUSRC)/drcfe.h \ $(CPUSRC)/drcuml.h \ $(CPUSRC)/drcumlsh.h \ + $(CPUSRC)/uml.h \ + $(CPUSRC)/drcbex86.h \ + $(CPUSRC)/drcbex64.h \ + $(CPUSRC)/x86emit.h \ # fixme - need to make this work for other target architectures (PPC) ifndef FORCE_DRC_C_BACKEND ifeq ($(PTR64),1) - -DRCOBJ += \ - $(CPUOBJ)/drcbex64.o \ - $(CPUOBJ)/x86log.o $(CPUOBJ)/i386/i386dasm.o - -DRCDEPS += \ - $(CPUSRC)/x86emit.h - -DEFS += -DNATIVE_DRC=drcbe_x64_be_interface - +DEFS += -DNATIVE_DRC=drcbe_x64 else - -DRCOBJ += \ - $(CPUOBJ)/drcbex86.o \ - $(CPUOBJ)/x86log.o $(CPUOBJ)/i386/i386dasm.o - -DRCDEPS += \ - $(CPUSRC)/x86emit.h - -DEFS += -DNATIVE_DRC=drcbe_x86_be_interface - +DEFS += -DNATIVE_DRC=drcbe_x86 endif endif @@ -488,7 +480,8 @@ $(CPUOBJ)/sh2/sh2comn.o: $(CPUSRC)/sh2/sh2comn.c \ $(CPUOBJ)/sh2/sh2drc.o: $(CPUSRC)/sh2/sh2drc.c \ $(CPUSRC)/sh2/sh2.h \ - $(CPUSRC)/sh2/sh2comn.h + $(CPUSRC)/sh2/sh2comn.h \ + $(DRCDEPS) $(CPUOBJ)/sh2/sh2fe.o: $(CPUSRC)/sh2/sh2fe.c \ $(CPUSRC)/sh2/sh2.h \ diff --git a/src/emu/cpu/drcbec.c b/src/emu/cpu/drcbec.c index a2a51fb0698..f40ec76f9db 100644 --- a/src/emu/cpu/drcbec.c +++ b/src/emu/cpu/drcbec.c @@ -4,163 +4,192 @@ Interpreted C core back-end for the universal machine language. +**************************************************************************** + Copyright Aaron Giles - Released for general non-commercial use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ #include "emu.h" #include "debugger.h" -#include "drcuml.h" -#include "drcbeut.h" +#include "drcbec.h" #ifdef _MSC_VER #include <float.h> #define isnan _isnan #endif - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* define a bit to match each possible condition, starting at bit 12 */ -#define ZBIT (0x1000 << (DRCUML_COND_Z & 15)) -#define NZBIT (0x1000 << (DRCUML_COND_NZ & 15)) -#define SBIT (0x1000 << (DRCUML_COND_S & 15)) -#define NSBIT (0x1000 << (DRCUML_COND_NS & 15)) -#define CBIT (0x1000 << (DRCUML_COND_C & 15)) -#define NCBIT (0x1000 << (DRCUML_COND_NC & 15)) -#define VBIT (0x1000 << (DRCUML_COND_V & 15)) -#define NVBIT (0x1000 << (DRCUML_COND_NV & 15)) -#define UBIT (0x1000 << (DRCUML_COND_U & 15)) -#define NUBIT (0x1000 << (DRCUML_COND_NU & 15)) -#define ABIT (0x1000 << (DRCUML_COND_A & 15)) -#define BEBIT (0x1000 << (DRCUML_COND_BE & 15)) -#define GBIT (0x1000 << (DRCUML_COND_G & 15)) -#define GEBIT (0x1000 << (DRCUML_COND_GE & 15)) -#define LBIT (0x1000 << (DRCUML_COND_L & 15)) -#define LEBIT (0x1000 << (DRCUML_COND_LE & 15)) - - -/* internal opcodes */ +using namespace uml; + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// define a bit to match each possible condition, starting at bit 12 +#define ZBIT (0x1000 << (COND_Z & 15)) +#define NZBIT (0x1000 << (COND_NZ & 15)) +#define SBIT (0x1000 << (COND_S & 15)) +#define NSBIT (0x1000 << (COND_NS & 15)) +#define CBIT (0x1000 << (COND_C & 15)) +#define NCBIT (0x1000 << (COND_NC & 15)) +#define VBIT (0x1000 << (COND_V & 15)) +#define NVBIT (0x1000 << (COND_NV & 15)) +#define UBIT (0x1000 << (COND_U & 15)) +#define NUBIT (0x1000 << (COND_NU & 15)) +#define ABIT (0x1000 << (COND_A & 15)) +#define BEBIT (0x1000 << (COND_BE & 15)) +#define GBIT (0x1000 << (COND_G & 15)) +#define GEBIT (0x1000 << (COND_GE & 15)) +#define LBIT (0x1000 << (COND_L & 15)) +#define LEBIT (0x1000 << (COND_LE & 15)) + + +// internal opcodes enum { - DRCUML_OP_LOAD1 = DRCUML_OP_MAX, - DRCUML_OP_LOAD1x2, - DRCUML_OP_LOAD1x4, - DRCUML_OP_LOAD1x8, - DRCUML_OP_LOAD2x1, - DRCUML_OP_LOAD2, - DRCUML_OP_LOAD2x4, - DRCUML_OP_LOAD2x8, - DRCUML_OP_LOAD4x1, - DRCUML_OP_LOAD4x2, - DRCUML_OP_LOAD4, - DRCUML_OP_LOAD4x8, - DRCUML_OP_LOAD8x1, - DRCUML_OP_LOAD8x2, - DRCUML_OP_LOAD8x4, - DRCUML_OP_LOAD8, - DRCUML_OP_LOADS1, - DRCUML_OP_LOADS1x2, - DRCUML_OP_LOADS1x4, - DRCUML_OP_LOADS1x8, - DRCUML_OP_LOADS2x1, - DRCUML_OP_LOADS2, - DRCUML_OP_LOADS2x4, - DRCUML_OP_LOADS2x8, - DRCUML_OP_LOADS4x1, - DRCUML_OP_LOADS4x2, - DRCUML_OP_LOADS4, - DRCUML_OP_LOADS4x8, - DRCUML_OP_LOADS8x1, - DRCUML_OP_LOADS8x2, - DRCUML_OP_LOADS8x4, - DRCUML_OP_LOADS8, - DRCUML_OP_STORE1, - DRCUML_OP_STORE1x2, - DRCUML_OP_STORE1x4, - DRCUML_OP_STORE1x8, - DRCUML_OP_STORE2x1, - DRCUML_OP_STORE2, - DRCUML_OP_STORE2x4, - DRCUML_OP_STORE2x8, - DRCUML_OP_STORE4x1, - DRCUML_OP_STORE4x2, - DRCUML_OP_STORE4, - DRCUML_OP_STORE4x8, - DRCUML_OP_STORE8x1, - DRCUML_OP_STORE8x2, - DRCUML_OP_STORE8x4, - DRCUML_OP_STORE8, - DRCUML_OP_READ1, - DRCUML_OP_READ2, - DRCUML_OP_READ4, - DRCUML_OP_READ8, - DRCUML_OP_READM1, - DRCUML_OP_READM2, - DRCUML_OP_READM4, - DRCUML_OP_READM8, - DRCUML_OP_WRITE1, - DRCUML_OP_WRITE2, - DRCUML_OP_WRITE4, - DRCUML_OP_WRITE8, - DRCUML_OP_WRITEM1, - DRCUML_OP_WRITEM2, - DRCUML_OP_WRITEM4, - DRCUML_OP_WRITEM8, - DRCUML_OP_SEXT1, - DRCUML_OP_SEXT2, - DRCUML_OP_SEXT4, - DRCUML_OP_SEXT8, - DRCUML_OP_FTOI4T, - DRCUML_OP_FTOI4R, - DRCUML_OP_FTOI4C, - DRCUML_OP_FTOI4F, - DRCUML_OP_FTOI4, - DRCUML_OP_FTOI8T, - DRCUML_OP_FTOI8R, - DRCUML_OP_FTOI8C, - DRCUML_OP_FTOI8F, - DRCUML_OP_FTOI8, - DRCUML_OP_FFRI4, - DRCUML_OP_FFRI8, - DRCUML_OP_FFRFS, - DRCUML_OP_FFRFD, + OP_LOAD1 = OP_MAX, + OP_LOAD1x2, + OP_LOAD1x4, + OP_LOAD1x8, + OP_LOAD2x1, + OP_LOAD2, + OP_LOAD2x4, + OP_LOAD2x8, + OP_LOAD4x1, + OP_LOAD4x2, + OP_LOAD4, + OP_LOAD4x8, + OP_LOAD8x1, + OP_LOAD8x2, + OP_LOAD8x4, + OP_LOAD8, + OP_LOADS1, + OP_LOADS1x2, + OP_LOADS1x4, + OP_LOADS1x8, + OP_LOADS2x1, + OP_LOADS2, + OP_LOADS2x4, + OP_LOADS2x8, + OP_LOADS4x1, + OP_LOADS4x2, + OP_LOADS4, + OP_LOADS4x8, + OP_LOADS8x1, + OP_LOADS8x2, + OP_LOADS8x4, + OP_LOADS8, + OP_STORE1, + OP_STORE1x2, + OP_STORE1x4, + OP_STORE1x8, + OP_STORE2x1, + OP_STORE2, + OP_STORE2x4, + OP_STORE2x8, + OP_STORE4x1, + OP_STORE4x2, + OP_STORE4, + OP_STORE4x8, + OP_STORE8x1, + OP_STORE8x2, + OP_STORE8x4, + OP_STORE8, + OP_READ1, + OP_READ2, + OP_READ4, + OP_READ8, + OP_READM1, + OP_READM2, + OP_READM4, + OP_READM8, + OP_WRITE1, + OP_WRITE2, + OP_WRITE4, + OP_WRITE8, + OP_WRITEM1, + OP_WRITEM2, + OP_WRITEM4, + OP_WRITEM8, + OP_SEXT1, + OP_SEXT2, + OP_SEXT4, + OP_SEXT8, + OP_FTOI4T, + OP_FTOI4R, + OP_FTOI4C, + OP_FTOI4F, + OP_FTOI4, + OP_FTOI8T, + OP_FTOI8R, + OP_FTOI8C, + OP_FTOI8F, + OP_FTOI8, + OP_FFRI4, + OP_FFRI8, + OP_FFRFS, + OP_FFRFD, }; -/*************************************************************************** - MACROS -***************************************************************************/ +//************************************************************************** +// MACROS +//************************************************************************** -/* opcode format: +// +// opcode format: +// +// bits 31..28 == number of words following the opcode itself (0-15) +// bits 27..12 == bitmask specify which condition code we care about +// bits 11.. 2 == opcode +// bit 1 == flags/condition summary (0 if no condition/flags, 1 otherwise) +// bit 0 == operation size (0=32-bit, 1=64-bit) +// - bits 31..28 == number of words following the opcode itself (0-15) - bits 27..12 == bitmask specify which condition code we care about - bits 11.. 2 == opcode - bit 1 == flags/condition summary (0 if no condition/flags, 1 otherwise) - bit 0 == operation size (0=32-bit, 1=64-bit) -*/ - -/* build a short opcode from the raw opcode and size */ +// build a short opcode from the raw opcode and size #define MAKE_OPCODE_SHORT(op, size, conditionorflags) \ ((((size) == 8) << 0) | (((conditionorflags) != 0) << 1) | ((op) << 2)) -/* build a full opcode from the raw opcode, size, condition/flags, and immediate count */ +// build a full opcode from the raw opcode, size, condition/flags, and immediate count #define MAKE_OPCODE_FULL(op, size, condition, flags, pwords) \ - (MAKE_OPCODE_SHORT(op, size, (condition | flags)) | ((condition != DRCUML_COND_ALWAYS) ? (0x1000 << ((condition) & 15)) : 0) | ((pwords) << 28)) + (MAKE_OPCODE_SHORT(op, size, (condition | flags)) | ((condition != COND_ALWAYS) ? (0x1000 << ((condition) & 15)) : 0) | ((pwords) << 28)) -/* extract various parts of the opcode */ +// extract various parts of the opcode #define OPCODE_GET_SHORT(op) ((op) & 0xfff) -#define OPCODE_PASS_CONDITION(op,f) (((op) & condition_map[f]) != 0) -#define OPCODE_FAIL_CONDITION(op,f) (((op) & condition_map[f]) == 0) +#define OPCODE_PASS_CONDITION(op,f) (((op) & s_condition_map[f]) != 0) +#define OPCODE_FAIL_CONDITION(op,f) (((op) & s_condition_map[f]) == 0) #define OPCODE_GET_PWORDS(op) ((op) >> 28) -/* shorthand for accessing parameters in the instruction stream */ +// shorthand for accessing parameters in the instruction stream #define PARAM0 (*inst[0].puint32) #define PARAM1 (*inst[1].puint32) #define PARAM2 (*inst[2].puint32) @@ -181,51 +210,36 @@ enum #define FDPARAM2 (*inst[2].pdouble) #define FDPARAM3 (*inst[3].pdouble) -/* compute C and V flags for 32-bit add/subtract */ +// compute C and V flags for 32-bit add/subtract #define FLAGS32_C_ADD(a,b) ((UINT32)~(a) < (UINT32)(b)) #define FLAGS32_C_SUB(a,b) ((UINT32)(b) > (UINT32)(a)) -#define FLAGS32_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 30) & DRCUML_FLAG_V) -#define FLAGS32_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 30) & DRCUML_FLAG_V) +#define FLAGS32_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 30) & FLAG_V) +#define FLAGS32_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 30) & FLAG_V) -/* compute N and Z flags for 32-bit operations */ -#define FLAGS32_NZ(v) ((((v) >> 28) & DRCUML_FLAG_S) | (((UINT32)(v) == 0) << 2)) +// compute N and Z flags for 32-bit operations +#define FLAGS32_NZ(v) ((((v) >> 28) & FLAG_S) | (((UINT32)(v) == 0) << 2)) #define FLAGS32_NZCV_ADD(r,a,b) (FLAGS32_NZ(r) | FLAGS32_C_ADD(a,b) | FLAGS32_V_ADD(r,a,b)) #define FLAGS32_NZCV_SUB(r,a,b) (FLAGS32_NZ(r) | FLAGS32_C_SUB(a,b) | FLAGS32_V_SUB(r,a,b)) -/* compute C and V flags for 64-bit add/subtract */ +// compute C and V flags for 64-bit add/subtract #define FLAGS64_C_ADD(a,b) ((UINT64)~(a) < (UINT64)(b)) #define FLAGS64_C_SUB(a,b) ((UINT64)(b) > (UINT64)(a)) -#define FLAGS64_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 62) & DRCUML_FLAG_V) -#define FLAGS64_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 62) & DRCUML_FLAG_V) +#define FLAGS64_V_SUB(r,a,b) (((((a) ^ (b)) & ((a) ^ (r))) >> 62) & FLAG_V) +#define FLAGS64_V_ADD(r,a,b) (((~((a) ^ (b)) & ((a) ^ (r))) >> 62) & FLAG_V) -/* compute N and Z flags for 64-bit operations */ -#define FLAGS64_NZ(v) ((((v) >> 60) & DRCUML_FLAG_S) | (((UINT64)(v) == 0) << 2)) +// compute N and Z flags for 64-bit operations +#define FLAGS64_NZ(v) ((((v) >> 60) & FLAG_S) | (((UINT64)(v) == 0) << 2)) #define FLAGS64_NZCV_ADD(r,a,b) (FLAGS64_NZ(r) | FLAGS64_C_ADD(a,b) | FLAGS64_V_ADD(r,a,b)) #define FLAGS64_NZCV_SUB(r,a,b) (FLAGS64_NZ(r) | FLAGS64_C_SUB(a,b) | FLAGS64_V_SUB(r,a,b)) -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* internal backend-specific state */ -struct _drcbe_state -{ - device_t * device; /* CPU device we are associated with */ - address_space * space[ADDRESS_SPACES]; /* pointers to CPU's address space */ - drcuml_state * drcuml; /* pointer back to our owner */ - drc_cache * cache; /* pointer to the cache */ - drcuml_machine_state state; /* state of the machine */ - drc_hash_table * hash; /* hash table state */ - drc_map_variables * map; /* code map */ - drc_label_list * labels; /* label list */ -}; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** - -/* union to simplify accessing data via the instruction stream */ -typedef union _drcbec_instruction drcbec_instruction; -union _drcbec_instruction +// union to simplify accessing data via the instruction stream +union drcbec_instruction { UINT32 i; void * v; @@ -242,39 +256,20 @@ union _drcbec_instruction double * pdouble; void (*cfunc)(void *); drcuml_machine_state *state; - const drcuml_codehandle *handle; + const code_handle * handle; const drcbec_instruction *inst; const drcbec_instruction **pinst; }; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* primary back-end callbacks */ -static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits); -static void drcbec_free(drcbe_state *drcbe); -static void drcbec_reset(drcbe_state *drcbe); -static int drcbec_execute(drcbe_state *state, drcuml_codehandle *entry); -static void drcbec_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst); -static int drcbec_hash_exists(drcbe_state *state, UINT32 mode, UINT32 pc); -static void drcbec_get_info(drcbe_state *state, drcbe_info *info); +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* private helper functions */ -static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, void **immedptr, int size, const drcuml_parameter *param); -static void fixup_label(void *parameter, drccodeptr labelcodeptr); -static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int flags); -static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags); +UINT64 drcbe_c::s_immediate_zero = 0; - - -/*************************************************************************** - TABLES -***************************************************************************/ - -static const UINT32 condition_map[] = +const UINT32 drcbe_c::s_condition_map[] = { /* ..... */ NCBIT | NVBIT | NZBIT | NSBIT | NUBIT | ABIT | GBIT | GEBIT, /* ....C */ CBIT | NVBIT | NZBIT | NSBIT | NUBIT | BEBIT | GBIT | GEBIT, @@ -312,773 +307,699 @@ static const UINT32 condition_map[] = -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -static UINT64 immediate_zero = 0; - -extern const drcbe_interface drcbe_c_be_interface = -{ - drcbec_alloc, - drcbec_free, - drcbec_reset, - drcbec_execute, - drcbec_generate, - drcbec_hash_exists, - drcbec_get_info -}; - - - -/*************************************************************************** - BACKEND CALLBACKS -***************************************************************************/ +//************************************************************************** +// C BACKEND +//************************************************************************** -/*------------------------------------------------- - drcbec_alloc - allocate back-end-specific - state --------------------------------------------------*/ +//------------------------------------------------- +// drcbe_c - constructor +//------------------------------------------------- -static drcbe_state *drcbec_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits) +drcbe_c::drcbe_c(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits) + : drcbe_interface(drcuml, cache, device), + m_hash(cache, modes, addrbits, ignorebits), + m_map(cache, 0), + m_labels(cache) { - int spacenum; - - /* allocate space in the cache for our state */ - drcbe_state *drcbe = (drcbe_state *)cache->alloc(sizeof(*drcbe)); - if (drcbe == NULL) - return NULL; - memset(drcbe, 0, sizeof(*drcbe)); - - /* remember our pointers */ - drcbe->device = device; - for (spacenum = 0; spacenum < ARRAY_LENGTH(drcbe->space); spacenum++) - drcbe->space[spacenum] = downcast<cpu_device *>(device)->space(spacenum); - drcbe->drcuml = drcuml; - drcbe->cache = cache; - - /* allocate hash tables */ - drcbe->hash = auto_alloc(device->machine, drc_hash_table(*cache, modes, addrbits, ignorebits)); - - /* allocate code map */ - drcbe->map = auto_alloc(device->machine, drc_map_variables(*cache, 0)); - - /* allocate a label tracker */ - drcbe->labels = auto_alloc(device->machine, drc_label_list(*cache)); - - return drcbe; } -/*------------------------------------------------- - drcbec_free - free back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// ~drcbe_c - destructor +//------------------------------------------------- -static void drcbec_free(drcbe_state *drcbe) +drcbe_c::~drcbe_c() { } -/*------------------------------------------------- - drcbec_reset - reset back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// reset - reset back-end specific state +//------------------------------------------------- -static void drcbec_reset(drcbe_state *drcbe) +void drcbe_c::reset() { - /* reset our hash tables */ - drcbe->hash->reset(); - drcbe->hash->set_default_codeptr(NULL); + // reset our hash tables + m_hash.reset(); + m_hash.set_default_codeptr(NULL); } -/*------------------------------------------------- - drcbec_generate - generate code --------------------------------------------------*/ +//------------------------------------------------- +// drcbec_generate - generate code +//------------------------------------------------- -static void drcbec_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst) +void drcbe_c::generate(drcuml_block &block, const instruction *instlist, UINT32 numinst) { - drccodeptr *cachetop; - drcbec_instruction *base; - drcbec_instruction *dst; - int inum; - - /* tell all of our utility objects that a block is beginning */ - drcbe->hash->block_begin(*block, instlist, numinst); - drcbe->labels->block_begin(*block); - drcbe->map->block_begin(*block); - - /* begin codegen; fail if we can't */ - cachetop = drcbe->cache->begin_codegen(numinst * sizeof(drcbec_instruction) * 4); + // tell all of our utility objects that a block is beginning + m_hash.block_begin(block, instlist, numinst); + m_labels.block_begin(block); + m_map.block_begin(block); + + // begin codegen; fail if we can't + drccodeptr *cachetop = m_cache.begin_codegen(numinst * sizeof(drcbec_instruction) * 4); if (cachetop == NULL) - drcuml_block_abort(block); + block.abort(); - /* compute the base by aligning the cache top to an even multiple of drcbec_instruction */ - base = (drcbec_instruction *)(((FPTR)*cachetop + sizeof(drcbec_instruction) - 1) & ~(sizeof(drcbec_instruction) - 1)); - dst = base; + // compute the base by aligning the cache top to an even multiple of drcbec_instruction + drcbec_instruction *base = (drcbec_instruction *)(((FPTR)*cachetop + sizeof(drcbec_instruction) - 1) & ~(sizeof(drcbec_instruction) - 1)); + drcbec_instruction *dst = base; - /* generate code by copying the instructions and extracting immediates */ - for (inum = 0; inum < numinst; inum++) + // generate code by copying the instructions and extracting immediates + for (int inum = 0; inum < numinst; inum++) { - const drcuml_instruction *inst = &instlist[inum]; - UINT8 psize[ARRAY_LENGTH(instlist->param)]; - drcuml_instruction modified_inst; - int immedbytes, immedwords, pnum; - drcuml_opcode opcode = inst->opcode; - void *immed; - - /* handle most instructions generally, but a few special cases */ + const instruction &inst = instlist[inum]; + UINT8 psize[instruction::MAX_PARAMS]; + + // handle most instructions generally, but a few special cases + opcode_t opcode = inst.opcode(); switch (opcode) { - /* when we hit a HANDLE opcode, register the current pointer for the handle */ - case DRCUML_OP_HANDLE: - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_MEMORY); - drcuml_handle_set_codeptr((drcuml_codehandle *)(FPTR)inst->param[0].value, (drccodeptr)dst); + // when we hit a HANDLE opcode, register the current pointer for the handle + case OP_HANDLE: + inst.param(0).handle().set_codeptr((drccodeptr)dst); break; - /* when we hit a HASH opcode, register the current pointer for the mode/PC */ - case DRCUML_OP_HASH: - /* we already verified the parameter count and types above */ - drcbe->hash->set_codeptr(inst->param[0].value, inst->param[1].value, (drccodeptr)dst); + // when we hit a HASH opcode, register the current pointer for the mode/PC + case OP_HASH: + m_hash.set_codeptr(inst.param(0).immediate(), inst.param(1).immediate(), (drccodeptr)dst); break; - /* when we hit a LABEL opcode, register the current pointer for the label */ - case DRCUML_OP_LABEL: - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); - drcbe->labels->set_codeptr(inst->param[0].value, (drccodeptr)dst); + // when we hit a LABEL opcode, register the current pointer for the label + case OP_LABEL: + m_labels.set_codeptr(inst.param(0).label(), (drccodeptr)dst); break; - /* ignore COMMENT and NOP opcodes */ - case DRCUML_OP_COMMENT: - case DRCUML_OP_NOP: + // ignore COMMENT and NOP opcodes + case OP_COMMENT: + case OP_NOP: break; - /* when we hit a MAPVAR opcode, log the change for the current PC */ - case DRCUML_OP_MAPVAR: - assert(inst->numparams == 2); - assert(inst->param[0].type == DRCUML_PTYPE_MAPVAR); - assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); - drcbe->map->set_value((drccodeptr)dst, inst->param[0].value, inst->param[1].value); + // when we hit a MAPVAR opcode, log the change for the current PC + case OP_MAPVAR: + m_map.set_value((drccodeptr)dst, inst.param(0).mapvar(), inst.param(1).immediate()); break; - /* JMP instructions need to resolve their labels */ - case DRCUML_OP_JMP: - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); - (dst++)->i = MAKE_OPCODE_FULL(opcode, inst->size, inst->condition, inst->flags, 1); - dst->inst = (drcbec_instruction *)drcbe->labels->get_codeptr(inst->param[0].value, fixup_label, dst); + // JMP instructions need to resolve their labels + case OP_JMP: + (dst++)->i = MAKE_OPCODE_FULL(opcode, inst.size(), inst.condition(), inst.flags(), 1); + dst->inst = (drcbec_instruction *)m_labels.get_codeptr(inst.param(0).label(), fixup_label, dst); dst++; break; - /* generically handle everything else */ + // generically handle everything else default: - /* for RECOVER opcodes, we need to fixup the second parameter into an immediate */ - if (opcode == DRCUML_OP_RECOVER) - { - assert(inst->param[1].type == DRCUML_PTYPE_MAPVAR); - modified_inst = *inst; - modified_inst.param[1].type = DRCUML_PTYPE_IMMEDIATE; - inst = &modified_inst; - } - - /* determine the operand size for each operand; mostly this is just the instruction size */ - for (pnum = 0; pnum < inst->numparams; pnum++) - psize[pnum] = inst->size; - if (opcode == DRCUML_OP_LOAD || opcode == DRCUML_OP_FLOAD) + // determine the operand size for each operand; mostly this is just the instruction size + for (int pnum = 0; pnum < inst.numparams(); pnum++) + psize[pnum] = inst.size(); + if (opcode == OP_LOAD || opcode == OP_FLOAD) psize[2] = 4; - if (opcode == DRCUML_OP_STORE || opcode == DRCUML_OP_FSTORE) + if (opcode == OP_STORE || opcode == OP_FSTORE) psize[1] = 4; - if (opcode == DRCUML_OP_READ || opcode == DRCUML_OP_READM || opcode == DRCUML_OP_FREAD) - psize[0] = psize[1] = 4; - if (opcode == DRCUML_OP_WRITE || opcode == DRCUML_OP_WRITEM || opcode == DRCUML_OP_FWRITE) - psize[0] = psize[1] = 4; - if (opcode == DRCUML_OP_SEXT && inst->param[2].value != DRCUML_SIZE_QWORD) + if (opcode == OP_READ || opcode == OP_READM || opcode == OP_FREAD) + psize[1] = psize[2] = 4; + if (opcode == OP_WRITE || opcode == OP_WRITEM || opcode == OP_FWRITE) + psize[0] = psize[2] = 4; + if (opcode == OP_SEXT && inst.param(2).size() != SIZE_QWORD) psize[1] = 4; - if (opcode == DRCUML_OP_FTOINT) - psize[0] = 1 << inst->param[2].value; - if (opcode == DRCUML_OP_FFRINT || opcode == DRCUML_OP_FFRFLT) - psize[1] = 1 << inst->param[2].value; - - /* pre-expand opcodes that encode size/scale in them */ - if (opcode == DRCUML_OP_LOAD) - opcode = (drcuml_opcode)(DRCUML_OP_LOAD1 + (inst->param[3].value & 3) * 4 + ((inst->param[3].value >> 4) & 3)); - if (opcode == DRCUML_OP_LOADS) - opcode = (drcuml_opcode)(DRCUML_OP_LOADS1 + (inst->param[3].value & 3) * 4 + ((inst->param[3].value >> 4) & 3)); - if (opcode == DRCUML_OP_STORE) - opcode = (drcuml_opcode)(DRCUML_OP_STORE1 + (inst->param[3].value & 3) * 4 + ((inst->param[3].value >> 4) & 3)); - if (opcode == DRCUML_OP_READ) - opcode = (drcuml_opcode)(DRCUML_OP_READ1 + (inst->param[2].value & 3)); - if (opcode == DRCUML_OP_READM) - opcode = (drcuml_opcode)(DRCUML_OP_READM1 + (inst->param[3].value & 3)); - if (opcode == DRCUML_OP_WRITE) - opcode = (drcuml_opcode)(DRCUML_OP_WRITE1 + (inst->param[2].value & 3)); - if (opcode == DRCUML_OP_WRITEM) - opcode = (drcuml_opcode)(DRCUML_OP_WRITEM1 + (inst->param[3].value & 3)); - if (opcode == DRCUML_OP_SEXT) - opcode = (drcuml_opcode)(DRCUML_OP_SEXT1 + (inst->param[2].value & 3)); - if (opcode == DRCUML_OP_FTOINT) - opcode = (drcuml_opcode)(DRCUML_OP_FTOI4T + 5 * ((inst->param[2].value & 3) - 2) + inst->param[3].value); - if (opcode == DRCUML_OP_FFRINT) - opcode = (drcuml_opcode)(DRCUML_OP_FFRI4 + ((inst->param[2].value & 3) - 2)); - if (opcode == DRCUML_OP_FFRFLT) - opcode = (drcuml_opcode)(DRCUML_OP_FFRFS + ((inst->param[2].value & 3) - 2)); - - /* count how many bytes of immediates we need */ - immedbytes = 0; - for (pnum = 0; pnum < inst->numparams; pnum++) - if (inst->param[pnum].type == DRCUML_PTYPE_MAPVAR || - (inst->param[pnum].type == DRCUML_PTYPE_IMMEDIATE && inst->param[pnum].value != 0)) + if (opcode == OP_FTOINT) + psize[0] = 1 << inst.param(2).size(); + if (opcode == OP_FFRINT || opcode == OP_FFRFLT) + psize[1] = 1 << inst.param(2).size(); + + // pre-expand opcodes that encode size/scale in them + if (opcode == OP_LOAD) + opcode = (opcode_t)(OP_LOAD1 + inst.param(3).size() * 4 + inst.param(3).scale()); + if (opcode == OP_LOADS) + opcode = (opcode_t)(OP_LOADS1 + inst.param(3).size() * 4 + inst.param(3).scale()); + if (opcode == OP_STORE) + opcode = (opcode_t)(OP_STORE1 + inst.param(3).size() * 4 + inst.param(3).scale()); + if (opcode == OP_READ) + opcode = (opcode_t)(OP_READ1 + inst.param(2).size()); + if (opcode == OP_READM) + opcode = (opcode_t)(OP_READM1 + inst.param(3).size()); + if (opcode == OP_WRITE) + opcode = (opcode_t)(OP_WRITE1 + inst.param(2).size()); + if (opcode == OP_WRITEM) + opcode = (opcode_t)(OP_WRITEM1 + inst.param(3).size()); + if (opcode == OP_SEXT) + opcode = (opcode_t)(OP_SEXT1 + inst.param(2).size()); + if (opcode == OP_FTOINT) + opcode = (opcode_t)(OP_FTOI4T + 5 * (inst.param(2).size() - 2) + inst.param(3).rounding()); + if (opcode == OP_FFRINT) + opcode = (opcode_t)(OP_FFRI4 + (inst.param(2).size() - 2)); + if (opcode == OP_FFRFLT) + opcode = (opcode_t)(OP_FFRFS + (inst.param(2).size() - 2)); + + // count how many bytes of immediates we need + int immedbytes = 0; + for (int pnum = 0; pnum < inst.numparams(); pnum++) + if (inst.param(pnum).is_mapvar() || + (inst.param(pnum).is_immediate() && inst.param(pnum).immediate() != 0) || + (inst.param(pnum).is_size_space() && inst.param(pnum).space() != 0)) immedbytes += psize[pnum]; - /* compute how many instruction words we need for that */ - immedwords = (immedbytes + sizeof(drcbec_instruction) - 1) / sizeof(drcbec_instruction); + // compute how many instruction words we need for that + int immedwords = (immedbytes + sizeof(drcbec_instruction) - 1) / sizeof(drcbec_instruction); - /* first item is the opcode, size, condition flags and length */ - (dst++)->i = MAKE_OPCODE_FULL(opcode, inst->size, inst->condition, inst->flags, inst->numparams + immedwords); + // first item is the opcode, size, condition flags and length + (dst++)->i = MAKE_OPCODE_FULL(opcode, inst.size(), inst.condition(), inst.flags(), inst.numparams() + immedwords); - /* immediates start after parameters */ - immed = dst + inst->numparams; + // immediates start after parameters + void *immed = dst + inst.numparams(); - /* output each of the parameters */ - for (pnum = 0; pnum < inst->numparams; pnum++) - output_parameter(drcbe, &dst, &immed, psize[pnum], &inst->param[pnum]); + // output each of the parameters + for (int pnum = 0; pnum < inst.numparams(); pnum++) + output_parameter(&dst, &immed, psize[pnum], inst.param(pnum)); - /* point past the end of the immediates */ + // point past the end of the immediates dst += immedwords; break; } } - /* complete codegen */ + // complete codegen *cachetop = (drccodeptr)dst; - drcbe->cache->end_codegen(); + m_cache.end_codegen(); - /* tell all of our utility objects that the block is finished */ - drcbe->hash->block_end(*block); - drcbe->labels->block_end(*block); - drcbe->map->block_end(*block); + // tell all of our utility objects that the block is finished + m_hash.block_end(block); + m_labels.block_end(block); + m_map.block_end(block); } -/*------------------------------------------------- - drcbec_hash_exists - return true if the - given mode/pc exists in the hash table --------------------------------------------------*/ +//------------------------------------------------- +// hash_exists - return true if the given mode/pc +// exists in the hash table +//------------------------------------------------- -static int drcbec_hash_exists(drcbe_state *state, UINT32 mode, UINT32 pc) +bool drcbe_c::hash_exists(UINT32 mode, UINT32 pc) { - return state->hash->code_exists(mode, pc); + return m_hash.code_exists(mode, pc); } -/*------------------------------------------------- - drcbec_get_info - return information about - the back-end implementation --------------------------------------------------*/ +//------------------------------------------------- +// get_info - return information about the +// back-end implementation +//------------------------------------------------- -static void drcbec_get_info(drcbe_state *state, drcbe_info *info) +void drcbe_c::get_info(drcbe_info &info) { - info->direct_iregs = 0; - info->direct_fregs = 0; + info.direct_iregs = 0; + info.direct_fregs = 0; } +//------------------------------------------------- +// execute - execute a block of code registered +// at the given mode/pc +//------------------------------------------------- -/*************************************************************************** - BACK-END EXECUTION -***************************************************************************/ - -/*------------------------------------------------- - drcbec_execute - execute a block of code - registered at the given mode/pc --------------------------------------------------*/ - -static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) +int drcbe_c::execute(code_handle &entry) { + // get the entry point + const drcbec_instruction *inst = (const drcbec_instruction *)entry.codeptr(); + assert_in_cache(m_cache, inst); + + // loop while we have cycles const drcbec_instruction *callstack[32]; const drcbec_instruction *newinst; - const drcbec_instruction *inst; UINT32 temp32; UINT64 temp64; int shift; UINT8 flags = 0; UINT8 sp = 0; - - /* get the entry point */ - inst = (const drcbec_instruction *)drcuml_handle_codeptr(entry); - assert_in_cache(drcbe->cache, inst); - - /* loop while we have cycles */ - while (TRUE) + while (true) { UINT32 opcode = (inst++)->i; switch (OPCODE_GET_SHORT(opcode)) { - /* ----------------------- Control Flow Operations ----------------------- */ + // ----------------------- Control Flow Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_HANDLE, 4, 0): /* HANDLE handle */ - case MAKE_OPCODE_SHORT(DRCUML_OP_HASH, 4, 0): /* HASH mode,pc */ - case MAKE_OPCODE_SHORT(DRCUML_OP_LABEL, 4, 0): /* LABEL imm */ - case MAKE_OPCODE_SHORT(DRCUML_OP_COMMENT, 4, 0): /* COMMENT string */ - case MAKE_OPCODE_SHORT(DRCUML_OP_MAPVAR, 4, 0): /* MAPVAR mapvar,value */ + case MAKE_OPCODE_SHORT(OP_HANDLE, 4, 0): // HANDLE handle + case MAKE_OPCODE_SHORT(OP_HASH, 4, 0): // HASH mode,pc + case MAKE_OPCODE_SHORT(OP_LABEL, 4, 0): // LABEL imm + case MAKE_OPCODE_SHORT(OP_COMMENT, 4, 0): // COMMENT string + case MAKE_OPCODE_SHORT(OP_MAPVAR, 4, 0): // MAPVAR mapvar,value - /* these opcodes should be processed at compile-time only */ + // these opcodes should be processed at compile-time only fatalerror("Unexpected opcode"); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DEBUG, 4, 0): /* DEBUG pc */ - debugger_instruction_hook(drcbe->device, PARAM0); + case MAKE_OPCODE_SHORT(OP_DEBUG, 4, 0): // DEBUG pc + debugger_instruction_hook(&m_device, PARAM0); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_HASHJMP, 4, 0): /* HASHJMP mode,pc,handle */ + case MAKE_OPCODE_SHORT(OP_HASHJMP, 4, 0): // HASHJMP mode,pc,handle sp = 0; - newinst = (const drcbec_instruction *)drcbe->hash->get_codeptr(PARAM0, PARAM1); + newinst = (const drcbec_instruction *)m_hash.get_codeptr(PARAM0, PARAM1); if (newinst == NULL) { assert(sp < ARRAY_LENGTH(callstack)); - drcbe->state.exp = PARAM1; - newinst = (const drcbec_instruction *)drcuml_handle_codeptr(inst[2].handle); + m_state.exp = PARAM1; + newinst = (const drcbec_instruction *)inst[2].handle->codeptr(); callstack[sp++] = inst; } - assert_in_cache(drcbe->cache, newinst); + assert_in_cache(m_cache, newinst); inst = newinst; continue; - case MAKE_OPCODE_SHORT(DRCUML_OP_EXIT, 4, 1): /* EXIT src1[,c] */ + case MAKE_OPCODE_SHORT(OP_EXIT, 4, 1): // EXIT src1[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_EXIT, 4, 0): + case MAKE_OPCODE_SHORT(OP_EXIT, 4, 0): return PARAM0; - case MAKE_OPCODE_SHORT(DRCUML_OP_JMP, 4, 1): /* JMP imm[,c] */ + case MAKE_OPCODE_SHORT(OP_JMP, 4, 1): // JMP imm[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_JMP, 4, 0): + case MAKE_OPCODE_SHORT(OP_JMP, 4, 0): newinst = inst[0].inst; - assert_in_cache(drcbe->cache, newinst); + assert_in_cache(m_cache, newinst); inst = newinst; continue; - case MAKE_OPCODE_SHORT(DRCUML_OP_CALLH, 4, 1): /* CALLH handle[,c] */ + case MAKE_OPCODE_SHORT(OP_CALLH, 4, 1): // CALLH handle[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_CALLH, 4, 0): + case MAKE_OPCODE_SHORT(OP_CALLH, 4, 0): assert(sp < ARRAY_LENGTH(callstack)); - newinst = (const drcbec_instruction *)drcuml_handle_codeptr(inst[0].handle); - assert_in_cache(drcbe->cache, newinst); + newinst = (const drcbec_instruction *)inst[0].handle->codeptr(); + assert_in_cache(m_cache, newinst); callstack[sp++] = inst + OPCODE_GET_PWORDS(opcode); inst = newinst; continue; - case MAKE_OPCODE_SHORT(DRCUML_OP_RET, 4, 1): /* RET [c] */ + case MAKE_OPCODE_SHORT(OP_RET, 4, 1): // RET [c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_RET, 4, 0): + case MAKE_OPCODE_SHORT(OP_RET, 4, 0): assert(sp > 0); newinst = callstack[--sp]; - assert_in_cache(drcbe->cache, newinst); + assert_in_cache(m_cache, newinst); inst = newinst; continue; - case MAKE_OPCODE_SHORT(DRCUML_OP_EXH, 4, 1): /* EXH handle,param[,c] */ + case MAKE_OPCODE_SHORT(OP_EXH, 4, 1): // EXH handle,param[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_EXH, 4, 0): + case MAKE_OPCODE_SHORT(OP_EXH, 4, 0): assert(sp < ARRAY_LENGTH(callstack)); - newinst = (const drcbec_instruction *)drcuml_handle_codeptr(inst[0].handle); - assert_in_cache(drcbe->cache, newinst); - drcbe->state.exp = PARAM1; + newinst = (const drcbec_instruction *)inst[0].handle->codeptr(); + assert_in_cache(m_cache, newinst); + m_state.exp = PARAM1; callstack[sp++] = inst; inst = newinst; continue; - case MAKE_OPCODE_SHORT(DRCUML_OP_CALLC, 4, 1): /* CALLC func,ptr[,c] */ + case MAKE_OPCODE_SHORT(OP_CALLC, 4, 1): // CALLC func,ptr[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_CALLC, 4, 0): + case MAKE_OPCODE_SHORT(OP_CALLC, 4, 0): (*inst[0].cfunc)(inst[1].v); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RECOVER, 4, 0): /* RECOVER dst,mapvar */ + case MAKE_OPCODE_SHORT(OP_RECOVER, 4, 0): // RECOVER dst,mapvar assert(sp > 0); - PARAM0 = drcbe->map->get_value((drccodeptr)callstack[0], PARAM1); + PARAM0 = m_map.get_value((drccodeptr)callstack[0], PARAM1); break; - /* ----------------------- Internal Register Operations ----------------------- */ + // ----------------------- Internal Register Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_SETFMOD, 4, 0): /* SETFMOD src */ - drcbe->state.fmod = PARAM0; + case MAKE_OPCODE_SHORT(OP_SETFMOD, 4, 0): // SETFMOD src + m_state.fmod = PARAM0; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_GETFMOD, 4, 0): /* GETFMOD dst */ - PARAM0 = drcbe->state.fmod; + case MAKE_OPCODE_SHORT(OP_GETFMOD, 4, 0): // GETFMOD dst + PARAM0 = m_state.fmod; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_GETEXP, 4, 0): /* GETEXP dst */ - PARAM0 = drcbe->state.exp; + case MAKE_OPCODE_SHORT(OP_GETEXP, 4, 0): // GETEXP dst + PARAM0 = m_state.exp; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_GETFLGS, 4, 0): /* GETFLGS dst[,f] */ + case MAKE_OPCODE_SHORT(OP_GETFLGS, 4, 0): // GETFLGS dst[,f] PARAM0 = flags & PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SAVE, 4, 0): /* SAVE dst */ - *inst[0].state = drcbe->state; + case MAKE_OPCODE_SHORT(OP_SAVE, 4, 0): // SAVE dst + *inst[0].state = m_state; inst[0].state->flags = flags; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RESTORE, 4, 0): /* RESTORE dst */ - case MAKE_OPCODE_SHORT(DRCUML_OP_RESTORE, 4, 1): /* RESTORE dst */ - drcbe->state = *inst[0].state; + case MAKE_OPCODE_SHORT(OP_RESTORE, 4, 0): // RESTORE dst + case MAKE_OPCODE_SHORT(OP_RESTORE, 4, 1): // RESTORE dst + m_state = *inst[0].state; flags = inst[0].state->flags; break; - /* ----------------------- 32-Bit Integer Operations ----------------------- */ + // ----------------------- 32-Bit Integer Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1, 4, 0): /* LOAD dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_LOAD1, 4, 0): // LOAD dst,base,index,BYTE PARAM0 = inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x2, 4, 0): /* LOAD dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x2, 4, 0): // LOAD dst,base,index,BYTE_x2 PARAM0 = *(UINT8 *)&inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x4, 4, 0): /* LOAD dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x4, 4, 0): // LOAD dst,base,index,BYTE_x4 PARAM0 = *(UINT8 *)&inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x8, 4, 0): /* LOAD dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x8, 4, 0): // LOAD dst,base,index,BYTE_x8 PARAM0 = *(UINT8 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x1, 4, 0): /* LOAD dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x1, 4, 0): // LOAD dst,base,index,WORD_x1 PARAM0 = *(UINT16 *)&inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2, 4, 0): /* LOAD dst,base,index,WORD */ + case MAKE_OPCODE_SHORT(OP_LOAD2, 4, 0): // LOAD dst,base,index,WORD PARAM0 = inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x4, 4, 0): /* LOAD dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x4, 4, 0): // LOAD dst,base,index,WORD_x4 PARAM0 = *(UINT16 *)&inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x8, 4, 0): /* LOAD dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x8, 4, 0): // LOAD dst,base,index,WORD_x8 PARAM0 = *(UINT16 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x1, 4, 0): /* LOAD dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x1, 4, 0): // LOAD dst,base,index,DWORD_x1 PARAM0 = *(UINT32 *)&inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x2, 4, 0): /* LOAD dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x2, 4, 0): // LOAD dst,base,index,DWORD_x2 PARAM0 = *(UINT32 *)&inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4, 4, 0): /* LOAD dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_LOAD4, 4, 0): // LOAD dst,base,index,DWORD PARAM0 = inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x8, 4, 0): /* LOAD dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x8, 4, 0): // LOAD dst,base,index,DWORD_x8 PARAM0 = *(UINT32 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1, 4, 0): /* LOADS dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_LOADS1, 4, 0): // LOADS dst,base,index,BYTE PARAM0 = inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x2, 4, 0): /* LOADS dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x2, 4, 0): // LOADS dst,base,index,BYTE_x2 PARAM0 = *(INT8 *)&inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x4, 4, 0): /* LOADS dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x4, 4, 0): // LOADS dst,base,index,BYTE_x4 PARAM0 = *(INT8 *)&inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x8, 4, 0): /* LOADS dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x8, 4, 0): // LOADS dst,base,index,BYTE_x8 PARAM0 = *(INT8 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x1, 4, 0): /* LOADS dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x1, 4, 0): // LOADS dst,base,index,WORD_x1 PARAM0 = *(INT16 *)&inst[1].pint8[PARAM2]; break; - - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2, 4, 0): /* LOADS dst,base,index,WORD */ + + case MAKE_OPCODE_SHORT(OP_LOADS2, 4, 0): // LOADS dst,base,index,WORD PARAM0 = inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x4, 4, 0): /* LOADS dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x4, 4, 0): // LOADS dst,base,index,WORD_x4 PARAM0 = *(INT16 *)&inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x8, 4, 0): /* LOADS dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x8, 4, 0): // LOADS dst,base,index,WORD_x8 PARAM0 = *(INT16 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x1, 4, 0): /* LOADS dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x1, 4, 0): // LOADS dst,base,index,DWORD_x1 PARAM0 = *(INT32 *)&inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x2, 4, 0): /* LOADS dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x2, 4, 0): // LOADS dst,base,index,DWORD_x2 PARAM0 = *(INT32 *)&inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4, 4, 0): /* LOADS dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_LOADS4, 4, 0): // LOADS dst,base,index,DWORD PARAM0 = inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x8, 4, 0): /* LOADS dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x8, 4, 0): // LOADS dst,base,index,DWORD_x8 PARAM0 = *(INT32 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 4, 0): /* STORE dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_STORE1, 4, 0): // STORE dst,base,index,BYTE inst[0].puint8[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x2, 4, 0): /* STORE dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_STORE1x2, 4, 0): // STORE dst,base,index,BYTE_x2 *(UINT8 *)&inst[0].puint16[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x4, 4, 0): /* STORE dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_STORE1x4, 4, 0): // STORE dst,base,index,BYTE_x4 *(UINT8 *)&inst[0].puint32[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x8, 4, 0): /* STORE dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE1x8, 4, 0): // STORE dst,base,index,BYTE_x8 *(UINT8 *)&inst[0].puint64[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x1, 4, 0): /* STORE dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_STORE2x1, 4, 0): // STORE dst,base,index,WORD_x1 *(UINT16 *)&inst[0].puint8[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 4, 0): /* STORE dst,base,index,WORD */ + case MAKE_OPCODE_SHORT(OP_STORE2, 4, 0): // STORE dst,base,index,WORD inst[0].puint16[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x4, 4, 0): /* STORE dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_STORE2x4, 4, 0): // STORE dst,base,index,WORD_x4 *(UINT16 *)&inst[0].puint32[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x8, 4, 0): /* STORE dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE2x8, 4, 0): // STORE dst,base,index,WORD_x8 *(UINT16 *)&inst[0].puint64[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x1, 4, 0): /* STORE dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_STORE4x1, 4, 0): // STORE dst,base,index,DWORD_x1 *(UINT32 *)&inst[0].puint8[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x2, 4, 0): /* STORE dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_STORE4x2, 4, 0): // STORE dst,base,index,DWORD_x2 *(UINT32 *)&inst[0].puint16[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 4, 0): /* STORE dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_STORE4, 4, 0): // STORE dst,base,index,DWORD inst[0].puint32[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x8, 4, 0): /* STORE dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE4x8, 4, 0): // STORE dst,base,index,DWORD_x8 *(UINT32 *)&inst[0].puint64[PARAM1] = PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ1, 4, 0): /* READ dst,src1,space_BYTE */ - PARAM0 = drcbe->space[PARAM2 / 16]->read_byte(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ1, 4, 0): // READ dst,src1,space_BYTE + PARAM0 = m_space[PARAM2]->read_byte(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ2, 4, 0): /* READ dst,src1,space_WORD */ - PARAM0 = drcbe->space[PARAM2 / 16]->read_word(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ2, 4, 0): // READ dst,src1,space_WORD + PARAM0 = m_space[PARAM2]->read_word(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ4, 4, 0): /* READ dst,src1,space_DWORD */ - PARAM0 = drcbe->space[PARAM2 / 16]->read_dword(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ4, 4, 0): // READ dst,src1,space_DWORD + PARAM0 = m_space[PARAM2]->read_dword(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READM2, 4, 0): /* READM dst,src1,mask,space_WORD */ - PARAM0 = drcbe->space[PARAM3 / 16]->read_word(PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_READM2, 4, 0): // READM dst,src1,mask,space_WORD + PARAM0 = m_space[PARAM3]->read_word(PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READM4, 4, 0): /* READM dst,src1,mask,space_DWORD */ - PARAM0 = drcbe->space[PARAM3 / 16]->read_dword(PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_READM4, 4, 0): // READM dst,src1,mask,space_DWORD + PARAM0 = m_space[PARAM3]->read_dword(PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 4, 0): /* WRITE dst,src1,space_BYTE */ - drcbe->space[PARAM2 / 16]->write_byte(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE1, 4, 0): // WRITE dst,src1,space_BYTE + m_space[PARAM2]->write_byte(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 4, 0): /* WRITE dst,src1,space_WORD */ - drcbe->space[PARAM2 / 16]->write_word(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE2, 4, 0): // WRITE dst,src1,space_WORD + m_space[PARAM2]->write_word(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 4, 0): /* WRITE dst,src1,space_DWORD */ - drcbe->space[PARAM2 / 16]->write_dword(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE4, 4, 0): // WRITE dst,src1,space_DWORD + m_space[PARAM2]->write_dword(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM2, 4, 0): /* WRITEM dst,src1,mask,space_WORD */ - drcbe->space[PARAM3 / 16]->write_word(PARAM0, PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_WRITEM2, 4, 0): // WRITEM dst,src1,mask,space_WORD + m_space[PARAM3]->write_word(PARAM0, PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM4, 4, 0): /* WRITEM dst,src1,mask,space_DWORD */ - drcbe->space[PARAM3 / 16]->write_dword(PARAM0, PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_WRITEM4, 4, 0): // WRITEM dst,src1,mask,space_DWORD + m_space[PARAM3]->write_dword(PARAM0, PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_CARRY, 4, 1): /* CARRY src,bitnum */ - flags = (flags & ~DRCUML_FLAG_C) | ((PARAM0 >> (PARAM1 & 31)) & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_CARRY, 4, 1): // CARRY src,bitnum + flags = (flags & ~FLAG_C) | ((PARAM0 >> (PARAM1 & 31)) & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MOV, 4, 1): /* MOV dst,src[,c] */ + case MAKE_OPCODE_SHORT(OP_MOV, 4, 1): // MOV dst,src[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_MOV, 4, 0): + case MAKE_OPCODE_SHORT(OP_MOV, 4, 0): PARAM0 = PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SET, 4, 1): /* SET dst,c */ + case MAKE_OPCODE_SHORT(OP_SET, 4, 1): // SET dst,c PARAM0 = OPCODE_FAIL_CONDITION(opcode, flags) ? 0 : 1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 4, 0): /* SEXT1 dst,src */ + case MAKE_OPCODE_SHORT(OP_SEXT1, 4, 0): // SEXT1 dst,src PARAM0 = (INT8)PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 4, 1): + case MAKE_OPCODE_SHORT(OP_SEXT1, 4, 1): temp32 = (INT8)PARAM1; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 4, 0): /* SEXT2 dst,src */ + case MAKE_OPCODE_SHORT(OP_SEXT2, 4, 0): // SEXT2 dst,src PARAM0 = (INT16)PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 4, 1): + case MAKE_OPCODE_SHORT(OP_SEXT2, 4, 1): temp32 = (INT16)PARAM1; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 4, 0): /* ROLAND dst,src,count,mask[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLAND, 4, 0): // ROLAND dst,src,count,mask[,f] shift = PARAM2 & 31; PARAM0 = ((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 4, 1): + case MAKE_OPCODE_SHORT(OP_ROLAND, 4, 1): shift = PARAM2 & 31; temp32 = ((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 4, 0): /* ROLINS dst,src,count,mask[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLINS, 4, 0): // ROLINS dst,src,count,mask[,f] shift = PARAM2 & 31; PARAM0 = (PARAM0 & ~PARAM3) | (((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 4, 1): + case MAKE_OPCODE_SHORT(OP_ROLINS, 4, 1): shift = PARAM2 & 31; temp32 = (PARAM0 & ~PARAM3) | (((PARAM1 << shift) | (PARAM1 >> (32 - shift))) & PARAM3); flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADD, 4, 0): /* ADD dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_ADD, 4, 0): // ADD dst,src1,src2[,f] PARAM0 = PARAM1 + PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADD, 4, 1): + case MAKE_OPCODE_SHORT(OP_ADD, 4, 1): temp32 = PARAM1 + PARAM2; flags = FLAGS32_NZCV_ADD(temp32, PARAM1, PARAM2); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 4, 0): /* ADDC dst,src1,src2[,f] */ - PARAM0 = PARAM1 + PARAM2 + (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_ADDC, 4, 0): // ADDC dst,src1,src2[,f] + PARAM0 = PARAM1 + PARAM2 + (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 4, 1): - temp32 = PARAM1 + PARAM2 + (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_ADDC, 4, 1): + temp32 = PARAM1 + PARAM2 + (flags & FLAG_C); if (PARAM2 + 1 != 0) - flags = FLAGS32_NZCV_ADD(temp32, PARAM1, PARAM2 + (flags & DRCUML_FLAG_C)); + flags = FLAGS32_NZCV_ADD(temp32, PARAM1, PARAM2 + (flags & FLAG_C)); else - flags = FLAGS32_NZCV_ADD(temp32, PARAM1 + (flags & DRCUML_FLAG_C), PARAM2); + flags = FLAGS32_NZCV_ADD(temp32, PARAM1 + (flags & FLAG_C), PARAM2); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUB, 4, 0): /* SUB dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_SUB, 4, 0): // SUB dst,src1,src2[,f] PARAM0 = PARAM1 - PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUB, 4, 1): + case MAKE_OPCODE_SHORT(OP_SUB, 4, 1): temp32 = PARAM1 - PARAM2; flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 4, 0): /* SUBB dst,src1,src2[,f] */ - PARAM0 = PARAM1 - PARAM2 - (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_SUBB, 4, 0): // SUBB dst,src1,src2[,f] + PARAM0 = PARAM1 - PARAM2 - (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 4, 1): - temp32 = PARAM1 - PARAM2 - (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_SUBB, 4, 1): + temp32 = PARAM1 - PARAM2 - (flags & FLAG_C); if (PARAM2 + 1 != 0) - flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2 + (flags & DRCUML_FLAG_C)); + flags = FLAGS32_NZCV_SUB(temp32, PARAM1, PARAM2 + (flags & FLAG_C)); else - flags = FLAGS32_NZCV_SUB(temp32, PARAM1 - (flags & DRCUML_FLAG_C), PARAM2); + flags = FLAGS32_NZCV_SUB(temp32, PARAM1 - (flags & FLAG_C), PARAM2); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_CMP, 4, 1): /* CMP src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_CMP, 4, 1): // CMP src1,src2[,f] temp32 = PARAM0 - PARAM1; flags = FLAGS32_NZCV_SUB(temp32, PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULU, 4, 0): /* MULU dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_MULU, 4, 0): // MULU dst,edst,src1,src2[,f] temp64 = (UINT64)(UINT32)PARAM2 * (UINT64)(UINT32)PARAM3; PARAM1 = temp64 >> 32; PARAM0 = (UINT32)temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULU, 4, 1): + case MAKE_OPCODE_SHORT(OP_MULU, 4, 1): temp64 = (UINT64)(UINT32)PARAM2 * (UINT64)(UINT32)PARAM3; flags = FLAGS64_NZ(temp64); PARAM1 = temp64 >> 32; PARAM0 = (UINT32)temp64; if (temp64 != (UINT32)temp64) - flags |= DRCUML_FLAG_V; + flags |= FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULS, 4, 0): /* MULS dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_MULS, 4, 0): // MULS dst,edst,src1,src2[,f] temp64 = (INT64)(INT32)PARAM2 * (INT64)(INT32)PARAM3; PARAM1 = temp64 >> 32; PARAM0 = (UINT32)temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULS, 4, 1): + case MAKE_OPCODE_SHORT(OP_MULS, 4, 1): temp64 = (INT64)(INT32)PARAM2 * (INT64)(INT32)PARAM3; flags = FLAGS64_NZ(temp64); PARAM1 = temp64 >> 32; PARAM0 = (UINT32)temp64; if (temp64 != (INT32)temp64) - flags |= DRCUML_FLAG_V; + flags |= FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVU, 4, 0): /* DIVU dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_DIVU, 4, 0): // DIVU dst,edst,src1,src2[,f] if (PARAM3 != 0) { temp32 = (UINT32)PARAM2 / (UINT32)PARAM3; @@ -1087,7 +1008,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) } break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVU, 4, 1): + case MAKE_OPCODE_SHORT(OP_DIVU, 4, 1): if (PARAM3 != 0) { temp32 = (UINT32)PARAM2 / (UINT32)PARAM3; @@ -1096,10 +1017,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) PARAM0 = temp32; } else - flags = DRCUML_FLAG_V; + flags = FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVS, 4, 0): /* DIVS dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_DIVS, 4, 0): // DIVS dst,edst,src1,src2[,f] if (PARAM3 != 0) { temp32 = (INT32)PARAM2 / (INT32)PARAM3; @@ -1108,7 +1029,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) } break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVS, 4, 1): + case MAKE_OPCODE_SHORT(OP_DIVS, 4, 1): if (PARAM3 != 0) { temp32 = (INT32)PARAM2 / (INT32)PARAM3; @@ -1117,559 +1038,559 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) PARAM0 = temp32; } else - flags = DRCUML_FLAG_V; + flags = FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_AND, 4, 0): /* AND dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_AND, 4, 0): // AND dst,src1,src2[,f] PARAM0 = PARAM1 & PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_AND, 4, 1): + case MAKE_OPCODE_SHORT(OP_AND, 4, 1): temp32 = PARAM1 & PARAM2; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_TEST, 4, 1): /* TEST src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_TEST, 4, 1): // TEST src1,src2[,f] temp32 = PARAM0 & PARAM1; flags = FLAGS32_NZ(temp32); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_OR, 4, 0): /* OR dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_OR, 4, 0): // OR dst,src1,src2[,f] PARAM0 = PARAM1 | PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_OR, 4, 1): + case MAKE_OPCODE_SHORT(OP_OR, 4, 1): temp32 = PARAM1 | PARAM2; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_XOR, 4, 0): /* XOR dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_XOR, 4, 0): // XOR dst,src1,src2[,f] PARAM0 = PARAM1 ^ PARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_XOR, 4, 1): + case MAKE_OPCODE_SHORT(OP_XOR, 4, 1): temp32 = PARAM1 ^ PARAM2; flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LZCNT, 4, 0): /* LZCNT dst,src */ + case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 0): // LZCNT dst,src PARAM0 = count_leading_zeros(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LZCNT, 4, 1): + case MAKE_OPCODE_SHORT(OP_LZCNT, 4, 1): temp32 = count_leading_zeros(PARAM1); flags = FLAGS32_NZ(temp32); PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_BSWAP, 4, 0): /* BSWAP dst,src */ + case MAKE_OPCODE_SHORT(OP_BSWAP, 4, 0): // BSWAP dst,src temp32 = PARAM1; PARAM0 = FLIPENDIAN_INT32(temp32); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_BSWAP, 4, 1): + case MAKE_OPCODE_SHORT(OP_BSWAP, 4, 1): temp32 = PARAM1; flags = FLAGS32_NZ(temp32); PARAM0 = FLIPENDIAN_INT32(temp32); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHL, 4, 0): /* SHL dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SHL, 4, 0): // SHL dst,src,count[,f] PARAM0 = PARAM1 << (PARAM2 & 31); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHL, 4, 1): + case MAKE_OPCODE_SHORT(OP_SHL, 4, 1): shift = PARAM2 & 31; temp32 = PARAM1 << shift; flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHR, 4, 0): /* SHR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SHR, 4, 0): // SHR dst,src,count[,f] PARAM0 = PARAM1 >> (PARAM2 & 31); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHR, 4, 1): + case MAKE_OPCODE_SHORT(OP_SHR, 4, 1): shift = PARAM2 & 31; temp32 = PARAM1 >> shift; flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SAR, 4, 0): /* SAR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SAR, 4, 0): // SAR dst,src,count[,f] PARAM0 = (INT32)PARAM1 >> (PARAM2 & 31); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SAR, 4, 1): + case MAKE_OPCODE_SHORT(OP_SAR, 4, 1): shift = PARAM2 & 31; temp32 = (INT32)PARAM1 >> shift; flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROL, 4, 0): /* ROL dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROL, 4, 0): // ROL dst,src,count[,f] shift = PARAM2 & 31; PARAM0 = (PARAM1 << shift) | (PARAM1 >> ((32 - shift) & 31)); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROL, 4, 1): + case MAKE_OPCODE_SHORT(OP_ROL, 4, 1): shift = PARAM2 & 31; temp32 = (PARAM1 << shift) | (PARAM1 >> ((32 - shift) & 31)); flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLC, 4, 0): /* ROLC dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLC, 4, 0): // ROLC dst,src,count[,f] shift = PARAM2 & 31; if (shift > 1) - PARAM0 = (PARAM1 << shift) | ((flags & DRCUML_FLAG_C) << (shift - 1)) | (PARAM1 >> (33 - shift)); + PARAM0 = (PARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (PARAM1 >> (33 - shift)); else if (shift == 1) - PARAM0 = (PARAM1 << shift) | (flags & DRCUML_FLAG_C); + PARAM0 = (PARAM1 << shift) | (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLC, 4, 1): + case MAKE_OPCODE_SHORT(OP_ROLC, 4, 1): shift = PARAM2 & 31; if (shift > 1) - temp32 = (PARAM1 << shift) | ((flags & DRCUML_FLAG_C) << (shift - 1)) | (PARAM1 >> (33 - shift)); + temp32 = (PARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (PARAM1 >> (33 - shift)); else if (shift == 1) - temp32 = (PARAM1 << shift) | (flags & DRCUML_FLAG_C); + temp32 = (PARAM1 << shift) | (flags & FLAG_C); else temp32 = PARAM1; flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((PARAM1 << (shift - 1)) >> 31) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROR, 4, 0): /* ROR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROR, 4, 0): // ROR dst,src,count[,f] shift = PARAM2 & 31; PARAM0 = (PARAM1 >> shift) | (PARAM1 << ((32 - shift) & 31)); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROR, 4, 1): + case MAKE_OPCODE_SHORT(OP_ROR, 4, 1): shift = PARAM2 & 31; temp32 = (PARAM1 >> shift) | (PARAM1 << ((32 - shift) & 31)); flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C; PARAM0 = temp32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RORC, 4, 0): /* RORC dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_RORC, 4, 0): // RORC dst,src,count[,f] shift = PARAM2 & 31; if (shift > 1) - PARAM0 = (PARAM1 >> shift) | (((flags & DRCUML_FLAG_C) << 31) >> (shift - 1)) | (PARAM1 << (33 - shift)); + PARAM0 = (PARAM1 >> shift) | (((flags & FLAG_C) << 31) >> (shift - 1)) | (PARAM1 << (33 - shift)); else if (shift == 1) - PARAM0 = (PARAM1 >> shift) | ((flags & DRCUML_FLAG_C) << 31); + PARAM0 = (PARAM1 >> shift) | ((flags & FLAG_C) << 31); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RORC, 4, 1): + case MAKE_OPCODE_SHORT(OP_RORC, 4, 1): shift = PARAM2 & 31; if (shift > 1) - temp32 = (PARAM1 >> shift) | (((flags & DRCUML_FLAG_C) << 31) >> (shift - 1)) | (PARAM1 << (33 - shift)); + temp32 = (PARAM1 >> shift) | (((flags & FLAG_C) << 31) >> (shift - 1)) | (PARAM1 << (33 - shift)); else if (shift == 1) - temp32 = (PARAM1 >> shift) | ((flags & DRCUML_FLAG_C) << 31); + temp32 = (PARAM1 >> shift) | ((flags & FLAG_C) << 31); else temp32 = PARAM1; flags = FLAGS32_NZ(temp32); - if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (PARAM1 >> (shift - 1)) & FLAG_C; PARAM0 = temp32; break; - /* ----------------------- 64-Bit Integer Operations ----------------------- */ + // ----------------------- 64-Bit Integer Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1, 8, 0): /* DLOAD dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_LOAD1, 8, 0): // DLOAD dst,base,index,BYTE DPARAM0 = inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x2, 8, 0): /* DLOAD dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x2, 8, 0): // DLOAD dst,base,index,BYTE_x2 DPARAM0 = *(UINT8 *)&inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x4, 8, 0): /* DLOAD dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x4, 8, 0): // DLOAD dst,base,index,BYTE_x4 DPARAM0 = *(UINT8 *)&inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD1x8, 8, 0): /* DLOAD dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD1x8, 8, 0): // DLOAD dst,base,index,BYTE_x8 DPARAM0 = *(UINT8 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x1, 8, 0): /* DLOAD dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x1, 8, 0): // DLOAD dst,base,index,WORD_x1 DPARAM0 = *(UINT16 *)&inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2, 8, 0): /* DLOAD dst,base,index,WORD */ + case MAKE_OPCODE_SHORT(OP_LOAD2, 8, 0): // DLOAD dst,base,index,WORD DPARAM0 = inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x4, 8, 0): /* DLOAD dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x4, 8, 0): // DLOAD dst,base,index,WORD_x4 DPARAM0 = *(UINT16 *)&inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD2x8, 8, 0): /* DLOAD dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD2x8, 8, 0): // DLOAD dst,base,index,WORD_x8 DPARAM0 = *(UINT16 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x1, 8, 0): /* DLOAD dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x1, 8, 0): // DLOAD dst,base,index,DWORD_x1 DPARAM0 = *(UINT32 *)&inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x2, 8, 0): /* DLOAD dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x2, 8, 0): // DLOAD dst,base,index,DWORD_x2 DPARAM0 = *(UINT32 *)&inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4, 8, 0): /* DLOAD dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_LOAD4, 8, 0): // DLOAD dst,base,index,DWORD DPARAM0 = inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD4x8, 8, 0): /* DLOAD dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOAD4x8, 8, 0): // DLOAD dst,base,index,DWORD_x8 DPARAM0 = *(UINT32 *)&inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8x1, 8, 0): /* DLOAD dst,base,index,QWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOAD8x1, 8, 0): // DLOAD dst,base,index,QWORD_x1 DPARAM0 = *(UINT64 *)&inst[1].puint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8x2, 8, 0): /* DLOAD dst,base,index,QWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOAD8x2, 8, 0): // DLOAD dst,base,index,QWORD_x2 DPARAM0 = *(UINT64 *)&inst[1].puint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8x4, 8, 0): /* DLOAD dst,base,index,QWORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOAD8x4, 8, 0): // DLOAD dst,base,index,QWORD_x4 DPARAM0 = *(UINT64 *)&inst[1].puint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOAD8, 8, 0): /* DLOAD dst,base,index,QWORD */ + case MAKE_OPCODE_SHORT(OP_LOAD8, 8, 0): // DLOAD dst,base,index,QWORD DPARAM0 = inst[1].puint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1, 8, 0): /* DLOADS dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_LOADS1, 8, 0): // DLOADS dst,base,index,BYTE DPARAM0 = inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x2, 8, 0): /* DLOADS dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x2, 8, 0): // DLOADS dst,base,index,BYTE_x2 DPARAM0 = *(INT8 *)&inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x4, 8, 0): /* DLOADS dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x4, 8, 0): // DLOADS dst,base,index,BYTE_x4 DPARAM0 = *(INT8 *)&inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS1x8, 8, 0): /* DLOADS dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS1x8, 8, 0): // DLOADS dst,base,index,BYTE_x8 DPARAM0 = *(INT8 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x1, 8, 0): /* DLOADS dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x1, 8, 0): // DLOADS dst,base,index,WORD_x1 DPARAM0 = *(INT16 *)&inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2, 8, 0): /* DLOADS dst,base,index,WORD */ + case MAKE_OPCODE_SHORT(OP_LOADS2, 8, 0): // DLOADS dst,base,index,WORD DPARAM0 = inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x4, 8, 0): /* DLOADS dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x4, 8, 0): // DLOADS dst,base,index,WORD_x4 DPARAM0 = *(INT16 *)&inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS2x8, 8, 0): /* DLOADS dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS2x8, 8, 0): // DLOADS dst,base,index,WORD_x8 DPARAM0 = *(INT16 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x1, 8, 0): /* DLOADS dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x1, 8, 0): // DLOADS dst,base,index,DWORD_x1 DPARAM0 = *(INT32 *)&inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x2, 8, 0): /* DLOADS dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x2, 8, 0): // DLOADS dst,base,index,DWORD_x2 DPARAM0 = *(INT32 *)&inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4, 8, 0): /* DLOADS dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_LOADS4, 8, 0): // DLOADS dst,base,index,DWORD DPARAM0 = inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS4x8, 8, 0): /* DLOADS dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_LOADS4x8, 8, 0): // DLOADS dst,base,index,DWORD_x8 DPARAM0 = *(INT32 *)&inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS8x1, 8, 0): /* DLOADS dst,base,index,QWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_LOADS8x1, 8, 0): // DLOADS dst,base,index,QWORD_x1 DPARAM0 = *(INT64 *)&inst[1].pint8[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS8x2, 8, 0): /* DLOADS dst,base,index,QWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_LOADS8x2, 8, 0): // DLOADS dst,base,index,QWORD_x2 DPARAM0 = *(INT64 *)&inst[1].pint16[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS8x4, 8, 0): /* DLOADS dst,base,index,QWORD_x4 */ + case MAKE_OPCODE_SHORT(OP_LOADS8x4, 8, 0): // DLOADS dst,base,index,QWORD_x4 DPARAM0 = *(INT64 *)&inst[1].pint32[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LOADS8, 8, 0): /* DLOADS dst,base,index,QWORD */ + case MAKE_OPCODE_SHORT(OP_LOADS8, 8, 0): // DLOADS dst,base,index,QWORD DPARAM0 = inst[1].pint64[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1, 8, 0): /* DSTORE dst,base,index,BYTE */ + case MAKE_OPCODE_SHORT(OP_STORE1, 8, 0): // DSTORE dst,base,index,BYTE inst[0].puint8[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x2, 8, 0): /* DSTORE dst,base,index,BYTE_x2 */ + case MAKE_OPCODE_SHORT(OP_STORE1x2, 8, 0): // DSTORE dst,base,index,BYTE_x2 *(UINT8 *)&inst[0].puint16[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x4, 8, 0): /* DSTORE dst,base,index,BYTE_x4 */ + case MAKE_OPCODE_SHORT(OP_STORE1x4, 8, 0): // DSTORE dst,base,index,BYTE_x4 *(UINT8 *)&inst[0].puint32[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE1x8, 8, 0): /* DSTORE dst,base,index,BYTE_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE1x8, 8, 0): // DSTORE dst,base,index,BYTE_x8 *(UINT8 *)&inst[0].puint64[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x1, 8, 0): /* DSTORE dst,base,index,WORD_x1 */ + case MAKE_OPCODE_SHORT(OP_STORE2x1, 8, 0): // DSTORE dst,base,index,WORD_x1 *(UINT16 *)&inst[0].puint8[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2, 8, 0): /* DSTORE dst,base,index,WORD */ + case MAKE_OPCODE_SHORT(OP_STORE2, 8, 0): // DSTORE dst,base,index,WORD inst[0].puint16[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x4, 8, 0): /* DSTORE dst,base,index,WORD_x4 */ + case MAKE_OPCODE_SHORT(OP_STORE2x4, 8, 0): // DSTORE dst,base,index,WORD_x4 *(UINT16 *)&inst[0].puint32[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE2x8, 8, 0): /* DSTORE dst,base,index,WORD_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE2x8, 8, 0): // DSTORE dst,base,index,WORD_x8 *(UINT16 *)&inst[0].puint64[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x1, 8, 0): /* DSTORE dst,base,index,DWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_STORE4x1, 8, 0): // DSTORE dst,base,index,DWORD_x1 *(UINT32 *)&inst[0].puint8[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x2, 8, 0): /* DSTORE dst,base,index,DWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_STORE4x2, 8, 0): // DSTORE dst,base,index,DWORD_x2 *(UINT32 *)&inst[0].puint16[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4, 8, 0): /* DSTORE dst,base,index,DWORD */ + case MAKE_OPCODE_SHORT(OP_STORE4, 8, 0): // DSTORE dst,base,index,DWORD inst[0].puint32[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE4x8, 8, 0): /* DSTORE dst,base,index,DWORD_x8 */ + case MAKE_OPCODE_SHORT(OP_STORE4x8, 8, 0): // DSTORE dst,base,index,DWORD_x8 *(UINT32 *)&inst[0].puint64[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8x1, 8, 0): /* DSTORE dst,base,index,QWORD_x1 */ + case MAKE_OPCODE_SHORT(OP_STORE8x1, 8, 0): // DSTORE dst,base,index,QWORD_x1 *(UINT64 *)&inst[0].puint8[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8x2, 8, 0): /* DSTORE dst,base,index,QWORD_x2 */ + case MAKE_OPCODE_SHORT(OP_STORE8x2, 8, 0): // DSTORE dst,base,index,QWORD_x2 *(UINT64 *)&inst[0].puint16[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8x4, 8, 0): /* DSTORE dst,base,index,QWORD_x4 */ + case MAKE_OPCODE_SHORT(OP_STORE8x4, 8, 0): // DSTORE dst,base,index,QWORD_x4 *(UINT64 *)&inst[0].puint32[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_STORE8, 8, 0): /* DSTORE dst,base,index,QWORD */ + case MAKE_OPCODE_SHORT(OP_STORE8, 8, 0): // DSTORE dst,base,index,QWORD inst[0].puint64[PARAM1] = DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ1, 8, 0): /* DREAD dst,src1,space_BYTE */ - DPARAM0 = drcbe->space[PARAM2 / 16]->read_byte(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ1, 8, 0): // DREAD dst,src1,space_BYTE + DPARAM0 = m_space[PARAM2]->read_byte(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ2, 8, 0): /* DREAD dst,src1,space_WORD */ - DPARAM0 = drcbe->space[PARAM2 / 16]->read_word(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ2, 8, 0): // DREAD dst,src1,space_WORD + DPARAM0 = m_space[PARAM2]->read_word(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ4, 8, 0): /* DREAD dst,src1,space_DWORD */ - DPARAM0 = drcbe->space[PARAM2 / 16]->read_dword(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ4, 8, 0): // DREAD dst,src1,space_DWORD + DPARAM0 = m_space[PARAM2]->read_dword(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READ8, 8, 0): /* DREAD dst,src1,space_QOWRD */ - DPARAM0 = drcbe->space[PARAM2 / 16]->read_qword(PARAM1); + case MAKE_OPCODE_SHORT(OP_READ8, 8, 0): // DREAD dst,src1,space_QOWRD + DPARAM0 = m_space[PARAM2]->read_qword(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READM2, 8, 0): /* DREADM dst,src1,mask,space_WORD */ - DPARAM0 = drcbe->space[PARAM3 / 16]->read_word(PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_READM2, 8, 0): // DREADM dst,src1,mask,space_WORD + DPARAM0 = m_space[PARAM3]->read_word(PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READM4, 8, 0): /* DREADM dst,src1,mask,space_DWORD */ - DPARAM0 = drcbe->space[PARAM3 / 16]->read_dword(PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_READM4, 8, 0): // DREADM dst,src1,mask,space_DWORD + DPARAM0 = m_space[PARAM3]->read_dword(PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_READM8, 8, 0): /* DREADM dst,src1,mask,space_QWORD */ - DPARAM0 = drcbe->space[PARAM3 / 16]->read_qword(PARAM1, PARAM2); + case MAKE_OPCODE_SHORT(OP_READM8, 8, 0): // DREADM dst,src1,mask,space_QWORD + DPARAM0 = m_space[PARAM3]->read_qword(PARAM1, PARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE1, 8, 0): /* DWRITE dst,src1,space_BYTE */ - drcbe->space[PARAM2 / 16]->write_byte(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE1, 8, 0): // DWRITE dst,src1,space_BYTE + m_space[PARAM2]->write_byte(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE2, 8, 0): /* DWRITE dst,src1,space_WORD */ - drcbe->space[PARAM2 / 16]->write_word(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE2, 8, 0): // DWRITE dst,src1,space_WORD + m_space[PARAM2]->write_word(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE4, 8, 0): /* DWRITE dst,src1,space_DWORD */ - drcbe->space[PARAM2 / 16]->write_dword(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE4, 8, 0): // DWRITE dst,src1,space_DWORD + m_space[PARAM2]->write_dword(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITE8, 8, 0): /* DWRITE dst,src1,space_QWORD */ - drcbe->space[PARAM2 / 16]->write_qword(PARAM0, DPARAM1); + case MAKE_OPCODE_SHORT(OP_WRITE8, 8, 0): // DWRITE dst,src1,space_QWORD + m_space[PARAM2]->write_qword(PARAM0, DPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM2, 8, 0): /* DWRITEM dst,src1,mask,space_WORD */ - drcbe->space[PARAM3 / 16]->write_word(PARAM0, DPARAM1, DPARAM2); + case MAKE_OPCODE_SHORT(OP_WRITEM2, 8, 0): // DWRITEM dst,src1,mask,space_WORD + m_space[PARAM3]->write_word(PARAM0, DPARAM1, DPARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM4, 8, 0): /* DWRITEM dst,src1,mask,space_DWORD */ - drcbe->space[PARAM3 / 16]->write_dword(PARAM0, DPARAM1, DPARAM2); + case MAKE_OPCODE_SHORT(OP_WRITEM4, 8, 0): // DWRITEM dst,src1,mask,space_DWORD + m_space[PARAM3]->write_dword(PARAM0, DPARAM1, DPARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_WRITEM8, 8, 0): /* DWRITEM dst,src1,mask,space_QWORD */ - drcbe->space[PARAM3 / 16]->write_qword(PARAM0, DPARAM1, DPARAM2); + case MAKE_OPCODE_SHORT(OP_WRITEM8, 8, 0): // DWRITEM dst,src1,mask,space_QWORD + m_space[PARAM3]->write_qword(PARAM0, DPARAM1, DPARAM2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_CARRY, 8, 0): /* DCARRY src,bitnum */ - flags = (flags & ~DRCUML_FLAG_C) | ((DPARAM0 >> (DPARAM1 & 63)) & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_CARRY, 8, 0): // DCARRY src,bitnum + flags = (flags & ~FLAG_C) | ((DPARAM0 >> (DPARAM1 & 63)) & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MOV, 8, 1): /* DMOV dst,src[,c] */ + case MAKE_OPCODE_SHORT(OP_MOV, 8, 1): // DMOV dst,src[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_MOV, 8, 0): + case MAKE_OPCODE_SHORT(OP_MOV, 8, 0): DPARAM0 = DPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SET, 8, 1): /* DSET dst,c */ + case MAKE_OPCODE_SHORT(OP_SET, 8, 1): // DSET dst,c DPARAM0 = OPCODE_FAIL_CONDITION(opcode, flags) ? 0 : 1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 8, 0): /* DSEXT dst,src,BYTE */ + case MAKE_OPCODE_SHORT(OP_SEXT1, 8, 0): // DSEXT dst,src,BYTE DPARAM0 = (INT8)PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT1, 8, 1): + case MAKE_OPCODE_SHORT(OP_SEXT1, 8, 1): temp64 = (INT8)PARAM1; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 8, 0): /* DSEXT dst,src,WORD */ + case MAKE_OPCODE_SHORT(OP_SEXT2, 8, 0): // DSEXT dst,src,WORD DPARAM0 = (INT16)PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT2, 8, 1): + case MAKE_OPCODE_SHORT(OP_SEXT2, 8, 1): temp64 = (INT16)PARAM1; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT4, 8, 0): /* DSEXT dst,src,DWORD */ + case MAKE_OPCODE_SHORT(OP_SEXT4, 8, 0): // DSEXT dst,src,DWORD DPARAM0 = (INT32)PARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SEXT4, 8, 1): + case MAKE_OPCODE_SHORT(OP_SEXT4, 8, 1): temp64 = (INT32)PARAM1; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 8, 0): /* DROLAND dst,src,count,mask[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLAND, 8, 0): // DROLAND dst,src,count,mask[,f] shift = DPARAM2 & 63; DPARAM0 = ((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLAND, 8, 1): + case MAKE_OPCODE_SHORT(OP_ROLAND, 8, 1): shift = DPARAM2 & 63; temp64 = ((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 8, 0): /* DROLINS dst,src,count,mask[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLINS, 8, 0): // DROLINS dst,src,count,mask[,f] shift = DPARAM2 & 63; DPARAM0 = (DPARAM0 & ~DPARAM3) | (((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLINS, 8, 1): + case MAKE_OPCODE_SHORT(OP_ROLINS, 8, 1): shift = DPARAM2 & 63; temp64 = (DPARAM0 & ~DPARAM3) | (((DPARAM1 << shift) | (DPARAM1 >> (64 - shift))) & DPARAM3); flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADD, 8, 0): /* DADD dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_ADD, 8, 0): // DADD dst,src1,src2[,f] DPARAM0 = DPARAM1 + DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADD, 8, 1): + case MAKE_OPCODE_SHORT(OP_ADD, 8, 1): temp64 = DPARAM1 + DPARAM2; flags = FLAGS64_NZCV_ADD(temp64, DPARAM1, DPARAM2); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 8, 0): /* DADDC dst,src1,src2[,f] */ - DPARAM0 = DPARAM1 + DPARAM2 + (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_ADDC, 8, 0): // DADDC dst,src1,src2[,f] + DPARAM0 = DPARAM1 + DPARAM2 + (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ADDC, 8, 1): - temp64 = DPARAM1 + DPARAM2 + (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_ADDC, 8, 1): + temp64 = DPARAM1 + DPARAM2 + (flags & FLAG_C); if (DPARAM2 + 1 != 0) - flags = FLAGS64_NZCV_ADD(temp64, DPARAM1, DPARAM2 + (flags & DRCUML_FLAG_C)); + flags = FLAGS64_NZCV_ADD(temp64, DPARAM1, DPARAM2 + (flags & FLAG_C)); else - flags = FLAGS64_NZCV_ADD(temp64, DPARAM1 + (flags & DRCUML_FLAG_C), DPARAM2); + flags = FLAGS64_NZCV_ADD(temp64, DPARAM1 + (flags & FLAG_C), DPARAM2); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUB, 8, 0): /* DSUB dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_SUB, 8, 0): // DSUB dst,src1,src2[,f] DPARAM0 = DPARAM1 - DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUB, 8, 1): + case MAKE_OPCODE_SHORT(OP_SUB, 8, 1): temp64 = DPARAM1 - DPARAM2; flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 8, 0): /* DSUBB dst,src1,src2[,f] */ - DPARAM0 = DPARAM1 - DPARAM2 - (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_SUBB, 8, 0): // DSUBB dst,src1,src2[,f] + DPARAM0 = DPARAM1 - DPARAM2 - (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SUBB, 8, 1): - temp64 = DPARAM1 - DPARAM2 - (flags & DRCUML_FLAG_C); + case MAKE_OPCODE_SHORT(OP_SUBB, 8, 1): + temp64 = DPARAM1 - DPARAM2 - (flags & FLAG_C); if (DPARAM2 + 1 != 0) - flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2 + (flags & DRCUML_FLAG_C)); + flags = FLAGS64_NZCV_SUB(temp64, DPARAM1, DPARAM2 + (flags & FLAG_C)); else - flags = FLAGS64_NZCV_SUB(temp64, DPARAM1 - (flags & DRCUML_FLAG_C), DPARAM2); + flags = FLAGS64_NZCV_SUB(temp64, DPARAM1 - (flags & FLAG_C), DPARAM2); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_CMP, 8, 1): /* DCMP src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_CMP, 8, 1): // DCMP src1,src2[,f] temp64 = DPARAM0 - DPARAM1; flags = FLAGS64_NZCV_SUB(temp64, DPARAM0, DPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULU, 8, 0): /* DMULU dst,edst,src1,src2[,f] */ - dmulu(inst[0].puint64, inst[1].puint64, DPARAM2, DPARAM3, FALSE); + case MAKE_OPCODE_SHORT(OP_MULU, 8, 0): // DMULU dst,edst,src1,src2[,f] + dmulu(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, FALSE); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULU, 8, 1): - flags = dmulu(inst[0].puint64, inst[1].puint64, DPARAM2, DPARAM3, TRUE); + case MAKE_OPCODE_SHORT(OP_MULU, 8, 1): + flags = dmulu(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, TRUE); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULS, 8, 0): /* DMULS dst,edst,src1,src2[,f] */ - dmuls(inst[0].puint64, inst[1].puint64, DPARAM2, DPARAM3, FALSE); + case MAKE_OPCODE_SHORT(OP_MULS, 8, 0): // DMULS dst,edst,src1,src2[,f] + dmuls(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, FALSE); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_MULS, 8, 1): - flags = dmuls(inst[0].puint64, inst[1].puint64, DPARAM2, DPARAM3, TRUE); + case MAKE_OPCODE_SHORT(OP_MULS, 8, 1): + flags = dmuls(*inst[0].puint64, *inst[1].puint64, DPARAM2, DPARAM3, TRUE); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVU, 8, 0): /* DDIVU dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_DIVU, 8, 0): // DDIVU dst,edst,src1,src2[,f] if (DPARAM3 != 0) { temp64 = (UINT64)DPARAM2 / (UINT64)DPARAM3; @@ -1678,7 +1599,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) } break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVU, 8, 1): + case MAKE_OPCODE_SHORT(OP_DIVU, 8, 1): if (DPARAM3 != 0) { temp64 = (UINT64)DPARAM2 / (UINT64)DPARAM3; @@ -1687,10 +1608,10 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) DPARAM0 = temp64; } else - flags = DRCUML_FLAG_V; + flags = FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVS, 8, 0): /* DDIVS dst,edst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_DIVS, 8, 0): // DDIVS dst,edst,src1,src2[,f] if (DPARAM3 != 0) { temp64 = (INT64)DPARAM2 / (INT64)DPARAM3; @@ -1699,7 +1620,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) } break; - case MAKE_OPCODE_SHORT(DRCUML_OP_DIVS, 8, 1): + case MAKE_OPCODE_SHORT(OP_DIVS, 8, 1): if (DPARAM3 != 0) { temp64 = (INT64)DPARAM2 / (INT64)DPARAM3; @@ -1708,52 +1629,52 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) DPARAM0 = temp64; } else - flags = DRCUML_FLAG_V; + flags = FLAG_V; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_AND, 8, 0): /* DAND dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_AND, 8, 0): // DAND dst,src1,src2[,f] DPARAM0 = DPARAM1 & DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_AND, 8, 1): + case MAKE_OPCODE_SHORT(OP_AND, 8, 1): temp64 = DPARAM1 & DPARAM2; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_TEST, 8, 1): /* DTEST src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_TEST, 8, 1): // DTEST src1,src2[,f] temp64 = DPARAM1 & DPARAM2; flags = FLAGS64_NZ(temp64); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_OR, 8, 0): /* DOR dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_OR, 8, 0): // DOR dst,src1,src2[,f] DPARAM0 = DPARAM1 | DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_OR, 8, 1): + case MAKE_OPCODE_SHORT(OP_OR, 8, 1): temp64 = DPARAM1 | DPARAM2; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_XOR, 8, 0): /* DXOR dst,src1,src2[,f] */ + case MAKE_OPCODE_SHORT(OP_XOR, 8, 0): // DXOR dst,src1,src2[,f] DPARAM0 = DPARAM1 ^ DPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_XOR, 8, 1): + case MAKE_OPCODE_SHORT(OP_XOR, 8, 1): temp64 = DPARAM1 ^ DPARAM2; flags = FLAGS64_NZ(temp64); DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LZCNT, 8, 0): /* DLZCNT dst,src */ + case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 0): // DLZCNT dst,src if ((UINT32)(DPARAM1 >> 32) != 0) DPARAM0 = count_leading_zeros(DPARAM1 >> 32); else DPARAM0 = 32 + count_leading_zeros(DPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_LZCNT, 8, 1): + case MAKE_OPCODE_SHORT(OP_LZCNT, 8, 1): if ((UINT32)(DPARAM1 >> 32) != 0) temp64 = count_leading_zeros(DPARAM1 >> 32); else @@ -1762,392 +1683,392 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_BSWAP, 8, 0): /* DBSWAP dst,src */ + case MAKE_OPCODE_SHORT(OP_BSWAP, 8, 0): // DBSWAP dst,src temp64 = DPARAM1; DPARAM0 = FLIPENDIAN_INT64(temp64); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_BSWAP, 8, 1): + case MAKE_OPCODE_SHORT(OP_BSWAP, 8, 1): temp64 = DPARAM1; flags = FLAGS64_NZ(temp64); DPARAM0 = FLIPENDIAN_INT64(temp64); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHL, 8, 0): /* DSHL dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SHL, 8, 0): // DSHL dst,src,count[,f] DPARAM0 = DPARAM1 << (DPARAM2 & 63); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHL, 8, 1): + case MAKE_OPCODE_SHORT(OP_SHL, 8, 1): shift = DPARAM2 & 63; temp64 = DPARAM1 << shift; flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHR, 8, 0): /* DSHR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SHR, 8, 0): // DSHR dst,src,count[,f] DPARAM0 = DPARAM1 >> (DPARAM2 & 63); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SHR, 8, 1): + case MAKE_OPCODE_SHORT(OP_SHR, 8, 1): shift = DPARAM2 & 63; temp64 = DPARAM1 >> shift; flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SAR, 8, 0): /* DSAR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_SAR, 8, 0): // DSAR dst,src,count[,f] DPARAM0 = (INT64)DPARAM1 >> (DPARAM2 & 63); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_SAR, 8, 1): + case MAKE_OPCODE_SHORT(OP_SAR, 8, 1): shift = DPARAM2 & 63; temp64 = (INT32)DPARAM1 >> shift; flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROL, 8, 0): /* DROL dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROL, 8, 0): // DROL dst,src,count[,f] shift = DPARAM2 & 31; DPARAM0 = (DPARAM1 << shift) | (DPARAM1 >> ((64 - shift) & 63)); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROL, 8, 1): + case MAKE_OPCODE_SHORT(OP_ROL, 8, 1): shift = DPARAM2 & 63; temp64 = (DPARAM1 << shift) | (DPARAM1 >> ((64 - shift) & 63)); flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLC, 8, 0): /* DROLC dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROLC, 8, 0): // DROLC dst,src,count[,f] shift = DPARAM2 & 63; if (shift > 1) - DPARAM0 = (DPARAM1 << shift) | ((flags & DRCUML_FLAG_C) << (shift - 1)) | (DPARAM1 >> (65 - shift)); + DPARAM0 = (DPARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (DPARAM1 >> (65 - shift)); else if (shift == 1) - DPARAM0 = (DPARAM1 << shift) | (flags & DRCUML_FLAG_C); + DPARAM0 = (DPARAM1 << shift) | (flags & FLAG_C); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROLC, 8, 1): + case MAKE_OPCODE_SHORT(OP_ROLC, 8, 1): shift = DPARAM2 & 63; if (shift > 1) - temp64 = (DPARAM1 << shift) | ((flags & DRCUML_FLAG_C) << (shift - 1)) | (DPARAM1 >> (65 - shift)); + temp64 = (DPARAM1 << shift) | ((flags & FLAG_C) << (shift - 1)) | (DPARAM1 >> (65 - shift)); else if (shift == 1) - temp64 = (DPARAM1 << shift) | (flags & DRCUML_FLAG_C); + temp64 = (DPARAM1 << shift) | (flags & FLAG_C); else temp64 = DPARAM1; flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & DRCUML_FLAG_C; + if (shift != 0) flags |= ((DPARAM1 << (shift - 1)) >> 63) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROR, 8, 0): /* DROR dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_ROR, 8, 0): // DROR dst,src,count[,f] shift = DPARAM2 & 63; DPARAM0 = (DPARAM1 >> shift) | (DPARAM1 << ((64 - shift) & 63)); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_ROR, 8, 1): + case MAKE_OPCODE_SHORT(OP_ROR, 8, 1): shift = DPARAM2 & 63; temp64 = (DPARAM1 >> shift) | (DPARAM1 << ((64 - shift) & 63)); flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C; DPARAM0 = temp64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RORC, 8, 0): /* DRORC dst,src,count[,f] */ + case MAKE_OPCODE_SHORT(OP_RORC, 8, 0): // DRORC dst,src,count[,f] shift = DPARAM2 & 63; if (shift > 1) - DPARAM0 = (DPARAM1 >> shift) | ((((UINT64)flags & DRCUML_FLAG_C) << 63) >> (shift - 1)) | (DPARAM1 << (65 - shift)); + DPARAM0 = (DPARAM1 >> shift) | ((((UINT64)flags & FLAG_C) << 63) >> (shift - 1)) | (DPARAM1 << (65 - shift)); else if (shift == 1) - DPARAM0 = (DPARAM1 >> shift) | (((UINT64)flags & DRCUML_FLAG_C) << 63); + DPARAM0 = (DPARAM1 >> shift) | (((UINT64)flags & FLAG_C) << 63); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_RORC, 8, 1): + case MAKE_OPCODE_SHORT(OP_RORC, 8, 1): shift = DPARAM2 & 63; if (shift > 1) - temp64 = (DPARAM1 >> shift) | ((((UINT64)flags & DRCUML_FLAG_C) << 63) >> (shift - 1)) | (DPARAM1 << (65 - shift)); + temp64 = (DPARAM1 >> shift) | ((((UINT64)flags & FLAG_C) << 63) >> (shift - 1)) | (DPARAM1 << (65 - shift)); else if (shift == 1) - temp64 = (DPARAM1 >> shift) | (((UINT64)flags & DRCUML_FLAG_C) << 63); + temp64 = (DPARAM1 >> shift) | (((UINT64)flags & FLAG_C) << 63); else temp64 = DPARAM1; flags = FLAGS64_NZ(temp64); - if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & DRCUML_FLAG_C; + if (shift != 0) flags |= (DPARAM1 >> (shift - 1)) & FLAG_C; DPARAM0 = temp64; break; - /* ----------------------- 32-Bit Floating Point Operations ----------------------- */ + // ----------------------- 32-Bit Floating Point Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_FLOAD, 4, 0): /* FSLOAD dst,base,index */ + case MAKE_OPCODE_SHORT(OP_FLOAD, 4, 0): // FSLOAD dst,base,index FSPARAM0 = inst[1].pfloat[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSTORE, 4, 0): /* FSSTORE dst,base,index */ + case MAKE_OPCODE_SHORT(OP_FSTORE, 4, 0): // FSSTORE dst,base,index inst[0].pfloat[PARAM1] = FSPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 4, 0): /* FSREAD dst,src1,space */ - PARAM0 = drcbe->space[PARAM2]->read_dword(PARAM1); + case MAKE_OPCODE_SHORT(OP_FREAD, 4, 0): // FSREAD dst,src1,space + PARAM0 = m_space[PARAM2]->read_dword(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 4, 0): /* FSWRITE dst,src1,space */ - drcbe->space[PARAM2]->write_dword(PARAM0, PARAM1); + case MAKE_OPCODE_SHORT(OP_FWRITE, 4, 0): // FSWRITE dst,src1,space + m_space[PARAM2]->write_dword(PARAM0, PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 4, 1): /* FSMOV dst,src[,c] */ + case MAKE_OPCODE_SHORT(OP_FMOV, 4, 1): // FSMOV dst,src[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 4, 0): + case MAKE_OPCODE_SHORT(OP_FMOV, 4, 0): FSPARAM0 = FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4T, 4, 0): /* FSTOI4T dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4T, 4, 0): // FSTOI4T dst,src1 if (FSPARAM1 >= 0) *inst[0].pint32 = floor(FSPARAM1); else *inst[0].pint32 = ceil(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4R, 4, 0): /* FSTOI4R dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4R, 4, 0): // FSTOI4R dst,src1 if (FSPARAM1 >= 0) *inst[0].pint32 = floor(FSPARAM1 + 0.5f); else *inst[0].pint32 = ceil(FSPARAM1 - 0.5f); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4F, 4, 0): /* FSTOI4F dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4F, 4, 0): // FSTOI4F dst,src1 *inst[0].pint32 = floor(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4C, 4, 0): /* FSTOI4C dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4C, 4, 0): // FSTOI4C dst,src1 *inst[0].pint32 = ceil(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 4, 0): /* FSTOI4 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4, 4, 0): // FSTOI4 dst,src1 *inst[0].pint32 = FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8T, 4, 0): /* FSTOI8T dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8T, 4, 0): // FSTOI8T dst,src1 if (FSPARAM1 >= 0) *inst[0].pint64 = floor(FSPARAM1); else *inst[0].pint64 = ceil(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8R, 4, 0): /* FSTOI8R dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8R, 4, 0): // FSTOI8R dst,src1 if (FSPARAM1 >= 0) *inst[0].pint64 = floor(FSPARAM1 + 0.5f); else *inst[0].pint64 = ceil(FSPARAM1 - 0.5f); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8F, 4, 0): /* FSTOI8F dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8F, 4, 0): // FSTOI8F dst,src1 *inst[0].pint64 = floor(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8C, 4, 0): /* FSTOI8C dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8C, 4, 0): // FSTOI8C dst,src1 *inst[0].pint64 = ceil(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 4, 0): /* FSTOI8 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8, 4, 0): // FSTOI8 dst,src1 *inst[0].pint64 = FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI4, 4, 0): /* FSFRI4 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRI4, 4, 0): // FSFRI4 dst,src1 FSPARAM0 = *inst[1].pint32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI8, 4, 0): /* FSFRI8 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRI8, 4, 0): // FSFRI8 dst,src1 FSPARAM0 = *inst[1].pint64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFD, 4, 0): /* FSFRFD dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRFD, 4, 0): // FSFRFD dst,src1 FSPARAM0 = FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FADD, 4, 0): /* FSADD dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FADD, 4, 0): // FSADD dst,src1,src2 FSPARAM0 = FSPARAM1 + FSPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSUB, 4, 0): /* FSSUB dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FSUB, 4, 0): // FSSUB dst,src1,src2 FSPARAM0 = FSPARAM1 - FSPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FCMP, 4, 1): /* FSCMP src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FCMP, 4, 1): // FSCMP src1,src2 if (isnan(FSPARAM0) || isnan(FSPARAM1)) - flags = DRCUML_FLAG_U; + flags = FLAG_U; else flags = (FSPARAM0 < FSPARAM1) | ((FSPARAM0 == FSPARAM1) << 2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FMUL, 4, 0): /* FSMUL dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FMUL, 4, 0): // FSMUL dst,src1,src2 FSPARAM0 = FSPARAM1 * FSPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FDIV, 4, 0): /* FSDIV dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FDIV, 4, 0): // FSDIV dst,src1,src2 FSPARAM0 = FSPARAM1 / FSPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FNEG, 4, 0): /* FSNEG dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FNEG, 4, 0): // FSNEG dst,src1 FSPARAM0 = -FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FABS, 4, 0): /* FSABS dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FABS, 4, 0): // FSABS dst,src1 FSPARAM0 = fabs(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSQRT, 4, 0): /* FSSQRT dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FSQRT, 4, 0): // FSSQRT dst,src1 FSPARAM0 = sqrt(FSPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FRECIP, 4, 0): /* FSRECIP dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FRECIP, 4, 0): // FSRECIP dst,src1 FSPARAM0 = 1.0f / FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FRSQRT, 4, 0): /* FSRSQRT dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FRSQRT, 4, 0): // FSRSQRT dst,src1 FSPARAM0 = 1.0f / sqrt(FSPARAM1); break; - /* ----------------------- 64-Bit Floating Point Operations ----------------------- */ + // ----------------------- 64-Bit Floating Point Operations ----------------------- - case MAKE_OPCODE_SHORT(DRCUML_OP_FLOAD, 8, 0): /* FDLOAD dst,base,index */ + case MAKE_OPCODE_SHORT(OP_FLOAD, 8, 0): // FDLOAD dst,base,index FDPARAM0 = inst[1].pdouble[PARAM2]; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSTORE, 8, 0): /* FDSTORE dst,base,index */ + case MAKE_OPCODE_SHORT(OP_FSTORE, 8, 0): // FDSTORE dst,base,index inst[0].pdouble[PARAM1] = FDPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FREAD, 8, 0): /* FDREAD dst,src1,space */ - DPARAM0 = drcbe->space[PARAM2]->read_qword(PARAM1); + case MAKE_OPCODE_SHORT(OP_FREAD, 8, 0): // FDREAD dst,src1,space + DPARAM0 = m_space[PARAM2]->read_qword(PARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FWRITE, 8, 0): /* FDWRITE dst,src1,space */ - drcbe->space[PARAM2]->write_qword(PARAM0, DPARAM1); + case MAKE_OPCODE_SHORT(OP_FWRITE, 8, 0): // FDWRITE dst,src1,space + m_space[PARAM2]->write_qword(PARAM0, DPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 8, 1): /* FDMOV dst,src[,c] */ + case MAKE_OPCODE_SHORT(OP_FMOV, 8, 1): // FDMOV dst,src[,c] if (OPCODE_FAIL_CONDITION(opcode, flags)) break; - /* fall through... */ + // fall through... - case MAKE_OPCODE_SHORT(DRCUML_OP_FMOV, 8, 0): + case MAKE_OPCODE_SHORT(OP_FMOV, 8, 0): FDPARAM0 = FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4T, 8, 0): /* FDTOI4T dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4T, 8, 0): // FDTOI4T dst,src1 if (FDPARAM1 >= 0) *inst[0].pint32 = floor(FDPARAM1); else *inst[0].pint32 = ceil(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4R, 8, 0): /* FDTOI4R dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4R, 8, 0): // FDTOI4R dst,src1 if (FDPARAM1 >= 0) *inst[0].pint32 = floor(FDPARAM1 + 0.5); else *inst[0].pint32 = ceil(FDPARAM1 - 0.5); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4F, 8, 0): /* FDTOI4F dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4F, 8, 0): // FDTOI4F dst,src1 *inst[0].pint32 = floor(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4C, 8, 0): /* FDTOI4C dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4C, 8, 0): // FDTOI4C dst,src1 *inst[0].pint32 = ceil(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI4, 8, 0): /* FDTOI4 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI4, 8, 0): // FDTOI4 dst,src1 *inst[0].pint32 = FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8T, 8, 0): /* FDTOI8T dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8T, 8, 0): // FDTOI8T dst,src1 if (FDPARAM1 >= 0) *inst[0].pint64 = floor(FDPARAM1); else *inst[0].pint64 = ceil(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8R, 8, 0): /* FDTOI8R dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8R, 8, 0): // FDTOI8R dst,src1 if (FDPARAM1 >= 0) *inst[0].pint64 = floor(FDPARAM1 + 0.5); else *inst[0].pint64 = ceil(FDPARAM1 - 0.5); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8F, 8, 0): /* FDTOI8F dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8F, 8, 0): // FDTOI8F dst,src1 *inst[0].pint64 = floor(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8C, 8, 0): /* FDTOI8C dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8C, 8, 0): // FDTOI8C dst,src1 *inst[0].pint64 = ceil(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FTOI8, 8, 0): /* FDTOI8 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FTOI8, 8, 0): // FDTOI8 dst,src1 *inst[0].pint64 = FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI4, 8, 0): /* FDFRI4 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRI4, 8, 0): // FDFRI4 dst,src1 FDPARAM0 = *inst[1].pint32; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRI8, 8, 0): /* FDFRI8 dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRI8, 8, 0): // FDFRI8 dst,src1 FDPARAM0 = *inst[1].pint64; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FFRFS, 8, 0): /* FDFRFS dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FFRFS, 8, 0): // FDFRFS dst,src1 FDPARAM0 = FSPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FRNDS, 8, 0): /* FDRNDS dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FRNDS, 8, 0): // FDRNDS dst,src1 FDPARAM0 = (float)FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FADD, 8, 0): /* FDADD dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FADD, 8, 0): // FDADD dst,src1,src2 FDPARAM0 = FDPARAM1 + FDPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSUB, 8, 0): /* FDSUB dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FSUB, 8, 0): // FDSUB dst,src1,src2 FDPARAM0 = FDPARAM1 - FDPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FCMP, 8, 1): /* FDCMP src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FCMP, 8, 1): // FDCMP src1,src2 if (isnan(FDPARAM0) || isnan(FDPARAM1)) - flags = DRCUML_FLAG_U; + flags = FLAG_U; else flags = (FDPARAM0 < FDPARAM1) | ((FDPARAM0 == FDPARAM1) << 2); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FMUL, 8, 0): /* FDMUL dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FMUL, 8, 0): // FDMUL dst,src1,src2 FDPARAM0 = FDPARAM1 * FDPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FDIV, 8, 0): /* FDDIV dst,src1,src2 */ + case MAKE_OPCODE_SHORT(OP_FDIV, 8, 0): // FDDIV dst,src1,src2 FDPARAM0 = FDPARAM1 / FDPARAM2; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FNEG, 8, 0): /* FDNEG dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FNEG, 8, 0): // FDNEG dst,src1 FDPARAM0 = -FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FABS, 8, 0): /* FDABS dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FABS, 8, 0): // FDABS dst,src1 FDPARAM0 = fabs(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FSQRT, 8, 0): /* FDSQRT dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FSQRT, 8, 0): // FDSQRT dst,src1 FDPARAM0 = sqrt(FDPARAM1); break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FRECIP, 8, 0): /* FDRECIP dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FRECIP, 8, 0): // FDRECIP dst,src1 FDPARAM0 = 1.0 / FDPARAM1; break; - case MAKE_OPCODE_SHORT(DRCUML_OP_FRSQRT, 8, 0): /* FDRSQRT dst,src1 */ + case MAKE_OPCODE_SHORT(OP_FRSQRT, 8, 0): // FDRSQRT dst,src1 FDPARAM0 = 1.0 / sqrt(FDPARAM1); break; @@ -2156,7 +2077,7 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) break; } - /* advance past the parameters and immediates */ + // advance past the parameters and immediates inst += OPCODE_GET_PWORDS(opcode); } @@ -2164,65 +2085,84 @@ static int drcbec_execute(drcbe_state *drcbe, drcuml_codehandle *entry) } +//------------------------------------------------- +// output_parameter - output a parameter +//------------------------------------------------- -/*************************************************************************** - PRIVATE HELPER FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - output_parameter - output a parameter --------------------------------------------------*/ - -static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, void **immedptr, int size, const drcuml_parameter *param) +void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int size, const parameter ¶m) { drcbec_instruction *dst = *dstptr; void *immed = *immedptr; - drcuml_parameter temp_param; + parameter temp_param; - switch (param->type) + switch (param.type()) { - /* convert mapvars to immediates */ - case DRCUML_PTYPE_MAPVAR: - temp_param.value = drcbe->map->get_last_value(param->value); - param = &temp_param; - /* fall through to immediate case */ - - /* immediates store a pointer to the immediate data, which is stored at the end of the instruction */ - case DRCUML_PTYPE_IMMEDIATE: - if (param->value == 0) - (dst++)->v = &immediate_zero; + // immediates store a pointer to the immediate data, which is stored at the end of the instruction + case parameter::PTYPE_IMMEDIATE: + if (param.immediate() == 0) + (dst++)->v = &s_immediate_zero; else { (dst++)->v = immed; if (size == 4) - *(UINT32 *)immed = (UINT32)param->value; + *(UINT32 *)immed = (UINT32)param.immediate(); else - *(UINT64 *)immed = (UINT64)param->value; + *(UINT64 *)immed = (UINT64)param.immediate(); immed = (UINT8 *)immed + size; } break; - - /* int registers point to the appropriate part of the integer register state */ - case DRCUML_PTYPE_INT_REGISTER: + + // int registers point to the appropriate part of the integer register state + case parameter::PTYPE_INT_REGISTER: if (size == 4) - (dst++)->puint32 = &drcbe->state.r[param->value - DRCUML_REG_I0].w.l; + (dst++)->puint32 = &m_state.r[param.ireg() - REG_I0].w.l; else - (dst++)->puint64 = &drcbe->state.r[param->value - DRCUML_REG_I0].d; + (dst++)->puint64 = &m_state.r[param.ireg() - REG_I0].d; break; - /* float registers point to the appropriate part of the floating point register state */ - case DRCUML_PTYPE_FLOAT_REGISTER: + // float registers point to the appropriate part of the floating point register state + case parameter::PTYPE_FLOAT_REGISTER: if (size == 4) - (dst++)->pfloat = &drcbe->state.f[param->value - DRCUML_REG_F0].s.l; + (dst++)->pfloat = &m_state.f[param.freg() - REG_F0].s.l; else - (dst++)->pdouble = &drcbe->state.f[param->value - DRCUML_REG_F0].d; + (dst++)->pdouble = &m_state.f[param.freg() - REG_F0].d; break; - /* memory just points to the memory */ - case DRCUML_PTYPE_MEMORY: - (dst++)->v = (void *)(FPTR)param->value; - break; + // convert mapvars to immediates + case parameter::PTYPE_MAPVAR: + temp_param = m_map.get_last_value(param.mapvar()); + return output_parameter(dstptr, immedptr, size, temp_param); + // memory just points to the memory + case parameter::PTYPE_MEMORY: + (dst++)->v = param.memory(); + break; + + // ignore these parameters: they are directly encoded in the opcode + case parameter::PTYPE_SIZE: + case parameter::PTYPE_SIZE_SCALE: + case parameter::PTYPE_ROUNDING: + case parameter::PTYPE_STRING: + return output_parameter(dstptr, immedptr, size, 0); + + // space/size parameters; sizes are built into our opcodes, but space needs to be encoded + case parameter::PTYPE_SIZE_SPACE: + return output_parameter(dstptr, immedptr, size, param.space()); + + // code handle just points to the handle + case parameter::PTYPE_CODE_HANDLE: + (dst++)->handle = ¶m.handle(); + break; + + // code label just contains the label value + case parameter::PTYPE_CODE_LABEL: + return output_parameter(dstptr, immedptr, size, UINT32(param.label())); + + // c_function just points to the C function + case parameter::PTYPE_C_FUNCTION: + (dst++)->cfunc = param.cfunc(); + break; + default: fatalerror("Unexpected param->type"); break; @@ -2233,50 +2173,47 @@ static void output_parameter(drcbe_state *drcbe, drcbec_instruction **dstptr, vo } -/*------------------------------------------------- - fixup_label - callback to fixup forward- - referenced labels --------------------------------------------------*/ +//------------------------------------------------- +// fixup_label - callback to fixup forward- +// referenced labels +//------------------------------------------------- -static void fixup_label(void *parameter, drccodeptr labelcodeptr) +void drcbe_c::fixup_label(void *parameter, drccodeptr labelcodeptr) { drcbec_instruction *dst = (drcbec_instruction *)parameter; dst->inst = (drcbec_instruction *)labelcodeptr; } -/*------------------------------------------------- - dmulu - perform a double-wide unsigned multiply --------------------------------------------------*/ +//------------------------------------------------- +// dmulu - perform a double-wide unsigned multiply +//------------------------------------------------- -static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int flags) +int drcbe_c::dmulu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2, int flags) { - UINT64 lo, hi, prevlo; - UINT64 a, b, temp; - - /* shortcut if we don't care about the high bits or the flags */ - if (dstlo == dsthi && flags == 0) + // shortcut if we don't care about the high bits or the flags + if (&dstlo == &dsthi && flags == 0) { - *dstlo = src1 * src2; + dstlo = src1 * src2; return 0; } - /* fetch source values */ - a = src1; - b = src2; + // fetch source values + UINT64 a = src1; + UINT64 b = src2; if (a == 0 || b == 0) { - *dsthi = *dstlo = 0; - return DRCUML_FLAG_Z; + dsthi = dstlo = 0; + return FLAG_Z; } - /* compute high and low parts first */ - lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); - hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); + // compute high and low parts first + UINT64 lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); + UINT64 hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); - /* compute middle parts */ - prevlo = lo; - temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); + // compute middle parts + UINT64 prevlo = lo; + UINT64 temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); @@ -2285,45 +2222,42 @@ static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int fla lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); - /* store the results */ - *dsthi = hi; - *dstlo = lo; - return ((hi >> 60) & DRCUML_FLAG_S) | ((*dsthi != 0) << 1); + // store the results + dsthi = hi; + dstlo = lo; + return ((hi >> 60) & FLAG_S) | ((dsthi != 0) << 1); } -/*------------------------------------------------- - dmuls - perform a double-wide signed multiply --------------------------------------------------*/ +//------------------------------------------------- +// dmuls - perform a double-wide signed multiply +//------------------------------------------------- -static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags) +int drcbe_c::dmuls(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2, int flags) { - UINT64 lo, hi, prevlo; - UINT64 a, b, temp; - - /* shortcut if we don't care about the high bits or the flags */ - if (dstlo == dsthi && flags == 0) + // shortcut if we don't care about the high bits or the flags + if (&dstlo == &dsthi && flags == 0) { - *dstlo = src1 * src2; + dstlo = src1 * src2; return 0; } - /* fetch absolute source values */ - a = src1; if ((INT64)a < 0) a = -a; - b = src2; if ((INT64)b < 0) b = -b; + // fetch absolute source values + UINT64 a = src1; if ((INT64)a < 0) a = -a; + UINT64 b = src2; if ((INT64)b < 0) b = -b; if (a == 0 || b == 0) { - *dsthi = *dstlo = 0; - return DRCUML_FLAG_Z; + dsthi = dstlo = 0; + return FLAG_Z; } - /* compute high and low parts first */ - lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); - hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); + // compute high and low parts first + UINT64 lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); + UINT64 hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); - /* compute middle parts */ - prevlo = lo; - temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); + // compute middle parts + UINT64 prevlo = lo; + UINT64 temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); @@ -2332,15 +2266,15 @@ static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); - /* adjust for signage */ + // adjust for signage if ((INT64)(src1 ^ src2) < 0) { hi = ~hi + (lo == 0); lo = ~lo + 1; } - /* store the results */ - *dsthi = hi; - *dstlo = lo; - return ((hi >> 60) & DRCUML_FLAG_S) | ((*dsthi != ((INT64)lo >> 63)) << 1); + // store the results + dsthi = hi; + dstlo = lo; + return ((hi >> 60) & FLAG_S) | ((dsthi != ((INT64)lo >> 63)) << 1); } diff --git a/src/emu/cpu/drcbec.h b/src/emu/cpu/drcbec.h new file mode 100644 index 00000000000..93bdb68937f --- /dev/null +++ b/src/emu/cpu/drcbec.h @@ -0,0 +1,87 @@ +/*************************************************************************** + + drcbec.h + + Interpreted C core back-end for the universal machine language. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#pragma once + +#ifndef __DRCBEC_H__ +#define __DRCBEC_H__ + +#include "drcuml.h" +#include "drcbeut.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +union drcbec_instruction; + +class drcbe_c : public drcbe_interface +{ +public: + // construction/destruction + drcbe_c(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits); + virtual ~drcbe_c(); + + // required overrides + virtual void reset(); + virtual int execute(uml::code_handle &entry); + virtual void generate(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst); + virtual bool hash_exists(UINT32 mode, UINT32 pc); + virtual void get_info(drcbe_info &info); + +private: + // helpers + void output_parameter(drcbec_instruction **dstptr, void **immedptr, int size, const uml::parameter ¶m); + static void fixup_label(void *parameter, drccodeptr labelcodeptr); + int dmulu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2, int flags); + int dmuls(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2, int flags); + + // internal state + drc_hash_table m_hash; // hash table state + drc_map_variables m_map; // code map + drc_label_list m_labels; // label list + + static const UINT32 s_condition_map[32]; + static UINT64 s_immediate_zero; +}; + + +#endif /* __DRCBEC_H__ */ diff --git a/src/emu/cpu/drcbeut.c b/src/emu/cpu/drcbeut.c index a3edc383e2c..a2552b25dbe 100644 --- a/src/emu/cpu/drcbeut.c +++ b/src/emu/cpu/drcbeut.c @@ -40,6 +40,8 @@ #include "emu.h" #include "drcbeut.h" +using namespace uml; + //************************************************************************** // DEBUGGING @@ -112,32 +114,30 @@ bool drc_hash_table::reset() // block_begin - note the beginning of a block //------------------------------------------------- -void drc_hash_table::block_begin(drcuml_block &block, const drcuml_instruction *instlist, UINT32 numinst) +void drc_hash_table::block_begin(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst) { // before generating code, pre-allocate any hash entries; we do this by setting dummy hash values for (int inum = 0; inum < numinst; inum++) { - const drcuml_instruction &inst = instlist[inum]; + const uml::instruction &inst = instlist[inum]; // if the opcode is a hash, verify that it makes sense and then set a NULL entry - if (inst.opcode == DRCUML_OP_HASH) + if (inst.opcode() == OP_HASH) { - assert(inst.numparams == 2); - assert(inst.param[0].type == DRCUML_PTYPE_IMMEDIATE); - assert(inst.param[1].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 2); // if we fail to allocate, we must abort the block - if (!set_codeptr(inst.param[0].value, inst.param[1].value, NULL)) - drcuml_block_abort(&block); + if (!set_codeptr(inst.param(0).immediate(), inst.param(1).immediate(), NULL)) + block.abort(); } // if the opcode is a hashjmp to a fixed location, make sure we preallocate the tables - if (inst.opcode == DRCUML_OP_HASHJMP && inst.param[0].type == DRCUML_PTYPE_IMMEDIATE && inst.param[1].type == DRCUML_PTYPE_IMMEDIATE) + if (inst.opcode() == OP_HASHJMP && inst.param(0).is_immediate() && inst.param(1).is_immediate()) { // if we fail to allocate, we must abort the block - drccodeptr code = get_codeptr(inst.param[0].value, inst.param[1].value); - if (!set_codeptr(inst.param[0].value, inst.param[1].value, code)) - drcuml_block_abort(&block); + drccodeptr code = get_codeptr(inst.param(0).immediate(), inst.param(1).immediate()); + if (!set_codeptr(inst.param(0).immediate(), inst.param(1).immediate(), code)) + block.abort(); } } } @@ -275,7 +275,7 @@ void drc_map_variables::block_end(drcuml_block &block) // begin "code generation" aligned to an 8-byte boundary drccodeptr *top = m_cache.begin_codegen(sizeof(UINT64) + sizeof(UINT32) + 2 * sizeof(UINT32) * m_entry_list.count()); if (top == NULL) - drcuml_block_abort(&block); + block.abort(); UINT32 *dest = (UINT32 *)(((FPTR)*top + 7) & ~7); // store the cookie first @@ -288,8 +288,8 @@ void drc_map_variables::block_end(drcuml_block &block) dest++; // now iterate over entries and store them - UINT32 curvalue[DRCUML_MAPVAR_END - DRCUML_MAPVAR_M0] = { 0 }; - bool changed[DRCUML_MAPVAR_END - DRCUML_MAPVAR_M0] = { false }; + UINT32 curvalue[MAPVAR_COUNT] = { 0 }; + bool changed[MAPVAR_COUNT] = { false }; for (map_entry *entry = m_entry_list.first(); entry != NULL; entry = entry->next()) { // update the current value of the variable and detect changes @@ -352,24 +352,24 @@ void drc_map_variables::block_end(drcuml_block &block) void drc_map_variables::set_value(drccodeptr codebase, UINT32 mapvar, UINT32 newvalue) { - assert(mapvar >= DRCUML_MAPVAR_M0 && mapvar < DRCUML_MAPVAR_END); + assert(mapvar >= MAPVAR_M0 && mapvar < MAPVAR_END); // if this value isn't different, skip it - if (m_mapvalue[mapvar - DRCUML_MAPVAR_M0] == newvalue) + if (m_mapvalue[mapvar - MAPVAR_M0] == newvalue) return; // allocate a new entry and fill it in map_entry *entry = (map_entry *)m_cache.alloc(sizeof(*entry)); entry->m_next = NULL; entry->m_codeptr = codebase; - entry->m_mapvar = mapvar - DRCUML_MAPVAR_M0; + entry->m_mapvar = mapvar - MAPVAR_M0; entry->m_newval = newvalue; // hook us into the end of the list m_entry_list.append(*entry); // update our state in the table as well - m_mapvalue[mapvar - DRCUML_MAPVAR_M0] = newvalue; + m_mapvalue[mapvar - MAPVAR_M0] = newvalue; } @@ -380,8 +380,8 @@ void drc_map_variables::set_value(drccodeptr codebase, UINT32 mapvar, UINT32 new UINT32 drc_map_variables::get_value(drccodeptr codebase, UINT32 mapvar) const { - assert(mapvar >= DRCUML_MAPVAR_M0 && mapvar < DRCUML_MAPVAR_END); - mapvar -= DRCUML_MAPVAR_M0; + assert(mapvar >= MAPVAR_M0 && mapvar < MAPVAR_END); + mapvar -= MAPVAR_M0; // get an aligned pointer to start scanning UINT64 *curscan = (UINT64 *)(((FPTR)codebase | 7) + 1); @@ -448,8 +448,8 @@ UINT32 drc_map_variables::static_get_value(drc_map_variables &map, drccodeptr co UINT32 drc_map_variables::get_last_value(UINT32 mapvar) { - assert(mapvar >= DRCUML_MAPVAR_M0 && mapvar < DRCUML_MAPVAR_END); - return m_mapvalue[mapvar - DRCUML_MAPVAR_M0]; + assert(mapvar >= MAPVAR_M0 && mapvar < MAPVAR_END); + return m_mapvalue[mapvar - MAPVAR_M0]; } @@ -508,7 +508,7 @@ void drc_label_list::block_end(drcuml_block &block) // undefined //------------------------------------------------- -drccodeptr drc_label_list::get_codeptr(drcuml_codelabel label, fixup_func fixup, void *param) +drccodeptr drc_label_list::get_codeptr(uml::code_label label, fixup_func fixup, void *param) { label_entry *curlabel = find_or_allocate(label); @@ -524,7 +524,7 @@ drccodeptr drc_label_list::get_codeptr(drcuml_codelabel label, fixup_func fixup, // set_codeptr - set the pointer to a new label //------------------------------------------------- -void drc_label_list::set_codeptr(drcuml_codelabel label, drccodeptr codeptr) +void drc_label_list::set_codeptr(uml::code_label label, drccodeptr codeptr) { // set the code pointer label_entry *curlabel = find_or_allocate(label); @@ -546,7 +546,7 @@ void drc_label_list::reset(bool fatal_on_leftovers) { // fatal if we were a leftover if (fatal_on_leftovers && curlabel->m_codeptr == NULL) - fatalerror("Label %08X never defined!", curlabel->m_label); + fatalerror("Label %08X never defined!", curlabel->m_label.label()); // free the label m_cache.dealloc(curlabel, sizeof(*curlabel)); @@ -559,7 +559,7 @@ void drc_label_list::reset(bool fatal_on_leftovers) // allocate a new one if not found //------------------------------------------------- -drc_label_list::label_entry *drc_label_list::find_or_allocate(drcuml_codelabel label) +drc_label_list::label_entry *drc_label_list::find_or_allocate(uml::code_label label) { // find the label, or else allocate a new one label_entry *curlabel; diff --git a/src/emu/cpu/drcbeut.h b/src/emu/cpu/drcbeut.h index efad6d669e2..4c707bb3c2e 100644 --- a/src/emu/cpu/drcbeut.h +++ b/src/emu/cpu/drcbeut.h @@ -73,7 +73,7 @@ public: void set_default_codeptr(drccodeptr code); // block begin/end - void block_begin(drcuml_block &block, const drcuml_instruction *instlist, UINT32 numinst); + void block_begin(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst); void block_end(drcuml_block &block); // code pointer access @@ -127,7 +127,7 @@ private: // internal state drc_cache & m_cache; // pointer to the cache UINT64 m_uniquevalue; // unique value used to find the table - UINT32 m_mapvalue[DRCUML_MAPVAR_END - DRCUML_MAPVAR_M0]; // array of current values + UINT32 m_mapvalue[uml::MAPVAR_END - uml::MAPVAR_M0]; // array of current values // list of entries struct map_entry @@ -160,21 +160,21 @@ public: void block_end(drcuml_block &block); // get/set values - drccodeptr get_codeptr(drcuml_codelabel label, fixup_func fixup, void *param); - void set_codeptr(drcuml_codelabel label, drccodeptr codeptr); + drccodeptr get_codeptr(uml::code_label label, fixup_func fixup, void *param); + void set_codeptr(uml::code_label label, drccodeptr codeptr); private: struct label_entry { label_entry *next() const { return m_next; } label_entry * m_next; // pointer to next label - drcuml_codelabel m_label; // the label specified + uml::code_label m_label; // the label specified drccodeptr m_codeptr; // pointer to the relevant code }; // internal helpers void reset(bool fatal_on_leftovers); - label_entry *find_or_allocate(drcuml_codelabel label); + label_entry *find_or_allocate(uml::code_label label); static void oob_callback(drccodeptr *codeptr, void *param1, void *param2, void *param3); // internal state diff --git a/src/emu/cpu/drcbex64.c b/src/emu/cpu/drcbex64.c index 9d803f24cd9..4a3e5503194 100644 --- a/src/emu/cpu/drcbex64.c +++ b/src/emu/cpu/drcbex64.c @@ -4,9 +4,36 @@ 64-bit x64 back-end for the universal machine language. +**************************************************************************** + Copyright Aaron Giles - Released for general non-commercial use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. **************************************************************************** @@ -171,15 +198,16 @@ #include "emu.h" #include "debugger.h" #include "drcuml.h" -#include "drcbeut.h" -#include "x86emit.h" -#include "x86log.h" +#include "drcbex64.h" +using namespace uml; +using namespace x64emit; -/*************************************************************************** - DEBUGGING -***************************************************************************/ + +//************************************************************************** +// DEBUGGING +//************************************************************************** #define LOG_HASHJMPS (0) @@ -190,162 +218,68 @@ -/*************************************************************************** - CONSTANTS -***************************************************************************/ +//************************************************************************** +// CONSTANTS +//************************************************************************** -#define PTYPE_M (1 << DRCUML_PTYPE_MEMORY) -#define PTYPE_I (1 << DRCUML_PTYPE_IMMEDIATE) -#define PTYPE_R (1 << DRCUML_PTYPE_INT_REGISTER) -#define PTYPE_F (1 << DRCUML_PTYPE_FLOAT_REGISTER) -#define PTYPE_MI (PTYPE_M | PTYPE_I) -#define PTYPE_RI (PTYPE_R | PTYPE_I) -#define PTYPE_MR (PTYPE_M | PTYPE_R) -#define PTYPE_MRI (PTYPE_M | PTYPE_R | PTYPE_I) -#define PTYPE_MF (PTYPE_M | PTYPE_F) +const UINT32 PTYPE_M = 1 << parameter::PTYPE_MEMORY; +const UINT32 PTYPE_I = 1 << parameter::PTYPE_IMMEDIATE; +const UINT32 PTYPE_R = 1 << parameter::PTYPE_INT_REGISTER; +const UINT32 PTYPE_F = 1 << parameter::PTYPE_FLOAT_REGISTER; +const UINT32 PTYPE_MI = PTYPE_M | PTYPE_I; +const UINT32 PTYPE_RI = PTYPE_R | PTYPE_I; +const UINT32 PTYPE_MR = PTYPE_M | PTYPE_R; +const UINT32 PTYPE_MRI = PTYPE_M | PTYPE_R | PTYPE_I; +const UINT32 PTYPE_MF = PTYPE_M | PTYPE_F; #ifdef X64_WINDOWS_ABI -#define REG_PARAM1 REG_RCX -#define REG_PARAM2 REG_RDX -#define REG_PARAM3 REG_R8 -#define REG_PARAM4 REG_R9 +const int REG_PARAM1 = REG_RCX; +const int REG_PARAM2 = REG_RDX; +const int REG_PARAM3 = REG_R8; +const int REG_PARAM4 = REG_R9; #else -#define REG_PARAM1 REG_RDI -#define REG_PARAM2 REG_RSI -#define REG_PARAM3 REG_RDX -#define REG_PARAM4 REG_RCX +const int REG_PARAM1 = REG_RDI; +const int REG_PARAM2 = REG_RSI; +const int REG_PARAM3 = REG_RDX; +const int REG_PARAM4 = REG_RCX; #endif -/*************************************************************************** - MACROS -***************************************************************************/ - -#define X86_CONDITION(condition) (condition_map[condition - DRCUML_COND_Z]) -#define X86_NOT_CONDITION(condition) (condition_map[condition - DRCUML_COND_Z] ^ 1) - -#undef MABS -#define MABS(drcbe, ptr) MBD(REG_RBP, offset_from_rbp(drcbe, (FPTR)(ptr))) +//************************************************************************** +// MACROS +//************************************************************************** -#define assert_no_condition(inst) assert((inst)->condition == DRCUML_COND_ALWAYS) -#define assert_any_condition(inst) assert((inst)->condition == DRCUML_COND_ALWAYS || ((inst)->condition >= DRCUML_COND_Z && (inst)->condition < DRCUML_COND_MAX)) -#define assert_no_flags(inst) assert((inst)->flags == 0) -#define assert_flags(inst, valid) assert(((inst)->flags & ~(valid)) == 0) +#define X86_CONDITION(condition) (condition_map[condition - uml::COND_Z]) +#define X86_NOT_CONDITION(condition) (condition_map[condition - uml::COND_Z] ^ 1) - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* entry point */ -typedef UINT32 (*x86_entry_point_func)(UINT8 *rbpvalue, x86code *entry); - -/* opcode handler */ -typedef x86code *(*opcode_generate_func)(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - - -/* opcode table entry */ -typedef struct _opcode_table_entry opcode_table_entry; -struct _opcode_table_entry +inline x86_memref drcbe_x64::MABS(const void *ptr) { - drcuml_opcode opcode; /* opcode in question */ - opcode_generate_func func; /* function pointer to the work */ -}; - - -/* internal backend-specific state */ -struct _drcbe_state -{ - device_t * device; /* CPU device we are associated with */ - drcuml_state * drcuml; /* pointer back to our owner */ - drc_cache * cache; /* pointer to the cache */ - drcuml_machine_state state; /* state of the machine */ - drc_hash_table * hash; /* hash table state */ - drc_map_variables * map; /* code map */ - drc_label_list * labels; /* label list */ - - x86_entry_point_func entry; /* entry point */ - x86code * exit; /* exit point */ - x86code * nocode; /* nocode handler */ - - x86code * debug_cpu_instruction_hook;/* debugger callback */ - x86code * debug_log_hashjmp; /* hashjmp debugging */ - x86code * debug_log_hashjmp_fail; /* hashjmp debugging */ - x86code * drcmap_get_value; /* map lookup helper */ - data_accessors accessors[ADDRESS_SPACES]; /* memory accessors */ - address_space * space[ADDRESS_SPACES]; /* address spaces */ - - UINT8 sse41; /* do we have SSE4.1 support? */ - UINT32 ssemode; /* saved SSE mode */ - UINT32 ssemodesave; /* temporary location for saving */ - UINT32 ssecontrol[4]; /* copy of the sse_control array */ - UINT32 * absmask32; /* absolute value mask (32-bit) */ - UINT64 * absmask64; /* absolute value mask (32-bit) */ - float single1; /* 1.0 is single-precision */ - double double1; /* 1.0 in double-precision */ - - void * stacksave; /* saved stack pointer */ - void * hashstacksave; /* saved stack pointer for hashjmp */ - - UINT8 * rbpvalue; /* value of RBP */ - UINT8 flagsmap[0x1000]; /* flags map */ - UINT64 flagsunmap[0x20]; /* flags unmapper */ - - x86log_context * log; /* logging */ -}; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* primary back-end callbacks */ -static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits); -static void drcbex64_free(drcbe_state *drcbe); -static void drcbex64_reset(drcbe_state *drcbe); -static int drcbex64_execute(drcbe_state *drcbe, drcuml_codehandle *entry); -static void drcbex64_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst); -static int drcbex64_hash_exists(drcbe_state *drcbe, UINT32 mode, UINT32 pc); -static void drcbex64_get_info(drcbe_state *state, drcbe_info *info); - -/* private helper functions */ -static void fixup_label(void *parameter, drccodeptr labelcodeptr); -static void debug_log_hashjmp(offs_t pc, int mode); -static void debug_log_hashjmp_fail(); + return MBD(REG_BP, offset_from_rbp(ptr)); +} +#define assert_no_condition(inst) assert((inst).condition() == uml::COND_ALWAYS) +#define assert_any_condition(inst) assert((inst).condition() == uml::COND_ALWAYS || ((inst).condition() >= uml::COND_Z && (inst).condition() < uml::COND_MAX)) +#define assert_no_flags(inst) assert((inst).flags() == 0) +#define assert_flags(inst, valid) assert(((inst).flags() & ~(valid)) == 0) -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ -/* globally-accessible interface to the backend */ -extern const drcbe_interface drcbe_x64_be_interface = -{ - drcbex64_alloc, - drcbex64_free, - drcbex64_reset, - drcbex64_execute, - drcbex64_generate, - drcbex64_hash_exists, - drcbex64_get_info -}; +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* opcode table */ -static opcode_generate_func opcode_table[DRCUML_OP_MAX]; +drcbe_x64::opcode_generate_func drcbe_x64::s_opcode_table[OP_MAX]; -/* size-to-mask table */ +// size-to-mask table static const UINT64 size_to_mask[] = { 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0, U64(0xffffffffffffffff) }; -/* register mapping tables */ -static const UINT8 int_register_map[DRCUML_REG_I_END - DRCUML_REG_I0] = +// register mapping tables +static const UINT8 int_register_map[REG_I_COUNT] = { #ifdef X64_WINDOWS_ABI REG_RBX, REG_RSI, REG_RDI, REG_R12, REG_R13, REG_R14, REG_R15 @@ -354,303 +288,292 @@ static const UINT8 int_register_map[DRCUML_REG_I_END - DRCUML_REG_I0] = #endif }; -static UINT8 float_register_map[DRCUML_REG_F_END - DRCUML_REG_F0] = +static UINT8 float_register_map[REG_F_COUNT] = { 0 }; -/* condition mapping table */ -static const UINT8 condition_map[DRCUML_COND_MAX - DRCUML_COND_Z] = -{ - COND_Z, /* DRCUML_COND_Z = 0x80, requires Z */ - COND_NZ, /* DRCUML_COND_NZ, requires Z */ - COND_S, /* DRCUML_COND_S, requires S */ - COND_NS, /* DRCUML_COND_NS, requires S */ - COND_C, /* DRCUML_COND_C, requires C */ - COND_NC, /* DRCUML_COND_NC, requires C */ - COND_O, /* DRCUML_COND_V, requires V */ - COND_NO, /* DRCUML_COND_NV, requires V */ - COND_P, /* DRCUML_COND_U, requires U */ - COND_NP, /* DRCUML_COND_NU, requires U */ - COND_A, /* DRCUML_COND_A, requires CZ */ - COND_BE, /* DRCUML_COND_BE, requires CZ */ - COND_G, /* DRCUML_COND_G, requires SVZ */ - COND_LE, /* DRCUML_COND_LE, requires SVZ */ - COND_L, /* DRCUML_COND_L, requires SV */ - COND_GE, /* DRCUML_COND_GE, requires SV */ +// condition mapping table +static const UINT8 condition_map[uml::COND_MAX - uml::COND_Z] = +{ + x64emit::COND_Z, // COND_Z = 0x80, requires Z + x64emit::COND_NZ, // COND_NZ, requires Z + x64emit::COND_S, // COND_S, requires S + x64emit::COND_NS, // COND_NS, requires S + x64emit::COND_C, // COND_C, requires C + x64emit::COND_NC, // COND_NC, requires C + x64emit::COND_O, // COND_V, requires V + x64emit::COND_NO, // COND_NV, requires V + x64emit::COND_P, // COND_U, requires U + x64emit::COND_NP, // COND_NU, requires U + x64emit::COND_A, // COND_A, requires CZ + x64emit::COND_BE, // COND_BE, requires CZ + x64emit::COND_G, // COND_G, requires SVZ + x64emit::COND_LE, // COND_LE, requires SVZ + x64emit::COND_L, // COND_L, requires SV + x64emit::COND_GE, // COND_GE, requires SV }; -/* rounding mode mapping table */ +// rounding mode mapping table static const UINT8 fprnd_map[4] = { - FPRND_CHOP, /* DRCUML_FMOD_TRUNC, truncate */ - FPRND_NEAR, /* DRCUML_FMOD_ROUND, round */ - FPRND_UP, /* DRCUML_FMOD_CEIL, round up */ - FPRND_DOWN /* DRCUML_FMOD_FLOOR round down */ + FPRND_CHOP, // ROUND_TRUNC, truncate + FPRND_NEAR, // ROUND_ROUND, round + FPRND_UP, // ROUND_CEIL, round up + FPRND_DOWN // ROUND_FLOOR round down }; -/*************************************************************************** - TABLES -***************************************************************************/ -static x86code *op_handle(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_hash(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_label(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_comment(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mapvar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_nop(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_debug(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_exit(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_hashjmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_jmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_callh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ret(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_callc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_recover(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_subc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_cmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mulu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_muls(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_divu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_divs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_and(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_test(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_or(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_xor(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_lzcnt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_bswap(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_shl(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_shr(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ror(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rol(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rorc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rolc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_fload(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fstore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fmul(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fdiv(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fneg(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fabs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frecip(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static const opcode_table_entry opcode_table_source[] = -{ - /* Compile-time opcodes */ - { DRCUML_OP_HANDLE, op_handle }, /* HANDLE handle */ - { DRCUML_OP_HASH, op_hash }, /* HASH mode,pc */ - { DRCUML_OP_LABEL, op_label }, /* LABEL imm */ - { DRCUML_OP_COMMENT, op_comment }, /* COMMENT string */ - { DRCUML_OP_MAPVAR, op_mapvar }, /* MAPVAR mapvar,value */ - - /* Control Flow Operations */ - { DRCUML_OP_NOP, op_nop }, /* NOP */ - { DRCUML_OP_DEBUG, op_debug }, /* DEBUG pc */ - { DRCUML_OP_EXIT, op_exit }, /* EXIT src1[,c] */ - { DRCUML_OP_HASHJMP, op_hashjmp }, /* HASHJMP mode,pc,handle */ - { DRCUML_OP_JMP, op_jmp }, /* JMP imm[,c] */ - { DRCUML_OP_EXH, op_exh }, /* EXH handle,param[,c] */ - { DRCUML_OP_CALLH, op_callh }, /* CALLH handle[,c] */ - { DRCUML_OP_RET, op_ret }, /* RET [c] */ - { DRCUML_OP_CALLC, op_callc }, /* CALLC func,ptr[,c] */ - { DRCUML_OP_RECOVER, op_recover }, /* RECOVER dst,mapvar */ - - /* Internal Register Operations */ - { DRCUML_OP_SETFMOD, op_setfmod }, /* SETFMOD src */ - { DRCUML_OP_GETFMOD, op_getfmod }, /* GETFMOD dst */ - { DRCUML_OP_GETEXP, op_getexp }, /* GETEXP dst */ - { DRCUML_OP_GETFLGS, op_getflgs }, /* GETFLGS dst[,f] */ - { DRCUML_OP_SAVE, op_save }, /* SAVE dst */ - { DRCUML_OP_RESTORE, op_restore }, /* RESTORE dst */ - - /* Integer Operations */ - { DRCUML_OP_LOAD, op_load }, /* LOAD dst,base,index,size */ - { DRCUML_OP_LOADS, op_loads }, /* LOADS dst,base,index,size */ - { DRCUML_OP_STORE, op_store }, /* STORE base,index,src,size */ - { DRCUML_OP_READ, op_read }, /* READ dst,src1,spacesize */ - { DRCUML_OP_READM, op_readm }, /* READM dst,src1,mask,spacesize */ - { DRCUML_OP_WRITE, op_write }, /* WRITE dst,src1,spacesize */ - { DRCUML_OP_WRITEM, op_writem }, /* WRITEM dst,src1,spacesize */ - { DRCUML_OP_CARRY, op_carry }, /* CARRY src,bitnum */ - { DRCUML_OP_SET, op_set }, /* SET dst,c */ - { DRCUML_OP_MOV, op_mov }, /* MOV dst,src[,c] */ - { DRCUML_OP_SEXT, op_sext }, /* SEXT dst,src */ - { DRCUML_OP_ROLAND, op_roland }, /* ROLAND dst,src1,src2,src3 */ - { DRCUML_OP_ROLINS, op_rolins }, /* ROLINS dst,src1,src2,src3 */ - { DRCUML_OP_ADD, op_add }, /* ADD dst,src1,src2[,f] */ - { DRCUML_OP_ADDC, op_addc }, /* ADDC dst,src1,src2[,f] */ - { DRCUML_OP_SUB, op_sub }, /* SUB dst,src1,src2[,f] */ - { DRCUML_OP_SUBB, op_subc }, /* SUBB dst,src1,src2[,f] */ - { DRCUML_OP_CMP, op_cmp }, /* CMP src1,src2[,f] */ - { DRCUML_OP_MULU, op_mulu }, /* MULU dst,edst,src1,src2[,f] */ - { DRCUML_OP_MULS, op_muls }, /* MULS dst,edst,src1,src2[,f] */ - { DRCUML_OP_DIVU, op_divu }, /* DIVU dst,edst,src1,src2[,f] */ - { DRCUML_OP_DIVS, op_divs }, /* DIVS dst,edst,src1,src2[,f] */ - { DRCUML_OP_AND, op_and }, /* AND dst,src1,src2[,f] */ - { DRCUML_OP_TEST, op_test }, /* TEST src1,src2[,f] */ - { DRCUML_OP_OR, op_or }, /* OR dst,src1,src2[,f] */ - { DRCUML_OP_XOR, op_xor }, /* XOR dst,src1,src2[,f] */ - { DRCUML_OP_LZCNT, op_lzcnt }, /* LZCNT dst,src[,f] */ - { DRCUML_OP_BSWAP, op_bswap }, /* BSWAP dst,src */ - { DRCUML_OP_SHL, op_shl }, /* SHL dst,src,count[,f] */ - { DRCUML_OP_SHR, op_shr }, /* SHR dst,src,count[,f] */ - { DRCUML_OP_SAR, op_sar }, /* SAR dst,src,count[,f] */ - { DRCUML_OP_ROL, op_rol }, /* ROL dst,src,count[,f] */ - { DRCUML_OP_ROLC, op_rolc }, /* ROLC dst,src,count[,f] */ - { DRCUML_OP_ROR, op_ror }, /* ROR dst,src,count[,f] */ - { DRCUML_OP_RORC, op_rorc }, /* RORC dst,src,count[,f] */ - - /* Floating Point Operations */ - { DRCUML_OP_FLOAD, op_fload }, /* FLOAD dst,base,index */ - { DRCUML_OP_FSTORE, op_fstore }, /* FSTORE base,index,src */ - { DRCUML_OP_FREAD, op_fread }, /* FREAD dst,space,src1 */ - { DRCUML_OP_FWRITE, op_fwrite }, /* FWRITE space,dst,src1 */ - { DRCUML_OP_FMOV, op_fmov }, /* FMOV dst,src1[,c] */ - { DRCUML_OP_FTOINT, op_ftoint }, /* FTOINT dst,src1,size,round */ - { DRCUML_OP_FFRINT, op_ffrint }, /* FFRINT dst,src1,size */ - { DRCUML_OP_FFRFLT, op_ffrflt }, /* FFRFLT dst,src1,size */ - { DRCUML_OP_FRNDS, op_frnds }, /* FRNDS dst,src1 */ - { DRCUML_OP_FADD, op_fadd }, /* FADD dst,src1,src2 */ - { DRCUML_OP_FSUB, op_fsub }, /* FSUB dst,src1,src2 */ - { DRCUML_OP_FCMP, op_fcmp }, /* FCMP src1,src2 */ - { DRCUML_OP_FMUL, op_fmul }, /* FMUL dst,src1,src2 */ - { DRCUML_OP_FDIV, op_fdiv }, /* FDIV dst,src1,src2 */ - { DRCUML_OP_FNEG, op_fneg }, /* FNEG dst,src1 */ - { DRCUML_OP_FABS, op_fabs }, /* FABS dst,src1 */ - { DRCUML_OP_FSQRT, op_fsqrt }, /* FSQRT dst,src1 */ - { DRCUML_OP_FRECIP, op_frecip }, /* FRECIP dst,src1 */ - { DRCUML_OP_FRSQRT, op_frsqrt } /* FRSQRT dst,src1 */ +//************************************************************************** +// TABLES +//************************************************************************** + +const drcbe_x64::opcode_table_entry drcbe_x64::s_opcode_table_source[] = +{ + // Compile-time opcodes + { uml::OP_HANDLE, &drcbe_x64::op_handle }, // HANDLE handle + { uml::OP_HASH, &drcbe_x64::op_hash }, // HASH mode,pc + { uml::OP_LABEL, &drcbe_x64::op_label }, // LABEL imm + { uml::OP_COMMENT, &drcbe_x64::op_comment }, // COMMENT string + { uml::OP_MAPVAR, &drcbe_x64::op_mapvar }, // MAPVAR mapvar,value + + // Control Flow Operations + { uml::OP_NOP, &drcbe_x64::op_nop }, // NOP + { uml::OP_DEBUG, &drcbe_x64::op_debug }, // DEBUG pc + { uml::OP_EXIT, &drcbe_x64::op_exit }, // EXIT src1[,c] + { uml::OP_HASHJMP, &drcbe_x64::op_hashjmp }, // HASHJMP mode,pc,handle + { uml::OP_JMP, &drcbe_x64::op_jmp }, // JMP imm[,c] + { uml::OP_EXH, &drcbe_x64::op_exh }, // EXH handle,param[,c] + { uml::OP_CALLH, &drcbe_x64::op_callh }, // CALLH handle[,c] + { uml::OP_RET, &drcbe_x64::op_ret }, // RET [c] + { uml::OP_CALLC, &drcbe_x64::op_callc }, // CALLC func,ptr[,c] + { uml::OP_RECOVER, &drcbe_x64::op_recover }, // RECOVER dst,mapvar + + // Internal Register Operations + { uml::OP_SETFMOD, &drcbe_x64::op_setfmod }, // SETFMOD src + { uml::OP_GETFMOD, &drcbe_x64::op_getfmod }, // GETFMOD dst + { uml::OP_GETEXP, &drcbe_x64::op_getexp }, // GETEXP dst + { uml::OP_GETFLGS, &drcbe_x64::op_getflgs }, // GETFLGS dst[,f] + { uml::OP_SAVE, &drcbe_x64::op_save }, // SAVE dst + { uml::OP_RESTORE, &drcbe_x64::op_restore }, // RESTORE dst + + // Integer Operations + { uml::OP_LOAD, &drcbe_x64::op_load }, // LOAD dst,base,index,size + { uml::OP_LOADS, &drcbe_x64::op_loads }, // LOADS dst,base,index,size + { uml::OP_STORE, &drcbe_x64::op_store }, // STORE base,index,src,size + { uml::OP_READ, &drcbe_x64::op_read }, // READ dst,src1,spacesize + { uml::OP_READM, &drcbe_x64::op_readm }, // READM dst,src1,mask,spacesize + { uml::OP_WRITE, &drcbe_x64::op_write }, // WRITE dst,src1,spacesize + { uml::OP_WRITEM, &drcbe_x64::op_writem }, // WRITEM dst,src1,spacesize + { uml::OP_CARRY, &drcbe_x64::op_carry }, // CARRY src,bitnum + { uml::OP_SET, &drcbe_x64::op_set }, // SET dst,c + { uml::OP_MOV, &drcbe_x64::op_mov }, // MOV dst,src[,c] + { uml::OP_SEXT, &drcbe_x64::op_sext }, // SEXT dst,src + { uml::OP_ROLAND, &drcbe_x64::op_roland }, // ROLAND dst,src1,src2,src3 + { uml::OP_ROLINS, &drcbe_x64::op_rolins }, // ROLINS dst,src1,src2,src3 + { uml::OP_ADD, &drcbe_x64::op_add }, // ADD dst,src1,src2[,f] + { uml::OP_ADDC, &drcbe_x64::op_addc }, // ADDC dst,src1,src2[,f] + { uml::OP_SUB, &drcbe_x64::op_sub }, // SUB dst,src1,src2[,f] + { uml::OP_SUBB, &drcbe_x64::op_subc }, // SUBB dst,src1,src2[,f] + { uml::OP_CMP, &drcbe_x64::op_cmp }, // CMP src1,src2[,f] + { uml::OP_MULU, &drcbe_x64::op_mulu }, // MULU dst,edst,src1,src2[,f] + { uml::OP_MULS, &drcbe_x64::op_muls }, // MULS dst,edst,src1,src2[,f] + { uml::OP_DIVU, &drcbe_x64::op_divu }, // DIVU dst,edst,src1,src2[,f] + { uml::OP_DIVS, &drcbe_x64::op_divs }, // DIVS dst,edst,src1,src2[,f] + { uml::OP_AND, &drcbe_x64::op_and }, // AND dst,src1,src2[,f] + { uml::OP_TEST, &drcbe_x64::op_test }, // TEST src1,src2[,f] + { uml::OP_OR, &drcbe_x64::op_or }, // OR dst,src1,src2[,f] + { uml::OP_XOR, &drcbe_x64::op_xor }, // XOR dst,src1,src2[,f] + { uml::OP_LZCNT, &drcbe_x64::op_lzcnt }, // LZCNT dst,src[,f] + { uml::OP_BSWAP, &drcbe_x64::op_bswap }, // BSWAP dst,src + { uml::OP_SHL, &drcbe_x64::op_shl }, // SHL dst,src,count[,f] + { uml::OP_SHR, &drcbe_x64::op_shr }, // SHR dst,src,count[,f] + { uml::OP_SAR, &drcbe_x64::op_sar }, // SAR dst,src,count[,f] + { uml::OP_ROL, &drcbe_x64::op_rol }, // ROL dst,src,count[,f] + { uml::OP_ROLC, &drcbe_x64::op_rolc }, // ROLC dst,src,count[,f] + { uml::OP_ROR, &drcbe_x64::op_ror }, // ROR dst,src,count[,f] + { uml::OP_RORC, &drcbe_x64::op_rorc }, // RORC dst,src,count[,f] + + // Floating Point Operations + { uml::OP_FLOAD, &drcbe_x64::op_fload }, // FLOAD dst,base,index + { uml::OP_FSTORE, &drcbe_x64::op_fstore }, // FSTORE base,index,src + { uml::OP_FREAD, &drcbe_x64::op_fread }, // FREAD dst,space,src1 + { uml::OP_FWRITE, &drcbe_x64::op_fwrite }, // FWRITE space,dst,src1 + { uml::OP_FMOV, &drcbe_x64::op_fmov }, // FMOV dst,src1[,c] + { uml::OP_FTOINT, &drcbe_x64::op_ftoint }, // FTOINT dst,src1,size,round + { uml::OP_FFRINT, &drcbe_x64::op_ffrint }, // FFRINT dst,src1,size + { uml::OP_FFRFLT, &drcbe_x64::op_ffrflt }, // FFRFLT dst,src1,size + { uml::OP_FRNDS, &drcbe_x64::op_frnds }, // FRNDS dst,src1 + { uml::OP_FADD, &drcbe_x64::op_fadd }, // FADD dst,src1,src2 + { uml::OP_FSUB, &drcbe_x64::op_fsub }, // FSUB dst,src1,src2 + { uml::OP_FCMP, &drcbe_x64::op_fcmp }, // FCMP src1,src2 + { uml::OP_FMUL, &drcbe_x64::op_fmul }, // FMUL dst,src1,src2 + { uml::OP_FDIV, &drcbe_x64::op_fdiv }, // FDIV dst,src1,src2 + { uml::OP_FNEG, &drcbe_x64::op_fneg }, // FNEG dst,src1 + { uml::OP_FABS, &drcbe_x64::op_fabs }, // FABS dst,src1 + { uml::OP_FSQRT, &drcbe_x64::op_fsqrt }, // FSQRT dst,src1 + { uml::OP_FRECIP, &drcbe_x64::op_frecip }, // FRECIP dst,src1 + { uml::OP_FRSQRT, &drcbe_x64::op_frsqrt } // FRSQRT dst,src1 }; -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** -/*------------------------------------------------- - param_select_register - select a register - to use, avoiding conflicts with the optional - checkparam --------------------------------------------------*/ +//------------------------------------------------- +// param_normalize - convert a full parameter +// into a reduced set +//------------------------------------------------- -INLINE int param_select_register(int defreg, const drcuml_parameter *param, const drcuml_parameter *checkparam) +drcbe_x64::be_parameter::be_parameter(drcbe_x64 &drcbe, const parameter ¶m, UINT32 allowed) { - if ((param->type == DRCUML_PTYPE_INT_REGISTER || param->type == DRCUML_PTYPE_FLOAT_REGISTER) && (checkparam == NULL || param->type != checkparam->type || param->value != checkparam->value)) - return param->value; - return defreg; + int regnum; + + switch (param.type()) + { + // immediates pass through + case parameter::PTYPE_IMMEDIATE: + assert(allowed & PTYPE_I); + *this = param.immediate(); + break; + + // memory passes through + case parameter::PTYPE_MEMORY: + assert(allowed & PTYPE_M); + *this = make_memory(param.memory()); + break; + + // if a register maps to a register, keep it as a register; otherwise map it to memory + case parameter::PTYPE_INT_REGISTER: + assert(allowed & PTYPE_R); + assert(allowed & PTYPE_M); + regnum = int_register_map[param.ireg() - REG_I0]; + if (regnum != 0) + *this = make_ireg(regnum); + else + *this = make_memory(&drcbe.m_state.r[param.ireg() - REG_I0]); + break; + + // if a register maps to a register, keep it as a register; otherwise map it to memory + case parameter::PTYPE_FLOAT_REGISTER: + assert(allowed & PTYPE_F); + assert(allowed & PTYPE_M); + regnum = float_register_map[param.freg() - REG_F0]; + if (regnum != 0) + *this = make_freg(regnum); + else + *this = make_memory(&drcbe.m_state.f[param.freg() - REG_F0]); + break; + + // everything else is unexpected + default: + fatalerror("Unexpected parameter type"); + break; + } } -/*------------------------------------------------- - param_select_register2 - select a register - to use, avoiding conflicts with the optional - checkparam --------------------------------------------------*/ +//------------------------------------------------- +// select_register - select a register to use, +// avoiding conflicts with the optional +// checkparam +//------------------------------------------------- -INLINE int param_select_register2(int defreg, const drcuml_parameter *param, const drcuml_parameter *checkparam1, const drcuml_parameter *checkparam2) +inline int drcbe_x64::be_parameter::select_register(int defreg) const { - if (param->type == DRCUML_PTYPE_INT_REGISTER && (param->type != checkparam1->type || param->value != checkparam1->value) && (param->type != checkparam2->type || param->value != checkparam2->value)) - return param->value; + if (m_type == PTYPE_INT_REGISTER || m_type == PTYPE_FLOAT_REGISTER || m_type == PTYPE_VECTOR_REGISTER) + return m_value; return defreg; } +inline int drcbe_x64::be_parameter::select_register(int defreg, const be_parameter &checkparam) const +{ + if (*this == checkparam) + return defreg; + return select_register(defreg); +} + +inline int drcbe_x64::be_parameter::select_register(int defreg, const be_parameter &checkparam, const be_parameter &checkparam2) const +{ + if (*this == checkparam || *this == checkparam2) + return defreg; + return select_register(defreg); +} -/*------------------------------------------------- - offset_from_rbp - return the verified offset - from rbp --------------------------------------------------*/ -INLINE INT32 offset_from_rbp(drcbe_state *drcbe, FPTR ptr) +//------------------------------------------------- +// select_register - select a register to use, +// avoiding conflicts with the optional +// checkparam +//------------------------------------------------- + +inline void drcbe_x64::normalize_commutative(be_parameter &inner, be_parameter &outer) { - INT64 delta = (UINT8 *)ptr - drcbe->rbpvalue; - assert_always((INT32)delta == delta, "offset_from_rbp: delta out of range"); - return (INT32)delta; + // if the inner parameter is a memory operand, push it to the outer + if (inner.is_memory()) + { + be_parameter temp = inner; + inner = outer; + outer = temp; + } + + // if the inner parameter is an immediate, push it to the outer + if (inner.is_immediate()) + { + be_parameter temp = inner; + inner = outer; + outer = temp; + } } -/*------------------------------------------------- - short_immediate - true if the given immediate - fits as a signed 32-bit value --------------------------------------------------*/ +//------------------------------------------------- +// offset_from_rbp - return the verified offset +// from rbp +//------------------------------------------------- -INLINE int short_immediate(INT64 immediate) +inline INT32 drcbe_x64::offset_from_rbp(const void *ptr) { - return (INT32)immediate == immediate; + INT64 delta = reinterpret_cast<UINT8 *>(const_cast<void *>(ptr)) - m_rbpvalue; + assert_always((INT32)delta == delta, "offset_from_rbp: delta out of range"); + return (INT32)delta; } -/*------------------------------------------------- - get_base_register_and_offset - determine right - base register and offset to access the given - target address --------------------------------------------------*/ +//------------------------------------------------- +// get_base_register_and_offset - determine right +// base register and offset to access the given +// target address +//------------------------------------------------- -INLINE int get_base_register_and_offset(drcbe_state *drcbe, x86code **dst, FPTR target, UINT8 reg, INT32 *offset) +inline int drcbe_x64::get_base_register_and_offset(x86code *&dst, void *target, UINT8 reg, INT32 &offset) { - INT64 delta = (UINT8 *)target - drcbe->rbpvalue; + INT64 delta = (UINT8 *)target - m_rbpvalue; if (short_immediate(delta)) { - *offset = delta; + offset = delta; return REG_RBP; } else { - *offset = 0; - emit_mov_r64_imm(dst, reg, target); // mov reg,target + offset = 0; + emit_mov_r64_imm(dst, reg, (FPTR)target); // mov reg,target return reg; } } -/*------------------------------------------------- - emit_smart_call_r64 - generate a call either - directly or via a call through pointer --------------------------------------------------*/ +//------------------------------------------------- +// emit_smart_call_r64 - generate a call either +// directly or via a call through pointer +//------------------------------------------------- -INLINE void emit_smart_call_r64(drcbe_state *drcbe, x86code **dst, x86code *target, UINT8 reg) +inline void drcbe_x64::emit_smart_call_r64(x86code *&dst, x86code *target, UINT8 reg) { - INT64 delta = target - (*dst + 5); + INT64 delta = target - (dst + 5); if (short_immediate(delta)) emit_call(dst, target); // call target else @@ -661,159 +584,135 @@ INLINE void emit_smart_call_r64(drcbe_state *drcbe, x86code **dst, x86code *targ } -/*------------------------------------------------- - emit_smart_call_m64 - generate a call either - directly or via a call through pointer --------------------------------------------------*/ +//------------------------------------------------- +// emit_smart_call_m64 - generate a call either +// directly or via a call through pointer +//------------------------------------------------- -INLINE void emit_smart_call_m64(drcbe_state *drcbe, x86code **dst, x86code **target) +inline void drcbe_x64::emit_smart_call_m64(x86code *&dst, x86code **target) { - INT64 delta = *target - (*dst + 5); + INT64 delta = *target - (dst + 5); if (short_immediate(delta)) emit_call(dst, *target); // call *target else - emit_call_m64(dst, MABS(drcbe, target)); // call [target] + emit_call_m64(dst, MABS(target)); // call [target] } -/*************************************************************************** - BACKEND CALLBACKS -***************************************************************************/ +//************************************************************************** +// BACKEND CALLBACKS +//************************************************************************** -/*------------------------------------------------- - drcbex64_alloc - allocate back-end-specific - state --------------------------------------------------*/ +//------------------------------------------------- +// drcbe_x64 - constructor +//------------------------------------------------- -static drcbe_state *drcbex64_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits) +drcbe_x64::drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits) + : drcbe_interface(drcuml, cache, device), + m_hash(cache, modes, addrbits, ignorebits), + m_map(cache, 0), + m_labels(cache), + m_log(NULL), + m_sse41(false), + m_absmask32((UINT32 *)cache.alloc_near(16*2 + 15)), + m_absmask64(NULL), + m_rbpvalue(cache.near() + 0x80), + m_entry(NULL), + m_exit(NULL), + m_nocode(NULL), + m_near(*(near_state *)cache.alloc_near(sizeof(m_near))) { - /* SSE control register mapping */ + // build up necessary arrays static const UINT32 sse_control[4] = { - 0xffc0, /* DRCUML_FMOD_TRUNC */ - 0x9fc0, /* DRCUML_FMOD_ROUND */ - 0xdfc0, /* DRCUML_FMOD_CEIL */ - 0xbfc0 /* DRCUML_FMOD_FLOOR */ + 0xffc0, // ROUND_TRUNC + 0x9fc0, // ROUND_ROUND + 0xdfc0, // ROUND_CEIL + 0xbfc0 // ROUND_FLOOR }; - drcbe_state *drcbe; - int opnum, entry; - int spacenum; - - /* allocate space in the cache for our state */ - drcbe = (drcbe_state *)cache->alloc_near(sizeof(*drcbe)); - if (drcbe == NULL) - return NULL; - memset(drcbe, 0, sizeof(*drcbe)); - - /* remember our pointers */ - drcbe->device = device; - drcbe->drcuml = drcuml; - drcbe->cache = cache; - drcbe->rbpvalue = cache->near() + 0x80; - - /* get address spaces and accessors */ - for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++) - { - drcbe->space[spacenum] = downcast<cpu_device *>(device)->space(spacenum); - if (drcbe->space[spacenum] != NULL) - drcbe->space[spacenum]->accessors(drcbe->accessors[spacenum]); - } - - /* build up necessary arrays */ - memcpy(drcbe->ssecontrol, sse_control, sizeof(drcbe->ssecontrol)); - drcbe->absmask32 = (UINT32 *)cache->alloc_near(16*2 + 15); - drcbe->absmask32 = (UINT32 *)(((FPTR)drcbe->absmask32 + 15) & ~15); - drcbe->absmask32[0] = drcbe->absmask32[1] = drcbe->absmask32[2] = drcbe->absmask32[3] = 0x7fffffff; - drcbe->absmask64 = (UINT64 *)&drcbe->absmask32[4]; - drcbe->absmask64[0] = drcbe->absmask64[1] = U64(0x7fffffffffffffff); - drcbe->single1 = 1.0f; - drcbe->double1 = 1.0; - - /* get pointers to C functions we need to call */ - drcbe->debug_cpu_instruction_hook = (x86code *)debugger_instruction_hook; + memcpy(m_near.ssecontrol, sse_control, sizeof(m_near.ssecontrol)); + m_near.single1 = 1.0f; + m_near.double1 = 1.0; + + // create absolute value masks that are aligned to SSE boundaries + m_absmask32 = (UINT32 *)(((FPTR)m_absmask32 + 15) & ~15); + m_absmask32[0] = m_absmask32[1] = m_absmask32[2] = m_absmask32[3] = 0x7fffffff; + m_absmask64 = (UINT64 *)&m_absmask32[4]; + m_absmask64[0] = m_absmask64[1] = U64(0x7fffffffffffffff); + + // get pointers to C functions we need to call + m_near.debug_cpu_instruction_hook = (x86code *)debugger_instruction_hook; if (LOG_HASHJMPS) { - drcbe->debug_log_hashjmp = (x86code *)debug_log_hashjmp; - drcbe->debug_log_hashjmp_fail = (x86code *)debug_log_hashjmp_fail; + m_near.debug_log_hashjmp = (x86code *)debug_log_hashjmp; + m_near.debug_log_hashjmp_fail = (x86code *)debug_log_hashjmp_fail; } - drcbe->drcmap_get_value = (x86code *)&drc_map_variables::static_get_value; - - /* allocate hash tables */ - drcbe->hash = auto_alloc(device->machine, drc_hash_table(*cache, modes, addrbits, ignorebits)); - - /* allocate code map */ - drcbe->map = auto_alloc(device->machine, drc_map_variables(*cache, 0)); + m_near.drcmap_get_value = (x86code *)&drc_map_variables::static_get_value; - /* allocate a label tracker */ - drcbe->labels = auto_alloc(device->machine, drc_label_list(*cache)); - - /* build the opcode table (static but it doesn't hurt to regenerate it) */ - for (opnum = 0; opnum < ARRAY_LENGTH(opcode_table_source); opnum++) - opcode_table[opcode_table_source[opnum].opcode] = opcode_table_source[opnum].func; - - /* build the flags map */ - for (entry = 0; entry < ARRAY_LENGTH(drcbe->flagsmap); entry++) + // build the flags map + for (int entry = 0; entry < ARRAY_LENGTH(m_near.flagsmap); entry++) { UINT8 flags = 0; - if (entry & 0x001) flags |= DRCUML_FLAG_C; - if (entry & 0x004) flags |= DRCUML_FLAG_U; - if (entry & 0x040) flags |= DRCUML_FLAG_Z; - if (entry & 0x080) flags |= DRCUML_FLAG_S; - if (entry & 0x800) flags |= DRCUML_FLAG_V; - drcbe->flagsmap[entry] = flags; + if (entry & 0x001) flags |= FLAG_C; + if (entry & 0x004) flags |= FLAG_U; + if (entry & 0x040) flags |= FLAG_Z; + if (entry & 0x080) flags |= FLAG_S; + if (entry & 0x800) flags |= FLAG_V; + m_near.flagsmap[entry] = flags; } - for (entry = 0; entry < ARRAY_LENGTH(drcbe->flagsunmap); entry++) + for (int entry = 0; entry < ARRAY_LENGTH(m_near.flagsunmap); entry++) { UINT64 flags = 0; - if (entry & DRCUML_FLAG_C) flags |= 0x001; - if (entry & DRCUML_FLAG_U) flags |= 0x004; - if (entry & DRCUML_FLAG_Z) flags |= 0x040; - if (entry & DRCUML_FLAG_S) flags |= 0x080; - if (entry & DRCUML_FLAG_V) flags |= 0x800; - drcbe->flagsunmap[entry] = flags; + if (entry & FLAG_C) flags |= 0x001; + if (entry & FLAG_U) flags |= 0x004; + if (entry & FLAG_Z) flags |= 0x040; + if (entry & FLAG_S) flags |= 0x080; + if (entry & FLAG_V) flags |= 0x800; + m_near.flagsunmap[entry] = flags; } - /* create the log */ - if (flags & DRCUML_OPTION_LOG_NATIVE) - drcbe->log = x86log_create_context("drcbex64.asm"); + // build the opcode table (static but it doesn't hurt to regenerate it) + for (int opnum = 0; opnum < ARRAY_LENGTH(s_opcode_table_source); opnum++) + s_opcode_table[s_opcode_table_source[opnum].opcode] = s_opcode_table_source[opnum].func; - return drcbe; + // create the log + if (flags & DRCUML_OPTION_LOG_NATIVE) + m_log = x86log_create_context("drcbex64.asm"); } -/*------------------------------------------------- - drcbex64_free - free back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// ~drcbe_x64 - destructor +//------------------------------------------------- -static void drcbex64_free(drcbe_state *drcbe) +drcbe_x64::~drcbe_x64() { - /* free the log context */ - if (drcbe->log != NULL) - x86log_free_context(drcbe->log); + // free the log context + if (m_log != NULL) + x86log_free_context(m_log); } -/*------------------------------------------------- - drcbex64_reset - reset back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// reset - reset back-end specific state +//------------------------------------------------- -static void drcbex64_reset(drcbe_state *drcbe) +void drcbe_x64::reset() { - UINT32 (*cpuid_ecx_stub)(void); - x86code **dst; - - /* output a note to the log */ - if (drcbe->log != NULL) - x86log_printf(drcbe->log, "\n\n===========\nCACHE RESET\n===========\n\n"); + // output a note to the log + if (m_log != NULL) + x86log_printf(m_log, "\n\n===========\nCACHE RESET\n===========\n\n"); - /* generate a little bit of glue code to set up the environment */ - dst = (x86code **)drcbe->cache->begin_codegen(500); - if (dst == NULL) + // generate a little bit of glue code to set up the environment + drccodeptr *cachetop = m_cache.begin_codegen(500); + if (cachetop == NULL) fatalerror("Out of cache space after a reset!"); - /* generate a simple CPUID stub */ - cpuid_ecx_stub = (UINT32 (*)(void))*dst; + x86code *dst = (x86code *)*cachetop; + + // generate a simple CPUID stub + UINT32 (*cpuid_ecx_stub)(void) = (UINT32 (*)(void))dst; emit_push_r64(dst, REG_RBX); // push rbx emit_mov_r32_imm(dst, REG_EAX, 1); // mov eax,1 emit_cpuid(dst); // cpuid @@ -821,11 +720,11 @@ static void drcbex64_reset(drcbe_state *drcbe) emit_pop_r64(dst, REG_RBX); // pop rbx emit_ret(dst); // ret - /* call it to determine if we have SSE4.1 support */ - drcbe->sse41 = (((*cpuid_ecx_stub)() & 0x80000) != 0); + // call it to determine if we have SSE4.1 support + m_sse41 = (((*cpuid_ecx_stub)() & 0x80000) != 0); - /* generate an entry point */ - drcbe->entry = (x86_entry_point_func)*dst; + // generate an entry point + m_entry = (x86_entry_point_func)dst; emit_push_r64(dst, REG_RBX); // push rbx emit_push_r64(dst, REG_RSI); // push rsi emit_push_r64(dst, REG_RDI); // push rdi @@ -836,18 +735,18 @@ static void drcbex64_reset(drcbe_state *drcbe) emit_push_r64(dst, REG_R15); // push r15 emit_mov_r64_r64(dst, REG_RBP, REG_PARAM1); // mov rbp,param1 emit_sub_r64_imm(dst, REG_RSP, 32); // sub rsp,32 - emit_mov_m64_r64(dst, MABS(drcbe, &drcbe->hashstacksave), REG_RSP); // mov [hashstacksave],rsp + emit_mov_m64_r64(dst, MABS(&m_near.hashstacksave), REG_RSP); // mov [hashstacksave],rsp emit_sub_r64_imm(dst, REG_RSP, 8); // sub rsp,8 - emit_mov_m64_r64(dst, MABS(drcbe, &drcbe->stacksave), REG_RSP); // mov [stacksave],rsp - emit_stmxcsr_m32(dst, MABS(drcbe, &drcbe->ssemode)); // stmxcsr [ssemode] + emit_mov_m64_r64(dst, MABS(&m_near.stacksave), REG_RSP); // mov [stacksave],rsp + emit_stmxcsr_m32(dst, MABS(&m_near.ssemode)); // stmxcsr [ssemode] emit_jmp_r64(dst, REG_PARAM2); // jmp param2 - if (drcbe->log != NULL) - x86log_disasm_code_range(drcbe->log, "entry_point", (x86code *)drcbe->entry, *dst); + if (m_log != NULL) + x86log_disasm_code_range(m_log, "entry_point", (x86code *)m_entry, dst); - /* generate an exit point */ - drcbe->exit = *dst; - emit_ldmxcsr_m32(dst, MABS(drcbe, &drcbe->ssemode)); // ldmxcsr [ssemode] - emit_mov_r64_m64(dst, REG_RSP, MABS(drcbe, &drcbe->hashstacksave)); // mov rsp,[hashstacksave] + // generate an exit point + m_exit = dst; + emit_ldmxcsr_m32(dst, MABS(&m_near.ssemode)); // ldmxcsr [ssemode] + emit_mov_r64_m64(dst, REG_RSP, MABS(&m_near.hashstacksave)); // mov rsp,[hashstacksave] emit_add_r64_imm(dst, REG_RSP, 32); // add rsp,32 emit_pop_r64(dst, REG_R15); // pop r15 emit_pop_r64(dst, REG_R14); // pop r14 @@ -858,1138 +757,902 @@ static void drcbex64_reset(drcbe_state *drcbe) emit_pop_r64(dst, REG_RSI); // pop rsi emit_pop_r64(dst, REG_RBX); // pop rbx emit_ret(dst); // ret - if (drcbe->log != NULL) - x86log_disasm_code_range(drcbe->log, "exit_point", drcbe->exit, *dst); + if (m_log != NULL) + x86log_disasm_code_range(m_log, "exit_point", m_exit, dst); - /* generate a no code point */ - drcbe->nocode = *dst; + // generate a no code point + m_nocode = dst; emit_ret(dst); // ret - if (drcbe->log != NULL) - x86log_disasm_code_range(drcbe->log, "nocode", drcbe->nocode, *dst); + if (m_log != NULL) + x86log_disasm_code_range(m_log, "nocode", m_nocode, dst); - /* finish up codegen */ - drcbe->cache->end_codegen(); + // finish up codegen + *cachetop = (drccodeptr)dst; + m_cache.end_codegen(); - /* reset our hash tables */ - drcbe->hash->reset(); - drcbe->hash->set_default_codeptr(drcbe->nocode); + // reset our hash tables + m_hash.reset(); + m_hash.set_default_codeptr(m_nocode); } -/*------------------------------------------------- - drcbex64_execute - execute a block of code - referenced by the given handle --------------------------------------------------*/ +//------------------------------------------------- +// execute - execute a block of code referenced +// by the given handle +//------------------------------------------------- -static int drcbex64_execute(drcbe_state *drcbe, drcuml_codehandle *entry) +int drcbe_x64::execute(code_handle &entry) { - /* call our entry point which will jump to the destination */ - return (*drcbe->entry)(drcbe->rbpvalue, (x86code *)drcuml_handle_codeptr(entry)); + // call our entry point which will jump to the destination + return (*m_entry)(m_rbpvalue, (x86code *)entry.codeptr()); } -/*------------------------------------------------- - drcbex64_generate - generate code --------------------------------------------------*/ +//------------------------------------------------- +// drcbex64_generate - generate code +//------------------------------------------------- -static void drcbex64_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst) +void drcbe_x64::generate(drcuml_block &block, const instruction *instlist, UINT32 numinst) { - const char *blockname = NULL; - char blockbuffer[100]; - drccodeptr *cachetop; - x86code *base; - x86code *dst; - int inum; - - /* tell all of our utility objects that a block is beginning */ - drcbe->hash->block_begin(*block, instlist, numinst); - drcbe->labels->block_begin(*block); - drcbe->map->block_begin(*block); - - /* begin codegen; fail if we can't */ - cachetop = drcbe->cache->begin_codegen(numinst * 8 * 4); + // tell all of our utility objects that a block is beginning + m_hash.block_begin(block, instlist, numinst); + m_labels.block_begin(block); + m_map.block_begin(block); + + // begin codegen; fail if we can't + drccodeptr *cachetop = m_cache.begin_codegen(numinst * 8 * 4); if (cachetop == NULL) - drcuml_block_abort(block); + block.abort(); - /* compute the base by aligning the cache top to a cache line (assumed to be 64 bytes) */ - base = (x86code *)(((FPTR)*cachetop + 63) & ~63); - dst = base; + // compute the base by aligning the cache top to a cache line (assumed to be 64 bytes) + x86code *base = (x86code *)(((FPTR)*cachetop + 63) & ~63); + x86code *dst = base; - /* generate code */ - for (inum = 0; inum < numinst; inum++) + // generate code + astring tempstring; + const char *blockname = NULL; + for (int inum = 0; inum < numinst; inum++) { - const drcuml_instruction *inst = &instlist[inum]; - assert(inst->opcode < ARRAY_LENGTH(opcode_table)); + const instruction &inst = instlist[inum]; + assert(inst.opcode() < ARRAY_LENGTH(s_opcode_table)); - /* add a comment */ - if (drcbe->log != NULL) + // add a comment + if (m_log != NULL) { - char dasm[256]; - drcuml_disasm(inst, dasm, drcbe->drcuml); - x86log_add_comment(drcbe->log, dst, "%s", dasm); + astring dasm; + inst.disasm(dasm, &m_drcuml); + x86log_add_comment(m_log, dst, "%s", dasm.cstr()); } - /* extract a blockname */ + // extract a blockname if (blockname == NULL) { - if (inst->opcode == DRCUML_OP_HANDLE) - blockname = drcuml_handle_name((drcuml_codehandle *)(FPTR)inst->param[0].value); - else if (inst->opcode == DRCUML_OP_HASH) - { - sprintf(blockbuffer, "Code: mode=%d PC=%08X", (UINT32)inst->param[0].value, (offs_t)inst->param[1].value); - blockname = blockbuffer; - } + if (inst.opcode() == OP_HANDLE) + blockname = inst.param(0).handle().string(); + else if (inst.opcode() == OP_HASH) + blockname = tempstring.format("Code: mode=%d PC=%08X", (UINT32)inst.param(0).immediate(), (offs_t)inst.param(1).immediate()); } - /* generate code */ - dst = (*opcode_table[inst->opcode])(drcbe, dst, inst); + // generate code + (this->*s_opcode_table[inst.opcode()])(dst, inst); } - /* complete codegen */ + // complete codegen *cachetop = (drccodeptr)dst; - drcbe->cache->end_codegen(); + m_cache.end_codegen(); - /* log it */ - if (drcbe->log != NULL) - x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drcbe->cache->top()); + // log it + if (m_log != NULL) + x86log_disasm_code_range(m_log, (blockname == NULL) ? "Unknown block" : blockname, base, m_cache.top()); - /* tell all of our utility objects that the block is finished */ - drcbe->hash->block_end(*block); - drcbe->labels->block_end(*block); - drcbe->map->block_end(*block); + // tell all of our utility objects that the block is finished + m_hash.block_end(block); + m_labels.block_end(block); + m_map.block_end(block); } -/*------------------------------------------------- - drcbex64_hash_exists - return true if the - given mode/pc exists in the hash table --------------------------------------------------*/ +//------------------------------------------------- +// hash_exists - return true if the given mode/pc +// exists in the hash table +//------------------------------------------------- -static int drcbex64_hash_exists(drcbe_state *drcbe, UINT32 mode, UINT32 pc) +bool drcbe_x64::hash_exists(UINT32 mode, UINT32 pc) { - return drcbe->hash->code_exists(mode, pc); + return m_hash.code_exists(mode, pc); } -/*------------------------------------------------- - drcbex64_get_info - return information about - the back-end implementation --------------------------------------------------*/ +//------------------------------------------------- +// get_info - return information about the +// back-end implementation +//------------------------------------------------- -static void drcbex64_get_info(drcbe_state *state, drcbe_info *info) +void drcbe_x64::get_info(drcbe_info &info) { - for (info->direct_iregs = 0; info->direct_iregs < DRCUML_REG_I_END - DRCUML_REG_I0; info->direct_iregs++) - if (int_register_map[info->direct_iregs] == 0) + for (info.direct_iregs = 0; info.direct_iregs < REG_I_COUNT; info.direct_iregs++) + if (int_register_map[info.direct_iregs] == 0) break; - for (info->direct_fregs = 0; info->direct_fregs < DRCUML_REG_F_END - DRCUML_REG_F0; info->direct_fregs++) - if (float_register_map[info->direct_fregs] == 0) + for (info.direct_fregs = 0; info.direct_fregs < REG_F_COUNT; info.direct_fregs++) + if (float_register_map[info.direct_fregs] == 0) break; } /*************************************************************************** - COMPILE HELPERS -***************************************************************************/ - -/*------------------------------------------------- - param_normalize - convert a full parameter - into a reduced set --------------------------------------------------*/ - -static void param_normalize(drcbe_state *drcbe, const drcuml_parameter *src, drcuml_parameter *dest, UINT32 allowed) -{ - int regnum; - - switch (src->type) - { - /* immediates pass through */ - case DRCUML_PTYPE_IMMEDIATE: - assert(allowed & PTYPE_I); - dest->type = DRCUML_PTYPE_IMMEDIATE; - dest->value = src->value; - break; - - /* memory passes through */ - case DRCUML_PTYPE_MEMORY: - assert(allowed & PTYPE_M); - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = (FPTR)src->value; - break; - - /* if a register maps to a register, keep it as a register; otherwise map it to memory */ - case DRCUML_PTYPE_INT_REGISTER: - assert(allowed & PTYPE_R); - assert(allowed & PTYPE_M); - regnum = int_register_map[src->value - DRCUML_REG_I0]; - if (regnum != 0) - { - dest->type = DRCUML_PTYPE_INT_REGISTER; - dest->value = regnum; - } - else - { - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = (FPTR)&drcbe->state.r[src->value - DRCUML_REG_I0]; - } - break; - - /* if a register maps to a register, keep it as a register; otherwise map it to memory */ - case DRCUML_PTYPE_FLOAT_REGISTER: - assert(allowed & PTYPE_F); - assert(allowed & PTYPE_M); - regnum = float_register_map[src->value - DRCUML_REG_F0]; - if (regnum != 0) - { - dest->type = DRCUML_PTYPE_FLOAT_REGISTER; - dest->value = regnum; - } - else - { - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = (FPTR)&drcbe->state.f[src->value - DRCUML_REG_F0]; - } - break; - - /* everything else is unexpected */ - default: - fatalerror("Unexpected parameter type"); - break; - } -} - - -/*------------------------------------------------- - param_normalize_1 - normalize a single - parameter instruction --------------------------------------------------*/ - -static void param_normalize_1(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0) -{ - assert(inst->numparams == 1); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); -} - - -/*------------------------------------------------- - param_normalize_2 - normalize a 2 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_2(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1) -{ - assert(inst->numparams == 2); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); -} - - -/*------------------------------------------------- - param_normalize_2_commutative - normalize a 2 - parameter instruction, shuffling the - parameters on the assumption that the two - parameters can be swapped --------------------------------------------------*/ - -static void param_normalize_2_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1) -{ - param_normalize_2(drcbe, inst, dest0, allowed0, dest1, allowed1); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest0->type == DRCUML_PTYPE_MEMORY) - { - drcuml_parameter temp = *dest0; - *dest0 = *dest1; - *dest1 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest0->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest0; - *dest0 = *dest1; - *dest1 = temp; - } -} - - -/*------------------------------------------------- - param_normalize_3 - normalize a 3 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_3(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2) -{ - assert(inst->numparams == 3); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); - param_normalize(drcbe, &inst->param[2], dest2, allowed2); -} - - -/*------------------------------------------------- - param_normalize_3_commutative - normalize a 3 - parameter instruction, shuffling the - parameters on the assumption that the last - 2 can be swapped --------------------------------------------------*/ - -static void param_normalize_3_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2) -{ - param_normalize_3(drcbe, inst, dest0, allowed0, dest1, allowed1, dest2, allowed2); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest1->type == DRCUML_PTYPE_MEMORY) - { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest1->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } - - /* if the destination and outer parameters are equal, move the outer to the inner */ - if (dest0->type == dest2->type && dest0->value == dest2->value && dest0->type != DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } -} - - -/*------------------------------------------------- - param_normalize_4 - normalize a 4 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_4(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2, drcuml_parameter *dest3, UINT32 allowed3) -{ - assert(inst->numparams == 4); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); - param_normalize(drcbe, &inst->param[2], dest2, allowed2); - param_normalize(drcbe, &inst->param[3], dest3, allowed3); -} - - -/*------------------------------------------------- - param_normalize_4_commutative - normalize a 4 - parameter instruction, shuffling the - parameters on the assumption that the last - 2 can be swapped --------------------------------------------------*/ - -static void param_normalize_4_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2, drcuml_parameter *dest3, UINT32 allowed3) -{ - param_normalize_4(drcbe, inst, dest0, allowed0, dest1, allowed1, dest2, allowed2, dest3, allowed3); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest2->type == DRCUML_PTYPE_MEMORY) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest2->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } - - /* if the destination and outer parameters are equal, move the outer to the inner */ - if (dest0->type == dest3->type && dest0->value == dest3->value && dest0->type != DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } -} - - - -/*************************************************************************** EMITTERS FOR 32-BIT OPERATIONS WITH PARAMETERS ***************************************************************************/ -/*------------------------------------------------- - emit_mov_r32_p32 - move a 32-bit parameter - into a register --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r32_p32 - move a 32-bit parameter +// into a register +//------------------------------------------------- -static void emit_mov_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (param->value == 0) + if (param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg else - emit_mov_r32_imm(dst, reg, param->value); // mov reg,param + emit_mov_r32_imm(dst, reg, param.immediate()); // mov reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_r32_m32(dst, reg, MABS(drcbe, param->value)); // mov reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_memory()) + emit_mov_r32_m32(dst, reg, MABS(param.memory())); // mov reg,[param] + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r32_r32(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_movsx_r64_p32 - move a 32-bit parameter - sign-extended into a register --------------------------------------------------*/ +//------------------------------------------------- +// emit_movsx_r64_p32 - move a 32-bit parameter +// sign-extended into a register +//------------------------------------------------- -static void emit_movsx_r64_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_movsx_r64_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (param->value == 0) + if (param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg - else if ((INT32)param->value >= 0) - emit_mov_r32_imm(dst, reg, param->value); // mov reg,param + else if ((INT32)param.immediate() >= 0) + emit_mov_r32_imm(dst, reg, param.immediate()); // mov reg,param else - emit_mov_r64_imm(dst, reg, (INT32)param->value); // mov reg,param + emit_mov_r64_imm(dst, reg, (INT32)param.immediate()); // mov reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_movsxd_r64_m32(dst, reg, MABS(drcbe, param->value)); // movsxd reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_movsxd_r64_r32(dst, reg, param->value); // movsdx reg,param + else if (param.is_memory()) + emit_movsxd_r64_m32(dst, reg, MABS(param.memory())); // movsxd reg,[param] + else if (param.is_int_register()) + emit_movsxd_r64_r32(dst, reg, param.ireg()); // movsdx reg,param } -/*------------------------------------------------- - emit_mov_r32_p32_keepflags - move a 32-bit - parameter into a register without affecting - any flags --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r32_p32_keepflags - move a 32-bit +// parameter into a register without affecting +// any flags +//------------------------------------------------- -static void emit_mov_r32_p32_keepflags(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r32_imm(dst, reg, param->value); // mov reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_r32_m32(dst, reg, MABS(drcbe, param->value)); // mov reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + if (param.is_immediate()) + emit_mov_r32_imm(dst, reg, param.immediate()); // mov reg,param + else if (param.is_memory()) + emit_mov_r32_m32(dst, reg, MABS(param.memory())); // mov reg,[param] + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r32_r32(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_mov_m32_p32 - move a 32-bit parameter - into a memory location --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_m32_p32 - move a 32-bit parameter +// into a memory location +//------------------------------------------------- -static void emit_mov_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param) +void drcbe_x64::emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_m32_imm(dst, MEMPARAMS, param->value); // mov [mem],param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) + emit_mov_m32_imm(dst, memref, param.immediate()); // mov [mem],param + else if (param.is_memory()) { - emit_mov_r32_m32(dst, REG_EAX, MABS(drcbe, param->value)); // mov eax,[param] - emit_mov_m32_r32(dst, MEMPARAMS, REG_EAX); // mov [mem],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(param.memory())); // mov eax,[param] + emit_mov_m32_r32(dst, memref, REG_EAX); // mov [mem],eax } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(dst, MEMPARAMS, param->value); // mov [mem],param + else if (param.is_int_register()) + emit_mov_m32_r32(dst, memref, param.ireg()); // mov [mem],param } -/*------------------------------------------------- - emit_mov_p32_r32 - move a register into a - 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_p32_r32 - move a register into a +// 32-bit parameter +//------------------------------------------------- -static void emit_mov_p32_r32(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reg) +void drcbe_x64::emit_mov_p32_r32(x86code *&dst, const be_parameter ¶m, UINT8 reg) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(dst, MABS(drcbe, param->value), reg); // mov [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_mov_m32_r32(dst, MABS(param.memory()), reg); // mov [param],reg + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, param->value, reg); // mov param,reg + if (reg != param.ireg()) + emit_mov_r32_r32(dst, param.ireg(), reg); // mov param,reg } } -/*------------------------------------------------- - emit_add_r32_p32 - add operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_r32_p32 - add operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_add_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_add_r32_imm(dst, reg, param->value); // add reg,param + if (inst.flags() != 0 || param.immediate() != 0) + emit_add_r32_imm(dst, reg, param.immediate()); // add reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_add_r32_m32(dst, reg, MABS(drcbe, param->value)); // add reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_add_r32_r32(dst, reg, param->value); // add reg,param + else if (param.is_memory()) + emit_add_r32_m32(dst, reg, MABS(param.memory())); // add reg,[param] + else if (param.is_int_register()) + emit_add_r32_r32(dst, reg, param.ireg()); // add reg,param } -/*------------------------------------------------- - emit_add_m32_p32 - add operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_m32_p32 - add operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_add_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_add_m32_imm(dst, MEMPARAMS, param->value); // add [dest],param + if (inst.flags() != 0 || param.immediate() != 0) + emit_add_m32_imm(dst, memref, param.immediate()); // add [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_add_m32_r32(dst, MEMPARAMS, reg); // add [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_add_m32_r32(dst, memref, reg); // add [dest],reg } } -/*------------------------------------------------- - emit_adc_r32_p32 - adc operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_r32_p32 - adc operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_adc_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_adc_r32_imm(dst, reg, param->value); // adc reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_adc_r32_m32(dst, reg, MABS(drcbe, param->value)); // adc reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_adc_r32_r32(dst, reg, param->value); // adc reg,param + if (param.is_immediate()) + emit_adc_r32_imm(dst, reg, param.immediate()); // adc reg,param + else if (param.is_memory()) + emit_adc_r32_m32(dst, reg, MABS(param.memory())); // adc reg,[param] + else if (param.is_int_register()) + emit_adc_r32_r32(dst, reg, param.ireg()); // adc reg,param } -/*------------------------------------------------- - emit_adc_m32_p32 - adc operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_m32_p32 - adc operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_adc_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_adc_m32_imm(dst, MEMPARAMS, param->value); // adc [dest],param + if (param.is_immediate()) + emit_adc_m32_imm(dst, memref, param.immediate()); // adc [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_adc_m32_r32(dst, MEMPARAMS, reg); // adc [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32_keepflags(dst, reg, param); // mov reg,param + emit_adc_m32_r32(dst, memref, reg); // adc [dest],reg } } -/*------------------------------------------------- - emit_sub_r32_p32 - sub operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_r32_p32 - sub operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sub_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_sub_r32_imm(dst, reg, param->value); // sub reg,param + if (inst.flags() != 0 || param.immediate() != 0) + emit_sub_r32_imm(dst, reg, param.immediate()); // sub reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sub_r32_m32(dst, reg, MABS(drcbe, param->value)); // sub reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sub_r32_r32(dst, reg, param->value); // sub reg,param + else if (param.is_memory()) + emit_sub_r32_m32(dst, reg, MABS(param.memory())); // sub reg,[param] + else if (param.is_int_register()) + emit_sub_r32_r32(dst, reg, param.ireg()); // sub reg,param } -/*------------------------------------------------- - emit_sub_m32_p32 - sub operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_m32_p32 - sub operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sub_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_sub_m32_imm(dst, MEMPARAMS, param->value); // sub [dest],param + if (inst.flags() != 0 || param.immediate() != 0) + emit_sub_m32_imm(dst, memref, param.immediate()); // sub [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_sub_m32_r32(dst, MEMPARAMS, reg); // sub [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_sub_m32_r32(dst, memref, reg); // sub [dest],reg } } -/*------------------------------------------------- - emit_sbb_r32_p32 - sbb operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_r32_p32 - sbb operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sbb_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_sbb_r32_imm(dst, reg, param->value); // sbb reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sbb_r32_m32(dst, reg, MABS(drcbe, param->value)); // sbb reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sbb_r32_r32(dst, reg, param->value); // sbb reg,param + if (param.is_immediate()) + emit_sbb_r32_imm(dst, reg, param.immediate()); // sbb reg,param + else if (param.is_memory()) + emit_sbb_r32_m32(dst, reg, MABS(param.memory())); // sbb reg,[param] + else if (param.is_int_register()) + emit_sbb_r32_r32(dst, reg, param.ireg()); // sbb reg,param } -/*------------------------------------------------- - emit_sbb_m32_p32 - sbb operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_m32_p32 - sbb operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sbb_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_sbb_m32_imm(dst, MEMPARAMS, param->value); // sbb [dest],param + if (param.is_immediate()) + emit_sbb_m32_imm(dst, memref, param.immediate()); // sbb [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_sbb_m32_r32(dst, MEMPARAMS, reg); // sbb [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32_keepflags(dst, reg, param); // mov reg,param + emit_sbb_m32_r32(dst, memref, reg); // sbb [dest],reg } } -/*------------------------------------------------- - emit_cmp_r32_p32 - cmp operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_r32_p32 - cmp operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_cmp_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_cmp_r32_imm(dst, reg, param->value); // cmp reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_cmp_r32_m32(dst, reg, MABS(drcbe, param->value)); // cmp reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_cmp_r32_r32(dst, reg, param->value); // cmp reg,param + if (param.is_immediate()) + emit_cmp_r32_imm(dst, reg, param.immediate()); // cmp reg,param + else if (param.is_memory()) + emit_cmp_r32_m32(dst, reg, MABS(param.memory())); // cmp reg,[param] + else if (param.is_int_register()) + emit_cmp_r32_r32(dst, reg, param.ireg()); // cmp reg,param } -/*------------------------------------------------- - emit_cmp_m32_p32 - cmp operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_m32_p32 - cmp operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_cmp_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_cmp_m32_imm(dst, MEMPARAMS, param->value); // cmp [dest],param + if (param.is_immediate()) + emit_cmp_m32_imm(dst, memref, param.immediate()); // cmp [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_cmp_m32_r32(dst, MEMPARAMS, reg); // cmp [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_cmp_m32_r32(dst, memref, reg); // cmp [dest],reg } } -/*------------------------------------------------- - emit_and_r32_p32 - and operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_r32_p32 - and operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_and_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg else - emit_and_r32_imm(dst, reg, param->value); // and reg,param + emit_and_r32_imm(dst, reg, param.immediate()); // and reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_and_r32_m32(dst, reg, MABS(drcbe, param->value)); // and reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_and_r32_r32(dst, reg, param->value); // and reg,param + else if (param.is_memory()) + emit_and_r32_m32(dst, reg, MABS(param.memory())); // and reg,[param] + else if (param.is_int_register()) + emit_and_r32_r32(dst, reg, param.ireg()); // and reg,param } -/*------------------------------------------------- - emit_and_m32_p32 - and operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_m32_p32 - and operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_and_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) - emit_mov_m32_imm(dst, MEMPARAMS, 0); // mov [dest],0 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + emit_mov_m32_imm(dst, memref, 0); // mov [dest],0 else - emit_and_m32_imm(dst, MEMPARAMS, param->value); // and [dest],param + emit_and_m32_imm(dst, memref, param.immediate()); // and [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_and_m32_r32(dst, MEMPARAMS, reg); // and [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_and_m32_r32(dst, memref, reg); // and [dest],reg } } -/*------------------------------------------------- - emit_test_r32_p32 - test operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_r32_p32 - test operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_test_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_test_r32_imm(dst, reg, param->value); // test reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_test_m32_r32(dst, MABS(drcbe, param->value), reg); // test [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_r32_r32(dst, reg, param->value); // test reg,param + if (param.is_immediate()) + emit_test_r32_imm(dst, reg, param.immediate()); // test reg,param + else if (param.is_memory()) + emit_test_m32_r32(dst, MABS(param.memory()), reg); // test [param],reg + else if (param.is_int_register()) + emit_test_r32_r32(dst, reg, param.ireg()); // test reg,param } -/*------------------------------------------------- - emit_test_m32_p32 - test operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_m32_p32 - test operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_test_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_test_m32_imm(dst, MEMPARAMS, param->value); // test [dest],param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) + emit_test_m32_imm(dst, memref, param.immediate()); // test [dest],param + else if (param.is_memory()) { - emit_mov_r32_p32(drcbe, dst, REG_EAX, param); // mov reg,param - emit_test_m32_r32(dst, MEMPARAMS, REG_EAX); // test [dest],reg + emit_mov_r32_p32(dst, REG_EAX, param); // mov reg,param + emit_test_m32_r32(dst, memref, REG_EAX); // test [dest],reg } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_m32_r32(dst, MEMPARAMS, param->value); // test [dest],param + else if (param.is_int_register()) + emit_test_m32_r32(dst, memref, param.ireg()); // test [dest],param } -/*------------------------------------------------- - emit_or_r32_p32 - or operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_r32_p32 - or operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_or_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_mov_r32_imm(dst, reg, -1); // mov reg,-1 else - emit_or_r32_imm(dst, reg, param->value); // or reg,param + emit_or_r32_imm(dst, reg, param.immediate()); // or reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_or_r32_m32(dst, reg, MABS(drcbe, param->value)); // or reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_or_r32_r32(dst, reg, param->value); // or reg,param + else if (param.is_memory()) + emit_or_r32_m32(dst, reg, MABS(param.memory())); // or reg,[param] + else if (param.is_int_register()) + emit_or_r32_r32(dst, reg, param.ireg()); // or reg,param } -/*------------------------------------------------- - emit_or_m32_p32 - or operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_m32_p32 - or operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_or_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_mov_m32_imm(dst, MEMPARAMS, -1); // mov [dest],-1 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_mov_m32_imm(dst, memref, -1); // mov [dest],-1 else - emit_or_m32_imm(dst, MEMPARAMS, param->value); // or [dest],param + emit_or_m32_imm(dst, memref, param.immediate()); // or [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_or_m32_r32(dst, MEMPARAMS, reg); // or [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_or_m32_r32(dst, memref, reg); // or [dest],reg } } -/*------------------------------------------------- - emit_xor_r32_p32 - xor operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_r32_p32 - xor operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_xor_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_not_r32(dst, reg); // not reg else - emit_xor_r32_imm(dst, reg, param->value); // xor reg,param + emit_xor_r32_imm(dst, reg, param.immediate()); // xor reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_xor_r32_m32(dst, reg, MABS(drcbe, param->value)); // xor reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_xor_r32_r32(dst, reg, param->value); // xor reg,param + else if (param.is_memory()) + emit_xor_r32_m32(dst, reg, MABS(param.memory())); // xor reg,[param] + else if (param.is_int_register()) + emit_xor_r32_r32(dst, reg, param.ireg()); // xor reg,param } -/*------------------------------------------------- - emit_xor_m32_p32 - xor operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_m32_p32 - xor operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_xor_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_not_m32(dst, MEMPARAMS); // not [dest] + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_not_m32(dst, memref); // not [dest] else - emit_xor_m32_imm(dst, MEMPARAMS, param->value); // xor [dest],param + emit_xor_m32_imm(dst, memref, param.immediate()); // xor [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_xor_m32_r32(dst, MEMPARAMS, reg); // xor [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_xor_m32_r32(dst, memref, reg); // xor [dest],reg } } -/*------------------------------------------------- - emit_shl_r32_p32 - shl operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_r32_p32 - shl operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_shl_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shl_r32_imm(dst, reg, param->value); // shl reg,param + emit_shl_r32_imm(dst, reg, param.immediate()); // shl reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_shl_r32_cl(dst, reg); // shl reg,cl } } -/*------------------------------------------------- - emit_shl_m32_p32 - shl operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_m32_p32 - shl operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_shl_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shl_m32_imm(dst, MEMPARAMS, param->value); // shl [dest],param + emit_shl_m32_imm(dst, memref, param.immediate()); // shl [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_shl_m32_cl(dst, MEMPARAMS); // shl [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_shl_m32_cl(dst, memref); // shl [dest],cl } } -/*------------------------------------------------- - emit_shr_r32_p32 - shr operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_r32_p32 - shr operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_shr_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shr_r32_imm(dst, reg, param->value); // shr reg,param + emit_shr_r32_imm(dst, reg, param.immediate()); // shr reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_shr_r32_cl(dst, reg); // shr reg,cl } } -/*------------------------------------------------- - emit_shr_m32_p32 - shr operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_m32_p32 - shr operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_shr_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shr_m32_imm(dst, MEMPARAMS, param->value); // shr [dest],param + emit_shr_m32_imm(dst, memref, param.immediate()); // shr [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_shr_m32_cl(dst, MEMPARAMS); // shr [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_shr_m32_cl(dst, memref); // shr [dest],cl } } -/*------------------------------------------------- - emit_sar_r32_p32 - sar operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_r32_p32 - sar operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sar_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_sar_r32_imm(dst, reg, param->value); // sar reg,param + emit_sar_r32_imm(dst, reg, param.immediate()); // sar reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_sar_r32_cl(dst, reg); // sar reg,cl } } -/*------------------------------------------------- - emit_sar_m32_p32 - sar operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_m32_p32 - sar operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sar_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_sar_m32_imm(dst, MEMPARAMS, param->value); // sar [dest],param + emit_sar_m32_imm(dst, memref, param.immediate()); // sar [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_sar_m32_cl(dst, MEMPARAMS); // sar [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_sar_m32_cl(dst, memref); // sar [dest],cl } } -/*------------------------------------------------- - emit_rol_r32_p32 - rol operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_r32_p32 - rol operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rol_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rol_r32_imm(dst, reg, param->value); // rol reg,param + emit_rol_r32_imm(dst, reg, param.immediate()); // rol reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_rol_r32_cl(dst, reg); // rol reg,cl } } -/*------------------------------------------------- - emit_rol_m32_p32 - rol operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_m32_p32 - rol operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rol_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rol_m32_imm(dst, MEMPARAMS, param->value); // rol [dest],param + emit_rol_m32_imm(dst, memref, param.immediate()); // rol [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rol_m32_cl(dst, MEMPARAMS); // rol [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_rol_m32_cl(dst, memref); // rol [dest],cl } } -/*------------------------------------------------- - emit_ror_r32_p32 - ror operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_r32_p32 - ror operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_ror_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_ror_r32_imm(dst, reg, param->value); // ror reg,param + emit_ror_r32_imm(dst, reg, param.immediate()); // ror reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_ror_r32_cl(dst, reg); // ror reg,cl } } -/*------------------------------------------------- - emit_ror_m32_p32 - ror operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_m32_p32 - ror operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_ror_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_ror_m32_imm(dst, MEMPARAMS, param->value); // ror [dest],param + emit_ror_m32_imm(dst, memref, param.immediate()); // ror [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_ror_m32_cl(dst, MEMPARAMS); // ror [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_ror_m32_cl(dst, memref); // ror [dest],cl } } -/*------------------------------------------------- - emit_rcl_r32_p32 - rcl operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_r32_p32 - rcl operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rcl_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcl_r32_imm(dst, reg, param->value); // rcl reg,param + emit_rcl_r32_imm(dst, reg, param.immediate()); // rcl reg,param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param emit_rcl_r32_cl(dst, reg); // rcl reg,cl } } -/*------------------------------------------------- - emit_rcl_m32_p32 - rcl operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_m32_p32 - rcl operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rcl_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcl_m32_imm(dst, MEMPARAMS, param->value); // rcl [dest],param + emit_rcl_m32_imm(dst, memref, param.immediate()); // rcl [dest],param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rcl_m32_cl(dst, MEMPARAMS); // rcl [dest],cl + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param + emit_rcl_m32_cl(dst, memref); // rcl [dest],cl } } -/*------------------------------------------------- - emit_rcr_r32_p32 - rcr operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_r32_p32 - rcr operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rcr_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcr_r32_imm(dst, reg, param->value); // rcr reg,param + emit_rcr_r32_imm(dst, reg, param.immediate()); // rcr reg,param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param emit_rcr_r32_cl(dst, reg); // rcr reg,cl } } -/*------------------------------------------------- - emit_rcr_m32_p32 - rcr operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_m32_p32 - rcr operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rcr_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcr_m32_imm(dst, MEMPARAMS, param->value); // rcr [dest],param + emit_rcr_m32_imm(dst, memref, param.immediate()); // rcr [dest],param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rcr_m32_cl(dst, MEMPARAMS); // rcr [dest],cl + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param + emit_rcr_m32_cl(dst, memref); // rcr [dest],cl } } @@ -1999,825 +1662,825 @@ static void emit_rcr_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAM EMITTERS FOR 64-BIT OPERATIONS WITH PARAMETERS ***************************************************************************/ -/*------------------------------------------------- - emit_mov_r64_p64 - move a 64-bit parameter - into a register --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r64_p64 - move a 64-bit parameter +// into a register +//------------------------------------------------- -static void emit_mov_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_mov_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (param->value == 0) + if (param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg else - emit_mov_r64_imm(dst, reg, param->value); // mov reg,param + emit_mov_r64_imm(dst, reg, param.immediate()); // mov reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_r64_m64(dst, reg, MABS(drcbe, param->value)); // mov reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_memory()) + emit_mov_r64_m64(dst, reg, MABS(param.memory())); // mov reg,[param] + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r64_r64(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r64_r64(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_mov_r64_p64_keepflags - move a 64-bit - parameter into a register without affecting - any flags --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r64_p64_keepflags - move a 64-bit +// parameter into a register without affecting +// any flags +//------------------------------------------------- -static void emit_mov_r64_p64_keepflags(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r64_imm(dst, reg, param->value); // mov reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_r64_m64(dst, reg, MABS(drcbe, param->value)); // mov reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + if (param.is_immediate()) + emit_mov_r64_imm(dst, reg, param.immediate()); // mov reg,param + else if (param.is_memory()) + emit_mov_r64_m64(dst, reg, MABS(param.memory())); // mov reg,[param] + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r64_r64(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r64_r64(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_mov_p64_r64 - move a registers into a - 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_p64_r64 - move a registers into a +// 64-bit parameter +//------------------------------------------------- -static void emit_mov_p64_r64(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reg) +void drcbe_x64::emit_mov_p64_r64(x86code *&dst, const be_parameter ¶m, UINT8 reg) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_m64_r64(dst, MABS(drcbe, param->value), reg); // mov [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_mov_m64_r64(dst, MABS(param.memory()), reg); // mov [param],reg + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r64_r64(dst, param->value, reg); // mov param,reg + if (reg != param.ireg()) + emit_mov_r64_r64(dst, param.ireg(), reg); // mov param,reg } } -/*------------------------------------------------- - emit_add_r64_p64 - add operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_r64_p64 - add operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_add_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_add_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_add_r64_imm(dst, reg, param->value); // add reg,param + if (short_immediate(param.immediate())) + emit_add_r64_imm(dst, reg, param.immediate()); // add reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_add_r64_r64(dst, reg, REG_R11); // add reg,r11 } } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_add_r64_m64(dst, reg, MABS(drcbe, param->value)); // add reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_add_r64_r64(dst, reg, param->value); // add reg,param + else if (param.is_memory()) + emit_add_r64_m64(dst, reg, MABS(param.memory())); // add reg,[param] + else if (param.is_int_register()) + emit_add_r64_r64(dst, reg, param.ireg()); // add reg,param } -/*------------------------------------------------- - emit_add_m64_p64 - add operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_m64_p64 - add operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_add_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_add_m64_imm(dst, MEMPARAMS, param->value); // add [mem],param + if (short_immediate(param.immediate())) + emit_add_m64_imm(dst, memref, param.immediate()); // add [mem],param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param - emit_add_m64_r64(dst, MEMPARAMS, REG_R11); // add [mem],r11 + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param + emit_add_m64_r64(dst, memref, REG_R11); // add [mem],r11 } } } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_add_m64_r64(dst, MEMPARAMS, reg); // add [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_add_m64_r64(dst, memref, reg); // add [dest],reg } } -/*------------------------------------------------- - emit_adc_r64_p64 - adc operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_r64_p64 - adc operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_adc_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_adc_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (short_immediate(param->value)) - emit_adc_r64_imm(dst, reg, param->value); // adc reg,param + if (short_immediate(param.immediate())) + emit_adc_r64_imm(dst, reg, param.immediate()); // adc reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_adc_r64_r64(dst, reg, REG_R11); // adc reg,r11 } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_adc_r64_m64(dst, reg, MABS(drcbe, param->value)); // adc reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_adc_r64_r64(dst, reg, param->value); // adc reg,param + else if (param.is_memory()) + emit_adc_r64_m64(dst, reg, MABS(param.memory())); // adc reg,[param] + else if (param.is_int_register()) + emit_adc_r64_r64(dst, reg, param.ireg()); // adc reg,param } -/*------------------------------------------------- - emit_adc_m64_p64 - adc operation to a 64-bit - memory locaiton from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_m64_p64 - adc operation to a 64-bit +// memory locaiton from a 64-bit parameter +//------------------------------------------------- -static void emit_adc_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE && short_immediate(param->value)) - emit_adc_m64_imm(dst, MEMPARAMS, param->value); // adc [mem],param + if (param.is_immediate() && short_immediate(param.immediate())) + emit_adc_m64_imm(dst, memref, param.immediate()); // adc [mem],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_adc_m64_r64(dst, MEMPARAMS, reg); // adc [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64_keepflags(dst, reg, param); // mov reg,param + emit_adc_m64_r64(dst, memref, reg); // adc [dest],reg } } -/*------------------------------------------------- - emit_sub_r64_p64 - sub operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_r64_p64 - sub operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_sub_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sub_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_sub_r64_imm(dst, reg, param->value); // sub reg,param + if (short_immediate(param.immediate())) + emit_sub_r64_imm(dst, reg, param.immediate()); // sub reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_sub_r64_r64(dst, reg, REG_R11); // sub reg,r11 } } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sub_r64_m64(dst, reg, MABS(drcbe, param->value)); // sub reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sub_r64_r64(dst, reg, param->value); // sub reg,param + else if (param.is_memory()) + emit_sub_r64_m64(dst, reg, MABS(param.memory())); // sub reg,[param] + else if (param.is_int_register()) + emit_sub_r64_r64(dst, reg, param.ireg()); // sub reg,param } -/*------------------------------------------------- - emit_sub_m64_p64 - sub operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_m64_p64 - sub operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_sub_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_sub_m64_imm(dst, MEMPARAMS, param->value); // sub [mem],param + if (short_immediate(param.immediate())) + emit_sub_m64_imm(dst, memref, param.immediate()); // sub [mem],param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param - emit_sub_m64_r64(dst, MEMPARAMS, REG_R11); // sub [mem],r11 + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param + emit_sub_m64_r64(dst, memref, REG_R11); // sub [mem],r11 } } } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_sub_m64_r64(dst, MEMPARAMS, reg); // sub [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_sub_m64_r64(dst, memref, reg); // sub [dest],reg } } -/*------------------------------------------------- - emit_sbb_r64_p64 - sbb operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_r64_p64 - sbb operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_sbb_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sbb_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (short_immediate(param->value)) - emit_sbb_r64_imm(dst, reg, param->value); // sbb reg,param + if (short_immediate(param.immediate())) + emit_sbb_r64_imm(dst, reg, param.immediate()); // sbb reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_sbb_r64_r64(dst, reg, REG_R11); // sbb reg,r11 } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sbb_r64_m64(dst, reg, MABS(drcbe, param->value)); // sbb reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sbb_r64_r64(dst, reg, param->value); // sbb reg,param + else if (param.is_memory()) + emit_sbb_r64_m64(dst, reg, MABS(param.memory())); // sbb reg,[param] + else if (param.is_int_register()) + emit_sbb_r64_r64(dst, reg, param.ireg()); // sbb reg,param } -/*------------------------------------------------- - emit_sbb_m64_p64 - sbb operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_m64_p64 - sbb operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_sbb_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE && short_immediate(param->value)) - emit_sbb_m64_imm(dst, MEMPARAMS, param->value); // sbb [mem],param + if (param.is_immediate() && short_immediate(param.immediate())) + emit_sbb_m64_imm(dst, memref, param.immediate()); // sbb [mem],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_sbb_m64_r64(dst, MEMPARAMS, reg); // sbb [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64_keepflags(dst, reg, param); // mov reg,param + emit_sbb_m64_r64(dst, memref, reg); // sbb [dest],reg } } -/*------------------------------------------------- - emit_cmp_r64_p64 - cmp operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_r64_p64 - cmp operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_cmp_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_cmp_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (short_immediate(param->value)) - emit_cmp_r64_imm(dst, reg, param->value); // cmp reg,param + if (short_immediate(param.immediate())) + emit_cmp_r64_imm(dst, reg, param.immediate()); // cmp reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_cmp_r64_r64(dst, reg, REG_R11); // cmp reg,r11 } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_cmp_r64_m64(dst, reg, MABS(drcbe, param->value)); // cmp reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_cmp_r64_r64(dst, reg, param->value); // cmp reg,param + else if (param.is_memory()) + emit_cmp_r64_m64(dst, reg, MABS(param.memory())); // cmp reg,[param] + else if (param.is_int_register()) + emit_cmp_r64_r64(dst, reg, param.ireg()); // cmp reg,param } -/*------------------------------------------------- - emit_cmp_m64_p64 - cmp operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_m64_p64 - cmp operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_cmp_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_cmp_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE && short_immediate(param->value)) - emit_cmp_m64_imm(dst, MEMPARAMS, param->value); // cmp [dest],param + if (param.is_immediate() && short_immediate(param.immediate())) + emit_cmp_m64_imm(dst, memref, param.immediate()); // cmp [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_cmp_m64_r64(dst, MEMPARAMS, reg); // cmp [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_cmp_m64_r64(dst, memref, reg); // cmp [dest],reg } } -/*------------------------------------------------- - emit_and_r64_p64 - and operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_r64_p64 - and operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_and_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_and_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != U64(0xffffffffffffffff)) + if (inst.flags() != 0 || param.immediate() != U64(0xffffffffffffffff)) { - if (short_immediate(param->value)) - emit_and_r64_imm(dst, reg, param->value); // and reg,param + if (short_immediate(param.immediate())) + emit_and_r64_imm(dst, reg, param.immediate()); // and reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_and_r64_r64(dst, reg, REG_R11); // and reg,r11 } } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_and_r64_m64(dst, reg, MABS(drcbe, param->value)); // and reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_and_r64_r64(dst, reg, param->value); // and reg,param + else if (param.is_memory()) + emit_and_r64_m64(dst, reg, MABS(param.memory())); // and reg,[param] + else if (param.is_int_register()) + emit_and_r64_r64(dst, reg, param.ireg()); // and reg,param } -/*------------------------------------------------- - emit_and_m64_p64 - and operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_m64_p64 - and operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_and_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != U64(0xffffffffffffffff)) + if (inst.flags() != 0 || param.immediate() != U64(0xffffffffffffffff)) { - if (short_immediate(param->value)) - emit_and_m64_imm(dst, MEMPARAMS, param->value); // and [mem],param + if (short_immediate(param.immediate())) + emit_and_m64_imm(dst, memref, param.immediate()); // and [mem],param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param - emit_and_m64_r64(dst, MEMPARAMS, REG_R11); // and [mem],r11 + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param + emit_and_m64_r64(dst, memref, REG_R11); // and [mem],r11 } } } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_and_m64_r64(dst, MEMPARAMS, reg); // and [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_and_m64_r64(dst, memref, reg); // and [dest],reg } } -/*------------------------------------------------- - emit_test_r64_p64 - test operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_r64_p64 - test operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_test_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_test_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (short_immediate(param->value)) - emit_test_r64_imm(dst, reg, param->value); // test reg,param + if (short_immediate(param.immediate())) + emit_test_r64_imm(dst, reg, param.immediate()); // test reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_test_r64_r64(dst, reg, REG_R11); // test reg,r11 } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_test_m64_r64(dst, MABS(drcbe, param->value), reg); // test [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_r64_r64(dst, reg, param->value); // test reg,param + else if (param.is_memory()) + emit_test_m64_r64(dst, MABS(param.memory()), reg); // test [param],reg + else if (param.is_int_register()) + emit_test_r64_r64(dst, reg, param.ireg()); // test reg,param } -/*------------------------------------------------- - emit_test_m64_p64 - test operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_m64_p64 - test operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_test_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE && short_immediate(param->value)) - emit_test_m64_imm(dst, MEMPARAMS, param->value); // test [dest],param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate() && short_immediate(param.immediate())) + emit_test_m64_imm(dst, memref, param.immediate()); // test [dest],param + else if (param.is_memory()) { - emit_mov_r64_p64(drcbe, dst, REG_EAX, param); // mov reg,param - emit_test_m64_r64(dst, MEMPARAMS, REG_EAX); // test [dest],reg + emit_mov_r64_p64(dst, REG_EAX, param); // mov reg,param + emit_test_m64_r64(dst, memref, REG_EAX); // test [dest],reg } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_m64_r64(dst, MEMPARAMS, param->value); // test [dest],param + else if (param.is_int_register()) + emit_test_m64_r64(dst, memref, param.ireg()); // test [dest],param } -/*------------------------------------------------- - emit_or_r64_p64 - or operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_r64_p64 - or operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_or_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_or_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_or_r64_imm(dst, reg, param->value); // or reg,param + if (short_immediate(param.immediate())) + emit_or_r64_imm(dst, reg, param.immediate()); // or reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_or_r64_r64(dst, reg, REG_R11); // or reg,r11 } } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_or_r64_m64(dst, reg, MABS(drcbe, param->value)); // or reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_or_r64_r64(dst, reg, param->value); // or reg,param + else if (param.is_memory()) + emit_or_r64_m64(dst, reg, MABS(param.memory())); // or reg,[param] + else if (param.is_int_register()) + emit_or_r64_r64(dst, reg, param.ireg()); // or reg,param } -/*------------------------------------------------- - emit_or_m64_p64 - or operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_m64_p64 - or operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_or_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (short_immediate(param->value)) - emit_or_m64_imm(dst, MEMPARAMS, param->value); // or [mem],param + if (short_immediate(param.immediate())) + emit_or_m64_imm(dst, memref, param.immediate()); // or [mem],param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param - emit_or_m64_r64(dst, MEMPARAMS, REG_R11); // or [mem],r11 + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param + emit_or_m64_r64(dst, memref, REG_R11); // or [mem],r11 } } } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_or_m64_r64(dst, MEMPARAMS, reg); // or [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_or_m64_r64(dst, memref, reg); // or [dest],reg } } -/*------------------------------------------------- - emit_xor_r64_p64 - xor operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_r64_p64 - xor operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_xor_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_xor_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (param->value == U64(0xffffffffffffffff)) + if (param.immediate() == U64(0xffffffffffffffff)) emit_not_r64(dst, reg); // not reg - else if (short_immediate(param->value)) - emit_xor_r64_imm(dst, reg, param->value); // xor reg,param + else if (short_immediate(param.immediate())) + emit_xor_r64_imm(dst, reg, param.immediate()); // xor reg,param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param emit_xor_r64_r64(dst, reg, REG_R11); // xor reg,r11 } } } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_xor_r64_m64(dst, reg, MABS(drcbe, param->value)); // xor reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_xor_r64_r64(dst, reg, param->value); // xor reg,param + else if (param.is_memory()) + emit_xor_r64_m64(dst, reg, MABS(param.memory())); // xor reg,[param] + else if (param.is_int_register()) + emit_xor_r64_r64(dst, reg, param.ireg()); // xor reg,param } -/*------------------------------------------------- - emit_xor_m64_p64 - xor operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_m64_p64 - xor operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_xor_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) + if (inst.flags() != 0 || param.immediate() != 0) { - if (param->value == U64(0xffffffffffffffff)) - emit_not_m64(dst, MEMPARAMS); // not [mem] - else if (short_immediate(param->value)) - emit_xor_m64_imm(dst, MEMPARAMS, param->value); // xor [mem],param + if (param.immediate() == U64(0xffffffffffffffff)) + emit_not_m64(dst, memref); // not [mem] + else if (short_immediate(param.immediate())) + emit_xor_m64_imm(dst, memref, param.immediate()); // xor [mem],param else { - emit_mov_r64_imm(dst, REG_R11, param->value); // mov r11,param - emit_xor_m64_r64(dst, MEMPARAMS, REG_R11); // xor [mem],r11 + emit_mov_r64_imm(dst, REG_R11, param.immediate()); // mov r11,param + emit_xor_m64_r64(dst, memref, REG_R11); // xor [mem],r11 } } } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r64_p64(drcbe, dst, reg, param); // mov reg,param - emit_xor_m64_r64(dst, MEMPARAMS, reg); // xor [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r64_p64(dst, reg, param); // mov reg,param + emit_xor_m64_r64(dst, memref, reg); // xor [dest],reg } } -/*------------------------------------------------- - emit_shl_r64_p64 - shl operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_r64_p64 - shl operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_shl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shl_r64_imm(dst, reg, param->value); // shl reg,param + emit_shl_r64_imm(dst, reg, param.immediate()); // shl reg,param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param emit_shl_r64_cl(dst, reg); // shl reg,cl } } -/*------------------------------------------------- - emit_shl_m64_p64 - shl operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_m64_p64 - shl operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_shl_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_shl_m64_imm(dst, MEMPARAMS, param->value); // shl [dest],param + emit_shl_m64_imm(dst, memref, param.immediate()); // shl [dest],param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_shl_m64_cl(dst, MEMPARAMS); // shl [dest],cl + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param + emit_shl_m64_cl(dst, memref); // shl [dest],cl } } -/*------------------------------------------------- - emit_shr_r64_p64 - shr operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_r64_p64 - shr operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_shr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shr_r64_imm(dst, reg, param->value); // shr reg,param + emit_shr_r64_imm(dst, reg, param.immediate()); // shr reg,param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param emit_shr_r64_cl(dst, reg); // shr reg,cl } } -/*------------------------------------------------- - emit_shr_m64_p64 - shr operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_m64_p64 - shr operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_shr_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_shr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_shr_m64_imm(dst, MEMPARAMS, param->value); // shr [dest],param + emit_shr_m64_imm(dst, memref, param.immediate()); // shr [dest],param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_shr_m64_cl(dst, MEMPARAMS); // shr [dest],cl + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param + emit_shr_m64_cl(dst, memref); // shr [dest],cl } } -/*------------------------------------------------- - emit_sar_r64_p64 - sar operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_r64_p64 - sar operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_sar_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sar_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_sar_r64_imm(dst, reg, param->value); // sar reg,param + emit_sar_r64_imm(dst, reg, param.immediate()); // sar reg,param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param emit_sar_r64_cl(dst, reg); // sar reg,cl } } -/*------------------------------------------------- - emit_sar_m64_p64 - sar operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_m64_p64 - sar operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_sar_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_sar_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_sar_m64_imm(dst, MEMPARAMS, param->value); // sar [dest],param + emit_sar_m64_imm(dst, memref, param.immediate()); // sar [dest],param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_sar_m64_cl(dst, MEMPARAMS); // sar [dest],cl + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param + emit_sar_m64_cl(dst, memref); // sar [dest],cl } } -/*------------------------------------------------- - emit_rol_r64_p64 - rol operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_r64_p64 - rol operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rol_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rol_r64_imm(dst, reg, param->value); // rol reg,param + emit_rol_r64_imm(dst, reg, param.immediate()); // rol reg,param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param emit_rol_r64_cl(dst, reg); // rol reg,cl } } -/*------------------------------------------------- - emit_rol_m64_p64 - rol operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_m64_p64 - rol operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_rol_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rol_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_rol_m64_imm(dst, MEMPARAMS, param->value); // rol [dest],param + emit_rol_m64_imm(dst, memref, param.immediate()); // rol [dest],param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_rol_m64_cl(dst, MEMPARAMS); // rol [dest],cl + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param + emit_rol_m64_cl(dst, memref); // rol [dest],cl } } -/*------------------------------------------------- - emit_ror_r64_p64 - ror operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_r64_p64 - ror operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_ror_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_ror_r64_imm(dst, reg, param->value); // ror reg,param + emit_ror_r64_imm(dst, reg, param.immediate()); // ror reg,param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param emit_ror_r64_cl(dst, reg); // ror reg,cl } } -/*------------------------------------------------- - emit_ror_m64_p64 - ror operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_m64_p64 - ror operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_ror_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_ror_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_ror_m64_imm(dst, MEMPARAMS, param->value); // ror [dest],param + emit_ror_m64_imm(dst, memref, param.immediate()); // ror [dest],param } else { - emit_mov_r64_p64(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_ror_m64_cl(dst, MEMPARAMS); // ror [dest],cl + emit_mov_r64_p64(dst, REG_RCX, param); // mov rcx,param + emit_ror_m64_cl(dst, memref); // ror [dest],cl } } -/*------------------------------------------------- - emit_rcl_r64_p64 - rcl operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_r64_p64 - rcl operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_rcl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcl_r64_imm(dst, reg, param->value); // rcl reg,param + emit_rcl_r64_imm(dst, reg, param.immediate()); // rcl reg,param } else { - emit_mov_r64_p64_keepflags(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64_keepflags(dst, REG_RCX, param); // mov rcx,param emit_rcl_r64_cl(dst, reg); // rcl reg,cl } } -/*------------------------------------------------- - emit_rcl_m64_p64 - rcl operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_m64_p64 - rcl operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_rcl_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_rcl_m64_imm(dst, MEMPARAMS, param->value); // rcl [dest],param + emit_rcl_m64_imm(dst, memref, param.immediate()); // rcl [dest],param } else { - emit_mov_r64_p64_keepflags(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_rcl_m64_cl(dst, MEMPARAMS); // rcl [dest],cl + emit_mov_r64_p64_keepflags(dst, REG_RCX, param); // mov rcx,param + emit_rcl_m64_cl(dst, memref); // rcl [dest],cl } } -/*------------------------------------------------- - emit_rcr_r64_p64 - rcr operation to a 64-bit - register from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_r64_p64 - rcr operation to a 64-bit +// register from a 64-bit parameter +//------------------------------------------------- -static void emit_rcr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcr_r64_imm(dst, reg, param->value); // rcr reg,param + emit_rcr_r64_imm(dst, reg, param.immediate()); // rcr reg,param } else { - emit_mov_r64_p64_keepflags(drcbe, dst, REG_RCX, param); // mov rcx,param + emit_mov_r64_p64_keepflags(dst, REG_RCX, param); // mov rcx,param emit_rcr_r64_cl(dst, reg); // rcr reg,cl } } -/*------------------------------------------------- - emit_rcr_m64_p64 - rcr operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_m64_p64 - rcr operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_rcr_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x64::emit_rcr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT64)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT64)param.immediate() == 0) + ;// skip else - emit_rcr_m64_imm(dst, MEMPARAMS, param->value); // rcr [dest],param + emit_rcr_m64_imm(dst, memref, param.immediate()); // rcr [dest],param } else { - emit_mov_r64_p64_keepflags(drcbe, dst, REG_RCX, param); // mov rcx,param - emit_rcr_m64_cl(dst, MEMPARAMS); // rcr [dest],cl + emit_mov_r64_p64_keepflags(dst, REG_RCX, param); // mov rcx,param + emit_rcr_m64_cl(dst, memref); // rcr [dest],cl } } @@ -2827,74 +2490,74 @@ static void emit_rcr_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAM EMITTERS FOR FLOATING POINT OPERATIONS WITH PARAMETERS ***************************************************************************/ -/*------------------------------------------------- - emit_movss_r128_p32 - move a 32-bit parameter - into a register --------------------------------------------------*/ +//------------------------------------------------- +// emit_movss_r128_p32 - move a 32-bit parameter +// into a register +//------------------------------------------------- -static void emit_movss_r128_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_movss_r128_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_movss_r128_m32(dst, reg, MABS(drcbe, param->value)); // movss reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_movss_r128_m32(dst, reg, MABS(param.memory())); // movss reg,[param] + else if (param.is_float_register()) { - if (reg != param->value) - emit_movss_r128_r128(dst, reg, param->value); // movss reg,param + if (reg != param.freg()) + emit_movss_r128_r128(dst, reg, param.freg()); // movss reg,param } } -/*------------------------------------------------- - emit_movss_p32_r128 - move a register into a - 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_movss_p32_r128 - move a register into a +// 32-bit parameter +//------------------------------------------------- -static void emit_movss_p32_r128(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reg) +void drcbe_x64::emit_movss_p32_r128(x86code *&dst, const be_parameter ¶m, UINT8 reg) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_movss_m32_r128(dst, MABS(drcbe, param->value), reg); // movss [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_movss_m32_r128(dst, MABS(param.memory()), reg); // movss [param],reg + else if (param.is_float_register()) { - if (reg != param->value) - emit_movss_r128_r128(dst, param->value, reg); // movss param,reg + if (reg != param.freg()) + emit_movss_r128_r128(dst, param.freg(), reg); // movss param,reg } } -/*------------------------------------------------- - emit_movsd_r128_p64 - move a 64-bit parameter - into a register --------------------------------------------------*/ +//------------------------------------------------- +// emit_movsd_r128_p64 - move a 64-bit parameter +// into a register +//------------------------------------------------- -static void emit_movsd_r128_p64(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x64::emit_movsd_r128_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_movsd_r128_m64(dst, reg, MABS(drcbe, param->value)); // movsd reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_movsd_r128_m64(dst, reg, MABS(param.memory())); // movsd reg,[param] + else if (param.is_float_register()) { - if (reg != param->value) - emit_movsd_r128_r128(dst, reg, param->value); // movsd reg,param + if (reg != param.freg()) + emit_movsd_r128_r128(dst, reg, param.freg()); // movsd reg,param } } -/*------------------------------------------------- - emit_movsd_p64_r128 - move a register into a - 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_movsd_p64_r128 - move a register into a +// 64-bit parameter +//------------------------------------------------- -static void emit_movsd_p64_r128(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reg) +void drcbe_x64::emit_movsd_p64_r128(x86code *&dst, const be_parameter ¶m, UINT8 reg) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) - emit_movsd_m64_r128(dst, MABS(drcbe, param->value), reg); // movsd [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + assert(!param.is_immediate()); + if (param.is_memory()) + emit_movsd_m64_r128(dst, MABS(param.memory()), reg); // movsd [param],reg + else if (param.is_float_register()) { - if (reg != param->value) - emit_movsd_r128_r128(dst, param->value, reg); // movsd param,reg + if (reg != param.freg()) + emit_movsd_r128_r128(dst, param.freg(), reg); // movsd param,reg } } @@ -2904,16 +2567,16 @@ static void emit_movsd_p64_r128(drcbe_state *drcbe, x86code **dst, const drcuml_ OUT-OF-BAND CODE FIXUP CALLBACKS ***************************************************************************/ -/*------------------------------------------------- - fixup_label - callback to fixup forward- - referenced labels --------------------------------------------------*/ +//------------------------------------------------- +// fixup_label - callback to fixup forward- +// referenced labels +//------------------------------------------------- -static void fixup_label(void *parameter, drccodeptr labelcodeptr) +void drcbe_x64::fixup_label(void *parameter, drccodeptr labelcodeptr) { drccodeptr src = (drccodeptr)parameter; - /* find the end of the instruction */ + // find the end of the instruction if (src[0] == 0xe3) { src += 1 + 1; @@ -2934,66 +2597,65 @@ static void fixup_label(void *parameter, drccodeptr labelcodeptr) } -/*------------------------------------------------- - fixup_exception - callback to perform cleanup - and jump to an exception handler --------------------------------------------------*/ +//------------------------------------------------- +// fixup_exception - callback to perform cleanup +// and jump to an exception handler +//------------------------------------------------- -static void fixup_exception(drccodeptr *codeptr, void *param1, void *param2, void *param3) +void drcbe_x64::fixup_exception(drccodeptr *codeptr, void *param1, void *param2) { - drcuml_parameter handp, exp; - drcbe_state *drcbe = (drcbe_state *)param1; - drccodeptr src = (drccodeptr)param2; - const drcuml_instruction *inst = (const drcuml_instruction *)param3; - drccodeptr dst = *codeptr; - drccodeptr *targetptr; + drccodeptr src = (drccodeptr)param1; + const instruction &inst = *(const instruction *)param2; - /* normalize parameters */ - param_normalize_2(drcbe, inst, &handp, PTYPE_M, &exp, PTYPE_MRI); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); + be_parameter exp(*this, inst.param(1), PTYPE_MRI); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* first fixup the jump to get us here */ + // first fixup the jump to get us here + drccodeptr dst = *codeptr; ((UINT32 *)src)[-1] = dst - src; - /* then store the exception parameter */ - emit_mov_m32_p32(drcbe, &dst, MABS(drcbe, &drcbe->state.exp), &exp); // mov [exp],exp + // then store the exception parameter + emit_mov_m32_p32(dst, MABS(&m_state.exp), exp); // mov [exp],exp - /* push the original return address on the stack */ - emit_lea_r64_m64(&dst, REG_RAX, MABS(drcbe, src)); // lea rax,[return] - emit_push_r64(&dst, REG_RAX); // push rax + // push the original return address on the stack + emit_lea_r64_m64(dst, REG_RAX, MABS(src)); // lea rax,[return] + emit_push_r64(dst, REG_RAX); // push rax if (*targetptr != NULL) - emit_jmp(&dst, *targetptr); // jmp *targetptr + emit_jmp(dst, *targetptr); // jmp *targetptr else - emit_jmp_m64(&dst, MABS(drcbe, targetptr)); // jmp [targetptr] + emit_jmp_m64(dst, MABS(targetptr)); // jmp [targetptr] *codeptr = dst; } -/*************************************************************************** - DEBUG HELPERS -***************************************************************************/ +//************************************************************************** +// DEBUG HELPERS +//************************************************************************** -/*------------------------------------------------- - debug_log_hashjmp - callback to handle - logging of hashjmps --------------------------------------------------*/ +//------------------------------------------------- +// debug_log_hashjmp - callback to handle +// logging of hashjmps +//------------------------------------------------- -static void debug_log_hashjmp(offs_t pc, int mode) +void drcbe_x64::debug_log_hashjmp(offs_t pc, int mode) { printf("mode=%d PC=%08X\n", mode, pc); } -/*------------------------------------------------- - debug_log_hashjmp - callback to handle - logging of hashjmps --------------------------------------------------*/ +//------------------------------------------------- +// debug_log_hashjmp - callback to handle +// logging of hashjmps +//------------------------------------------------- -static void debug_log_hashjmp_fail() +void drcbe_x64::debug_log_hashjmp_fail() { printf(" (FAIL)\n"); } @@ -3004,98 +2666,92 @@ static void debug_log_hashjmp_fail() COMPILE-TIME OPCODES ***************************************************************************/ -/*------------------------------------------------- - op_handle - process a HANDLE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_handle - process a HANDLE opcode +//------------------------------------------------- -static x86code *op_handle(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_handle(x86code *&dst, const instruction &inst) { - emit_link skip; - assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_MEMORY); + assert(inst.numparams() == 1); + assert(inst.param(0).is_code_handle()); - /* emit a jump around the stack adjust in case code falls through here */ - emit_jmp_short_link(&dst, &skip); // jmp skip + // emit a jump around the stack adjust in case code falls through here + emit_link skip; + emit_jmp_short_link(dst, skip); // jmp skip - /* register the current pointer for the handle */ - drcuml_handle_set_codeptr((drcuml_codehandle *)(FPTR)inst->param[0].value, dst); + // register the current pointer for the handle + inst.param(0).handle().set_codeptr(dst); - /* by default, the handle points to prolog code that moves the stack pointer */ - emit_lea_r64_m64(&dst, REG_RSP, MBD(REG_RSP, -40)); // lea rsp,[rsp-40] - resolve_link(&dst, &skip); // skip: - return dst; + // by default, the handle points to prolog code that moves the stack pointer + emit_lea_r64_m64(dst, REG_RSP, MBD(REG_RSP, -40)); // lea rsp,[rsp-40] + resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_hash - process a HASH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_hash - process a HASH opcode +//------------------------------------------------- -static x86code *op_hash(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_hash(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 2); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); - assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 2); + assert(inst.param(0).is_immediate()); + assert(inst.param(1).is_immediate()); - /* register the current pointer for the mode/PC */ - drcbe->hash->set_codeptr(inst->param[0].value, inst->param[1].value, dst); - return dst; + // register the current pointer for the mode/PC + m_hash.set_codeptr(inst.param(0).immediate(), inst.param(1).immediate(), dst); } -/*------------------------------------------------- - op_label - process a LABEL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_label - process a LABEL opcode +//------------------------------------------------- -static x86code *op_label(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_label(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 1); + assert(inst.param(0).is_code_label()); - /* register the current pointer for the label */ - drcbe->labels->set_codeptr(inst->param[0].value, dst); - return dst; + // register the current pointer for the label + m_labels.set_codeptr(inst.param(0).label(), dst); } -/*------------------------------------------------- - op_comment - process a COMMENT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_comment - process a COMMENT opcode +//------------------------------------------------- -static x86code *op_comment(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_comment(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_MEMORY); + assert(inst.numparams() == 1); + assert(inst.param(0).is_string()); - /* do nothing */ - return dst; + // do nothing } -/*------------------------------------------------- - op_mapvar - process a MAPVAR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mapvar - process a MAPVAR opcode +//------------------------------------------------- -static x86code *op_mapvar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_mapvar(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 2); - assert(inst->param[0].type == DRCUML_PTYPE_MAPVAR); - assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 2); + assert(inst.param(0).is_mapvar()); + assert(inst.param(1).is_immediate()); - /* set the value of the specified mapvar */ - drcbe->map->set_value(dst, inst->param[0].value, inst->param[1].value); - return dst; + // set the value of the specified mapvar + m_map.set_value(dst, inst.param(0).mapvar(), inst.param(1).immediate()); } @@ -3104,367 +2760,342 @@ static x86code *op_mapvar(drcbe_state *drcbe, x86code *dst, const drcuml_instruc CONTROL FLOW OPCODES ***************************************************************************/ -/*------------------------------------------------- - op_nop - process a NOP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_nop - process a NOP opcode +//------------------------------------------------- -static x86code *op_nop(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_nop(x86code *&dst, const instruction &inst) { - /* nothing */ - return dst; + // nothing } -/*------------------------------------------------- - op_debug - process a DEBUG opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_debug - process a DEBUG opcode +//------------------------------------------------- -static x86code *op_debug(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_debug(x86code *&dst, const instruction &inst) { - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - if ((drcbe->device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0) + if ((m_device.machine->debug_flags & DEBUG_FLAG_ENABLED) != 0) { - drcuml_parameter pcp; - - /* normalize parameters */ - param_normalize_1(drcbe, inst, &pcp, PTYPE_MRI); + // normalize parameters + be_parameter pcp(*this, inst.param(0), PTYPE_MRI); - /* test and branch */ - emit_mov_r64_imm(&dst, REG_RAX, (FPTR)&drcbe->device->machine->debug_flags); // mov rax,&debug_flags - emit_test_m32_imm(&dst, MBD(REG_RAX, 0), DEBUG_FLAG_CALL_HOOK); // test [debug_flags],DEBUG_FLAG_CALL_HOOK - emit_jcc_short_link(&dst, COND_Z, &skip); // jz skip + // test and branch + emit_mov_r64_imm(dst, REG_RAX, (FPTR)&m_device.machine->debug_flags); // mov rax,&debug_flags + emit_test_m32_imm(dst, MBD(REG_RAX, 0), DEBUG_FLAG_CALL_HOOK); // test [debug_flags],DEBUG_FLAG_CALL_HOOK + emit_link skip = { 0 }; + emit_jcc_short_link(dst, x64emit::COND_Z, skip); // jz skip - /* push the parameter */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)drcbe->device); // mov param1,device - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &pcp); // mov param2,pcp - emit_smart_call_m64(drcbe, &dst, &drcbe->debug_cpu_instruction_hook); // call debug_cpu_instruction_hook + // push the parameter + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)&m_device); // mov param1,device + emit_mov_r32_p32(dst, REG_PARAM2, pcp); // mov param2,pcp + emit_smart_call_m64(dst, &m_near.debug_cpu_instruction_hook); // call debug_cpu_instruction_hook - resolve_link(&dst, &skip); // skip: + resolve_link(dst, skip); // skip: } - - return dst; } -/*------------------------------------------------- - op_exit - process an EXIT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_exit - process an EXIT opcode +//------------------------------------------------- -static x86code *op_exit(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_exit(x86code *&dst, const instruction &inst) { - drcuml_parameter retp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &retp, PTYPE_MRI); + // normalize parameters + be_parameter retp(*this, inst.param(0), PTYPE_MRI); - /* load the parameter into EAX */ - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &retp); // mov eax,retp - if (inst->condition == DRCUML_COND_ALWAYS) - emit_jmp(&dst, drcbe->exit); // jmp exit + // load the parameter into EAX + emit_mov_r32_p32(dst, REG_EAX, retp); // mov eax,retp + if (inst.condition() == uml::COND_ALWAYS) + emit_jmp(dst, m_exit); // jmp exit else - emit_jcc(&dst, X86_CONDITION(inst->condition), drcbe->exit); // jcc exit - - return dst; + emit_jcc(dst, X86_CONDITION(inst.condition()), m_exit); // jcc exit } -/*------------------------------------------------- - op_hashjmp - process a HASHJMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_hashjmp - process a HASHJMP opcode +//------------------------------------------------- -static x86code *op_hashjmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_hashjmp(x86code *&dst, const instruction &inst) { - drcuml_parameter modep, pcp, exp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &modep, PTYPE_MRI, &pcp, PTYPE_MRI, &exp, PTYPE_M); + // normalize parameters + be_parameter modep(*this, inst.param(0), PTYPE_MRI); + be_parameter pcp(*this, inst.param(1), PTYPE_MRI); + const parameter &exp = inst.param(2); + assert(exp.is_code_handle()); if (LOG_HASHJMPS) { - emit_mov_r32_p32(drcbe, &dst, REG_PARAM1, &pcp); - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &modep); - emit_smart_call_m64(drcbe, &dst, &drcbe->debug_log_hashjmp); + emit_mov_r32_p32(dst, REG_PARAM1, pcp); + emit_mov_r32_p32(dst, REG_PARAM2, modep); + emit_smart_call_m64(dst, &m_near.debug_log_hashjmp); } - /* load the stack base one word early so we end up at the right spot after our call below */ - emit_mov_r64_m64(&dst, REG_RSP, MABS(drcbe, &drcbe->hashstacksave)); // mov rsp,[hashstacksave] + // load the stack base one word early so we end up at the right spot after our call below + emit_mov_r64_m64(dst, REG_RSP, MABS(&m_near.hashstacksave)); // mov rsp,[hashstacksave] - /* fixed mode cases */ - if (modep.type == DRCUML_PTYPE_IMMEDIATE && drcbe->hash->is_mode_populated(modep.value)) + // fixed mode cases + if (modep.is_immediate() && m_hash.is_mode_populated(modep.immediate())) { - /* a straight immediate jump is direct, though we need the PC in EAX in case of failure */ - if (pcp.type == DRCUML_PTYPE_IMMEDIATE) + // a straight immediate jump is direct, though we need the PC in EAX in case of failure + if (pcp.is_immediate()) { - UINT32 l1val = (pcp.value >> drcbe->hash->l1shift()) & drcbe->hash->l1mask(); - UINT32 l2val = (pcp.value >> drcbe->hash->l2shift()) & drcbe->hash->l2mask(); - emit_call_m64(&dst, MABS(drcbe, &drcbe->hash->base()[modep.value][l1val][l2val])); + UINT32 l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask(); + UINT32 l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask(); + emit_call_m64(dst, MABS(&m_hash.base()[modep.immediate()][l1val][l2val])); // call hash[modep][l1val][l2val] } - /* a fixed mode but variable PC */ + // a fixed mode but variable PC else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &pcp); // mov eax,pcp - emit_mov_r32_r32(&dst, REG_EDX, REG_EAX); // mov edx,eax - emit_shr_r32_imm(&dst, REG_EDX, drcbe->hash->l1shift()); // shr edx,l1shift - emit_and_r32_imm(&dst, REG_EAX, drcbe->hash->l2mask() << drcbe->hash->l2shift());// and eax,l2mask << l2shift - emit_mov_r64_m64(&dst, REG_RDX, MBISD(REG_RBP, REG_RDX, 8, offset_from_rbp(drcbe, (FPTR)&drcbe->hash->base()[modep.value][0]))); + emit_mov_r32_p32(dst, REG_EAX, pcp); // mov eax,pcp + emit_mov_r32_r32(dst, REG_EDX, REG_EAX); // mov edx,eax + emit_shr_r32_imm(dst, REG_EDX, m_hash.l1shift()); // shr edx,l1shift + emit_and_r32_imm(dst, REG_EAX, m_hash.l2mask() << m_hash.l2shift()); // and eax,l2mask << l2shift + emit_mov_r64_m64(dst, REG_RDX, MBISD(REG_RBP, REG_RDX, 8, offset_from_rbp(&m_hash.base()[modep.immediate()][0]))); // mov rdx,hash[modep+edx*8] - emit_call_m64(&dst, MBISD(REG_RDX, REG_RAX, 8 >> drcbe->hash->l2shift(), 0));// call [rdx+rax*shift] + emit_call_m64(dst, MBISD(REG_RDX, REG_RAX, 8 >> m_hash.l2shift(), 0)); // call [rdx+rax*shift] } } else { - /* variable mode */ - int modereg = param_select_register(REG_ECX, &modep, NULL); - emit_mov_r32_p32(drcbe, &dst, modereg, &modep); // mov modereg,modep - emit_mov_r64_m64(&dst, REG_RCX, MBISD(REG_RBP, modereg, 8, offset_from_rbp(drcbe, (FPTR)drcbe->hash->base()))); + // variable mode + int modereg = modep.select_register(REG_ECX); + emit_mov_r32_p32(dst, modereg, modep); // mov modereg,modep + emit_mov_r64_m64(dst, REG_RCX, MBISD(REG_RBP, modereg, 8, offset_from_rbp(m_hash.base()))); // mov rcx,hash[modereg*8] - /* fixed PC */ - if (pcp.type == DRCUML_PTYPE_IMMEDIATE) + // fixed PC + if (pcp.is_immediate()) { - UINT32 l1val = (pcp.value >> drcbe->hash->l1shift()) & drcbe->hash->l1mask(); - UINT32 l2val = (pcp.value >> drcbe->hash->l2shift()) & drcbe->hash->l2mask(); - emit_mov_r64_m64(&dst, REG_RDX, MBD(REG_RCX, l1val*8)); // mov rdx,[rcx+l1val*8] - emit_call_m64(&dst, MBD(REG_RDX, l2val*8)); // call [l2val*8] + UINT32 l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask(); + UINT32 l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask(); + emit_mov_r64_m64(dst, REG_RDX, MBD(REG_RCX, l1val*8)); // mov rdx,[rcx+l1val*8] + emit_call_m64(dst, MBD(REG_RDX, l2val*8)); // call [l2val*8] } - /* variable PC */ + // variable PC else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &pcp); // mov eax,pcp - emit_mov_r32_r32(&dst, REG_EDX, REG_EAX); // mov edx,eax - emit_shr_r32_imm(&dst, REG_EDX, drcbe->hash->l1shift()); // shr edx,l1shift - emit_mov_r64_m64(&dst, REG_RDX, MBISD(REG_RCX, REG_RDX, 8, 0)); // mov rdx,[rcx+rdx*8] - emit_and_r32_imm(&dst, REG_EAX, drcbe->hash->l2mask() << drcbe->hash->l2shift());// and eax,l2mask << l2shift - emit_call_m64(&dst, MBISD(REG_RDX, REG_RAX, 8 >> drcbe->hash->l2shift(), 0)); // call [rdx+rax*shift] + emit_mov_r32_p32(dst, REG_EAX, pcp); // mov eax,pcp + emit_mov_r32_r32(dst, REG_EDX, REG_EAX); // mov edx,eax + emit_shr_r32_imm(dst, REG_EDX, m_hash.l1shift()); // shr edx,l1shift + emit_mov_r64_m64(dst, REG_RDX, MBISD(REG_RCX, REG_RDX, 8, 0)); // mov rdx,[rcx+rdx*8] + emit_and_r32_imm(dst, REG_EAX, m_hash.l2mask() << m_hash.l2shift()); // and eax,l2mask << l2shift + emit_call_m64(dst, MBISD(REG_RDX, REG_RAX, 8 >> m_hash.l2shift(), 0)); // call [rdx+rax*shift] } } - /* in all cases, if there is no code, we return here to generate the exception */ + // in all cases, if there is no code, we return here to generate the exception if (LOG_HASHJMPS) - emit_smart_call_m64(drcbe, &dst, &drcbe->debug_log_hashjmp_fail); + emit_smart_call_m64(dst, &m_near.debug_log_hashjmp_fail); - emit_mov_m32_p32(drcbe, &dst, MABS(drcbe, &drcbe->state.exp), &pcp); // mov [exp],param - emit_sub_r64_imm(&dst, REG_RSP, 8); // sub rsp,8 - emit_call_m64(&dst, MABS(drcbe, exp.value)); // call [exp] - - return dst; + emit_mov_m32_p32(dst, MABS(&m_state.exp), pcp); // mov [exp],param + emit_sub_r64_imm(dst, REG_RSP, 8); // sub rsp,8 + emit_call_m64(dst, MABS(exp.handle().codeptr_addr())); // call [exp] } -/*------------------------------------------------- - op_jmp - process a JMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_jmp - process a JMP opcode +//------------------------------------------------- -static x86code *op_jmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_jmp(x86code *&dst, const instruction &inst) { - drcuml_parameter labelp; - x86code *jmptarget; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &labelp, PTYPE_I); + // normalize parameters + const parameter &labelp = inst.param(0); + assert(labelp.is_code_label()); - /* look up the jump target and jump there */ - jmptarget = (x86code *)drcbe->labels->get_codeptr(labelp.value, fixup_label, dst); + // look up the jump target and jump there + x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), fixup_label, dst); if (jmptarget == NULL) jmptarget = dst + 0x7ffffff0; - if (inst->condition == DRCUML_COND_ALWAYS) - emit_jmp(&dst, jmptarget); // jmp target + if (inst.condition() == uml::COND_ALWAYS) + emit_jmp(dst, jmptarget); // jmp target else - emit_jcc(&dst, X86_CONDITION(inst->condition), jmptarget); // jcc target + emit_jcc(dst, X86_CONDITION(inst.condition()), jmptarget); // jcc target - return dst; } -/*------------------------------------------------- - op_exh - process an EXH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_exh - process an EXH opcode +//------------------------------------------------- -static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_exh(x86code *&dst, const instruction &inst) { - drcuml_parameter handp, exp; - drccodeptr *targetptr; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &handp, PTYPE_M, &exp, PTYPE_MRI); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); + be_parameter exp(*this, inst.param(1), PTYPE_MRI); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* perform the exception processing inline if unconditional */ - if (inst->condition == DRCUML_COND_ALWAYS) + // perform the exception processing inline if unconditional + if (inst.condition() == uml::COND_ALWAYS) { - emit_mov_m32_p32(drcbe, &dst, MABS(drcbe, &drcbe->state.exp), &exp); // mov [exp],exp + emit_mov_m32_p32(dst, MABS(&m_state.exp), exp); // mov [exp],exp if (*targetptr != NULL) - emit_call(&dst, *targetptr); // call *targetptr + emit_call(dst, *targetptr); // call *targetptr else - emit_call_m64(&dst, MABS(drcbe, targetptr)); // call [targetptr] + emit_call_m64(dst, MABS(targetptr)); // call [targetptr] } - /* otherwise, jump to an out-of-band handler */ + // otherwise, jump to an out-of-band handler else { - emit_jcc(&dst, X86_CONDITION(inst->condition), dst + 0x7ffffff0); // jcc exception - drcbe->cache->request_oob_codegen(fixup_exception, drcbe, dst, (void *)inst); + emit_jcc(dst, X86_CONDITION(inst.condition()), dst + 0x7ffffff0); // jcc exception + m_cache.request_oob_codegen(oob_func_stub<drcbe_x64, &drcbe_x64::fixup_exception>, dst, &const_cast<instruction &>(inst), this); } - return dst; } -/*------------------------------------------------- - op_callh - process a CALLH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_callh - process a CALLH opcode +//------------------------------------------------- -static x86code *op_callh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_callh(x86code *&dst, const instruction &inst) { - drcuml_parameter handp; - drccodeptr *targetptr; - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &handp, PTYPE_M); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* jump through the handle; directly if a normal jump */ + // jump through the handle; directly if a normal jump if (*targetptr != NULL) - emit_call(&dst, *targetptr); // call *targetptr + emit_call(dst, *targetptr); // call *targetptr else - emit_call_m64(&dst, MABS(drcbe, targetptr)); // call [targetptr] + emit_call_m64(dst, MABS(targetptr)); // call [targetptr] - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - resolve_link(&dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_ret - process a RET opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ret - process a RET opcode +//------------------------------------------------- -static x86code *op_ret(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_ret(x86code *&dst, const instruction &inst) { - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 0); + assert(inst.numparams() == 0); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* return */ - emit_lea_r64_m64(&dst, REG_RSP, MBD(REG_RSP, 40)); // lea rsp,[rsp+40] - emit_ret(&dst); // ret + // return + emit_lea_r64_m64(dst, REG_RSP, MBD(REG_RSP, 40)); // lea rsp,[rsp+40] + emit_ret(dst); // ret - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - resolve_link(&dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_callc - process a CALLC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_callc - process a CALLC opcode +//------------------------------------------------- -static x86code *op_callc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_callc(x86code *&dst, const instruction &inst) { - drcuml_parameter funcp, paramp; - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &funcp, PTYPE_M, ¶mp, PTYPE_M); + // normalize parameters + const parameter &funcp = inst.param(0); + assert(funcp.is_c_function()); + be_parameter paramp(*this, inst.param(1), PTYPE_M); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* perform the call */ - emit_mov_r64_imm(&dst, REG_PARAM1, paramp.value); // mov param1,paramp - emit_smart_call_r64(drcbe, &dst, (x86code *)(FPTR)funcp.value, REG_RAX); // call funcp + // perform the call + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)paramp.memory()); // mov param1,paramp + emit_smart_call_r64(dst, (x86code *)(FPTR)funcp.cfunc(), REG_RAX); // call funcp - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - resolve_link(&dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_recover - process a RECOVER opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_recover - process a RECOVER opcode +//------------------------------------------------- -static x86code *op_recover(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_recover(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize(drcbe, &inst->param[0], &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* call the recovery code */ - emit_mov_r64_m64(&dst, REG_RAX, MABS(drcbe, &drcbe->stacksave)); // mov rax,stacksave - emit_mov_r64_m64(&dst, REG_RAX, MBD(REG_RAX, -8)); // mov rax,[rax-4] - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)drcbe->map); // mov param1,drcbe->map - emit_lea_r64_m64(&dst, REG_PARAM2, MBD(REG_RAX, -1)); // lea param2,[rax-1] - emit_mov_r64_imm(&dst, REG_PARAM3, inst->param[1].value); // mov param3,param[1].value - emit_smart_call_m64(drcbe, &dst, &drcbe->drcmap_get_value); // call drcmap_get_value - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + // call the recovery code + emit_mov_r64_m64(dst, REG_RAX, MABS(&m_near.stacksave)); // mov rax,stacksave + emit_mov_r64_m64(dst, REG_RAX, MBD(REG_RAX, -8)); // mov rax,[rax-4] + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)&m_map); // mov param1,m_map + emit_lea_r64_m64(dst, REG_PARAM2, MBD(REG_RAX, -1)); // lea param2,[rax-1] + emit_mov_r64_imm(dst, REG_PARAM3, inst.param(1).mapvar()); // mov param3,param[1].value + emit_smart_call_m64(dst, &m_near.drcmap_get_value); // call drcmap_get_value + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax - return dst; } @@ -3473,364 +3104,336 @@ static x86code *op_recover(drcbe_state *drcbe, x86code *dst, const drcuml_instru INTERNAL REGISTER OPCODES ***************************************************************************/ -/*------------------------------------------------- - op_setfmod - process a SETFMOD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_setfmod - process a SETFMOD opcode +//------------------------------------------------- -static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_setfmod(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_MRI); - /* immediate case */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate case + if (srcp.is_immediate()) { - srcp.value &= 3; - emit_mov_m8_imm(&dst, MABS(drcbe, &drcbe->state.fmod), srcp.value); // mov [fmod],srcp - emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[srcp.value])); // ldmxcsr fp_control[srcp] + int value = srcp.immediate() & 3; + emit_mov_m8_imm(dst, MABS(&m_state.fmod), value); // mov [fmod],srcp + emit_ldmxcsr_m32(dst, MABS(&m_near.ssecontrol[value])); // ldmxcsr fp_control[srcp] } - /* register/memory case */ + // register/memory case else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &srcp); // mov eax,srcp - emit_and_r32_imm(&dst, REG_EAX, 3); // and eax,3 - emit_mov_m8_r8(&dst, MABS(drcbe, &drcbe->state.fmod), REG_AL); // mov [fmod],al - emit_ldmxcsr_m32(&dst, MBISD(REG_RBP, REG_RAX, 4, offset_from_rbp(drcbe, (FPTR)&drcbe->ssecontrol[0]))); + emit_mov_r32_p32(dst, REG_EAX, srcp); // mov eax,srcp + emit_and_r32_imm(dst, REG_EAX, 3); // and eax,3 + emit_mov_m8_r8(dst, MABS(&m_state.fmod), REG_AL); // mov [fmod],al + emit_ldmxcsr_m32(dst, MBISD(REG_RBP, REG_RAX, 4, offset_from_rbp(&m_near.ssecontrol[0]))); // ldmxcsr fp_control[eax] } - - return dst; } -/*------------------------------------------------- - op_getfmod - process a GETFMOD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getfmod - process a GETFMOD opcode +//------------------------------------------------- -static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_getfmod(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* fetch the current mode and store to the destination */ - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_m8(&dst, dstp.value, MABS(drcbe, &drcbe->state.fmod)); // movzx reg,[fmod] + // fetch the current mode and store to the destination + if (dstp.is_int_register()) + emit_movzx_r32_m8(dst, dstp.ireg(), MABS(&m_state.fmod)); // movzx reg,[fmod] else { - emit_movzx_r32_m8(&dst, REG_EAX, MABS(drcbe, &drcbe->state.fmod)); // movzx eax,[fmod] - emit_mov_m32_r32(&dst, MABS(drcbe, dstp.value), REG_EAX); // mov [dstp],eax + emit_movzx_r32_m8(dst, REG_EAX, MABS(&m_state.fmod)); // movzx eax,[fmod] + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax } - - return dst; } -/*------------------------------------------------- - op_getexp - process a GETEXP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getexp - process a GETEXP opcode +//------------------------------------------------- -static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_getexp(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* fetch the exception parameter and store to the destination */ - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe, &drcbe->state.exp)); // mov reg,[exp] + // fetch the exception parameter and store to the destination + if (dstp.is_int_register()) + emit_mov_r32_m32(dst, dstp.ireg(), MABS(&m_state.exp)); // mov reg,[exp] else { - emit_mov_r32_m32(&dst, REG_EAX, MABS(drcbe, &drcbe->state.exp)); // mov eax,[exp] - emit_mov_m32_r32(&dst, MABS(drcbe, dstp.value), REG_EAX); // mov [dstp],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.exp)); // mov eax,[exp] + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax } - - return dst; } -/*------------------------------------------------- - op_getflgs - process a GETFLGS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getflgs - process a GETFLGS opcode +//------------------------------------------------- -static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_getflgs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, maskp; - UINT32 flagmask = 0; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &maskp, PTYPE_I); - - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter maskp(*this, inst.param(1), PTYPE_I); - /* compute mask for flags */ - if (maskp.value & DRCUML_FLAG_C) flagmask |= 0x001; - if (maskp.value & DRCUML_FLAG_V) flagmask |= 0x800; - if (maskp.value & DRCUML_FLAG_Z) flagmask |= 0x040; - if (maskp.value & DRCUML_FLAG_S) flagmask |= 0x080; - if (maskp.value & DRCUML_FLAG_U) flagmask |= 0x004; + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - switch (maskp.value) - { - /* single flags only */ - case DRCUML_FLAG_C: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + // compute mask for flags + UINT32 flagmask = 0; + if (maskp.immediate() & FLAG_C) flagmask |= 0x001; + if (maskp.immediate() & FLAG_V) flagmask |= 0x800; + if (maskp.immediate() & FLAG_Z) flagmask |= 0x040; + if (maskp.immediate() & FLAG_S) flagmask |= 0x080; + if (maskp.immediate() & FLAG_U) flagmask |= 0x004; + + switch (maskp.immediate()) + { + // single flags only + case FLAG_C: + emit_setcc_r8(dst, x64emit::COND_C, REG_AL); // setc al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al break; - case DRCUML_FLAG_V: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + case FLAG_V: + emit_setcc_r8(dst, x64emit::COND_O, REG_AL); // seto al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - case DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_Z, REG_AL); // setz al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 2); // shl dstreg,2 + case FLAG_Z: + emit_setcc_r8(dst, x64emit::COND_Z, REG_AL); // setz al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 2); // shl dstreg,2 break; - case DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_S, REG_AL); // sets al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 3); // shl dstreg,3 + case FLAG_S: + emit_setcc_r8(dst, x64emit::COND_S, REG_AL); // sets al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 3); // shl dstreg,3 break; - case DRCUML_FLAG_U: - emit_setcc_r8(&dst, COND_P, REG_AL); // setp al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 4); // shl dstreg,4 + case FLAG_U: + emit_setcc_r8(dst, x64emit::COND_P, REG_AL); // setp al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 4); // shl dstreg,4 break; - /* carry plus another flag */ - case DRCUML_FLAG_C | DRCUML_FLAG_V: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_O, REG_CL); // seto cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + // carry plus another flag + case FLAG_C | FLAG_V: + emit_setcc_r8(dst, x64emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x64emit::COND_O, REG_CL); // seto cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] break; - case DRCUML_FLAG_C | DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_Z, REG_CL); // setz cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] + case FLAG_C | FLAG_Z: + emit_setcc_r8(dst, x64emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x64emit::COND_Z, REG_CL); // setz cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] break; - case DRCUML_FLAG_C | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0)); // lea dstreg,[eax+ecx*8] + case FLAG_C | FLAG_S: + emit_setcc_r8(dst, x64emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x64emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0)); // lea dstreg,[eax+ecx*8] break; - /* overflow plus another flag */ - case DRCUML_FLAG_V | DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_setcc_r8(&dst, COND_Z, REG_CL); // setz cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + // overflow plus another flag + case FLAG_V | FLAG_Z: + emit_setcc_r8(dst, x64emit::COND_O, REG_AL); // seto al + emit_setcc_r8(dst, x64emit::COND_Z, REG_CL); // setz cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - case DRCUML_FLAG_V | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + case FLAG_V | FLAG_S: + emit_setcc_r8(dst, x64emit::COND_O, REG_AL); // seto al + emit_setcc_r8(dst, x64emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - /* zero plus another flag */ - case DRCUML_FLAG_Z | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_Z, REG_AL); // setz al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] - emit_shl_r32_imm(&dst, dstreg, 2); // shl dstreg,2 + // zero plus another flag + case FLAG_Z | FLAG_S: + emit_setcc_r8(dst, x64emit::COND_Z, REG_AL); // setz al + emit_setcc_r8(dst, x64emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + emit_shl_r32_imm(dst, dstreg, 2); // shl dstreg,2 break; - /* default cases */ + // default cases default: - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_EAX); // pop eax - emit_and_r32_imm(&dst, REG_EAX, flagmask); // and eax,flagmask - emit_movzx_r32_m8(&dst, dstreg, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(drcbe, (FPTR)&drcbe->flagsmap[0]))); + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_EAX); // pop eax + emit_and_r32_imm(dst, REG_EAX, flagmask); // and eax,flagmask + emit_movzx_r32_m8(dst, dstreg, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(&m_near.flagsmap[0]))); // movzx dstreg,[flags_map] break; } - /* 32-bit form */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - - /* 64-bit form */ - else if (inst->size == 8) - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // 32-bit form + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - return dst; + // 64-bit form + else if (inst.size() == 8) + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } -/*------------------------------------------------- - op_save - process a SAVE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_save - process a SAVE opcode +//------------------------------------------------- -static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_save(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - int regoffs; - int regnum; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_M); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_M); - /* copy live state to the destination */ - emit_mov_r64_imm(&dst, REG_RCX, dstp.value); // mov rcx,dstp + // copy live state to the destination + emit_mov_r64_imm(dst, REG_RCX, (FPTR)dstp.memory()); // mov rcx,dstp - /* copy flags */ - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_RAX); // pop rax - emit_and_r32_imm(&dst, REG_EAX, 0x8c5); // and eax,0x8c5 - emit_mov_r8_m8(&dst, REG_AL, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(drcbe, (FPTR)&drcbe->flagsmap[0]))); + // copy flags + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_RAX); // pop rax + emit_and_r32_imm(dst, REG_EAX, 0x8c5); // and eax,0x8c5 + emit_mov_r8_m8(dst, REG_AL, MBISD(REG_RBP, REG_RAX, 1, offset_from_rbp(&m_near.flagsmap[0]))); // mov al,[flags_map] - emit_mov_m8_r8(&dst, MBD(REG_RCX, offsetof(drcuml_machine_state, flags)), REG_AL); // mov state->flags,al + emit_mov_m8_r8(dst, MBD(REG_RCX, offsetof(drcuml_machine_state, flags)), REG_AL); // mov state->flags,al - /* copy fmod and exp */ - emit_mov_r8_m8(&dst, REG_AL, MABS(drcbe, &drcbe->state.fmod)); // mov al,[fmod] - emit_mov_m8_r8(&dst, MBD(REG_RCX, offsetof(drcuml_machine_state, fmod)), REG_AL); // mov state->fmod,al - emit_mov_r32_m32(&dst, REG_EAX, MABS(drcbe, &drcbe->state.exp)); // mov eax,[exp] - emit_mov_m32_r32(&dst, MBD(REG_RCX, offsetof(drcuml_machine_state, exp)), REG_EAX); // mov state->exp,eax + // copy fmod and exp + emit_mov_r8_m8(dst, REG_AL, MABS(&m_state.fmod)); // mov al,[fmod] + emit_mov_m8_r8(dst, MBD(REG_RCX, offsetof(drcuml_machine_state, fmod)), REG_AL); // mov state->fmod,al + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.exp)); // mov eax,[exp] + emit_mov_m32_r32(dst, MBD(REG_RCX, offsetof(drcuml_machine_state, exp)), REG_EAX); // mov state->exp,eax - /* copy integer registers */ - regoffs = offsetof(drcuml_machine_state, r); - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.r); regnum++) + // copy integer registers + int regoffs = offsetof(drcuml_machine_state, r); + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.r); regnum++) { if (int_register_map[regnum] != 0) - emit_mov_m64_r64(&dst, MBD(REG_RCX, regoffs + 8 * regnum), int_register_map[regnum]); + emit_mov_m64_r64(dst, MBD(REG_RCX, regoffs + 8 * regnum), int_register_map[regnum]); else { - emit_mov_r64_m64(&dst, REG_RAX, MABS(drcbe, &drcbe->state.r[regnum].d)); - emit_mov_m64_r64(&dst, MBD(REG_RCX, regoffs + 8 * regnum), REG_RAX); + emit_mov_r64_m64(dst, REG_RAX, MABS(&m_state.r[regnum].d)); + emit_mov_m64_r64(dst, MBD(REG_RCX, regoffs + 8 * regnum), REG_RAX); } } - /* copy FP registers */ + // copy FP registers regoffs = offsetof(drcuml_machine_state, f); - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.f); regnum++) + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.f); regnum++) { if (float_register_map[regnum] != 0) - emit_movsd_m64_r128(&dst, MBD(REG_RCX, regoffs + 8 * regnum), float_register_map[regnum]); + emit_movsd_m64_r128(dst, MBD(REG_RCX, regoffs + 8 * regnum), float_register_map[regnum]); else { - emit_mov_r64_m64(&dst, REG_RAX, MABS(drcbe, &drcbe->state.f[regnum].d)); - emit_mov_m64_r64(&dst, MBD(REG_RCX, regoffs + 8 * regnum), REG_RAX); + emit_mov_r64_m64(dst, REG_RAX, MABS(&m_state.f[regnum].d)); + emit_mov_m64_r64(dst, MBD(REG_RCX, regoffs + 8 * regnum), REG_RAX); } } - - return dst; } -/*------------------------------------------------- - op_restore - process a RESTORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_restore - process a RESTORE opcode +//------------------------------------------------- -static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_restore(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - int regoffs; - int regnum; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_M); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_M); - /* copy live state from the destination */ - emit_mov_r64_imm(&dst, REG_ECX, dstp.value); // mov rcx,dstp + // copy live state from the destination + emit_mov_r64_imm(dst, REG_ECX, (FPTR)srcp.memory()); // mov rcx,dstp - /* copy integer registers */ - regoffs = offsetof(drcuml_machine_state, r); - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.r); regnum++) + // copy integer registers + int regoffs = offsetof(drcuml_machine_state, r); + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.r); regnum++) { if (int_register_map[regnum] != 0) - emit_mov_r64_m64(&dst, int_register_map[regnum], MBD(REG_RCX, regoffs + 8 * regnum)); + emit_mov_r64_m64(dst, int_register_map[regnum], MBD(REG_RCX, regoffs + 8 * regnum)); else { - emit_mov_r64_m64(&dst, REG_RAX, MBD(REG_RCX, regoffs + 8 * regnum)); - emit_mov_m64_r64(&dst, MABS(drcbe, &drcbe->state.r[regnum].d), REG_RAX); + emit_mov_r64_m64(dst, REG_RAX, MBD(REG_RCX, regoffs + 8 * regnum)); + emit_mov_m64_r64(dst, MABS(&m_state.r[regnum].d), REG_RAX); } } - /* copy FP registers */ + // copy FP registers regoffs = offsetof(drcuml_machine_state, f); - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.f); regnum++) + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.f); regnum++) { if (float_register_map[regnum] != 0) - emit_movsd_r128_m64(&dst, float_register_map[regnum], MBD(REG_RCX, regoffs + 8 * regnum)); + emit_movsd_r128_m64(dst, float_register_map[regnum], MBD(REG_RCX, regoffs + 8 * regnum)); else { - emit_mov_r64_m64(&dst, REG_RAX, MBD(REG_RCX, regoffs + 8 * regnum)); - emit_mov_m64_r64(&dst, MABS(drcbe, &drcbe->state.f[regnum].d), REG_RAX); + emit_mov_r64_m64(dst, REG_RAX, MBD(REG_RCX, regoffs + 8 * regnum)); + emit_mov_m64_r64(dst, MABS(&m_state.f[regnum].d), REG_RAX); } } - /* copy fmod and exp */ - emit_movzx_r32_m8(&dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, fmod)));// movzx eax,state->fmod - emit_and_r32_imm(&dst, REG_EAX, 3); // and eax,3 - emit_mov_m8_r8(&dst, MABS(drcbe, &drcbe->state.fmod), REG_AL); // mov [fmod],al - emit_ldmxcsr_m32(&dst, MBISD(REG_RBP, REG_RAX, 4, offset_from_rbp(drcbe, (FPTR)&drcbe->ssecontrol[0]))); - emit_mov_r32_m32(&dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, exp))); // mov eax,state->exp - emit_mov_m32_r32(&dst, MABS(drcbe, &drcbe->state.exp), REG_EAX); // mov [exp],eax + // copy fmod and exp + emit_movzx_r32_m8(dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, fmod)));// movzx eax,state->fmod + emit_and_r32_imm(dst, REG_EAX, 3); // and eax,3 + emit_mov_m8_r8(dst, MABS(&m_state.fmod), REG_AL); // mov [fmod],al + emit_ldmxcsr_m32(dst, MBISD(REG_RBP, REG_RAX, 4, offset_from_rbp(&m_near.ssecontrol[0]))); + emit_mov_r32_m32(dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, exp))); // mov eax,state->exp + emit_mov_m32_r32(dst, MABS(&m_state.exp), REG_EAX); // mov [exp],eax - /* copy flags */ - emit_movzx_r32_m8(&dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, flags)));// movzx eax,state->flags - emit_push_m64(&dst, MBISD(REG_RBP, REG_RAX, 8, offset_from_rbp(drcbe, (FPTR)&drcbe->flagsunmap[0]))); + // copy flags + emit_movzx_r32_m8(dst, REG_EAX, MBD(REG_RCX, offsetof(drcuml_machine_state, flags)));// movzx eax,state->flags + emit_push_m64(dst, MBISD(REG_RBP, REG_RAX, 8, offset_from_rbp(&m_near.flagsunmap[0]))); // push flags_unmap[eax*8] - emit_popf(&dst); // popf - - return dst; + emit_popf(dst); // popf } @@ -3839,2363 +3442,2309 @@ static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instru INTEGER OPERATIONS ***************************************************************************/ -/*------------------------------------------------- - op_load - process a LOAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_load - process a LOAD opcode +//------------------------------------------------- -static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_load(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp, scalesizep; - int basereg, dstreg, scale, size; - INT32 baseoffs; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + assert(scalesizep.is_size_scale()); + int scale = 1 << scalesizep.scale(); + int size = scalesizep.size(); - /* determine the pointer base */ - basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs); + // determine the pointer base + INT32 baseoffs; + int basereg = get_base_register_and_offset(dst, basep.memory(), REG_RDX, baseoffs); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate index + if (indp.is_immediate()) { - if (size == DRCUML_SIZE_BYTE) - emit_movzx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movzx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value));// movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) - emit_mov_r64_m64(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // mov dstreg,[basep + scale*indp] + if (size == SIZE_BYTE) + emit_movzx_r32_m8(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movzx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movzx_r32_m16(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movzx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate())); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) + emit_mov_r64_m64(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate())); // mov dstreg,[basep + scale*indp] } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_movsx_r64_p32(drcbe, &dst, indreg, &indp); - if (size == DRCUML_SIZE_BYTE) - emit_movzx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movzx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) - emit_mov_r64_m64(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] - } - - /* store result */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + int indreg = indp.select_register(REG_ECX); + emit_movsx_r64_p32(dst, indreg, indp); + if (size == SIZE_BYTE) + emit_movzx_r32_m8(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movzx_r32_m16(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) + emit_mov_r64_m64(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] + } + + // store result + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg else - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg - return dst; } -/*------------------------------------------------- - op_loads - process a LOADS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_loads - process a LOADS opcode +//------------------------------------------------- -static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_loads(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp, scalesizep; - int basereg, dstreg, scale, size; - INT32 baseoffs; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + assert(scalesizep.is_size_scale()); + int scale = 1 << scalesizep.scale(); + int size = scalesizep.size(); - /* determine the pointer base */ - basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs); + // determine the pointer base + INT32 baseoffs; + int basereg = get_base_register_and_offset(dst, basep.memory(), REG_RDX, baseoffs); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate index + if (indp.is_immediate()) { - if (inst->size == 4) + if (inst.size() == 4) { - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value));// movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // mov dstreg,[basep + scale*indp] + if (size == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate())); // mov dstreg,[basep + scale*indp] } - else if (inst->size == 8) + else if (inst.size() == 8) { - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r64_m8(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r64_m16(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value));// movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_movsxd_r64_m32(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value));// movsxd dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) - emit_mov_r64_m64(&dst, dstreg, MBD(basereg, baseoffs + scale*indp.value)); // mov dstreg,[basep + scale*indp] + if (size == SIZE_BYTE) + emit_movsx_r64_m8(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movzx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r64_m16(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movzx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_movsxd_r64_m32(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate()));// movsxd dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) + emit_mov_r64_m64(dst, dstreg, MBD(basereg, baseoffs + scale*indp.immediate())); // mov dstreg,[basep + scale*indp] } } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_movsx_r64_p32(drcbe, &dst, indreg, &indp); - if (inst->size == 4) + int indreg = indp.select_register(REG_ECX); + emit_movsx_r64_p32(dst, indreg, indp); + if (inst.size() == 4) { - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] + if (size == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] } - else if (inst->size == 8) + else if (inst.size() == 8) { - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r64_m8(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r64_m16(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_movsxd_r64_m32(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // movsxd dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) - emit_mov_r64_m64(&dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] + if (size == SIZE_BYTE) + emit_movsx_r64_m8(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r64_m16(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs));// movsx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_movsxd_r64_m32(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs));// movsxd dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) + emit_mov_r64_m64(dst, dstreg, MBISD(basereg, indreg, scale, baseoffs)); // mov dstreg,[basep + scale*indp] } } - /* store result */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store result + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg else - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg - return dst; } -/*------------------------------------------------- - op_store - process a STORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_store - process a STORE opcode +//------------------------------------------------- -static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_store(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, basep, indp, scalesizep; - int srcreg, basereg, scale, size; - INT32 baseoffs; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; + // normalize parameters + be_parameter basep(*this, inst.param(0), PTYPE_M); + be_parameter indp(*this, inst.param(1), PTYPE_MRI); + be_parameter srcp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + int scale = 1 << (scalesizep.scale()); + int size = scalesizep.size(); - /* determine the pointer base */ - basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs); + // determine the pointer base + INT32 baseoffs; + int basereg = get_base_register_and_offset(dst, basep.memory(), REG_RDX, baseoffs); - /* pick a source register for the general case */ - srcreg = param_select_register(REG_EAX, &srcp, NULL); + // pick a source register for the general case + int srcreg = srcp.select_register(REG_EAX); - /* degenerate case: constant index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // degenerate case: constant index + if (indp.is_immediate()) { - /* immediate source */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate source + if (srcp.is_immediate()) { - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_imm(&dst, MBD(basereg, baseoffs + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_imm(&dst, MBD(basereg, baseoffs + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_QWORD) + if (size == SIZE_BYTE) + emit_mov_m8_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcp.immediate());// mov [basep + scale*indp],srcp + else if (size == SIZE_WORD) + emit_mov_m16_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcp.immediate());// mov [basep + scale*indp],srcp + else if (size == SIZE_DWORD) + emit_mov_m32_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcp.immediate());// mov [basep + scale*indp],srcp + else if (size == SIZE_QWORD) { - if (short_immediate(srcp.value)) - emit_mov_m64_imm(&dst, MBD(basereg, baseoffs + scale*indp.value), srcp.value);// mov [basep + scale*indp],srcp + if (short_immediate(srcp.immediate())) + emit_mov_m64_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcp.immediate());// mov [basep + scale*indp],srcp else { - emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + scale*indp.value), srcp.value);// mov [basep + scale*indp],srcp - emit_mov_m32_imm(&dst, MBD(basereg, baseoffs + scale*indp.value + 4), srcp.value >> 32); + emit_mov_m32_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcp.immediate());// mov [basep + scale*indp],srcp + emit_mov_m32_imm(dst, MBD(basereg, baseoffs + scale*indp.immediate() + 4), srcp.immediate() >> 32); // mov [basep + scale*indp + 4],srcp >> 32 } } } - /* variable source */ + // variable source else { - if (size != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp + if (size != SIZE_QWORD) + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp else - emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_r8(&dst, MBD(basereg, baseoffs + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_r16(&dst, MBD(basereg, baseoffs + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_r32(&dst, MBD(basereg, baseoffs + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_QWORD) - emit_mov_m64_r64(&dst, MBD(basereg, baseoffs + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg + emit_mov_r64_p64(dst, srcreg, srcp); // mov srcreg,srcp + if (size == SIZE_BYTE) + emit_mov_m8_r8(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_WORD) + emit_mov_m16_r16(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_DWORD) + emit_mov_m32_r32(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_QWORD) + emit_mov_m64_r64(dst, MBD(basereg, baseoffs + scale*indp.immediate()), srcreg); // mov [basep + scale*indp],srcreg } } - /* normal case: variable index */ + // normal case: variable index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_movsx_r64_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp + int indreg = indp.select_register(REG_ECX); + emit_movsx_r64_p32(dst, indreg, indp); // mov indreg,indp - /* immediate source */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate source + if (srcp.is_immediate()) { - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_imm(&dst, MBISD(basereg, indreg, scale, baseoffs), srcp.value); // mov [basep + scale*ecx],srcp - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_imm(&dst, MBISD(basereg, indreg, scale, baseoffs), srcp.value);// mov [basep + scale*ecx],srcp - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_imm(&dst, MBISD(basereg, indreg, scale, baseoffs), srcp.value);// mov [basep + scale*ecx],srcp - else if (size == DRCUML_SIZE_QWORD) + if (size == SIZE_BYTE) + emit_mov_m8_imm(dst, MBISD(basereg, indreg, scale, baseoffs), srcp.immediate());// mov [basep + scale*ecx],srcp + else if (size == SIZE_WORD) + emit_mov_m16_imm(dst, MBISD(basereg, indreg, scale, baseoffs), srcp.immediate());// mov [basep + scale*ecx],srcp + else if (size == SIZE_DWORD) + emit_mov_m32_imm(dst, MBISD(basereg, indreg, scale, baseoffs), srcp.immediate());// mov [basep + scale*ecx],srcp + else if (size == SIZE_QWORD) { - if (short_immediate(srcp.value)) - emit_mov_m64_imm(&dst, MBISD(basereg, indreg, scale, baseoffs), srcp.value);// mov [basep + scale*indp],srcp + if (short_immediate(srcp.immediate())) + emit_mov_m64_imm(dst, MBISD(basereg, indreg, scale, baseoffs), srcp.immediate());// mov [basep + scale*indp],srcp else { - emit_mov_m32_imm(&dst, MBISD(basereg, indreg, scale, baseoffs), srcp.value);// mov [basep + scale*ecx],srcp - emit_mov_m32_imm(&dst, MBISD(basereg, indreg, scale, baseoffs + 4), srcp.value >> 32); + emit_mov_m32_imm(dst, MBISD(basereg, indreg, scale, baseoffs), srcp.immediate());// mov [basep + scale*ecx],srcp + emit_mov_m32_imm(dst, MBISD(basereg, indreg, scale, baseoffs + 4), srcp.immediate() >> 32); // mov [basep + scale*ecx + 4],srcp >> 32 } } } - /* variable source */ + // variable source else { - if (size != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp + if (size != SIZE_QWORD) + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp else - emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp); // mov edx:srcreg,srcp - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_r8(&dst, MBISD(basereg, indreg, scale, baseoffs), srcreg); // mov [basep + scale*ecx],srcreg - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_r16(&dst, MBISD(basereg, indreg, scale, baseoffs), srcreg);// mov [basep + scale*ecx],srcreg - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_r32(&dst, MBISD(basereg, indreg, scale, baseoffs), srcreg);// mov [basep + scale*ecx],srcreg - else if (size == DRCUML_SIZE_QWORD) - emit_mov_m64_r64(&dst, MBISD(basereg, indreg, scale, baseoffs), srcreg);// mov [basep + scale*ecx],srcreg + emit_mov_r64_p64(dst, srcreg, srcp); // mov edx:srcreg,srcp + if (size == SIZE_BYTE) + emit_mov_m8_r8(dst, MBISD(basereg, indreg, scale, baseoffs), srcreg); // mov [basep + scale*ecx],srcreg + else if (size == SIZE_WORD) + emit_mov_m16_r16(dst, MBISD(basereg, indreg, scale, baseoffs), srcreg); // mov [basep + scale*ecx],srcreg + else if (size == SIZE_DWORD) + emit_mov_m32_r32(dst, MBISD(basereg, indreg, scale, baseoffs), srcreg); // mov [basep + scale*ecx],srcreg + else if (size == SIZE_QWORD) + emit_mov_m64_r64(dst, MBISD(basereg, indreg, scale, baseoffs), srcreg); // mov [basep + scale*ecx],srcreg } } - return dst; } -/*------------------------------------------------- - op_read - process a READ opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_read - process a READ opcode +//------------------------------------------------- -static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_read(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, addrp, spacesizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacesizep = inst.param(2); + assert(spacesizep.is_size_space()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set up a call to the read byte handler */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacesizep.value / 16])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param2,addrp - if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE) + // set up a call to the read byte handler + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacesizep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param2,addrp + if (spacesizep.size() == SIZE_BYTE) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_byte); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_byte); // call read_byte - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al } - else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) + else if (spacesizep.size() == SIZE_WORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_word); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_word); // call read_word - emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax + emit_movzx_r32_r16(dst, dstreg, REG_AX); // movzx dstreg,ax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) + else if (spacesizep.size() == SIZE_DWORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_dword); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_dword); // call read_dword - if (dstreg != REG_EAX || inst->size == 8) - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + if (dstreg != REG_EAX || inst.size() == 8) + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) + else if (spacesizep.size() == SIZE_QWORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_qword); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_qword); // call read_qword if (dstreg != REG_RAX) - emit_mov_r64_r64(&dst, dstreg, REG_RAX); // mov dstreg,rax + emit_mov_r64_r64(dst, dstreg, REG_RAX); // mov dstreg,rax } - /* store result */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store result + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg else - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - - return dst; + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } -/*------------------------------------------------- - op_readm - process a READM opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_readm - process a READM opcode +//------------------------------------------------- -static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_readm(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, addrp, maskp, spacesizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I); - - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); - - /* set up a call to the read byte handler */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacesizep.value / 16])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param2,addrp - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &maskp); // mov param3,maskp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + be_parameter maskp(*this, inst.param(2), PTYPE_MRI); + const parameter &spacesizep = inst.param(3); + assert(spacesizep.is_size_space()); + + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); + + // set up a call to the read byte handler + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacesizep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param2,addrp + if (spacesizep.size() != SIZE_QWORD) + emit_mov_r32_p32(dst, REG_PARAM3, maskp); // mov param3,maskp else - emit_mov_r64_p64(drcbe, &dst, REG_PARAM3, &maskp); // mov param3,maskp - if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) + emit_mov_r64_p64(dst, REG_PARAM3, maskp); // mov param3,maskp + if (spacesizep.size() == SIZE_WORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_word_masked); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_word_masked); // call read_word_masked - emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax + emit_movzx_r32_r16(dst, dstreg, REG_AX); // movzx dstreg,ax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) + else if (spacesizep.size() == SIZE_DWORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_dword_masked); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_dword_masked); // call read_dword_masked - if (dstreg != REG_EAX || inst->size == 8) - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + if (dstreg != REG_EAX || inst.size() == 8) + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) + else if (spacesizep.size() == SIZE_QWORD) { - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].read_qword_masked); + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].read_qword_masked); // call read_qword_masked if (dstreg != REG_RAX) - emit_mov_r64_r64(&dst, dstreg, REG_RAX); // mov dstreg,rax + emit_mov_r64_r64(dst, dstreg, REG_RAX); // mov dstreg,rax } - /* store result */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store result + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg else - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - - return dst; + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } -/*------------------------------------------------- - op_write - process a WRITE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_write - process a WRITE opcode +//------------------------------------------------- -static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_write(x86code *&dst, const instruction &inst) { - drcuml_parameter addrp, srcp, spacesizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &spacesizep, PTYPE_I); - - /* set up a call to the write byte handler */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacesizep.value / 16])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param2,addrp - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &srcp); // mov param3,srcp + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacesizep = inst.param(2); + assert(spacesizep.is_size_space()); + + // set up a call to the write byte handler + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacesizep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param2,addrp + if (spacesizep.size() != SIZE_QWORD) + emit_mov_r32_p32(dst, REG_PARAM3, srcp); // mov param3,srcp else - emit_mov_r64_p64(drcbe, &dst, REG_PARAM3, &srcp); // mov param3,srcp - if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_byte); + emit_mov_r64_p64(dst, REG_PARAM3, srcp); // mov param3,srcp + if (spacesizep.size() == SIZE_BYTE) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_byte); // call write_byte - else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_word); + else if (spacesizep.size() == SIZE_WORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_word); // call write_word - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_dword); + else if (spacesizep.size() == SIZE_DWORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_dword); // call write_dword - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_qword); + else if (spacesizep.size() == SIZE_QWORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_qword); // call write_qword - return dst; } -/*------------------------------------------------- - op_writem - process a WRITEM opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_writem - process a WRITEM opcode +//------------------------------------------------- -static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_writem(x86code *&dst, const instruction &inst) { - drcuml_parameter addrp, srcp, maskp, spacesizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter maskp(*this, inst.param(2), PTYPE_MRI); + const parameter &spacesizep = inst.param(3); + assert(spacesizep.is_size_space()); - /* set up a call to the write byte handler */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacesizep.value / 16])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param2,addrp - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) + // set up a call to the write byte handler + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacesizep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param2,addrp + if (spacesizep.size() != SIZE_QWORD) { - emit_mov_r32_p32(drcbe, &dst, REG_PARAM3, &srcp); // mov param3,srcp - emit_mov_r32_p32(drcbe, &dst, REG_PARAM4, &maskp); // mov param4,maskp + emit_mov_r32_p32(dst, REG_PARAM3, srcp); // mov param3,srcp + emit_mov_r32_p32(dst, REG_PARAM4, maskp); // mov param4,maskp } else { - emit_mov_r64_p64(drcbe, &dst, REG_PARAM3, &srcp); // mov param3,srcp - emit_mov_r64_p64(drcbe, &dst, REG_PARAM4, &maskp); // mov param4,maskp + emit_mov_r64_p64(dst, REG_PARAM3, srcp); // mov param3,srcp + emit_mov_r64_p64(dst, REG_PARAM4, maskp); // mov param4,maskp } - if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_word_masked); + if (spacesizep.size() == SIZE_WORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_word_masked); // call write_word_masked - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_dword_masked); + else if (spacesizep.size() == SIZE_DWORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_dword_masked); // call write_dword_masked - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacesizep.value / 16].write_qword_masked); + else if (spacesizep.size() == SIZE_QWORD) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacesizep.space()].write_qword_masked); // call write_qword_masked - return dst; } -/*------------------------------------------------- - op_carry - process a CARRY opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_carry - process a CARRY opcode +//------------------------------------------------- -static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_carry(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, bitp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C); + assert_flags(inst, FLAG_C); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &srcp, PTYPE_MRI, &bitp, PTYPE_MRI); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_MRI); + be_parameter bitp(*this, inst.param(1), PTYPE_MRI); - /* degenerate case: source is immediate */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE && bitp.type == DRCUML_PTYPE_IMMEDIATE) + // degenerate case: source is immediate + if (srcp.is_immediate() && bitp.is_immediate()) { - if (srcp.value & ((UINT64)1 << bitp.value)) - emit_stc(&dst); + if (srcp.immediate() & ((UINT64)1 << bitp.immediate())) + emit_stc(dst); else - emit_clc(&dst); - return dst; - } + emit_clc(dst); + } - /* load non-immediate bit numbers into a register */ - if (bitp.type != DRCUML_PTYPE_IMMEDIATE) + // load non-immediate bit numbers into a register + if (!bitp.is_immediate()) { - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &bitp); - emit_and_r32_imm(&dst, REG_ECX, inst->size * 8 - 1); + emit_mov_r32_p32(dst, REG_ECX, bitp); + emit_and_r32_imm(dst, REG_ECX, inst.size() * 8 - 1); } - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - if (bitp.type == DRCUML_PTYPE_IMMEDIATE) + if (bitp.is_immediate()) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_imm(&dst, MABS(drcbe, srcp.value), bitp.value); // bt [srcp],bitp - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r32_imm(&dst, srcp.value, bitp.value); // bt srcp,bitp + if (srcp.is_memory()) + emit_bt_m32_imm(dst, MABS(srcp.memory()), bitp.immediate()); // bt [srcp],bitp + else if (srcp.is_int_register()) + emit_bt_r32_imm(dst, srcp.ireg(), bitp.immediate()); // bt srcp,bitp } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_r32(&dst, MABS(drcbe, srcp.value), REG_ECX); // bt [srcp],ecx - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r32_r32(&dst, srcp.value, REG_ECX); // bt srcp,ecx + if (srcp.is_memory()) + emit_bt_m32_r32(dst, MABS(srcp.memory()), REG_ECX); // bt [srcp],ecx + else if (srcp.is_int_register()) + emit_bt_r32_r32(dst, srcp.ireg(), REG_ECX); // bt srcp,ecx } } - /* 64-bit form */ + // 64-bit form else { - if (bitp.type == DRCUML_PTYPE_IMMEDIATE) + if (bitp.is_immediate()) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m64_imm(&dst, MABS(drcbe, srcp.value), bitp.value); // bt [srcp],bitp - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r64_imm(&dst, srcp.value, bitp.value); // bt srcp,bitp + if (srcp.is_memory()) + emit_bt_m64_imm(dst, MABS(srcp.memory()), bitp.immediate()); // bt [srcp],bitp + else if (srcp.is_int_register()) + emit_bt_r64_imm(dst, srcp.ireg(), bitp.immediate()); // bt srcp,bitp } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m64_r64(&dst, MABS(drcbe, srcp.value), REG_ECX); // bt [srcp],ecx - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r64_r64(&dst, srcp.value, REG_ECX); // bt srcp,ecx + if (srcp.is_memory()) + emit_bt_m64_r64(dst, MABS(srcp.memory()), REG_ECX); // bt [srcp],ecx + else if (srcp.is_int_register()) + emit_bt_r64_r64(dst, srcp.ireg(), REG_ECX); // bt srcp,ecx } } - return dst; } -/*------------------------------------------------- - op_set - process a SET opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_set - process a SET opcode +//------------------------------------------------- -static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_set(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set to AL */ - emit_setcc_r8(&dst, X86_CONDITION(inst->condition), REG_AL); // setcc al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + // set to AL + emit_setcc_r8(dst, X86_CONDITION(inst.condition()), REG_AL); // setcc al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al - /* 32-bit form */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // 32-bit form + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form */ - else if (inst->size == 8) - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // 64-bit form + else if (inst.size() == 8) + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg - return dst; } -/*------------------------------------------------- - op_mov - process a MOV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mov - process a MOV opcode +//------------------------------------------------- -static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_mov(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; x86code *savedst = dst; - emit_link skip = { 0 }; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters, but only if we got here directly */ - /* other opcodes call through here with pre-normalized parameters */ - if (inst->opcode == DRCUML_OP_MOV) - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); - else - { - dstp = inst->param[0]; - srcp = inst->param[1]; - } + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* always start with a jmp */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // always start with a jmp + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* register to memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(drcbe, dstp.value), srcp.value); // mov [dstp],srcp + // register to memory + if (dstp.is_memory() && srcp.is_int_register()) + emit_mov_m32_r32(dst, MABS(dstp.memory()), srcp.ireg()); // mov [dstp],srcp - /* immediate to memory */ - else if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_m32_imm(&dst, MABS(drcbe, dstp.value), srcp.value); // mov [dstp],srcp + // immediate to memory + else if (dstp.is_memory() && srcp.is_immediate()) + emit_mov_m32_imm(dst, MABS(dstp.memory()), srcp.immediate()); // mov [dstp],srcp - /* conditional memory to register */ - else if (inst->condition != 0 && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_MEMORY) + // conditional memory to register + else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_memory()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r32_m32(&dst, X86_CONDITION(inst->condition), dstp.value, MABS(drcbe, srcp.value)); + emit_cmovcc_r32_m32(dst, X86_CONDITION(inst.condition()), dstp.ireg(), MABS(srcp.memory())); // cmovcc dstp,[srcp] } - /* conditional register to register */ - else if (inst->condition != 0 && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_INT_REGISTER) + // conditional register to register + else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_int_register()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r32_r32(&dst, X86_CONDITION(inst->condition), dstp.value, srcp.value); + emit_cmovcc_r32_r32(dst, X86_CONDITION(inst.condition()), dstp.ireg(), srcp.ireg()); // cmovcc dstp,srcp } - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, srcp); // mov dstreg,srcp + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* register to memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m64_r64(&dst, MABS(drcbe, dstp.value), srcp.value); // mov [dstp],srcp + // register to memory + if (dstp.is_memory() && srcp.is_int_register()) + emit_mov_m64_r64(dst, MABS(dstp.memory()), srcp.ireg()); // mov [dstp],srcp - /* immediate to memory */ - else if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(srcp.value)) - emit_mov_m64_imm(&dst, MABS(drcbe, dstp.value), srcp.value); // mov [dstp],srcp + // immediate to memory + else if (dstp.is_memory() && srcp.is_immediate() && short_immediate(srcp.immediate())) + emit_mov_m64_imm(dst, MABS(dstp.memory()), srcp.immediate()); // mov [dstp],srcp - /* conditional memory to register */ - else if (inst->condition != 0 && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_MEMORY) + // conditional memory to register + else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_memory()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r64_m64(&dst, X86_CONDITION(inst->condition), dstp.value, MABS(drcbe, srcp.value)); + emit_cmovcc_r64_m64(dst, X86_CONDITION(inst.condition()), dstp.ireg(), MABS(srcp.memory())); // cmovcc dstp,[srcp] } - /* conditional register to register */ - else if (inst->condition != 0 && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_INT_REGISTER) + // conditional register to register + else if (inst.condition() != 0 && dstp.is_int_register() && srcp.is_int_register()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r64_r64(&dst, X86_CONDITION(inst->condition), dstp.value, srcp.value); + emit_cmovcc_r64_r64(dst, X86_CONDITION(inst.condition()), dstp.ireg(), srcp.ireg()); // cmovcc dstp,srcp } - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64_keepflags(dst, dstreg, srcp); // mov dstreg,srcp + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - /* resolve the jump */ + // resolve the jump if (skip.target != NULL) - resolve_link(&dst, &skip); - return dst; + resolve_link(dst, skip); } -/*------------------------------------------------- - op_sext - process a SEXT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sext - process a SEXT opcode +//------------------------------------------------- -static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_sext(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &sizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* general case */ - if (srcp.type == DRCUML_PTYPE_MEMORY) + // general case + if (srcp.is_memory()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MABS(drcbe, srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MABS(drcbe, srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // mov dstreg,[srcp] + if (sizep.size() == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABS(srcp.memory())); // mov dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + else if (srcp.is_int_register()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r32_r8(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r32_r16(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_DWORD) - emit_mov_r32_r32(&dst, dstreg, srcp.value); // mov dstreg,srcp + if (sizep.size() == SIZE_BYTE) + emit_movsx_r32_r8(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_WORD) + emit_movsx_r32_r16(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_DWORD) + emit_mov_r32_r32(dst, dstreg, srcp.ireg()); // mov dstreg,srcp } - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (inst->flags != 0) - emit_test_r32_r32(&dst, dstreg, dstreg); // test dstreg,dstreg + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg + if (inst.flags() != 0) + emit_test_r32_r32(dst, dstreg, dstreg); // test dstreg,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - if (srcp.type == DRCUML_PTYPE_MEMORY) + // general case + if (srcp.is_memory()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r64_m8(&dst, dstreg, MABS(drcbe, srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r64_m16(&dst, dstreg, MABS(drcbe, srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_DWORD) - emit_movsxd_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // movsxd dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_QWORD) - emit_mov_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // mov dstreg,[srcp] + if (sizep.size() == SIZE_BYTE) + emit_movsx_r64_m8(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_WORD) + emit_movsx_r64_m16(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_DWORD) + emit_movsxd_r64_m32(dst, dstreg, MABS(srcp.memory())); // movsxd dstreg,[srcp] + else if (sizep.size() == SIZE_QWORD) + emit_mov_r64_m64(dst, dstreg, MABS(srcp.memory())); // mov dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + else if (srcp.is_int_register()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r64_r8(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r64_r16(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_DWORD) - emit_movsxd_r64_r32(&dst, dstreg, srcp.value); // movsxd dstreg,srcp - else if (sizep.value == DRCUML_SIZE_QWORD) - emit_mov_r64_r64(&dst, dstreg, srcp.value); // mov dstreg,srcp + if (sizep.size() == SIZE_BYTE) + emit_movsx_r64_r8(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_WORD) + emit_movsx_r64_r16(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_DWORD) + emit_movsxd_r64_r32(dst, dstreg, srcp.ireg()); // movsxd dstreg,srcp + else if (sizep.size() == SIZE_QWORD) + emit_mov_r64_r64(dst, dstreg, srcp.ireg()); // mov dstreg,srcp } - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (inst->flags != 0) - emit_test_r64_r64(&dst, dstreg, dstreg); // test dstreg,dstreg + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg + if (inst.flags() != 0) + emit_test_r64_r64(dst, dstreg, dstreg); // test dstreg,dstreg } - return dst; } -/*------------------------------------------------- - op_roland - process an ROLAND opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_roland - process an ROLAND opcode +//------------------------------------------------- -static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_roland(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, shiftp, maskp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &shiftp, PTYPE_MRI, &maskp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter shiftp(*this, inst.param(2), PTYPE_MRI); + be_parameter maskp(*this, inst.param(3), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register2(REG_EAX, &dstp, &shiftp, &maskp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, shiftp, maskp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_rol_r32_p32(drcbe, &dst, dstreg, &shiftp, inst); // rol dstreg,shiftp - emit_and_r32_p32(drcbe, &dst, dstreg, &maskp, inst); // and dstreg,maskp - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,srcp + emit_rol_r32_p32(dst, dstreg, shiftp, inst); // rol dstreg,shiftp + emit_and_r32_p32(dst, dstreg, maskp, inst); // and dstreg,maskp + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_rol_r64_p64(drcbe, &dst, dstreg, &shiftp, inst); // rol dstreg,shiftp - emit_and_r64_p64(drcbe, &dst, dstreg, &maskp, inst); // and dstreg,maskp - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, srcp); // mov dstreg,srcp + emit_rol_r64_p64(dst, dstreg, shiftp, inst); // rol dstreg,shiftp + emit_and_r64_p64(dst, dstreg, maskp, inst); // and dstreg,maskp + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_rolins - process an ROLINS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rolins - process an ROLINS opcode +//------------------------------------------------- -static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_rolins(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, shiftp, maskp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &shiftp, PTYPE_MRI, &maskp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter shiftp(*this, inst.param(2), PTYPE_MRI); + be_parameter maskp(*this, inst.param(3), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register2(REG_ECX, &dstp, &shiftp, &maskp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_ECX, shiftp, maskp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &srcp); // mov eax,srcp - emit_rol_r32_p32(drcbe, &dst, REG_EAX, &shiftp, inst); // rol eax,shiftp - emit_mov_r32_p32(drcbe, &dst, dstreg, &dstp); // mov dstreg,dstp - if (maskp.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r32_p32(dst, REG_EAX, srcp); // mov eax,srcp + emit_rol_r32_p32(dst, REG_EAX, shiftp, inst); // rol eax,shiftp + emit_mov_r32_p32(dst, dstreg, dstp); // mov dstreg,dstp + if (maskp.is_immediate()) { - emit_and_r32_imm(&dst, REG_EAX, maskp.value); // and eax,maskp - emit_and_r32_imm(&dst, dstreg, ~maskp.value); // and dstreg,~maskp + emit_and_r32_imm(dst, REG_EAX, maskp.immediate()); // and eax,maskp + emit_and_r32_imm(dst, dstreg, ~maskp.immediate()); // and dstreg,~maskp } else { - emit_mov_r32_p32(drcbe, &dst, REG_EDX, &maskp); // mov edx,maskp - emit_and_r32_r32(&dst, REG_EAX, REG_EDX); // and eax,edx - emit_not_r32(&dst, REG_EDX); // not edx - emit_and_r32_r32(&dst, dstreg, REG_EDX); // and dstreg,edx + emit_mov_r32_p32(dst, REG_EDX, maskp); // mov edx,maskp + emit_and_r32_r32(dst, REG_EAX, REG_EDX); // and eax,edx + emit_not_r32(dst, REG_EDX); // not edx + emit_and_r32_r32(dst, dstreg, REG_EDX); // and dstreg,edx } - emit_or_r32_r32(&dst, dstreg, REG_EAX); // or dstreg,eax - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_or_r32_r32(dst, dstreg, REG_EAX); // or dstreg,eax + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &srcp); // mov rax,srcp - emit_mov_r64_p64(drcbe, &dst, REG_RDX, &maskp); // mov rdx,maskp - emit_rol_r64_p64(drcbe, &dst, REG_RAX, &shiftp, inst); // rol rax,shiftp - emit_mov_r64_p64(drcbe, &dst, dstreg, &dstp); // mov dstreg,dstp - emit_and_r64_r64(&dst, REG_RAX, REG_RDX); // and eax,rdx - emit_not_r64(&dst, REG_RDX); // not rdx - emit_and_r64_r64(&dst, dstreg, REG_RDX); // and dstreg,rdx - emit_or_r64_r64(&dst, dstreg, REG_RAX); // or dstreg,rax - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, REG_RAX, srcp); // mov rax,srcp + emit_mov_r64_p64(dst, REG_RDX, maskp); // mov rdx,maskp + emit_rol_r64_p64(dst, REG_RAX, shiftp, inst); // rol rax,shiftp + emit_mov_r64_p64(dst, dstreg, dstp); // mov dstreg,dstp + emit_and_r64_r64(dst, REG_RAX, REG_RDX); // and eax,rdx + emit_not_r64(dst, REG_RDX); // not rdx + emit_and_r64_r64(dst, dstreg, REG_RDX); // and dstreg,rdx + emit_or_r64_r64(dst, dstreg, REG_RAX); // or dstreg,rax + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_add - process a ADD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_add - process a ADD opcode +//------------------------------------------------- -static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_add(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_add_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // add [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_add_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // add [dstp],src2p - /* reg = reg + imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBD(src1p.value, src2p.value)); // lea dstp,[src1p+src2p] + // reg = reg + imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBD(src1p.ireg(), src2p.immediate())); // lea dstp,[src1p+src2p] - /* reg = reg + reg */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_INT_REGISTER && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBISD(src1p.value, src2p.value, 1, 0)); // lea dstp,[src1p+src2p] + // reg = reg + reg + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_int_register() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBISD(src1p.ireg(), src2p.ireg(), 1, 0));// lea dstp,[src1p+src2p] - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_add_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // add dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_add_r32_p32(dst, dstreg, src2p, inst); // add dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_add_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // add [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_add_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // add [dstp],src2p - /* reg = reg + imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(src2p.value) && inst->flags == 0) - emit_lea_r64_m64(&dst, dstp.value, MBD(src1p.value, src2p.value)); // lea dstp,[src1p+src2p] + // reg = reg + imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && short_immediate(src2p.immediate()) && inst.flags() == 0) + emit_lea_r64_m64(dst, dstp.ireg(), MBD(src1p.ireg(), src2p.immediate())); // lea dstp,[src1p+src2p] - /* reg = reg + reg */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_INT_REGISTER && inst->flags == 0) - emit_lea_r64_m64(&dst, dstp.value, MBISD(src1p.value, src2p.value, 1, 0)); // lea dstp,[src1p+src2p] + // reg = reg + reg + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_int_register() && inst.flags() == 0) + emit_lea_r64_m64(dst, dstp.ireg(), MBISD(src1p.ireg(), src2p.ireg(), 1, 0));// lea dstp,[src1p+src2p] - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_add_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // add dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_add_r64_p64(dst, dstreg, src2p, inst); // add dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_addc - process a ADDC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_addc - process a ADDC opcode +//------------------------------------------------- -static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_addc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_adc_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // adc [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_adc_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // adc [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_adc_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // adc dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_adc_r32_p32(dst, dstreg, src2p, inst); // adc dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_adc_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // adc [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_adc_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // adc [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_adc_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // adc dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_adc_r64_p64(dst, dstreg, src2p, inst); // adc dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_sub - process a SUB opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sub - process a SUB opcode +//------------------------------------------------- -static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_sub(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_sub_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sub [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sub_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sub [dstp],src2p - /* reg = reg - imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBD(src1p.value, -src2p.value)); // lea dstp,[src1p-src2p] + // reg = reg - imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBD(src1p.ireg(), -src2p.immediate())); // lea dstp,[src1p-src2p] - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sub_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sub dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_sub_r32_p32(dst, dstreg, src2p, inst); // sub dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_sub_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sub [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sub_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // sub [dstp],src2p - /* reg = reg - imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(src2p.value) && inst->flags == 0) - emit_lea_r64_m64(&dst, dstp.value, MBD(src1p.value, -src2p.value)); // lea dstp,[src1p-src2p] + // reg = reg - imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && short_immediate(src2p.immediate()) && inst.flags() == 0) + emit_lea_r64_m64(dst, dstp.ireg(), MBD(src1p.ireg(), -src2p.immediate())); // lea dstp,[src1p-src2p] - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sub_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // sub dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_sub_r64_p64(dst, dstreg, src2p, inst); // sub dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_subc - process a SUBC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_subc - process a SUBC opcode +//------------------------------------------------- -static x86code *op_subc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_subc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sbb_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sbb [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sbb_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sbb [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sbb_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sbb dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_sbb_r32_p32(dst, dstreg, src2p, inst); // sbb dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sbb_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sbb [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sbb_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // sbb [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sbb_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // sbb dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_sbb_r64_p64(dst, dstreg, src2p, inst); // sbb dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_cmp - process a CMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_cmp - process a CMP opcode +//------------------------------------------------- -static x86code *op_cmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_cmp(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - int src1reg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MRI); + be_parameter src2p(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - src1reg = param_select_register(REG_EAX, &src1p, NULL); + // pick a target register for the general case + int src1reg = src1p.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* memory versus anything */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_cmp_m32_p32(drcbe, &dst, MABS(drcbe, src1p.value), &src2p, inst); // cmp [dstp],src2p + // memory versus anything + if (src1p.is_memory()) + emit_cmp_m32_p32(dst, MABS(src1p.memory()), src2p, inst); // cmp [dstp],src2p - /* general case */ + // general case else { - if (src1p.type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r32_imm(&dst, src1reg, src1p.value); // mov src1reg,imm - emit_cmp_r32_p32(drcbe, &dst, src1reg, &src2p, inst); // cmp src1reg,src2p + if (src1p.is_immediate()) + emit_mov_r32_imm(dst, src1reg, src1p.immediate()); // mov src1reg,imm + emit_cmp_r32_p32(dst, src1reg, src2p, inst); // cmp src1reg,src2p } } - /* 64-bit form */ + // 64-bit form else { - /* memory versus anything */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_cmp_m64_p64(drcbe, &dst, MABS(drcbe, src1p.value), &src2p, inst); // cmp [dstp],src2p + // memory versus anything + if (src1p.is_memory()) + emit_cmp_m64_p64(dst, MABS(src1p.memory()), src2p, inst); // cmp [dstp],src2p - /* general case */ + // general case else { - if (src1p.type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r64_imm(&dst, src1reg, src1p.value); // mov src1reg,imm - emit_cmp_r64_p64(drcbe, &dst, src1reg, &src2p, inst); // cmp src1reg,src2p + if (src1p.is_immediate()) + emit_mov_r64_imm(dst, src1reg, src1p.immediate()); // mov src1reg,imm + emit_cmp_r64_p64(dst, src1reg, src2p, inst); // cmp src1reg,src2p } } - return dst; } -/*------------------------------------------------- - op_mulu - process a MULU opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mulu - process a MULU opcode +//------------------------------------------------- -static x86code *op_mulu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_mulu(x86code *&dst, const instruction &inst) { - UINT8 zsflags = inst->flags & (DRCUML_FLAG_Z | DRCUML_FLAG_S); - UINT8 vflag = inst->flags & DRCUML_FLAG_V; - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_hi; + UINT8 zsflags = inst.flags() & (FLAG_Z | FLAG_S); + UINT8 vflag = inst.flags() & FLAG_V; - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); - - /* normalize parameters */ - param_normalize_4_commutative(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_hi = (dstp.type != edstp.type || dstp.value != edstp.value); - - /* 32-bit form */ - if (inst->size == 4) - { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_mul_m32(&dst, MABS(drcbe, src2p.value)); // mul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_mul_r32(&dst, src2p.value); // mul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); + + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + normalize_commutative(src1p, src2p); + bool compute_hi = (dstp != edstp); + + // 32-bit form + if (inst.size() == 4) + { + // general case + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_mul_m32(dst, MABS(src2p.memory())); // mul [src2p] + else if (src2p.is_int_register()) + emit_mul_r32(dst, src2p.ireg()); // mul src2p + else if (src2p.is_immediate()) { - emit_mov_r32_imm(&dst, REG_EDX, src2p.value); // mov edx,src2p - emit_mul_r32(&dst, REG_EDX); // mul edx + emit_mov_r32_imm(dst, REG_EDX, src2p.immediate()); // mov edx,src2p + emit_mul_r32(dst, REG_EDX); // mul edx } - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_hi) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (zsflags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax - else if (zsflags == DRCUML_FLAG_S) - emit_test_r32_r32(&dst, REG_EDX, REG_EDX); // test edx,edx + if (zsflags == FLAG_Z) + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax + else if (zsflags == FLAG_S) + emit_test_r32_r32(dst, REG_EDX, REG_EDX); // test edx,edx else { - emit_movzx_r32_r16(&dst, REG_ECX, REG_AX); // movzx ecx,ax - emit_shr_r32_imm(&dst, REG_EAX, 16); // shr eax,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax + emit_movzx_r32_r16(dst, REG_ECX, REG_AX); // movzx ecx,ax + emit_shr_r32_imm(dst, REG_EAX, 16); // shr eax,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax } } else - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_RAX); // pop rax - emit_and_m64_imm(&dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 - emit_or_m64_r64(&dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_RAX); // pop rax + emit_and_m64_imm(dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 + emit_or_m64_r64(dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax + emit_popf(dst); // popf } } } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &src1p); // mov rax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_mul_m64(&dst, MABS(drcbe, src2p.value)); // mul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_mul_r64(&dst, src2p.value); // mul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + // general case + emit_mov_r64_p64(dst, REG_RAX, src1p); // mov rax,src1p + if (src2p.is_memory()) + emit_mul_m64(dst, MABS(src2p.memory())); // mul [src2p] + else if (src2p.is_int_register()) + emit_mul_r64(dst, src2p.ireg()); // mul src2p + else if (src2p.is_immediate()) { - emit_mov_r64_imm(&dst, REG_RDX, src2p.value); // mov rdx,src2p - emit_mul_r64(&dst, REG_RDX); // mul rdx + emit_mov_r64_imm(dst, REG_RDX, src2p.immediate()); // mov rdx,src2p + emit_mul_r64(dst, REG_RDX); // mul rdx } - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax if (compute_hi) - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX); // mov edstp,rdx + emit_mov_p64_r64(dst, edstp, REG_RDX); // mov edstp,rdx - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (zsflags == DRCUML_FLAG_Z) - emit_or_r64_r64(&dst, REG_RDX, REG_RAX); // or rdx,rax - else if (zsflags == DRCUML_FLAG_S) - emit_test_r64_r64(&dst, REG_RDX, REG_RDX); // test rdx,rdx + if (zsflags == FLAG_Z) + emit_or_r64_r64(dst, REG_RDX, REG_RAX); // or rdx,rax + else if (zsflags == FLAG_S) + emit_test_r64_r64(dst, REG_RDX, REG_RDX); // test rdx,rdx else { - emit_mov_r32_r32(&dst, REG_ECX, REG_EAX); // mov ecx,eax - emit_shr_r64_imm(&dst, REG_RAX, 32); // shr rax,32 - emit_or_r64_r64(&dst, REG_RDX, REG_RCX); // or rdx,rcx - emit_or_r64_r64(&dst, REG_RDX, REG_RAX); // or rdx,rax + emit_mov_r32_r32(dst, REG_ECX, REG_EAX); // mov ecx,eax + emit_shr_r64_imm(dst, REG_RAX, 32); // shr rax,32 + emit_or_r64_r64(dst, REG_RDX, REG_RCX); // or rdx,rcx + emit_or_r64_r64(dst, REG_RDX, REG_RAX); // or rdx,rax } } else - emit_test_r64_r64(&dst, REG_RAX, REG_RAX); // test rax,rax + emit_test_r64_r64(dst, REG_RAX, REG_RAX); // test rax,rax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_RAX); // pop rax - emit_and_m64_imm(&dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 - emit_or_m64_r64(&dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_RAX); // pop rax + emit_and_m64_imm(dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 + emit_or_m64_r64(dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax + emit_popf(dst); // popf } } } } - return dst; } -/*------------------------------------------------- - op_muls - process a MULS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_muls - process a MULS opcode +//------------------------------------------------- -static x86code *op_muls(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_muls(x86code *&dst, const instruction &inst) { - UINT8 zsflags = inst->flags & (DRCUML_FLAG_Z | DRCUML_FLAG_S); - UINT8 vflag = inst->flags & DRCUML_FLAG_V; - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_hi; + UINT8 zsflags = inst.flags() & (FLAG_Z | FLAG_S); + UINT8 vflag = inst.flags() & FLAG_V; - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4_commutative(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_hi = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + normalize_commutative(src1p, src2p); + bool compute_hi = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* 32-bit destination with memory/immediate or register/immediate */ - if (!compute_hi && src1p.type != DRCUML_PTYPE_IMMEDIATE && src2p.type == DRCUML_PTYPE_IMMEDIATE) + // 32-bit destination with memory/immediate or register/immediate + if (!compute_hi && !src1p.is_immediate() && src2p.is_immediate()) { - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r32_m32_imm(&dst, REG_EAX, MABS(drcbe, src1p.value), src2p.value); // imul eax,[src1p],src2p - else if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32_r32_imm(&dst, REG_EAX, src1p.value, src2p.value); // imul eax,src1p,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + if (src1p.is_memory()) + emit_imul_r32_m32_imm(dst, REG_EAX, MABS(src1p.memory()), src2p.immediate()); // imul eax,[src1p],src2p + else if (src1p.is_int_register()) + emit_imul_r32_r32_imm(dst, REG_EAX, src1p.ireg(), src2p.immediate()); // imul eax,src1p,src2p + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax } - /* 32-bit destination, general case */ + // 32-bit destination, general case else if (!compute_hi) { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r32_m32(&dst, REG_EAX, MABS(drcbe, src2p.value)); // imul eax,[src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32_r32(&dst, REG_EAX, src2p.value); // imul eax,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_imul_r32_m32(dst, REG_EAX, MABS(src2p.memory())); // imul eax,[src2p] + else if (src2p.is_int_register()) + emit_imul_r32_r32(dst, REG_EAX, src2p.ireg()); // imul eax,src2p + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax } - /* 64-bit destination, general case */ + // 64-bit destination, general case else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_m32(&dst, MABS(drcbe, src2p.value)); // imul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32(&dst, src2p.value); // imul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_imul_m32(dst, MABS(src2p.memory())); // imul [src2p] + else if (src2p.is_int_register()) + emit_imul_r32(dst, src2p.ireg()); // imul src2p + else if (src2p.is_immediate()) { - emit_mov_r32_imm(&dst, REG_EDX, src2p.value); // mov edx,src2p - emit_imul_r32(&dst, REG_EDX); // imul edx + emit_mov_r32_imm(dst, REG_EDX, src2p.immediate()); // mov edx,src2p + emit_imul_r32(dst, REG_EDX); // imul edx } - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx } - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (zsflags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax - else if (zsflags == DRCUML_FLAG_S) - emit_test_r32_r32(&dst, REG_EDX, REG_EDX); // test edx,edx + if (zsflags == FLAG_Z) + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax + else if (zsflags == FLAG_S) + emit_test_r32_r32(dst, REG_EDX, REG_EDX); // test edx,edx else { - emit_movzx_r32_r16(&dst, REG_ECX, REG_AX); // movzx ecx,ax - emit_shr_r32_imm(&dst, REG_EAX, 16); // shr eax,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax + emit_movzx_r32_r16(dst, REG_ECX, REG_AX); // movzx ecx,ax + emit_shr_r32_imm(dst, REG_EAX, 16); // shr eax,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax } } else - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_RAX); // pop rax - emit_and_m64_imm(&dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 - emit_or_m64_r64(&dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_RAX); // pop rax + emit_and_m64_imm(dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 + emit_or_m64_r64(dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax + emit_popf(dst); // popf } } } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* 64-bit destination with memory/immediate or register/immediate */ - if (!compute_hi && src1p.type != DRCUML_PTYPE_IMMEDIATE && src2p.type == DRCUML_PTYPE_IMMEDIATE && short_immediate(src2p.type)) + // 64-bit destination with memory/immediate or register/immediate + if (!compute_hi && !src1p.is_immediate() && src2p.is_immediate() && short_immediate(src2p.immediate())) { - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r64_m64_imm(&dst, REG_RAX, MABS(drcbe, src1p.value), src2p.value);// imul rax,[src1p],src2p - else if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r64_r64_imm(&dst, REG_RAX, src1p.value, src2p.value); // imul rax,src1p,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax + if (src1p.is_memory()) + emit_imul_r64_m64_imm(dst, REG_RAX, MABS(src1p.memory()), src2p.immediate());// imul rax,[src1p],src2p + else if (src1p.is_int_register()) + emit_imul_r64_r64_imm(dst, REG_RAX, src1p.ireg(), src2p.immediate()); // imul rax,src1p,src2p + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax } - /* 64-bit destination, general case */ + // 64-bit destination, general case else if (!compute_hi) { - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &src1p); // mov rax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r64_m64(&dst, REG_RAX, MABS(drcbe, src2p.value)); // imul rax,[src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r64_r64(&dst, REG_RAX, src2p.value); // imul rax,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax + emit_mov_r64_p64(dst, REG_RAX, src1p); // mov rax,src1p + if (src2p.is_memory()) + emit_imul_r64_m64(dst, REG_RAX, MABS(src2p.memory())); // imul rax,[src2p] + else if (src2p.is_int_register()) + emit_imul_r64_r64(dst, REG_RAX, src2p.ireg()); // imul rax,src2p + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax } - /* 128-bit destination, general case */ + // 128-bit destination, general case else { - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &src1p); // mov rax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_m64(&dst, MABS(drcbe, src2p.value)); // imul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r64(&dst, src2p.value); // imul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r64_p64(dst, REG_RAX, src1p); // mov rax,src1p + if (src2p.is_memory()) + emit_imul_m64(dst, MABS(src2p.memory())); // imul [src2p] + else if (src2p.is_int_register()) + emit_imul_r64(dst, src2p.ireg()); // imul src2p + else if (src2p.is_immediate()) { - emit_mov_r64_imm(&dst, REG_RDX, src2p.value); // mov rdx,src2p - emit_imul_r64(&dst, REG_RDX); // imul rdx + emit_mov_r64_imm(dst, REG_RDX, src2p.immediate()); // mov rdx,src2p + emit_imul_r64(dst, REG_RDX); // imul rdx } - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX); // mov edstp,rdx + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax + emit_mov_p64_r64(dst, edstp, REG_RDX); // mov edstp,rdx } - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (zsflags == DRCUML_FLAG_Z) - emit_or_r64_r64(&dst, REG_RDX, REG_RAX); // or rdx,rax - else if (zsflags == DRCUML_FLAG_S) - emit_test_r64_r64(&dst, REG_RDX, REG_RDX); // test rdx,rdx + if (zsflags == FLAG_Z) + emit_or_r64_r64(dst, REG_RDX, REG_RAX); // or rdx,rax + else if (zsflags == FLAG_S) + emit_test_r64_r64(dst, REG_RDX, REG_RDX); // test rdx,rdx else { - emit_mov_r32_r32(&dst, REG_ECX, REG_EAX); // mov ecx,eax - emit_shr_r64_imm(&dst, REG_RAX, 32); // shr rax,32 - emit_or_r64_r64(&dst, REG_RDX, REG_RCX); // or rdx,rcx - emit_or_r64_r64(&dst, REG_RDX, REG_RAX); // or rdx,rax + emit_mov_r32_r32(dst, REG_ECX, REG_EAX); // mov ecx,eax + emit_shr_r64_imm(dst, REG_RAX, 32); // shr rax,32 + emit_or_r64_r64(dst, REG_RDX, REG_RCX); // or rdx,rcx + emit_or_r64_r64(dst, REG_RDX, REG_RAX); // or rdx,rax } } else - emit_test_r64_r64(&dst, REG_RAX, REG_RAX); // test rax,rax + emit_test_r64_r64(dst, REG_RAX, REG_RAX); // test rax,rax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r64(&dst, REG_RAX); // pop rax - emit_and_m64_imm(&dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 - emit_or_m64_r64(&dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r64(dst, REG_RAX); // pop rax + emit_and_m64_imm(dst, MBD(REG_RSP, 0), ~0x84); // and [rsp],~0x84 + emit_or_m64_r64(dst, MBD(REG_RSP, 0), REG_RAX); // or [rsp],rax + emit_popf(dst); // popf } } } } - return dst; } -/*------------------------------------------------- - op_divu - process a DIVU opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_divu - process a DIVU opcode +//------------------------------------------------- -static x86code *op_divu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_divu(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_rem; - emit_link skip; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_rem = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + bool compute_rem = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &src2p); // mov ecx,src2p - if (inst->flags != 0) + // general case + emit_mov_r32_p32(dst, REG_ECX, src2p); // mov ecx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jecxz_link(&dst, &skip); // jecxz skip - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - emit_xor_r32_r32(&dst, REG_EDX, REG_EDX); // xor edx,edx - emit_div_r32(&dst, REG_ECX); // div ecx - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_link skip; + emit_jecxz_link(dst, skip); // jecxz skip + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + emit_xor_r32_r32(dst, REG_EDX, REG_EDX); // xor edx,edx + emit_div_r32(dst, REG_ECX); // div ecx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_rem) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx - if (inst->flags != 0) - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax - resolve_link(&dst, &skip); // skip: + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx + if (inst.flags() != 0) + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax + resolve_link(dst, skip); // skip: } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, REG_RCX, &src2p); // mov rcx,src2p - if (inst->flags != 0) + // general case + emit_mov_r64_p64(dst, REG_RCX, src2p); // mov rcx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jrcxz_link(&dst, &skip); // jrcxz skip - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &src1p); // mov rax,src1p - emit_xor_r32_r32(&dst, REG_EDX, REG_EDX); // xor edx,edx - emit_div_r64(&dst, REG_RCX); // div rcx - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax + emit_link skip; + emit_jrcxz_link(dst, skip); // jrcxz skip + emit_mov_r64_p64(dst, REG_RAX, src1p); // mov rax,src1p + emit_xor_r32_r32(dst, REG_EDX, REG_EDX); // xor edx,edx + emit_div_r64(dst, REG_RCX); // div rcx + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax if (compute_rem) - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX); // mov edstp,rdx - if (inst->flags != 0) - emit_test_r64_r64(&dst, REG_RAX, REG_RAX); // test eax,eax - resolve_link(&dst, &skip); // skip: + emit_mov_p64_r64(dst, edstp, REG_RDX); // mov edstp,rdx + if (inst.flags() != 0) + emit_test_r64_r64(dst, REG_RAX, REG_RAX); // test eax,eax + resolve_link(dst, skip); // skip: } - return dst; } -/*------------------------------------------------- - op_divs - process a DIVS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_divs - process a DIVS opcode +//------------------------------------------------- -static x86code *op_divs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_divs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_rem; - emit_link skip; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_rem = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + bool compute_rem = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &src2p); // mov ecx,src2p - if (inst->flags != 0) + // general case + emit_mov_r32_p32(dst, REG_ECX, src2p); // mov ecx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jecxz_link(&dst, &skip); // jecxz skip - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - emit_cdq(&dst); // cdq - emit_idiv_r32(&dst, REG_ECX); // idiv ecx - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_link skip; + emit_jecxz_link(dst, skip); // jecxz skip + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + emit_cdq(dst); // cdq + emit_idiv_r32(dst, REG_ECX); // idiv ecx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_rem) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx - if (inst->flags != 0) - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax - resolve_link(&dst, &skip); // skip: + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx + if (inst.flags() != 0) + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax + resolve_link(dst, skip); // skip: } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, REG_RCX, &src2p); // mov rcx,src2p - if (inst->flags != 0) + // general case + emit_mov_r64_p64(dst, REG_RCX, src2p); // mov rcx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jrcxz_link(&dst, &skip); // jrcxz skip - emit_mov_r64_p64(drcbe, &dst, REG_RAX, &src1p); // mov rax,src1p - emit_cqo(&dst); // cqo - emit_idiv_r64(&dst, REG_RCX); // idiv rcx - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_RAX); // mov dstp,rax + emit_link skip; + emit_jrcxz_link(dst, skip); // jrcxz skip + emit_mov_r64_p64(dst, REG_RAX, src1p); // mov rax,src1p + emit_cqo(dst); // cqo + emit_idiv_r64(dst, REG_RCX); // idiv rcx + emit_mov_p64_r64(dst, dstp, REG_RAX); // mov dstp,rax if (compute_rem) - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_RDX); // mov edstp,rdx - if (inst->flags != 0) - emit_test_r64_r64(&dst, REG_RAX, REG_RAX); // test eax,eax - resolve_link(&dst, &skip); // skip: + emit_mov_p64_r64(dst, edstp, REG_RDX); // mov edstp,rdx + if (inst.flags() != 0) + emit_test_r64_r64(dst, REG_RAX, REG_RAX); // test eax,eax + resolve_link(dst, skip); // skip: } - return dst; } -/*------------------------------------------------- - op_and - process a AND opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_and - process a AND opcode +//------------------------------------------------- -static x86code *op_and(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_and(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_and_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // and [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_and_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // and [dstp],src2p - /* AND with immediate 0xff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xff && inst->flags == 0) + // AND with immediate 0xff + else if (src2p.is_immediate_value(0xff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r8(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m8(&dst, dstreg, MABS(drcbe, src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r8(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m8(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* AND with immediate 0xffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffff && inst->flags == 0) + // AND with immediate 0xffff + else if (src2p.is_immediate_value(0xffff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r16(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m16(&dst, dstreg, MABS(drcbe, src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r16(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m16(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_and_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // and dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_and_r32_p32(dst, dstreg, src2p, inst); // and dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_and_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // and [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_and_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // and [dstp],src2p - /* AND with immediate 0xff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xff && inst->flags == 0) + // AND with immediate 0xff + else if (src2p.is_immediate_value(0xff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r8(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m8(&dst, dstreg, MABS(drcbe, src1p.value)); // movzx dstreg,[src1p] - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r8(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m8(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - /* AND with immediate 0xffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffff && inst->flags == 0) + // AND with immediate 0xffff + else if (src2p.is_immediate_value(0xffff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r16(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m16(&dst, dstreg, MABS(drcbe, src1p.value)); // movzx dstreg,[src1p] - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r16(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m16(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - /* AND with immediate 0xffffffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffffffff && inst->flags == 0) + // AND with immediate 0xffffffff + else if (src2p.is_immediate_value(0xffffffff) && inst.flags() == 0) { - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_r32_r32(&dst, dstreg, dstreg); // mov dstreg,dstreg + if (dstp.is_int_register() && src1p == dstp) + emit_mov_r32_r32(dst, dstreg, dstreg); // mov dstreg,dstreg else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_and_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // and dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_and_r64_p64(dst, dstreg, src2p, inst); // and dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_test - process a TEST opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_test - process a TEST opcode +//------------------------------------------------- -static x86code *op_test(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_test(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - int src1reg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2_commutative(drcbe, inst, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MRI); + be_parameter src2p(*this, inst.param(1), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - src1reg = param_select_register(REG_EAX, &src1p, NULL); + // pick a target register for the general case + int src1reg = src1p.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* src1p in memory */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_test_m32_p32(drcbe, &dst, MABS(drcbe, src1p.value), &src2p, inst); // test [src1p],src2p + // src1p in memory + if (src1p.is_memory()) + emit_test_m32_p32(dst, MABS(src1p.memory()), src2p, inst); // test [src1p],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, src1reg, &src1p); // mov src1reg,src1p - emit_test_r32_p32(drcbe, &dst, src1reg, &src2p, inst); // test src1reg,src2p + emit_mov_r32_p32(dst, src1reg, src1p); // mov src1reg,src1p + emit_test_r32_p32(dst, src1reg, src2p, inst); // test src1reg,src2p } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* src1p in memory */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_test_m64_p64(drcbe, &dst, MABS(drcbe, src1p.value), &src2p, inst); // test [src1p],src2p + // src1p in memory + if (src1p.is_memory()) + emit_test_m64_p64(dst, MABS(src1p.memory()), src2p, inst); // test [src1p],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, src1reg, &src1p); // mov src1reg,src1p - emit_test_r64_p64(drcbe, &dst, src1reg, &src2p, inst); // test src1reg,src2p + emit_mov_r64_p64(dst, src1reg, src1p); // mov src1reg,src1p + emit_test_r64_p64(dst, src1reg, src2p, inst); // test src1reg,src2p } } - return dst; } -/*------------------------------------------------- - op_or - process a OR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_or - process a OR opcode +//------------------------------------------------- -static x86code *op_or(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_or(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_or_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // or [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_or_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // or [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_or_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // or dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_or_r32_p32(dst, dstreg, src2p, inst); // or dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_or_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // or [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_or_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // or [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_or_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // or dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_or_r64_p64(dst, dstreg, src2p, inst); // or dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_xor - process a XOR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_xor - process a XOR opcode +//------------------------------------------------- -static x86code *op_xor(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_xor(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_xor_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // xor [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_xor_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // xor [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_xor_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // xor dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_xor_r32_p32(dst, dstreg, src2p, inst); // xor dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_xor_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // xor [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_xor_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // xor [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_xor_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // xor dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_xor_r64_p64(dst, dstreg, src2p, inst); // xor dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_lzcnt - process a LZCNT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_lzcnt - process a LZCNT opcode +//------------------------------------------------- -static x86code *op_lzcnt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_lzcnt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_mov_r32_imm(&dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 - emit_bsr_r32_r32(&dst, dstreg, dstreg); // bsr dstreg,dstreg - emit_cmovcc_r32_r32(&dst, COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx - emit_xor_r32_imm(&dst, dstreg, 31); // xor dstreg,31 - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,src1p + emit_mov_r32_imm(dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 + emit_bsr_r32_r32(dst, dstreg, dstreg); // bsr dstreg,dstreg + emit_cmovcc_r32_r32(dst, x64emit::COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx + emit_xor_r32_imm(dst, dstreg, 31); // xor dstreg,31 + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_mov_r64_imm(&dst, REG_RCX, 64 ^ 63); // mov rcx,64 ^ 63 - emit_bsr_r64_r64(&dst, dstreg, dstreg); // bsr dstreg,dstreg - emit_cmovcc_r64_r64(&dst, COND_Z, dstreg, REG_RCX); // cmovz dstreg,rcx - emit_xor_r32_imm(&dst, dstreg, 63); // xor dstreg,63 - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, srcp); // mov dstreg,src1p + emit_mov_r64_imm(dst, REG_RCX, 64 ^ 63); // mov rcx,64 ^ 63 + emit_bsr_r64_r64(dst, dstreg, dstreg); // bsr dstreg,dstreg + emit_cmovcc_r64_r64(dst, x64emit::COND_Z, dstreg, REG_RCX); // cmovz dstreg,rcx + emit_xor_r32_imm(dst, dstreg, 63); // xor dstreg,63 + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_bswap - process a BSWAP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_bswap - process a BSWAP opcode +//------------------------------------------------- -static x86code *op_bswap(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_bswap(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_RAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_RAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_bswap_r32(&dst, dstreg); // bswap dstreg - if (inst->flags != 0) - emit_test_r32_r32(&dst, dstreg, dstreg); // test dstreg,dstreg - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,src1p + emit_bswap_r32(dst, dstreg); // bswap dstreg + if (inst.flags() != 0) + emit_test_r32_r32(dst, dstreg, dstreg); // test dstreg,dstreg + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_bswap_r64(&dst, dstreg); // bswap dstreg - if (inst->flags != 0) - emit_test_r64_r64(&dst, dstreg, dstreg); // test dstreg,dstreg - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, srcp); // mov dstreg,src1p + emit_bswap_r64(dst, dstreg); // bswap dstreg + if (inst.flags() != 0) + emit_test_r64_r64(dst, dstreg, dstreg); // test dstreg,dstreg + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_shl - process a SHL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_shl - process a SHL opcode +//------------------------------------------------- -static x86code *op_shl(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_shl(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shl_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // shl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shl_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // shl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shl_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // shl dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_shl_r32_p32(dst, dstreg, src2p, inst); // shl dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shl_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // shl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shl_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // shl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shl_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // shl dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_shl_r64_p64(dst, dstreg, src2p, inst); // shl dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_shr - process a SHR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_shr - process a SHR opcode +//------------------------------------------------- -static x86code *op_shr(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_shr(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shr_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // shr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shr_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // shr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shr_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // shr dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_shr_r32_p32(dst, dstreg, src2p, inst); // shr dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shr_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // shr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shr_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // shr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shr_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // shr dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_shr_r64_p64(dst, dstreg, src2p, inst); // shr dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_sar - process a SAR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sar - process a SAR opcode +//------------------------------------------------- -static x86code *op_sar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_sar(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sar_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sar [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sar_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sar [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sar_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sar dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_sar_r32_p32(dst, dstreg, src2p, inst); // sar dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sar_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // sar [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sar_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // sar [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sar_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // sar dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_sar_r64_p64(dst, dstreg, src2p, inst); // sar dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_rol - process a rol opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rol - process a rol opcode +//------------------------------------------------- -static x86code *op_rol(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_rol(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rol_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rol [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rol_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rol [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rol_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rol dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_rol_r32_p32(dst, dstreg, src2p, inst); // rol dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rol_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rol [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rol_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // rol [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rol_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // rol dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_rol_r64_p64(dst, dstreg, src2p, inst); // rol dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_ror - process a ROR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ror - process a ROR opcode +//------------------------------------------------- -static x86code *op_ror(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_ror(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_ror_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // ror [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_ror_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // ror [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_ror_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // ror dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_ror_r32_p32(dst, dstreg, src2p, inst); // ror dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_ror_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // ror [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_ror_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // ror [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_ror_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // ror dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64(dst, dstreg, src1p); // mov dstreg,src1p + emit_ror_r64_p64(dst, dstreg, src2p, inst); // ror dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_rolc - process a ROLC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rolc - process a ROLC opcode +//------------------------------------------------- -static x86code *op_rolc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_rolc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcl_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rcl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcl_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rcl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcl_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rcl dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcl_r32_p32(dst, dstreg, src2p, inst); // rcl dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcl_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rcl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcl_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // rcl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcl_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // rcl dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcl_r64_p64(dst, dstreg, src2p, inst); // rcl dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } -/*------------------------------------------------- - op_rorc - process a RORC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rorc - process a RORC opcode +//------------------------------------------------- -static x86code *op_rorc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_rorc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcr_m32_p32(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rcr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcr_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rcr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcr_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rcr dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcr_r32_p32(dst, dstreg, src2p, inst); // rcr dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcr_m64_p64(drcbe, &dst, MABS(drcbe, dstp.value), &src2p, inst); // rcr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcr_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // rcr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcr_r64_p64(drcbe, &dst, dstreg, &src2p, inst); // rcr dstreg,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r64_p64_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcr_r64_p64(dst, dstreg, src2p, inst); // rcr dstreg,src2p + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg } } - return dst; } @@ -6204,1016 +5753,981 @@ static x86code *op_rorc(drcbe_state *drcbe, x86code *dst, const drcuml_instructi FLOATING POINT OPERATIONS ***************************************************************************/ -/*------------------------------------------------- - op_fload - process a FLOAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fload - process a FLOAD opcode +//------------------------------------------------- -static x86code *op_fload(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fload(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp; - int basereg, dstreg; - INT32 baseoffs; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &basep, PTYPE_M, &indp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* determine the pointer base */ - basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs); + // determine the pointer base + INT32 baseoffs; + int basereg = get_base_register_and_offset(dst, basep.memory(), REG_RDX, baseoffs); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - emit_movss_r128_m32(&dst, dstreg, MBD(basereg, baseoffs + 4*indp.value)); // movss dstreg,[basep + 4*indp] + if (indp.is_immediate()) + emit_movss_r128_m32(dst, dstreg, MBD(basereg, baseoffs + 4*indp.immediate())); // movss dstreg,[basep + 4*indp] else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp - emit_movss_r128_m32(&dst, dstreg, MBISD(basereg, indreg, 4, baseoffs)); // movss dstreg,[basep + 4*indp] + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); // mov indreg,indp + emit_movss_r128_m32(dst, dstreg, MBISD(basereg, indreg, 4, baseoffs)); // movss dstreg,[basep + 4*indp] } - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - emit_movsd_r128_m64(&dst, dstreg, MBD(basereg, baseoffs + 8*indp.value)); // movsd dstreg,[basep + 8*indp] + if (indp.is_immediate()) + emit_movsd_r128_m64(dst, dstreg, MBD(basereg, baseoffs + 8*indp.immediate())); // movsd dstreg,[basep + 8*indp] else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp - emit_movsd_r128_m64(&dst, dstreg, MBISD(basereg, indreg, 8, baseoffs)); // movsd dstreg,[basep + 8*indp] + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); // mov indreg,indp + emit_movsd_r128_m64(dst, dstreg, MBISD(basereg, indreg, 8, baseoffs)); // movsd dstreg,[basep + 8*indp] } - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fstore - process a FSTORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fstore - process a FSTORE opcode +//------------------------------------------------- -static x86code *op_fstore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fstore(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, basep, indp; - int basereg, srcreg; - INT32 baseoffs; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MF); + // normalize parameters + be_parameter basep(*this, inst.param(0), PTYPE_M); + be_parameter indp(*this, inst.param(1), PTYPE_MRI); + be_parameter srcp(*this, inst.param(2), PTYPE_MF); - /* pick a target register for the general case */ - srcreg = param_select_register(REG_XMM0, &srcp, NULL); + // pick a target register for the general case + int srcreg = srcp.select_register(REG_XMM0); - /* determine the pointer base */ - basereg = get_base_register_and_offset(drcbe, &dst, basep.value, REG_RDX, &baseoffs); + // determine the pointer base + INT32 baseoffs; + int basereg = get_base_register_and_offset(dst, basep.memory(), REG_RDX, baseoffs); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, srcreg, &srcp); // movss srcreg,srcp - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - emit_movss_m32_r128(&dst, MBD(basereg, baseoffs + 4*indp.value), srcreg); // movss [basep + 4*indp],srcreg + emit_movss_r128_p32(dst, srcreg, srcp); // movss srcreg,srcp + if (indp.is_immediate()) + emit_movss_m32_r128(dst, MBD(basereg, baseoffs + 4*indp.immediate()), srcreg); // movss [basep + 4*indp],srcreg else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp - emit_movss_m32_r128(&dst, MBISD(basereg, indreg, 4, baseoffs), srcreg); // movss [basep + 4*indp],srcreg + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); // mov indreg,indp + emit_movss_m32_r128(dst, MBISD(basereg, indreg, 4, baseoffs), srcreg); // movss [basep + 4*indp],srcreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, srcreg, &srcp); // movsd srcreg,srcp - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - emit_movsd_m64_r128(&dst, MBD(basereg, baseoffs + 8*indp.value), srcreg); // movsd [basep + 8*indp],srcreg + emit_movsd_r128_p64(dst, srcreg, srcp); // movsd srcreg,srcp + if (indp.is_immediate()) + emit_movsd_m64_r128(dst, MBD(basereg, baseoffs + 8*indp.immediate()), srcreg); // movsd [basep + 8*indp],srcreg else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp - emit_movsd_m64_r128(&dst, MBISD(basereg, indreg, 8, baseoffs), srcreg); // movsd [basep + 8*indp],srcreg + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); // mov indreg,indp + emit_movsd_m64_r128(dst, MBISD(basereg, indreg, 8, baseoffs), srcreg); // movsd [basep + 8*indp],srcreg } } - return dst; } -/*------------------------------------------------- - op_fread - process a FREAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fread - process a FREAD opcode +//------------------------------------------------- -static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fread(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, spacep, addrp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &addrp, PTYPE_MRI, &spacep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacep = inst.param(2); + assert(spacep.is_size_space()); + assert((1 << spacep.size()) == inst.size()); - /* set up a call to the read dword/qword handler */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacep.value])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param2,addrp - if (inst->size == 4) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_dword);// call read_dword - else if (inst->size == 8) - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].read_qword);// call read_qword + // set up a call to the read dword/qword handler + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param2,addrp + if (inst.size() == 4) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacep.space()].read_dword); // call read_dword + else if (inst.size() == 8) + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacep.space()].read_qword); // call read_qword - /* store result */ - if (inst->size == 4) + // store result + if (inst.size() == 4) { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(&dst, MABS(drcbe, dstp.value), REG_EAX); // mov [dstp],eax - else if (dstp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_movd_r128_r32(&dst, dstp.value, REG_EAX); // movd dstp,eax + if (dstp.is_memory()) + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax + else if (dstp.is_float_register()) + emit_movd_r128_r32(dst, dstp.freg(), REG_EAX); // movd dstp,eax } - else if (inst->size == 8) + else if (inst.size() == 8) { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m64_r64(&dst, MABS(drcbe, dstp.value), REG_RAX); // mov [dstp],rax - else if (dstp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_movq_r128_r64(&dst, dstp.value, REG_RAX); // movq dstp,rax + if (dstp.is_memory()) + emit_mov_m64_r64(dst, MABS(dstp.memory()), REG_RAX); // mov [dstp],rax + else if (dstp.is_float_register()) + emit_movq_r128_r64(dst, dstp.freg(), REG_RAX); // movq dstp,rax } - return dst; } -/*------------------------------------------------- - op_fwrite - process a FWRITE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fwrite - process a FWRITE opcode +//------------------------------------------------- -static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fwrite(x86code *&dst, const instruction &inst) { - drcuml_parameter spacep, addrp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MF, &spacep, PTYPE_I); + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &spacep = inst.param(2); + assert(spacep.is_size_space()); + assert((1 << spacep.size()) == inst.size()); - /* general case */ - emit_mov_r64_imm(&dst, REG_PARAM1, (FPTR)(drcbe->space[spacep.value])); // mov param1,space - emit_mov_r32_p32(drcbe, &dst, REG_PARAM2, &addrp); // mov param21,addrp + // general case + emit_mov_r64_imm(dst, REG_PARAM1, (FPTR)(m_space[spacep.space()])); // mov param1,space + emit_mov_r32_p32(dst, REG_PARAM2, addrp); // mov param21,addrp - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_mov_r32_m32(&dst, REG_PARAM3, MABS(drcbe, srcp.value)); // mov param3,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_movd_r32_r128(&dst, REG_PARAM3, srcp.value); // movd param3,srcp - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_dword);// call write_dword + if (srcp.is_memory()) + emit_mov_r32_m32(dst, REG_PARAM3, MABS(srcp.memory())); // mov param3,[srcp] + else if (srcp.is_float_register()) + emit_movd_r32_r128(dst, REG_PARAM3, srcp.freg()); // movd param3,srcp + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacep.space()].write_dword); // call write_dword } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_mov_r64_m64(&dst, REG_PARAM3, MABS(drcbe, srcp.value)); // mov param3,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_movq_r64_r128(&dst, REG_PARAM3, srcp.value); // movq param3,srcp - emit_smart_call_m64(drcbe, &dst, (x86code **)&drcbe->accessors[spacep.value].write_qword);// call write_qword + if (srcp.is_memory()) + emit_mov_r64_m64(dst, REG_PARAM3, MABS(srcp.memory())); // mov param3,[srcp] + else if (srcp.is_float_register()) + emit_movq_r64_r128(dst, REG_PARAM3, srcp.freg()); // movq param3,srcp + emit_smart_call_m64(dst, (x86code **)&m_accessors[spacep.space()].write_qword); // call write_qword } - - return dst; } -/*------------------------------------------------- - op_fmov - process a FMOV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fmov - process a FMOV opcode +//------------------------------------------------- -static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fmov(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - emit_link skip = { 0 }; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* always start with a jmp */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // always start with a jmp + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &srcp); // movss dstreg,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, srcp); // movss dstreg,srcp + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &srcp); // movsd dstreg,srcp - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, srcp); // movsd dstreg,srcp + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - /* resolve the jump */ - if (inst->condition != DRCUML_COND_ALWAYS) - resolve_link(&dst, &skip); // skip: - return dst; + // resolve the jump + if (inst.condition() != uml::COND_ALWAYS) + resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_ftoint - process a FTOINT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ftoint - process a FTOINT opcode +//------------------------------------------------- -static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_ftoint(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep, roundp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF, &sizep, PTYPE_I, &roundp, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); + const parameter &roundp = inst.param(3); + assert(roundp.is_rounding()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set rounding mode if necessary */ - if (roundp.value != DRCUML_FMOD_DEFAULT && roundp.value != DRCUML_FMOD_TRUNC) + // set rounding mode if necessary + if (roundp.rounding() != ROUND_DEFAULT && roundp.rounding() != ROUND_TRUNC) { - emit_stmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // stmxcsr [ssemodesave] - emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssecontrol[roundp.value])); // ldmxcsr fpcontrol[mode] + emit_stmxcsr_m32(dst, MABS(&m_near.ssemodesave)); // stmxcsr [ssemodesave] + emit_ldmxcsr_m32(dst, MABS(&m_near.ssecontrol[roundp.rounding()])); // ldmxcsr fpcontrol[mode] } - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* 32-bit integer source */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 32-bit integer source + if (sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) + if (srcp.is_memory()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp] + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtss2si_r32_m32(dst, dstreg, MABS(srcp.memory())); // cvtss2si dstreg,[srcp] else - emit_cvttss2si_r32_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvttss2si dstreg,[srcp] + emit_cvttss2si_r32_m32(dst, dstreg, MABS(srcp.memory())); // cvttss2si dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) + else if (srcp.is_float_register()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtss2si_r32_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtss2si_r32_r128(dst, dstreg, srcp.freg()); // cvtss2si dstreg,srcp else - emit_cvttss2si_r32_r128(&dst, dstreg, srcp.value); // cvttss2si dstreg,srcp + emit_cvttss2si_r32_r128(dst, dstreg, srcp.freg()); // cvttss2si dstreg,srcp } } - /* 64-bit integer source */ - else if (sizep.value == DRCUML_SIZE_QWORD) + // 64-bit integer source + else if (sizep.size() == SIZE_QWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) + if (srcp.is_memory()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2si dstreg,[srcp] + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtss2si_r64_m32(dst, dstreg, MABS(srcp.memory())); // cvtss2si dstreg,[srcp] else - emit_cvttss2si_r64_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvttss2si dstreg,[srcp] + emit_cvttss2si_r64_m32(dst, dstreg, MABS(srcp.memory())); // cvttss2si dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) + else if (srcp.is_float_register()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtss2si_r64_r128(&dst, dstreg, srcp.value); // cvtss2si dstreg,srcp + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtss2si_r64_r128(dst, dstreg, srcp.freg()); // cvtss2si dstreg,srcp else - emit_cvttss2si_r64_r128(&dst, dstreg, srcp.value); // cvttss2si dstreg,srcp + emit_cvttss2si_r64_r128(dst, dstreg, srcp.freg()); // cvttss2si dstreg,srcp } } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* 32-bit integer source */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 32-bit integer source + if (sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) + if (srcp.is_memory()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp] + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtsd2si_r32_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2si dstreg,[srcp] else - emit_cvttsd2si_r32_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvttsd2si dstreg,[srcp] + emit_cvttsd2si_r32_m64(dst, dstreg, MABS(srcp.memory())); // cvttsd2si dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) + else if (srcp.is_float_register()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtsd2si_r32_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtsd2si_r32_r128(dst, dstreg, srcp.freg()); // cvtsd2si dstreg,srcp else - emit_cvttsd2si_r32_r128(&dst, dstreg, srcp.value); // cvttsd2si dstreg,srcp + emit_cvttsd2si_r32_r128(dst, dstreg, srcp.freg()); // cvttsd2si dstreg,srcp } } - /* 64-bit integer source */ - else if (sizep.value == DRCUML_SIZE_QWORD) + // 64-bit integer source + else if (sizep.size() == SIZE_QWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) + if (srcp.is_memory()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2si dstreg,[srcp] + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtsd2si_r64_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2si dstreg,[srcp] else - emit_cvttsd2si_r64_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvttsd2si dstreg,[srcp] + emit_cvttsd2si_r64_m64(dst, dstreg, MABS(srcp.memory())); // cvttsd2si dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) + else if (srcp.is_float_register()) { - if (roundp.value != DRCUML_FMOD_TRUNC) - emit_cvtsd2si_r64_r128(&dst, dstreg, srcp.value); // cvtsd2si dstreg,srcp + if (roundp.rounding() != ROUND_TRUNC) + emit_cvtsd2si_r64_r128(dst, dstreg, srcp.freg()); // cvtsd2si dstreg,srcp else - emit_cvttsd2si_r64_r128(&dst, dstreg, srcp.value); // cvttsd2si dstreg,srcp + emit_cvttsd2si_r64_r128(dst, dstreg, srcp.freg()); // cvttsd2si dstreg,srcp } } } - /* general case */ - if (sizep.value == DRCUML_SIZE_DWORD) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // general case + if (sizep.size() == SIZE_DWORD) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg else - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - - /* restore rounding mode */ - if (roundp.value != DRCUML_FMOD_DEFAULT && roundp.value != DRCUML_FMOD_TRUNC) - emit_ldmxcsr_m32(&dst, MABS(drcbe, &drcbe->ssemodesave)); // ldmxcsr [ssemodesave] + emit_mov_p64_r64(dst, dstp, dstreg); // mov dstp,dstreg - return dst; + // restore rounding mode + if (roundp.rounding() != ROUND_DEFAULT && roundp.rounding() != ROUND_TRUNC) + emit_ldmxcsr_m32(dst, MABS(&m_near.ssemodesave)); // ldmxcsr [ssemodesave] } -/*------------------------------------------------- - op_ffrint - process a FFRINT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ffrint - process a FFRINT opcode +//------------------------------------------------- -static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_ffrint(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI, &sizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* 32-bit integer source */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 32-bit integer source + if (sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsi2ss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsi2ss dstreg,[srcp] + if (srcp.is_memory()) + emit_cvtsi2ss_r128_m32(dst, dstreg, MABS(srcp.memory())); // cvtsi2ss dstreg,[srcp] else { - int srcreg = param_select_register(REG_EAX, &srcp, NULL); - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp - emit_cvtsi2ss_r128_r32(&dst, dstreg, srcreg); // cvtsi2ss dstreg,srcreg + int srcreg = srcp.select_register(REG_EAX); + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp + emit_cvtsi2ss_r128_r32(dst, dstreg, srcreg); // cvtsi2ss dstreg,srcreg } } - /* 64-bit integer source */ + // 64-bit integer source else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsi2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsi2ss dstreg,[srcp] + if (srcp.is_memory()) + emit_cvtsi2ss_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsi2ss dstreg,[srcp] else { - int srcreg = param_select_register(REG_RAX, &srcp, NULL); - emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp - emit_cvtsi2ss_r128_r64(&dst, dstreg, srcreg); // cvtsi2ss dstreg,srcreg + int srcreg = srcp.select_register(REG_RAX); + emit_mov_r64_p64(dst, srcreg, srcp); // mov srcreg,srcp + emit_cvtsi2ss_r128_r64(dst, dstreg, srcreg); // cvtsi2ss dstreg,srcreg } } - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* 32-bit integer source */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 32-bit integer source + if (sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsi2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsi2sd dstreg,[srcp] + if (srcp.is_memory()) + emit_cvtsi2sd_r128_m32(dst, dstreg, MABS(srcp.memory())); // cvtsi2sd dstreg,[srcp] else { - int srcreg = param_select_register(REG_EAX, &srcp, NULL); - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp - emit_cvtsi2sd_r128_r32(&dst, dstreg, srcreg); // cvtsi2sd dstreg,srcreg + int srcreg = srcp.select_register(REG_EAX); + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp + emit_cvtsi2sd_r128_r32(dst, dstreg, srcreg); // cvtsi2sd dstreg,srcreg } } - /* 64-bit integer source */ + // 64-bit integer source else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsi2sd_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsi2sd dstreg,[srcp] + if (srcp.is_memory()) + emit_cvtsi2sd_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsi2sd dstreg,[srcp] else { - int srcreg = param_select_register(REG_EAX, &srcp, NULL); - emit_mov_r64_p64(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp - emit_cvtsi2sd_r128_r64(&dst, dstreg, srcreg); // cvtsi2sd dstreg,srcreg + int srcreg = srcp.select_register(REG_EAX); + emit_mov_r64_p64(dst, srcreg, srcp); // mov srcreg,srcp + emit_cvtsi2sd_r128_r64(dst, dstreg, srcreg); // cvtsi2sd dstreg,srcreg } } - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_ffrflt - process a FFRFLT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ffrflt - process a FFRFLT opcode +//------------------------------------------------- -static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_ffrflt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF, &sizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* single-to-double */ - if (inst->size == 8 && sizep.value == DRCUML_SIZE_DWORD) + // single-to-double + if (inst.size() == 8 && sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtss2sd_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtss2sd dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_cvtss2sd_r128_r128(&dst, dstreg, srcp.value); // cvtss2sd dstreg,srcp - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + if (srcp.is_memory()) + emit_cvtss2sd_r128_m32(dst, dstreg, MABS(srcp.memory())); // cvtss2sd dstreg,[srcp] + else if (srcp.is_float_register()) + emit_cvtss2sd_r128_r128(dst, dstreg, srcp.freg()); // cvtss2sd dstreg,srcp + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - /* double-to-single */ - else if (inst->size == 4 && sizep.value == DRCUML_SIZE_QWORD) + // double-to-single + else if (inst.size() == 4 && sizep.size() == SIZE_QWORD) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2ss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value); // cvtsd2ss dstreg,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + if (srcp.is_memory()) + emit_cvtsd2ss_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2ss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_cvtsd2ss_r128_r128(dst, dstreg, srcp.freg()); // cvtsd2ss dstreg,srcp + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_frnds - process a FRNDS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frnds - process a FRNDS opcode +//------------------------------------------------- -static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_frnds(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 8); + // validate instruction + assert(inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* 64-bit form */ - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2ss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value); // cvtsd2ss dstreg,srcp - emit_cvtss2sd_r128_r128(&dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg - return dst; + // 64-bit form + if (srcp.is_memory()) + emit_cvtsd2ss_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2ss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_cvtsd2ss_r128_r128(dst, dstreg, srcp.freg()); // cvtsd2ss dstreg,srcp + emit_cvtss2sd_r128_r128(dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } -/*------------------------------------------------- - op_fadd - process a FADD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fadd - process a FADD opcode +//------------------------------------------------- -static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fadd(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &src1p); // movss dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_addss_r128_m32(&dst, dstreg, MABS(drcbe, src2p.value)); // addss dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_addss_r128_r128(&dst, dstreg, src2p.value); // addss dstreg,src2p - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, src1p); // movss dstreg,src1p + if (src2p.is_memory()) + emit_addss_r128_m32(dst, dstreg, MABS(src2p.memory())); // addss dstreg,[src2p] + else if (src2p.is_float_register()) + emit_addss_r128_r128(dst, dstreg, src2p.freg()); // addss dstreg,src2p + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &src1p); // movsd dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_addsd_r128_m64(&dst, dstreg, MABS(drcbe, src2p.value)); // addsd dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_addsd_r128_r128(&dst, dstreg, src2p.value); // addsd dstreg,src2p - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, src1p); // movsd dstreg,src1p + if (src2p.is_memory()) + emit_addsd_r128_m64(dst, dstreg, MABS(src2p.memory())); // addsd dstreg,[src2p] + else if (src2p.is_float_register()) + emit_addsd_r128_r128(dst, dstreg, src2p.freg()); // addsd dstreg,src2p + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fsub - process a FSUB opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fsub - process a FSUB opcode +//------------------------------------------------- -static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fsub(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &src1p); // movss dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_subss_r128_m32(&dst, dstreg, MABS(drcbe, src2p.value)); // subss dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_subss_r128_r128(&dst, dstreg, src2p.value); // subss dstreg,src2p - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, src1p); // movss dstreg,src1p + if (src2p.is_memory()) + emit_subss_r128_m32(dst, dstreg, MABS(src2p.memory())); // subss dstreg,[src2p] + else if (src2p.is_float_register()) + emit_subss_r128_r128(dst, dstreg, src2p.freg()); // subss dstreg,src2p + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &src1p); // movsd dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_subsd_r128_m64(&dst, dstreg, MABS(drcbe, src2p.value)); // subsd dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_subsd_r128_r128(&dst, dstreg, src2p.value); // subsd dstreg,src2p - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, src1p); // movsd dstreg,src1p + if (src2p.is_memory()) + emit_subsd_r128_m64(dst, dstreg, MABS(src2p.memory())); // subsd dstreg,[src2p] + else if (src2p.is_float_register()) + emit_subsd_r128_r128(dst, dstreg, src2p.freg()); // subsd dstreg,src2p + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fcmp - process a FCMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fcmp - process a FCMP opcode +//------------------------------------------------- -static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fcmp(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - int src1reg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_U); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MF); + be_parameter src2p(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - src1reg = param_select_register(REG_XMM0, &src1p, NULL); + // pick a target register for the general case + int src1reg = src1p.select_register(REG_XMM0); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, src1reg, &src1p); // movss src1reg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_comiss_r128_m32(&dst, src1reg, MABS(drcbe, src2p.value)); // comiss src1reg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_comiss_r128_r128(&dst, src1reg, src2p.value); // comiss src1reg,src2p + emit_movss_r128_p32(dst, src1reg, src1p); // movss src1reg,src1p + if (src2p.is_memory()) + emit_comiss_r128_m32(dst, src1reg, MABS(src2p.memory())); // comiss src1reg,[src2p] + else if (src2p.is_float_register()) + emit_comiss_r128_r128(dst, src1reg, src2p.freg()); // comiss src1reg,src2p } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, src1reg, &src1p); // movsd src1reg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_comisd_r128_m64(&dst, src1reg, MABS(drcbe, src2p.value)); // comisd src1reg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_comisd_r128_r128(&dst, src1reg, src2p.value); // comisd src1reg,src2p + emit_movsd_r128_p64(dst, src1reg, src1p); // movsd src1reg,src1p + if (src2p.is_memory()) + emit_comisd_r128_m64(dst, src1reg, MABS(src2p.memory())); // comisd src1reg,[src2p] + else if (src2p.is_float_register()) + emit_comisd_r128_r128(dst, src1reg, src2p.freg()); // comisd src1reg,src2p } - return dst; } -/*------------------------------------------------- - op_fmul - process a FMUL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fmul - process a FMUL opcode +//------------------------------------------------- -static x86code *op_fmul(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fmul(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &src1p); // movss dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_mulss_r128_m32(&dst, dstreg, MABS(drcbe, src2p.value)); // mulss dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_mulss_r128_r128(&dst, dstreg, src2p.value); // mulss dstreg,src2p - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, src1p); // movss dstreg,src1p + if (src2p.is_memory()) + emit_mulss_r128_m32(dst, dstreg, MABS(src2p.memory())); // mulss dstreg,[src2p] + else if (src2p.is_float_register()) + emit_mulss_r128_r128(dst, dstreg, src2p.freg()); // mulss dstreg,src2p + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &src1p); // movsd dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_mulsd_r128_m64(&dst, dstreg, MABS(drcbe, src2p.value)); // mulsd dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_mulsd_r128_r128(&dst, dstreg, src2p.value); // mulsd dstreg,src2p - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, src1p); // movsd dstreg,src1p + if (src2p.is_memory()) + emit_mulsd_r128_m64(dst, dstreg, MABS(src2p.memory())); // mulsd dstreg,[src2p] + else if (src2p.is_float_register()) + emit_mulsd_r128_r128(dst, dstreg, src2p.freg()); // mulsd dstreg,src2p + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fdiv - process a FDIV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fdiv - process a FDIV opcode +//------------------------------------------------- -static x86code *op_fdiv(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fdiv(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &src1p); // movss dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_divss_r128_m32(&dst, dstreg, MABS(drcbe, src2p.value)); // divss dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_divss_r128_r128(&dst, dstreg, src2p.value); // divss dstreg,src2p - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, src1p); // movss dstreg,src1p + if (src2p.is_memory()) + emit_divss_r128_m32(dst, dstreg, MABS(src2p.memory())); // divss dstreg,[src2p] + else if (src2p.is_float_register()) + emit_divss_r128_r128(dst, dstreg, src2p.freg()); // divss dstreg,src2p + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &src1p); // movsd dstreg,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_divsd_r128_m64(&dst, dstreg, MABS(drcbe, src2p.value)); // divsd dstreg,[src2p] - else if (src2p.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_divsd_r128_r128(&dst, dstreg, src2p.value); // divsd dstreg,src2p - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, src1p); // movsd dstreg,src1p + if (src2p.is_memory()) + emit_divsd_r128_m64(dst, dstreg, MABS(src2p.memory())); // divsd dstreg,[src2p] + else if (src2p.is_float_register()) + emit_divsd_r128_r128(dst, dstreg, src2p.freg()); // divsd dstreg,src2p + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fneg - process a FNEG opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fneg - process a FNEG opcode +//------------------------------------------------- -static x86code *op_fneg(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fneg(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &srcp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, srcp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_xorps_r128_r128(&dst, dstreg, dstreg); // xorps dstreg,dstreg - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_subss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // subss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_subss_r128_r128(&dst, dstreg, srcp.value); // subss dstreg,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_xorps_r128_r128(dst, dstreg, dstreg); // xorps dstreg,dstreg + if (srcp.is_memory()) + emit_subss_r128_m32(dst, dstreg, MABS(srcp.memory())); // subss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_subss_r128_r128(dst, dstreg, srcp.freg()); // subss dstreg,srcp + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_xorpd_r128_r128(&dst, dstreg, dstreg); // xorpd dstreg,dstreg - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_subsd_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // subsd dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_subsd_r128_r128(&dst, dstreg, srcp.value); // subsd dstreg,srcp - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_xorpd_r128_r128(dst, dstreg, dstreg); // xorpd dstreg,dstreg + if (srcp.is_memory()) + emit_subsd_r128_m64(dst, dstreg, MABS(srcp.memory())); // subsd dstreg,[srcp] + else if (srcp.is_float_register()) + emit_subsd_r128_r128(dst, dstreg, srcp.freg()); // subsd dstreg,srcp + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fabs - process a FABS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fabs - process a FABS opcode +//------------------------------------------------- -static x86code *op_fabs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fabs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, &srcp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0, srcp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_movss_r128_p32(drcbe, &dst, dstreg, &srcp); // movss dstreg,srcp - emit_andps_r128_m128(&dst, dstreg, MABS(drcbe, drcbe->absmask32)); // andps dstreg,[absmask32] - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_r128_p32(dst, dstreg, srcp); // movss dstreg,srcp + emit_andps_r128_m128(dst, dstreg, MABS(m_absmask32)); // andps dstreg,[absmask32] + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_movsd_r128_p64(drcbe, &dst, dstreg, &srcp); // movsd dstreg,srcp - emit_andpd_r128_m128(&dst, dstreg, MABS(drcbe, drcbe->absmask64)); // andpd dstreg,[absmask64] - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_r128_p64(dst, dstreg, srcp); // movsd dstreg,srcp + emit_andpd_r128_m128(dst, dstreg, MABS(m_absmask64)); // andpd dstreg,[absmask64] + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_fsqrt - process a FSQRT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fsqrt - process a FSQRT opcode +//------------------------------------------------- -static x86code *op_fsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_fsqrt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_sqrtss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // sqrtss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_sqrtss_r128_r128(&dst, dstreg, srcp.value); // sqrtss dstreg,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + if (srcp.is_memory()) + emit_sqrtss_r128_m32(dst, dstreg, MABS(srcp.memory())); // sqrtss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_sqrtss_r128_r128(dst, dstreg, srcp.freg()); // sqrtss dstreg,srcp + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_sqrtsd_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // sqrtsd dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_sqrtsd_r128_r128(&dst, dstreg, srcp.value); // sqrtsd dstreg,srcp - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + if (srcp.is_memory()) + emit_sqrtsd_r128_m64(dst, dstreg, MABS(srcp.memory())); // sqrtsd dstreg,[srcp] + else if (srcp.is_float_register()) + emit_sqrtsd_r128_r128(dst, dstreg, srcp.freg()); // sqrtsd dstreg,srcp + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } -/*------------------------------------------------- - op_frecip - process a FRECIP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frecip - process a FRECIP opcode +//------------------------------------------------- -static x86code *op_frecip(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_frecip(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { if (USE_RCPSS_FOR_SINGLES) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_rcpss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // rcpss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_rcpss_r128_r128(&dst, dstreg, srcp.value); // rcpss dstreg,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + if (srcp.is_memory()) + emit_rcpss_r128_m32(dst, dstreg, MABS(srcp.memory())); // rcpss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_rcpss_r128_r128(dst, dstreg, srcp.freg()); // rcpss dstreg,srcp + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } else { - emit_movss_r128_m32(&dst, REG_XMM1, MABS(drcbe, &drcbe->single1)); // movss xmm1,1.0 - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_divss_r128_m32(&dst, REG_XMM1, MABS(drcbe, srcp.value)); // divss xmm1,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_divss_r128_r128(&dst, REG_XMM1, srcp.value); // divss xmm1,srcp - emit_movss_p32_r128(drcbe, &dst, &dstp, REG_XMM1); // movss dstp,xmm1 + emit_movss_r128_m32(dst, REG_XMM1, MABS(&m_near.single1)); // movss xmm1,1.0 + if (srcp.is_memory()) + emit_divss_r128_m32(dst, REG_XMM1, MABS(srcp.memory())); // divss xmm1,[srcp] + else if (srcp.is_float_register()) + emit_divss_r128_r128(dst, REG_XMM1, srcp.freg()); // divss xmm1,srcp + emit_movss_p32_r128(dst, dstp, REG_XMM1); // movss dstp,xmm1 } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { if (USE_RCPSS_FOR_DOUBLES) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2ss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value); // cvtsd2ss dstreg,srcp - emit_rcpss_r128_r128(&dst, dstreg, dstreg); // rcpss dstreg,dstreg - emit_cvtss2sd_r128_r128(&dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg - emit_movsd_p64_r128(drcbe, &dst, &dstp, REG_XMM1); // movsd dstp,dstreg + if (srcp.is_memory()) + emit_cvtsd2ss_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2ss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_cvtsd2ss_r128_r128(dst, dstreg, srcp.freg()); // cvtsd2ss dstreg,srcp + emit_rcpss_r128_r128(dst, dstreg, dstreg); // rcpss dstreg,dstreg + emit_cvtss2sd_r128_r128(dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg + emit_movsd_p64_r128(dst, dstp, REG_XMM1); // movsd dstp,dstreg } else { - emit_movsd_r128_m64(&dst, REG_XMM1, MABS(drcbe, &drcbe->double1)); // movsd xmm1,1.0 - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_divsd_r128_m64(&dst, REG_XMM1, MABS(drcbe, srcp.value)); // divsd xmm1,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_divsd_r128_r128(&dst, REG_XMM1, srcp.value); // divsd xmm1,srcp - emit_movsd_p64_r128(drcbe, &dst, &dstp, REG_XMM1); // movsd dstp,xmm1 + emit_movsd_r128_m64(dst, REG_XMM1, MABS(&m_near.double1)); // movsd xmm1,1.0 + if (srcp.is_memory()) + emit_divsd_r128_m64(dst, REG_XMM1, MABS(srcp.memory())); // divsd xmm1,[srcp] + else if (srcp.is_float_register()) + emit_divsd_r128_r128(dst, REG_XMM1, srcp.freg()); // divsd xmm1,srcp + emit_movsd_p64_r128(dst, dstp, REG_XMM1); // movsd dstp,xmm1 } } - return dst; } -/*------------------------------------------------- - op_frsqrt - process a FRSQRT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frsqrt - process a FRSQRT opcode +//------------------------------------------------- -static x86code *op_frsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x64::op_frsqrt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_XMM0, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_XMM0); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { if (USE_RSQRTSS_FOR_SINGLES) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_rsqrtss_r128_m32(&dst, dstreg, MABS(drcbe, srcp.value)); // rsqrtss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_rsqrtss_r128_r128(&dst, dstreg, srcp.value); // rsqrtss dstreg,srcp + if (srcp.is_memory()) + emit_rsqrtss_r128_m32(dst, dstreg, MABS(srcp.memory())); // rsqrtss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_rsqrtss_r128_r128(dst, dstreg, srcp.freg()); // rsqrtss dstreg,srcp } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_sqrtss_r128_m32(&dst, REG_XMM1, MABS(drcbe, srcp.value)); // sqrtss xmm1,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_sqrtss_r128_r128(&dst, REG_XMM1, srcp.value); // sqrtss xmm1,srcp - emit_movss_r128_m32(&dst, dstreg, MABS(drcbe, &drcbe->single1)); // movss dstreg,1.0 - emit_divss_r128_r128(&dst, dstreg, REG_XMM1); // divss dstreg,xmm1 + if (srcp.is_memory()) + emit_sqrtss_r128_m32(dst, REG_XMM1, MABS(srcp.memory())); // sqrtss xmm1,[srcp] + else if (srcp.is_float_register()) + emit_sqrtss_r128_r128(dst, REG_XMM1, srcp.freg()); // sqrtss xmm1,srcp + emit_movss_r128_m32(dst, dstreg, MABS(&m_near.single1)); // movss dstreg,1.0 + emit_divss_r128_r128(dst, dstreg, REG_XMM1); // divss dstreg,xmm1 } - emit_movss_p32_r128(drcbe, &dst, &dstp, dstreg); // movss dstp,dstreg + emit_movss_p32_r128(dst, dstp, dstreg); // movss dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { if (USE_RSQRTSS_FOR_DOUBLES) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_cvtsd2ss_r128_m64(&dst, dstreg, MABS(drcbe, srcp.value)); // cvtsd2ss dstreg,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_cvtsd2ss_r128_r128(&dst, dstreg, srcp.value); // cvtsd2ss dstreg,srcp - emit_rsqrtss_r128_r128(&dst, dstreg, dstreg); // rsqrtss dstreg,dstreg - emit_cvtss2sd_r128_r128(&dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg + if (srcp.is_memory()) + emit_cvtsd2ss_r128_m64(dst, dstreg, MABS(srcp.memory())); // cvtsd2ss dstreg,[srcp] + else if (srcp.is_float_register()) + emit_cvtsd2ss_r128_r128(dst, dstreg, srcp.freg()); // cvtsd2ss dstreg,srcp + emit_rsqrtss_r128_r128(dst, dstreg, dstreg); // rsqrtss dstreg,dstreg + emit_cvtss2sd_r128_r128(dst, dstreg, dstreg); // cvtss2sd dstreg,dstreg } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_sqrtsd_r128_m64(&dst, REG_XMM1, MABS(drcbe, srcp.value)); // sqrtsd xmm1,[srcp] - else if (srcp.type == DRCUML_PTYPE_FLOAT_REGISTER) - emit_sqrtsd_r128_r128(&dst, REG_XMM1, srcp.value); // sqrtsd xmm1,srcp - emit_movsd_r128_m64(&dst, dstreg, MABS(drcbe, &drcbe->double1)); // movsd dstreg,1.0 - emit_divsd_r128_r128(&dst, dstreg, REG_XMM1); // divsd dstreg,xmm1 + if (srcp.is_memory()) + emit_sqrtsd_r128_m64(dst, REG_XMM1, MABS(srcp.memory())); // sqrtsd xmm1,[srcp] + else if (srcp.is_float_register()) + emit_sqrtsd_r128_r128(dst, REG_XMM1, srcp.freg()); // sqrtsd xmm1,srcp + emit_movsd_r128_m64(dst, dstreg, MABS(&m_near.double1)); // movsd dstreg,1.0 + emit_divsd_r128_r128(dst, dstreg, REG_XMM1); // divsd dstreg,xmm1 } - emit_movsd_p64_r128(drcbe, &dst, &dstp, dstreg); // movsd dstp,dstreg + emit_movsd_p64_r128(dst, dstp, dstreg); // movsd dstp,dstreg } - return dst; } diff --git a/src/emu/cpu/drcbex64.h b/src/emu/cpu/drcbex64.h new file mode 100644 index 00000000000..788ccfa5a66 --- /dev/null +++ b/src/emu/cpu/drcbex64.h @@ -0,0 +1,370 @@ +/*************************************************************************** + + drcbex64.h + + 64-bit x64 back-end for the universal machine language. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#pragma once + +#ifndef __DRCBEX64_H__ +#define __DRCBEX64_H__ + +#include "drcuml.h" +#include "drcbeut.h" +#include "x86log.h" + +#define X86EMIT_SIZE 64 +#include "x86emit.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class drcbe_x64 : public drcbe_interface +{ + typedef UINT32 (*x86_entry_point_func)(UINT8 *rbpvalue, x86code *entry); + +public: + // construction/destruction + drcbe_x64(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits); + virtual ~drcbe_x64(); + + // required overrides + virtual void reset(); + virtual int execute(uml::code_handle &entry); + virtual void generate(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst); + virtual bool hash_exists(UINT32 mode, UINT32 pc); + virtual void get_info(drcbe_info &info); + +private: + // a be_parameter is similar to a uml::parameter but maps to native registers/memory + class be_parameter + { + public: + // parameter types + enum be_parameter_type + { + PTYPE_NONE = 0, // invalid + PTYPE_IMMEDIATE, // immediate; value = sign-extended to 64 bits + PTYPE_INT_REGISTER, // integer register; value = 0-REG_MAX + PTYPE_FLOAT_REGISTER, // floating point register; value = 0-REG_MAX + PTYPE_VECTOR_REGISTER, // vector register; value = 0-REG_MAX + PTYPE_MEMORY, // memory; value = pointer to memory + PTYPE_MAX + }; + + // represents the value of a parameter + typedef UINT64 be_parameter_value; + + // construction + be_parameter() : m_type(PTYPE_NONE), m_value(0) { } + be_parameter(const be_parameter ¶m) : m_type(param.m_type), m_value(param.m_value) { } + be_parameter(UINT64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } + be_parameter(drcbe_x64 &drcbe, const uml::parameter ¶m, UINT32 allowed); + + // creators for types that don't safely default + static inline be_parameter make_ireg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_INT_REGISTER, regnum); } + static inline be_parameter make_freg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_FLOAT_REGISTER, regnum); } + static inline be_parameter make_vreg(int regnum) { assert(regnum >= 0 && regnum < x64emit::REG_MAX); return be_parameter(PTYPE_VECTOR_REGISTER, regnum); } + static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); } + static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); } + + // operators + bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); } + bool operator!=(const be_parameter &rhs) const { return (m_type != rhs.m_type || m_value != rhs.m_value); } + + // getters + be_parameter_type type() const { return m_type; } + UINT64 immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } + int ireg() const { assert(m_type == PTYPE_INT_REGISTER); assert(m_value >= 0 && m_value < x64emit::REG_MAX); return m_value; } + int freg() const { assert(m_type == PTYPE_FLOAT_REGISTER); assert(m_value >= 0 && m_value < x64emit::REG_MAX); return m_value; } + int vreg() const { assert(m_type == PTYPE_VECTOR_REGISTER); assert(m_value >= 0 && m_value < x64emit::REG_MAX); return m_value; } + void *memory() const { assert(m_type == PTYPE_MEMORY); return reinterpret_cast<void *>(m_value); } + + // type queries + bool is_immediate() const { return (m_type == PTYPE_IMMEDIATE); } + bool is_int_register() const { return (m_type == PTYPE_INT_REGISTER); } + bool is_float_register() const { return (m_type == PTYPE_FLOAT_REGISTER); } + bool is_vector_register() const { return (m_type == PTYPE_VECTOR_REGISTER); } + bool is_memory() const { return (m_type == PTYPE_MEMORY); } + + // other queries + bool is_immediate_value(UINT64 value) const { return (m_type == PTYPE_IMMEDIATE && m_value == value); } + + // helpers + int select_register(int defreg) const; + int select_register(int defreg, const be_parameter &checkparam) const; + int select_register(int defreg, const be_parameter &checkparam, const be_parameter &checkparam2) const; + + private: + // private constructor + be_parameter(be_parameter_type type, be_parameter_value value) : m_type(type), m_value(value) { } + + // internals + be_parameter_type m_type; // parameter type + be_parameter_value m_value; // parameter value + }; + + // helpers + x86_memref MABS(const void *ptr); + bool short_immediate(INT64 immediate) const { return (INT32)immediate == immediate; } + void normalize_commutative(be_parameter &inner, be_parameter &outer); + INT32 offset_from_rbp(const void *ptr); + int get_base_register_and_offset(x86code *&dst, void *target, UINT8 reg, INT32 &offset); + void emit_smart_call_r64(x86code *&dst, x86code *target, UINT8 reg); + void emit_smart_call_m64(x86code *&dst, x86code **target); + + static void fixup_label(void *parameter, drccodeptr labelcodeptr); + void fixup_exception(drccodeptr *codeptr, void *param1, void *param2); + + static void debug_log_hashjmp(offs_t pc, int mode); + static void debug_log_hashjmp_fail(); + + // code generators + void op_handle(x86code *&dst, const uml::instruction &inst); + void op_hash(x86code *&dst, const uml::instruction &inst); + void op_label(x86code *&dst, const uml::instruction &inst); + void op_comment(x86code *&dst, const uml::instruction &inst); + void op_mapvar(x86code *&dst, const uml::instruction &inst); + + void op_nop(x86code *&dst, const uml::instruction &inst); + void op_debug(x86code *&dst, const uml::instruction &inst); + void op_exit(x86code *&dst, const uml::instruction &inst); + void op_hashjmp(x86code *&dst, const uml::instruction &inst); + void op_jmp(x86code *&dst, const uml::instruction &inst); + void op_exh(x86code *&dst, const uml::instruction &inst); + void op_callh(x86code *&dst, const uml::instruction &inst); + void op_ret(x86code *&dst, const uml::instruction &inst); + void op_callc(x86code *&dst, const uml::instruction &inst); + void op_recover(x86code *&dst, const uml::instruction &inst); + + void op_setfmod(x86code *&dst, const uml::instruction &inst); + void op_getfmod(x86code *&dst, const uml::instruction &inst); + void op_getexp(x86code *&dst, const uml::instruction &inst); + void op_getflgs(x86code *&dst, const uml::instruction &inst); + void op_save(x86code *&dst, const uml::instruction &inst); + void op_restore(x86code *&dst, const uml::instruction &inst); + + void op_load(x86code *&dst, const uml::instruction &inst); + void op_loads(x86code *&dst, const uml::instruction &inst); + void op_store(x86code *&dst, const uml::instruction &inst); + void op_read(x86code *&dst, const uml::instruction &inst); + void op_readm(x86code *&dst, const uml::instruction &inst); + void op_write(x86code *&dst, const uml::instruction &inst); + void op_writem(x86code *&dst, const uml::instruction &inst); + void op_carry(x86code *&dst, const uml::instruction &inst); + void op_set(x86code *&dst, const uml::instruction &inst); + void op_mov(x86code *&dst, const uml::instruction &inst); + void op_sext(x86code *&dst, const uml::instruction &inst); + void op_roland(x86code *&dst, const uml::instruction &inst); + void op_rolins(x86code *&dst, const uml::instruction &inst); + void op_add(x86code *&dst, const uml::instruction &inst); + void op_addc(x86code *&dst, const uml::instruction &inst); + void op_sub(x86code *&dst, const uml::instruction &inst); + void op_subc(x86code *&dst, const uml::instruction &inst); + void op_cmp(x86code *&dst, const uml::instruction &inst); + void op_mulu(x86code *&dst, const uml::instruction &inst); + void op_muls(x86code *&dst, const uml::instruction &inst); + void op_divu(x86code *&dst, const uml::instruction &inst); + void op_divs(x86code *&dst, const uml::instruction &inst); + void op_and(x86code *&dst, const uml::instruction &inst); + void op_test(x86code *&dst, const uml::instruction &inst); + void op_or(x86code *&dst, const uml::instruction &inst); + void op_xor(x86code *&dst, const uml::instruction &inst); + void op_lzcnt(x86code *&dst, const uml::instruction &inst); + void op_bswap(x86code *&dst, const uml::instruction &inst); + void op_shl(x86code *&dst, const uml::instruction &inst); + void op_shr(x86code *&dst, const uml::instruction &inst); + void op_sar(x86code *&dst, const uml::instruction &inst); + void op_ror(x86code *&dst, const uml::instruction &inst); + void op_rol(x86code *&dst, const uml::instruction &inst); + void op_rorc(x86code *&dst, const uml::instruction &inst); + void op_rolc(x86code *&dst, const uml::instruction &inst); + + void op_fload(x86code *&dst, const uml::instruction &inst); + void op_fstore(x86code *&dst, const uml::instruction &inst); + void op_fread(x86code *&dst, const uml::instruction &inst); + void op_fwrite(x86code *&dst, const uml::instruction &inst); + void op_fmov(x86code *&dst, const uml::instruction &inst); + void op_ftoint(x86code *&dst, const uml::instruction &inst); + void op_ffrint(x86code *&dst, const uml::instruction &inst); + void op_ffrflt(x86code *&dst, const uml::instruction &inst); + void op_frnds(x86code *&dst, const uml::instruction &inst); + void op_fadd(x86code *&dst, const uml::instruction &inst); + void op_fsub(x86code *&dst, const uml::instruction &inst); + void op_fcmp(x86code *&dst, const uml::instruction &inst); + void op_fmul(x86code *&dst, const uml::instruction &inst); + void op_fdiv(x86code *&dst, const uml::instruction &inst); + void op_fneg(x86code *&dst, const uml::instruction &inst); + void op_fabs(x86code *&dst, const uml::instruction &inst); + void op_fsqrt(x86code *&dst, const uml::instruction &inst); + void op_frecip(x86code *&dst, const uml::instruction &inst); + void op_frsqrt(x86code *&dst, const uml::instruction &inst); + + // 32-bit code emission helpers + void emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_movsx_r64_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m); + void emit_mov_p32_r32(x86code *&dst, const be_parameter ¶m, UINT8 reg); + void emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + + // 64-bit code emission helpers + void emit_mov_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_p64_r64(x86code *&dst, const be_parameter ¶m, UINT8 reg); + void emit_add_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + + // floating-point code emission helpers + void emit_movss_r128_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_movss_p32_r128(x86code *&dst, const be_parameter ¶m, UINT8 reg); + void emit_movsd_r128_p64(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_movsd_p64_r128(x86code *&dst, const be_parameter ¶m, UINT8 reg); + + // internal state + drc_hash_table m_hash; // hash table state + drc_map_variables m_map; // code map + drc_label_list m_labels; // label list + x86log_context * m_log; // logging + bool m_sse41; // do we have SSE4.1 support? + + UINT32 * m_absmask32; // absolute value mask (32-bit) + UINT64 * m_absmask64; // absolute value mask (32-bit) + UINT8 * m_rbpvalue; // value of RBP + + x86_entry_point_func m_entry; // entry point + x86code * m_exit; // exit point + x86code * m_nocode; // nocode handler + + // state to live in the near cache + struct near_state + { + x86code * debug_cpu_instruction_hook;// debugger callback + x86code * debug_log_hashjmp; // hashjmp debugging + x86code * debug_log_hashjmp_fail; // hashjmp debugging + x86code * drcmap_get_value; // map lookup helper + + UINT32 ssemode; // saved SSE mode + UINT32 ssemodesave; // temporary location for saving + UINT32 ssecontrol[4]; // copy of the sse_control array + float single1; // 1.0 is single-precision + double double1; // 1.0 in double-precision + + void * stacksave; // saved stack pointer + void * hashstacksave; // saved stack pointer for hashjmp + + UINT8 flagsmap[0x1000]; // flags map + UINT64 flagsunmap[0x20]; // flags unmapper + }; + near_state & m_near; + + // globals + typedef void (drcbe_x64::*opcode_generate_func)(x86code *&dst, const uml::instruction &inst); + struct opcode_table_entry + { + uml::opcode_t opcode; // opcode in question + opcode_generate_func func; // function pointer to the work + }; + static const opcode_table_entry s_opcode_table_source[]; + static opcode_generate_func s_opcode_table[uml::OP_MAX]; +}; + + +#endif /* __DRCBEC_H__ */ diff --git a/src/emu/cpu/drcbex86.c b/src/emu/cpu/drcbex86.c index 9c61522038c..361f4662a24 100644 --- a/src/emu/cpu/drcbex86.c +++ b/src/emu/cpu/drcbex86.c @@ -1,16 +1,43 @@ /*************************************************************************** - drcbex86.c + drcbex86.c 32-bit x86 back-end for the universal machine language. +**************************************************************************** + Copyright Aaron Giles - Released for general non-commercial use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. **************************************************************************** - Future improvements/changes: + Future improvements/changes: * Optimize to avoid unnecessary reloads - especially EDX for 64-bit operations @@ -82,423 +109,316 @@ [esp+44] - ret [esp+48] - input parameter (entry handle) -***************************************************************************/ +**************************************************************************/ #include "emu.h" #include "debugger.h" #include "drcuml.h" -#include "drcbeut.h" -#include "x86emit.h" -#include "x86log.h" +#include "drcbex86.h" +using namespace uml; +using namespace x86emit; -/*************************************************************************** - DEBUGGING -***************************************************************************/ +//************************************************************************** +// DEBUGGING +//************************************************************************** #define LOG_HASHJMPS (0) -/*************************************************************************** - CONSTANTS -***************************************************************************/ +//************************************************************************** +// CONSTANTS +//************************************************************************** -#define PTYPE_M (1 << DRCUML_PTYPE_MEMORY) -#define PTYPE_I (1 << DRCUML_PTYPE_IMMEDIATE) -#define PTYPE_R (1 << DRCUML_PTYPE_INT_REGISTER) -#define PTYPE_F (1 << DRCUML_PTYPE_FLOAT_REGISTER) -#define PTYPE_MI (PTYPE_M | PTYPE_I) -#define PTYPE_RI (PTYPE_R | PTYPE_I) -#define PTYPE_MR (PTYPE_M | PTYPE_R) -#define PTYPE_MRI (PTYPE_M | PTYPE_R | PTYPE_I) -#define PTYPE_MF (PTYPE_M | PTYPE_F) +const UINT32 PTYPE_M = 1 << parameter::PTYPE_MEMORY; +const UINT32 PTYPE_I = 1 << parameter::PTYPE_IMMEDIATE; +const UINT32 PTYPE_R = 1 << parameter::PTYPE_INT_REGISTER; +const UINT32 PTYPE_F = 1 << parameter::PTYPE_FLOAT_REGISTER; +const UINT32 PTYPE_MI = PTYPE_M | PTYPE_I; +const UINT32 PTYPE_RI = PTYPE_R | PTYPE_I; +const UINT32 PTYPE_MR = PTYPE_M | PTYPE_R; +const UINT32 PTYPE_MRI = PTYPE_M | PTYPE_R | PTYPE_I; +const UINT32 PTYPE_MF = PTYPE_M | PTYPE_F; -/*************************************************************************** - MACROS -***************************************************************************/ +//************************************************************************** +// MACROS +//************************************************************************** -#define X86_CONDITION(condition) (condition_map[condition - DRCUML_COND_Z]) -#define X86_NOT_CONDITION(condition) (condition_map[condition - DRCUML_COND_Z] ^ 1) +#define X86_CONDITION(condition) (condition_map[condition - uml::COND_Z]) +#define X86_NOT_CONDITION(condition) (condition_map[condition - uml::COND_Z] ^ 1) -#define assert_no_condition(inst) assert((inst)->condition == DRCUML_COND_ALWAYS) -#define assert_any_condition(inst) assert((inst)->condition == DRCUML_COND_ALWAYS || ((inst)->condition >= DRCUML_COND_Z && (inst)->condition < DRCUML_COND_MAX)) -#define assert_no_flags(inst) assert((inst)->flags == 0) -#define assert_flags(inst, valid) assert(((inst)->flags & ~(valid)) == 0) +#define assert_no_condition(inst) assert((inst).condition() == uml::COND_ALWAYS) +#define assert_any_condition(inst) assert((inst).condition() == uml::COND_ALWAYS || ((inst).condition() >= uml::COND_Z && (inst).condition() < uml::COND_MAX)) +#define assert_no_flags(inst) assert((inst).flags() == 0) +#define assert_flags(inst, valid) assert(((inst).flags() & ~(valid)) == 0) -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** -/* entry point */ -typedef UINT32 (*x86_entry_point_func)(x86code *entry); - -/* opcode handler */ -typedef x86code *(*opcode_generate_func)(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); +drcbe_x86::opcode_generate_func drcbe_x86::s_opcode_table[OP_MAX]; +// size-to-mask table +static const UINT64 size_to_mask[] = { 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0, U64(0xffffffffffffffff) }; -/* opcode table entry */ -typedef struct _opcode_table_entry opcode_table_entry; -struct _opcode_table_entry +// register mapping tables +static const UINT8 int_register_map[REG_I_COUNT] = { - drcuml_opcode opcode; /* opcode in question */ - opcode_generate_func func; /* function pointer to the work */ + REG_EBX, REG_ESI, REG_EDI, REG_EBP }; +// flags mapping tables +static UINT8 flags_map[0x1000]; +static UINT32 flags_unmap[0x20]; -/* internal backend-specific state */ -struct _drcbe_state -{ - device_t * device; /* CPU device we are associated with */ - drcuml_state * drcuml; /* pointer back to our owner */ - drc_cache * cache; /* pointer to the cache */ - drcuml_machine_state state; /* state of the machine */ - drc_hash_table * hash; /* hash table state */ - drc_map_variables * map; /* code map */ - drc_label_list * labels; /* label list */ - - x86_entry_point_func entry; /* entry point */ - x86code * exit; /* exit point */ - x86code * nocode; /* nocode handler */ - x86code * save; /* save handler */ - x86code * restore; /* restore handler */ - - UINT32 * reglo[REG_MAX]; /* pointer to low part of data for each register */ - UINT32 * reghi[REG_MAX]; /* pointer to high part of data for each register */ - UINT8 last_lower_reg; /* last register we stored a lower from */ - x86code * last_lower_pc; /* PC after instruction where we last stored a lower register */ - UINT32 * last_lower_addr; /* address where we last stored an lower register */ - UINT8 last_upper_reg; /* last register we stored an upper from */ - x86code * last_upper_pc; /* PC after instruction where we last stored an upper register */ - UINT32 * last_upper_addr; /* address where we last stored an upper register */ - double fptemp; /* temporary storage for floating point */ - - data_accessors accessors[ADDRESS_SPACES]; /* memory accessors */ - address_space * space[ADDRESS_SPACES]; /* address spaces */ - - UINT8 sse3; /* do we have SSE3 support? */ - UINT16 fpumode; /* saved FPU mode */ - UINT16 fmodesave; /* temporary location for saving */ - - void * stacksave; /* saved stack pointer */ - void * hashstacksave; /* saved stack pointer for hashjmp */ - UINT64 reslo; /* extended low result */ - UINT64 reshi; /* extended high result */ - - x86log_context * log; /* logging */ - UINT8 logged_common; /* logged common code already? */ +// condition mapping table +static const UINT8 condition_map[uml::COND_MAX - uml::COND_Z] = +{ + x86emit::COND_Z, // COND_Z = 0x80, requires Z + x86emit::COND_NZ, // COND_NZ, requires Z + x86emit::COND_S, // COND_S, requires S + x86emit::COND_NS, // COND_NS, requires S + x86emit::COND_C, // COND_C, requires C + x86emit::COND_NC, // COND_NC, requires C + x86emit::COND_O, // COND_V, requires V + x86emit::COND_NO, // COND_NV, requires V + x86emit::COND_P, // COND_U, requires U + x86emit::COND_NP, // COND_NU, requires U + x86emit::COND_A, // COND_A, requires CZ + x86emit::COND_BE, // COND_BE, requires CZ + x86emit::COND_G, // COND_G, requires SVZ + x86emit::COND_LE, // COND_LE, requires SVZ + x86emit::COND_L, // COND_L, requires SV + x86emit::COND_GE, // COND_GE, requires SV }; - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* primary back-end callbacks */ -static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits); -static void drcbex86_free(drcbe_state *drcbe); -static void drcbex86_reset(drcbe_state *drcbe); -static int drcbex86_execute(drcbe_state *drcbe, drcuml_codehandle *entry); -static void drcbex86_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst); -static int drcbex86_hash_exists(drcbe_state *drcbe, UINT32 mode, UINT32 pc); -static void drcbex86_get_info(drcbe_state *state, drcbe_info *info); - -/* private helper functions */ -static void fixup_label(void *parameter, drccodeptr labelcodeptr); - -/* miscellaneous functions */ -static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int flags); -static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags); -static int ddivu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2); -static int ddivs(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2); +// FPU control register mapping +static const UINT16 fp_control[4] = +{ + 0x0e3f, // ROUND_TRUNC + 0x023f, // ROUND_ROUND + 0x0a3f, // ROUND_CEIL + 0x063f // ROUND_FLOOR +}; -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -/* globally-accessible interface to the backend */ -extern const drcbe_interface drcbe_x86_be_interface = -{ - drcbex86_alloc, - drcbex86_free, - drcbex86_reset, - drcbex86_execute, - drcbex86_generate, - drcbex86_hash_exists, - drcbex86_get_info +//************************************************************************** +// TABLES +//************************************************************************** + +const drcbe_x86::opcode_table_entry drcbe_x86::s_opcode_table_source[] = +{ + // Compile-time opcodes + { uml::OP_HANDLE, &drcbe_x86::op_handle }, // HANDLE handle + { uml::OP_HASH, &drcbe_x86::op_hash }, // HASH mode,pc + { uml::OP_LABEL, &drcbe_x86::op_label }, // LABEL imm + { uml::OP_COMMENT, &drcbe_x86::op_comment }, // COMMENT string + { uml::OP_MAPVAR, &drcbe_x86::op_mapvar }, // MAPVAR mapvar,value + + // Control Flow Operations + { uml::OP_NOP, &drcbe_x86::op_nop }, // NOP + { uml::OP_DEBUG, &drcbe_x86::op_debug }, // DEBUG pc + { uml::OP_EXIT, &drcbe_x86::op_exit }, // EXIT src1[,c] + { uml::OP_HASHJMP, &drcbe_x86::op_hashjmp }, // HASHJMP mode,pc,handle + { uml::OP_JMP, &drcbe_x86::op_jmp }, // JMP imm[,c] + { uml::OP_EXH, &drcbe_x86::op_exh }, // EXH handle,param[,c] + { uml::OP_CALLH, &drcbe_x86::op_callh }, // CALLH handle[,c] + { uml::OP_RET, &drcbe_x86::op_ret }, // RET [c] + { uml::OP_CALLC, &drcbe_x86::op_callc }, // CALLC func,ptr[,c] + { uml::OP_RECOVER, &drcbe_x86::op_recover }, // RECOVER dst,mapvar + + // Internal Register Operations + { uml::OP_SETFMOD, &drcbe_x86::op_setfmod }, // SETFMOD src + { uml::OP_GETFMOD, &drcbe_x86::op_getfmod }, // GETFMOD dst + { uml::OP_GETEXP, &drcbe_x86::op_getexp }, // GETEXP dst + { uml::OP_GETFLGS, &drcbe_x86::op_getflgs }, // GETFLGS dst[,f] + { uml::OP_SAVE, &drcbe_x86::op_save }, // SAVE dst + { uml::OP_RESTORE, &drcbe_x86::op_restore }, // RESTORE dst + + // Integer Operations + { uml::OP_LOAD, &drcbe_x86::op_load }, // LOAD dst,base,index,size + { uml::OP_LOADS, &drcbe_x86::op_loads }, // LOADS dst,base,index,size + { uml::OP_STORE, &drcbe_x86::op_store }, // STORE base,index,src,size + { uml::OP_READ, &drcbe_x86::op_read }, // READ dst,src1,spacesize + { uml::OP_READM, &drcbe_x86::op_readm }, // READM dst,src1,mask,spacesize + { uml::OP_WRITE, &drcbe_x86::op_write }, // WRITE dst,src1,spacesize + { uml::OP_WRITEM, &drcbe_x86::op_writem }, // WRITEM dst,src1,spacesize + { uml::OP_CARRY, &drcbe_x86::op_carry }, // CARRY src,bitnum + { uml::OP_SET, &drcbe_x86::op_set }, // SET dst,c + { uml::OP_MOV, &drcbe_x86::op_mov }, // MOV dst,src[,c] + { uml::OP_SEXT, &drcbe_x86::op_sext }, // SEXT dst,src + { uml::OP_ROLAND, &drcbe_x86::op_roland }, // ROLAND dst,src1,src2,src3 + { uml::OP_ROLINS, &drcbe_x86::op_rolins }, // ROLINS dst,src1,src2,src3 + { uml::OP_ADD, &drcbe_x86::op_add }, // ADD dst,src1,src2[,f] + { uml::OP_ADDC, &drcbe_x86::op_addc }, // ADDC dst,src1,src2[,f] + { uml::OP_SUB, &drcbe_x86::op_sub }, // SUB dst,src1,src2[,f] + { uml::OP_SUBB, &drcbe_x86::op_subc }, // SUBB dst,src1,src2[,f] + { uml::OP_CMP, &drcbe_x86::op_cmp }, // CMP src1,src2[,f] + { uml::OP_MULU, &drcbe_x86::op_mulu }, // MULU dst,edst,src1,src2[,f] + { uml::OP_MULS, &drcbe_x86::op_muls }, // MULS dst,edst,src1,src2[,f] + { uml::OP_DIVU, &drcbe_x86::op_divu }, // DIVU dst,edst,src1,src2[,f] + { uml::OP_DIVS, &drcbe_x86::op_divs }, // DIVS dst,edst,src1,src2[,f] + { uml::OP_AND, &drcbe_x86::op_and }, // AND dst,src1,src2[,f] + { uml::OP_TEST, &drcbe_x86::op_test }, // TEST src1,src2[,f] + { uml::OP_OR, &drcbe_x86::op_or }, // OR dst,src1,src2[,f] + { uml::OP_XOR, &drcbe_x86::op_xor }, // XOR dst,src1,src2[,f] + { uml::OP_LZCNT, &drcbe_x86::op_lzcnt }, // LZCNT dst,src[,f] + { uml::OP_BSWAP, &drcbe_x86::op_bswap }, // BSWAP dst,src + { uml::OP_SHL, &drcbe_x86::op_shl }, // SHL dst,src,count[,f] + { uml::OP_SHR, &drcbe_x86::op_shr }, // SHR dst,src,count[,f] + { uml::OP_SAR, &drcbe_x86::op_sar }, // SAR dst,src,count[,f] + { uml::OP_ROL, &drcbe_x86::op_rol }, // ROL dst,src,count[,f] + { uml::OP_ROLC, &drcbe_x86::op_rolc }, // ROLC dst,src,count[,f] + { uml::OP_ROR, &drcbe_x86::op_ror }, // ROR dst,src,count[,f] + { uml::OP_RORC, &drcbe_x86::op_rorc }, // RORC dst,src,count[,f] + + // Floating Point Operations + { uml::OP_FLOAD, &drcbe_x86::op_fload }, // FLOAD dst,base,index + { uml::OP_FSTORE, &drcbe_x86::op_fstore }, // FSTORE base,index,src + { uml::OP_FREAD, &drcbe_x86::op_fread }, // FREAD dst,space,src1 + { uml::OP_FWRITE, &drcbe_x86::op_fwrite }, // FWRITE space,dst,src1 + { uml::OP_FMOV, &drcbe_x86::op_fmov }, // FMOV dst,src1[,c] + { uml::OP_FTOINT, &drcbe_x86::op_ftoint }, // FTOINT dst,src1,size,round + { uml::OP_FFRINT, &drcbe_x86::op_ffrint }, // FFRINT dst,src1,size + { uml::OP_FFRFLT, &drcbe_x86::op_ffrflt }, // FFRFLT dst,src1,size + { uml::OP_FRNDS, &drcbe_x86::op_frnds }, // FRNDS dst,src1 + { uml::OP_FADD, &drcbe_x86::op_fadd }, // FADD dst,src1,src2 + { uml::OP_FSUB, &drcbe_x86::op_fsub }, // FSUB dst,src1,src2 + { uml::OP_FCMP, &drcbe_x86::op_fcmp }, // FCMP src1,src2 + { uml::OP_FMUL, &drcbe_x86::op_fmul }, // FMUL dst,src1,src2 + { uml::OP_FDIV, &drcbe_x86::op_fdiv }, // FDIV dst,src1,src2 + { uml::OP_FNEG, &drcbe_x86::op_fneg }, // FNEG dst,src1 + { uml::OP_FABS, &drcbe_x86::op_fabs }, // FABS dst,src1 + { uml::OP_FSQRT, &drcbe_x86::op_fsqrt }, // FSQRT dst,src1 + { uml::OP_FRECIP, &drcbe_x86::op_frecip }, // FRECIP dst,src1 + { uml::OP_FRSQRT, &drcbe_x86::op_frsqrt } // FRSQRT dst,src1 }; -/* opcode table */ -static opcode_generate_func opcode_table[DRCUML_OP_MAX]; -/* size-to-mask table */ -static const UINT64 size_to_mask[] = { 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0, U64(0xffffffffffffffff) }; -/* register mapping tables */ -static const UINT8 int_register_map[DRCUML_REG_I_END - DRCUML_REG_I0] = -{ - REG_EBX, REG_ESI, REG_EDI, REG_EBP -}; +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** -/* flags mapping tables */ -static UINT8 flags_map[0x1000]; -static UINT32 flags_unmap[0x20]; +//------------------------------------------------- +// param_normalize - convert a full parameter +// into a reduced set +//------------------------------------------------- -/* condition mapping table */ -static const UINT8 condition_map[DRCUML_COND_MAX - DRCUML_COND_Z] = -{ - COND_Z, /* DRCUML_COND_Z = 0x80, requires Z */ - COND_NZ, /* DRCUML_COND_NZ, requires Z */ - COND_S, /* DRCUML_COND_S, requires S */ - COND_NS, /* DRCUML_COND_NS, requires S */ - COND_C, /* DRCUML_COND_C, requires C */ - COND_NC, /* DRCUML_COND_NC, requires C */ - COND_O, /* DRCUML_COND_V, requires V */ - COND_NO, /* DRCUML_COND_NV, requires V */ - COND_P, /* DRCUML_COND_U, requires U */ - COND_NP, /* DRCUML_COND_NU, requires U */ - COND_A, /* DRCUML_COND_A, requires CZ */ - COND_BE, /* DRCUML_COND_BE, requires CZ */ - COND_G, /* DRCUML_COND_G, requires SVZ */ - COND_LE, /* DRCUML_COND_LE, requires SVZ */ - COND_L, /* DRCUML_COND_L, requires SV */ - COND_GE, /* DRCUML_COND_GE, requires SV */ -}; - -/* FPU control register mapping */ -static const UINT16 fp_control[4] = +drcbe_x86::be_parameter::be_parameter(drcbe_x86 &drcbe, const parameter ¶m, UINT32 allowed) { - 0x0e3f, /* DRCUML_FMOD_TRUNC */ - 0x023f, /* DRCUML_FMOD_ROUND */ - 0x0a3f, /* DRCUML_FMOD_CEIL */ - 0x063f /* DRCUML_FMOD_FLOOR */ -}; + int regnum; + switch (param.type()) + { + // immediates pass through + case parameter::PTYPE_IMMEDIATE: + assert(allowed & PTYPE_I); + *this = param.immediate(); + break; + // memory passes through + case parameter::PTYPE_MEMORY: + assert(allowed & PTYPE_M); + *this = make_memory(param.memory()); + break; -/*************************************************************************** - TABLES -***************************************************************************/ - -static x86code *op_handle(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_hash(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_label(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_comment(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mapvar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_nop(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_debug(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_exit(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_hashjmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_jmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_callh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ret(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_callc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_recover(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_subc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_cmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_mulu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_muls(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_divu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_divs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_and(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_test(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_or(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_xor(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_lzcnt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_bswap(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_shl(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_shr(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_sar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ror(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rol(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rorc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_rolc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static x86code *op_fload(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fstore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fmul(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fdiv(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fneg(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fabs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_fsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frecip(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); -static x86code *op_frsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst); - -static const opcode_table_entry opcode_table_source[] = -{ - /* Compile-time opcodes */ - { DRCUML_OP_HANDLE, op_handle }, /* HANDLE handle */ - { DRCUML_OP_HASH, op_hash }, /* HASH mode,pc */ - { DRCUML_OP_LABEL, op_label }, /* LABEL imm */ - { DRCUML_OP_COMMENT, op_comment }, /* COMMENT string */ - { DRCUML_OP_MAPVAR, op_mapvar }, /* MAPVAR mapvar,value */ - - /* Control Flow Operations */ - { DRCUML_OP_NOP, op_nop }, /* NOP */ - { DRCUML_OP_DEBUG, op_debug }, /* DEBUG pc */ - { DRCUML_OP_EXIT, op_exit }, /* EXIT src1[,c] */ - { DRCUML_OP_HASHJMP, op_hashjmp }, /* HASHJMP mode,pc,handle */ - { DRCUML_OP_JMP, op_jmp }, /* JMP imm[,c] */ - { DRCUML_OP_EXH, op_exh }, /* EXH handle,param[,c] */ - { DRCUML_OP_CALLH, op_callh }, /* CALLH handle[,c] */ - { DRCUML_OP_RET, op_ret }, /* RET [c] */ - { DRCUML_OP_CALLC, op_callc }, /* CALLC func,ptr[,c] */ - { DRCUML_OP_RECOVER, op_recover }, /* RECOVER dst,mapvar */ - - /* Internal Register Operations */ - { DRCUML_OP_SETFMOD, op_setfmod }, /* SETFMOD src */ - { DRCUML_OP_GETFMOD, op_getfmod }, /* GETFMOD dst */ - { DRCUML_OP_GETEXP, op_getexp }, /* GETEXP dst */ - { DRCUML_OP_GETFLGS, op_getflgs }, /* GETFLGS dst,mask */ - { DRCUML_OP_SAVE, op_save }, /* SAVE dst */ - { DRCUML_OP_RESTORE, op_restore }, /* RESTORE dst */ - - /* Integer Operations */ - { DRCUML_OP_LOAD, op_load }, /* LOAD dst,base,index,size */ - { DRCUML_OP_LOADS, op_loads }, /* LOADS dst,base,index,size */ - { DRCUML_OP_STORE, op_store }, /* STORE base,index,src,size */ - { DRCUML_OP_READ, op_read }, /* READ dst,src1,spacesize */ - { DRCUML_OP_READM, op_readm }, /* READM dst,src1,mask,spacesize */ - { DRCUML_OP_WRITE, op_write }, /* WRITE dst,src1,spacesize */ - { DRCUML_OP_WRITEM, op_writem }, /* WRITEM dst,src1,spacesize */ - { DRCUML_OP_CARRY, op_carry }, /* CARRY src,bitnum */ - { DRCUML_OP_SET, op_set }, /* SET dst,c */ - { DRCUML_OP_MOV, op_mov }, /* MOV dst,src[,c] */ - { DRCUML_OP_SEXT, op_sext }, /* SEXT dst,src */ - { DRCUML_OP_ROLAND, op_roland }, /* ROLAND dst,src1,src2,src3 */ - { DRCUML_OP_ROLINS, op_rolins }, /* ROLINS dst,src1,src2,src3 */ - { DRCUML_OP_ADD, op_add }, /* ADD dst,src1,src2[,f] */ - { DRCUML_OP_ADDC, op_addc }, /* ADDC dst,src1,src2[,f] */ - { DRCUML_OP_SUB, op_sub }, /* SUB dst,src1,src2[,f] */ - { DRCUML_OP_SUBB, op_subc }, /* SUBB dst,src1,src2[,f] */ - { DRCUML_OP_CMP, op_cmp }, /* CMP src1,src2[,f] */ - { DRCUML_OP_MULU, op_mulu }, /* MULU dst,edst,src1,src2[,f] */ - { DRCUML_OP_MULS, op_muls }, /* MULS dst,edst,src1,src2[,f] */ - { DRCUML_OP_DIVU, op_divu }, /* DIVU dst,edst,src1,src2[,f] */ - { DRCUML_OP_DIVS, op_divs }, /* DIVS dst,edst,src1,src2[,f] */ - { DRCUML_OP_AND, op_and }, /* AND dst,src1,src2[,f] */ - { DRCUML_OP_TEST, op_test }, /* TEST src1,src2[,f] */ - { DRCUML_OP_OR, op_or }, /* OR dst,src1,src2[,f] */ - { DRCUML_OP_XOR, op_xor }, /* XOR dst,src1,src2[,f] */ - { DRCUML_OP_LZCNT, op_lzcnt }, /* LZCNT dst,src */ - { DRCUML_OP_BSWAP, op_bswap }, /* BSWAP dst,src */ - { DRCUML_OP_SHL, op_shl }, /* SHL dst,src,count[,f] */ - { DRCUML_OP_SHR, op_shr }, /* SHR dst,src,count[,f] */ - { DRCUML_OP_SAR, op_sar }, /* SAR dst,src,count[,f] */ - { DRCUML_OP_ROL, op_rol }, /* ROL dst,src,count[,f] */ - { DRCUML_OP_ROLC, op_rolc }, /* ROLC dst,src,count[,f] */ - { DRCUML_OP_ROR, op_ror }, /* ROR dst,src,count[,f] */ - { DRCUML_OP_RORC, op_rorc }, /* RORC dst,src,count[,f] */ - - /* Floating Point Operations */ - { DRCUML_OP_FLOAD, op_fload }, /* FLOAD dst,base,index */ - { DRCUML_OP_FSTORE, op_fstore }, /* FSTORE base,index,src */ - { DRCUML_OP_FREAD, op_fread }, /* FREAD dst,src1,space */ - { DRCUML_OP_FWRITE, op_fwrite }, /* FWRITE dst,src1,space */ - { DRCUML_OP_FMOV, op_fmov }, /* FMOV dst,src1[,c] */ - { DRCUML_OP_FTOINT, op_ftoint }, /* FTOINT dst,src1,size,round */ - { DRCUML_OP_FFRINT, op_ffrint }, /* FFRINT dst,src1,size */ - { DRCUML_OP_FFRFLT, op_ffrflt }, /* FFRFLT dst,src1,size */ - { DRCUML_OP_FRNDS, op_frnds }, /* FRNDS dst,src1 */ - { DRCUML_OP_FADD, op_fadd }, /* FADD dst,src1,src2 */ - { DRCUML_OP_FSUB, op_fsub }, /* FSUB dst,src1,src2 */ - { DRCUML_OP_FCMP, op_fcmp }, /* FCMP src1,src2 */ - { DRCUML_OP_FMUL, op_fmul }, /* FMUL dst,src1,src2 */ - { DRCUML_OP_FDIV, op_fdiv }, /* FDIV dst,src1,src2 */ - { DRCUML_OP_FNEG, op_fneg }, /* FNEG dst,src1 */ - { DRCUML_OP_FABS, op_fabs }, /* FABS dst,src1 */ - { DRCUML_OP_FSQRT, op_fsqrt }, /* FSQRT dst,src1 */ - { DRCUML_OP_FRECIP, op_frecip }, /* FRECIP dst,src1 */ - { DRCUML_OP_FRSQRT, op_frsqrt } /* FRSQRT dst,src1 */ -}; + // if a register maps to a register, keep it as a register; otherwise map it to memory + case parameter::PTYPE_INT_REGISTER: + assert(allowed & PTYPE_R); + assert(allowed & PTYPE_M); + regnum = int_register_map[param.ireg() - REG_I0]; + if (regnum != 0) + *this = make_ireg(regnum); + else + *this = make_memory(&drcbe.m_state.r[param.ireg() - REG_I0]); + break; + // if a register maps to a register, keep it as a register; otherwise map it to memory + case parameter::PTYPE_FLOAT_REGISTER: + assert(allowed & PTYPE_F); + assert(allowed & PTYPE_M); + *this = make_memory(&drcbe.m_state.f[param.freg() - REG_F0]); + break; + // everything else is unexpected + default: + fatalerror("Unexpected parameter type"); + break; + } +} -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ -/*------------------------------------------------- - param_select_register - select a register - to use, avoiding conflicts with the optional - checkparam --------------------------------------------------*/ +//------------------------------------------------- +// select_register - select a register to use, +// avoiding conflicts with the optional +// checkparam +//------------------------------------------------- -INLINE int param_select_register(int defreg, const drcuml_parameter *param, const drcuml_parameter *checkparam) +inline int drcbe_x86::be_parameter::select_register(int defreg) const { - if (param->type == DRCUML_PTYPE_INT_REGISTER && (checkparam == NULL || param->type != checkparam->type || param->value != checkparam->value)) - return param->value; + if (m_type == PTYPE_INT_REGISTER || m_type == PTYPE_FLOAT_REGISTER || m_type == PTYPE_VECTOR_REGISTER) + return m_value; return defreg; } +inline int drcbe_x86::be_parameter::select_register(int defreg, const be_parameter &checkparam) const +{ + if (*this == checkparam) + return defreg; + return select_register(defreg); +} + +inline int drcbe_x86::be_parameter::select_register(int defreg, const be_parameter &checkparam, const be_parameter &checkparam2) const +{ + if (*this == checkparam || *this == checkparam2) + return defreg; + return select_register(defreg); +} + -/*------------------------------------------------- - param_select_register2 - select a register - to use, avoiding conflicts with the optional - checkparam --------------------------------------------------*/ +//------------------------------------------------- +// select_register - select a register to use, +// avoiding conflicts with the optional +// checkparam +//------------------------------------------------- -INLINE int param_select_register2(int defreg, const drcuml_parameter *param, const drcuml_parameter *checkparam1, const drcuml_parameter *checkparam2) +inline void drcbe_x86::normalize_commutative(be_parameter &inner, be_parameter &outer) { - if (param->type == DRCUML_PTYPE_INT_REGISTER && (param->type != checkparam1->type || param->value != checkparam1->value) && (param->type != checkparam2->type || param->value != checkparam2->value)) - return param->value; - return defreg; + // if the inner parameter is a memory operand, push it to the outer + if (inner.is_memory()) + { + be_parameter temp = inner; + inner = outer; + outer = temp; + } + + // if the inner parameter is an immediate, push it to the outer + if (inner.is_immediate()) + { + be_parameter temp = inner; + inner = outer; + outer = temp; + } } -/*------------------------------------------------- - emit_combine_z_flags - combine the Z flag from - two 32-bit operations --------------------------------------------------*/ +//------------------------------------------------- +// emit_combine_z_flags - combine the Z flag from +// two 32-bit operations +//------------------------------------------------- -INLINE void emit_combine_z_flags(x86code **dst) +inline void drcbe_x86::emit_combine_z_flags(x86code *&dst) { - /* this assumes that the flags from the low 32-bit op are on the stack */ - /* and the flags from the high 32-bit op are live */ + // this assumes that the flags from the low 32-bit op are on the stack + // and the flags from the high 32-bit op are live emit_pushf(dst); // pushf emit_mov_r32_m32(dst, REG_ECX, MBD(REG_ESP, 4)); // mov ecx,[esp+4] emit_or_r32_imm(dst, REG_ECX, ~0x40); // or ecx,~0x40 @@ -508,15 +428,15 @@ INLINE void emit_combine_z_flags(x86code **dst) } -/*------------------------------------------------- - emit_combine_z_shl_flags - combine the Z - flags from two 32-bit shift left operations --------------------------------------------------*/ +//------------------------------------------------- +// emit_combine_z_shl_flags - combine the Z +// flags from two 32-bit shift left operations +//------------------------------------------------- -INLINE void emit_combine_z_shl_flags(x86code **dst) +inline void drcbe_x86::emit_combine_z_shl_flags(x86code *&dst) { - /* this assumes that the flags from the high 32-bit op are on the stack */ - /* and the flags from the low 32-bit op are live */ + // this assumes that the flags from the high 32-bit op are on the stack + // and the flags from the low 32-bit op are live emit_pushf(dst); // pushf emit_pop_r32(dst, REG_ECX); // pop ecx emit_or_r32_imm(dst, REG_ECX, ~0x40); // or ecx,~0x40 @@ -525,79 +445,77 @@ INLINE void emit_combine_z_shl_flags(x86code **dst) } -/*------------------------------------------------- - reset_last_upper_lower_reg - reset the last - upper/lower register state --------------------------------------------------*/ +//------------------------------------------------- +// reset_last_upper_lower_reg - reset the last +// upper/lower register state +//------------------------------------------------- -INLINE void reset_last_upper_lower_reg(drcbe_state *drcbe) +inline void drcbe_x86::reset_last_upper_lower_reg() { - drcbe->last_lower_reg = REG_NONE; - drcbe->last_upper_reg = REG_NONE; + m_last_lower_reg = REG_NONE; + m_last_upper_reg = REG_NONE; } -/*------------------------------------------------- - set_last_lower_reg - note that we have just - loaded a lower register --------------------------------------------------*/ +//------------------------------------------------- +// set_last_lower_reg - note that we have just +// loaded a lower register +//------------------------------------------------- -INLINE void set_last_lower_reg(drcbe_state *drcbe, x86code *dst, const drcuml_parameter *param, UINT8 reglo) +inline void drcbe_x86::set_last_lower_reg(x86code *&dst, const be_parameter ¶m, UINT8 reglo) { - if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_memory()) { - drcbe->last_lower_reg = reglo; - drcbe->last_lower_addr = (UINT32 *)((FPTR)param->value); - drcbe->last_lower_pc = dst; + m_last_lower_reg = reglo; + m_last_lower_addr = (UINT32 *)((FPTR)param.memory()); + m_last_lower_pc = dst; } } -/*------------------------------------------------- - set_last_upper_reg - note that we have just - loaded an upper register --------------------------------------------------*/ +//------------------------------------------------- +// set_last_upper_reg - note that we have just +// loaded an upper register +//------------------------------------------------- -INLINE void set_last_upper_reg(drcbe_state *drcbe, x86code *dst, const drcuml_parameter *param, UINT8 reghi) +inline void drcbe_x86::set_last_upper_reg(x86code *&dst, const be_parameter ¶m, UINT8 reghi) { - drcbe->last_upper_reg = reghi; - drcbe->last_upper_addr = (param->type == DRCUML_PTYPE_INT_REGISTER) ? drcbe->reghi[param->value] : (UINT32 *)((FPTR)param->value + 4); - drcbe->last_upper_pc = dst; + m_last_upper_reg = reghi; + m_last_upper_addr = (param.is_int_register()) ? m_reghi[param.ireg()] : (UINT32 *)((FPTR)param.memory(4)); + m_last_upper_pc = dst; } -/*------------------------------------------------- - can_skip_lower_load - return TRUE if we can - skip re-loading a lower half of a register --------------------------------------------------*/ +//------------------------------------------------- +// can_skip_lower_load - return true if we can +// skip re-loading a lower half of a register +//------------------------------------------------- -INLINE int can_skip_lower_load(drcbe_state *drcbe, x86code *dst, UINT32 *memptr, UINT8 reglo) +inline bool drcbe_x86::can_skip_lower_load(x86code *&dst, UINT32 *memref, UINT8 reglo) { -// return FALSE; - return (dst == drcbe->last_lower_pc && memptr == drcbe->last_lower_addr && reglo == drcbe->last_lower_reg); + return (dst == m_last_lower_pc && memref == m_last_lower_addr && reglo == m_last_lower_reg); } -/*------------------------------------------------- - can_skip_upper_load - return TRUE if we can - skip re-loading an upper half of a register --------------------------------------------------*/ +//------------------------------------------------- +// can_skip_upper_load - return true if we can +// skip re-loading an upper half of a register +//------------------------------------------------- -INLINE int can_skip_upper_load(drcbe_state *drcbe, x86code *dst, UINT32 *memptr, UINT8 reghi) +inline bool drcbe_x86::can_skip_upper_load(x86code *&dst, UINT32 *memref, UINT8 reghi) { -// return FALSE; - return (dst == drcbe->last_upper_pc && memptr == drcbe->last_upper_addr && reghi == drcbe->last_upper_reg); + return (dst == m_last_upper_pc && memref == m_last_upper_addr && reghi == m_last_upper_reg); } -/*------------------------------------------------- - track_resolve_link - wrapper for resolve_link - that resets all register tracking info --------------------------------------------------*/ +//------------------------------------------------- +// track_resolve_link - wrapper for resolve_link +// that resets all register tracking info +//------------------------------------------------- -INLINE void track_resolve_link(drcbe_state *drcbe, x86code **destptr, const emit_link *linkinfo) +inline void drcbe_x86::track_resolve_link(x86code *&destptr, const emit_link &linkinfo) { - reset_last_upper_lower_reg(drcbe); + reset_last_upper_lower_reg(); resolve_link(destptr, linkinfo); } @@ -605,123 +523,112 @@ INLINE void track_resolve_link(drcbe_state *drcbe, x86code **destptr, const emit -/*************************************************************************** - BACKEND CALLBACKS -***************************************************************************/ - -/*------------------------------------------------- - drcbex86_alloc - allocate back-end-specific - state --------------------------------------------------*/ - -static drcbe_state *drcbex86_alloc(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits) -{ - int opnum, regnum, entry, spacenum; - drcbe_state *drcbe; - - /* allocate space in the cache for our state */ - drcbe = (drcbe_state *)cache->alloc(sizeof(*drcbe)); - if (drcbe == NULL) - return NULL; - memset(drcbe, 0, sizeof(*drcbe)); - - /* remember our pointers */ - drcbe->device = device; - drcbe->drcuml = drcuml; - drcbe->cache = cache; - - /* get address spaces and accessors */ - for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++) - { - drcbe->space[spacenum] = downcast<cpu_device *>(device)->space(spacenum); - if (drcbe->space[spacenum] != NULL) - drcbe->space[spacenum]->accessors(drcbe->accessors[spacenum]); - } - - /* allocate hash tables */ - drcbe->hash = auto_alloc(device->machine, drc_hash_table(*cache, modes, addrbits, ignorebits)); - - /* allocate code map */ - drcbe->map = auto_alloc(device->machine, drc_map_variables(*cache, 0)); - - /* allocate a label tracker */ - drcbe->labels = auto_alloc(device->machine, drc_label_list(*cache)); - - /* build the opcode table (static but it doesn't hurt to regenerate it) */ - for (opnum = 0; opnum < ARRAY_LENGTH(opcode_table_source); opnum++) - opcode_table[opcode_table_source[opnum].opcode] = opcode_table_source[opnum].func; +//************************************************************************** +// BACKEND CALLBACKS +//************************************************************************** + +//------------------------------------------------- +// drcbe_x86 - constructor +//------------------------------------------------- + +drcbe_x86::drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits) + : drcbe_interface(drcuml, cache, device), + m_hash(cache, modes, addrbits, ignorebits), + m_map(cache, 0), + m_labels(cache), + m_log(NULL), + m_logged_common(false), + m_sse3(false), + m_entry(NULL), + m_exit(NULL), + m_nocode(NULL), + m_save(NULL), + m_restore(NULL), + m_last_lower_reg(REG_NONE), + m_last_lower_pc(NULL), + m_last_lower_addr(NULL), + m_last_upper_reg(REG_NONE), + m_last_upper_pc(NULL), + m_last_upper_addr(NULL), + m_fptemp(0), + m_fpumode(0), + m_fmodesave(0), + m_stacksave(0), + m_hashstacksave(0), + m_reslo(0), + m_reshi(0) +{ + // compute hi pointers for each register + for (int regnum = 0; regnum < ARRAY_LENGTH(int_register_map); regnum++) + if (int_register_map[regnum] != 0) + { + m_reglo[int_register_map[regnum]] = &m_state.r[regnum].w.l; + m_reghi[int_register_map[regnum]] = &m_state.r[regnum].w.h; + } - /* build the flags map (static but it doesn't hurt to regenerate it) */ - for (entry = 0; entry < ARRAY_LENGTH(flags_map); entry++) + // build the flags map (static but it doesn't hurt to regenerate it) + for (int entry = 0; entry < ARRAY_LENGTH(flags_map); entry++) { UINT8 flags = 0; - if (entry & 0x001) flags |= DRCUML_FLAG_C; - if (entry & 0x004) flags |= DRCUML_FLAG_U; - if (entry & 0x040) flags |= DRCUML_FLAG_Z; - if (entry & 0x080) flags |= DRCUML_FLAG_S; - if (entry & 0x800) flags |= DRCUML_FLAG_V; + if (entry & 0x001) flags |= FLAG_C; + if (entry & 0x004) flags |= FLAG_U; + if (entry & 0x040) flags |= FLAG_Z; + if (entry & 0x080) flags |= FLAG_S; + if (entry & 0x800) flags |= FLAG_V; flags_map[entry] = flags; } - for (entry = 0; entry < ARRAY_LENGTH(flags_unmap); entry++) + for (int entry = 0; entry < ARRAY_LENGTH(flags_unmap); entry++) { UINT32 flags = 0; - if (entry & DRCUML_FLAG_C) flags |= 0x001; - if (entry & DRCUML_FLAG_U) flags |= 0x004; - if (entry & DRCUML_FLAG_Z) flags |= 0x040; - if (entry & DRCUML_FLAG_S) flags |= 0x080; - if (entry & DRCUML_FLAG_V) flags |= 0x800; + if (entry & FLAG_C) flags |= 0x001; + if (entry & FLAG_U) flags |= 0x004; + if (entry & FLAG_Z) flags |= 0x040; + if (entry & FLAG_S) flags |= 0x080; + if (entry & FLAG_V) flags |= 0x800; flags_unmap[entry] = flags; } - /* compute hi pointers for each register */ - for (regnum = 0; regnum < ARRAY_LENGTH(int_register_map); regnum++) - if (int_register_map[regnum] != 0) - { - drcbe->reglo[int_register_map[regnum]] = &drcbe->state.r[regnum].w.l; - drcbe->reghi[int_register_map[regnum]] = &drcbe->state.r[regnum].w.h; - } + // build the opcode table (static but it doesn't hurt to regenerate it) + for (int opnum = 0; opnum < ARRAY_LENGTH(s_opcode_table_source); opnum++) + s_opcode_table[s_opcode_table_source[opnum].opcode] = s_opcode_table_source[opnum].func; - /* create the log */ + // create the log if (flags & DRCUML_OPTION_LOG_NATIVE) - drcbe->log = x86log_create_context("drcbex86.asm"); - - return drcbe; + m_log = x86log_create_context("drcbex86.asm"); } -/*------------------------------------------------- - drcbex86_free - free back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// ~drcbe_x86 - destructor +//------------------------------------------------- -static void drcbex86_free(drcbe_state *drcbe) +drcbe_x86::~drcbe_x86() { - /* free the log context */ - if (drcbe->log != NULL) - x86log_free_context(drcbe->log); + // free the log context + if (m_log != NULL) + x86log_free_context(m_log); } -/*------------------------------------------------- - drcbex86_reset - reset back-end specific state --------------------------------------------------*/ +//------------------------------------------------- +// reset - reset back-end specific state +//------------------------------------------------- -static void drcbex86_reset(drcbe_state *drcbe) +void drcbe_x86::reset() { - UINT32 (*cpuid_ecx_stub)(void); - x86code **dst; - int regnum; - - /* output a note to the log */ - if (drcbe->log != NULL) - x86log_printf(drcbe->log, "\n\n===========\nCACHE RESET\n===========\n\n"); + // output a note to the log + if (m_log != NULL) + x86log_printf(m_log, "\n\n===========\nCACHE RESET\n===========\n\n"); - /* generate a little bit of glue code to set up the environment */ - dst = (x86code **)drcbe->cache->begin_codegen(500); - if (dst == NULL) + // generate a little bit of glue code to set up the environment + drccodeptr *cachetop = m_cache.begin_codegen(500); + if (cachetop == NULL) fatalerror("Out of cache space after a reset!"); - /* generate a simple CPUID stub */ - cpuid_ecx_stub = (UINT32 (*)(void))*dst; + x86code *dst = (x86code *)*cachetop; + + // generate a simple CPUID stub + UINT32 (*cpuid_ecx_stub)(void) = (UINT32 (*)(void))dst; emit_push_r32(dst, REG_EBX); // push ebx emit_mov_r32_imm(dst, REG_EAX, 1); // mov eax,1 emit_cpuid(dst); // cpuid @@ -729,1932 +636,1705 @@ static void drcbex86_reset(drcbe_state *drcbe) emit_pop_r32(dst, REG_EBX); // pop ebx emit_ret(dst); // ret - /* call it to determine if we have SSE3 support */ - drcbe->sse3 = (((*cpuid_ecx_stub)() & 1) != 0); + // call it to determine if we have SSE3 support + m_sse3 = (((*cpuid_ecx_stub)() & 1) != 0); - /* generate an entry point */ - drcbe->entry = (x86_entry_point_func)*dst; + // generate an entry point + m_entry = (x86_entry_point_func)dst; emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ESP, 4)); // mov eax,[esp+4] emit_push_r32(dst, REG_EBX); // push ebx emit_push_r32(dst, REG_ESI); // push esi emit_push_r32(dst, REG_EDI); // push edi emit_push_r32(dst, REG_EBP); // push ebp emit_sub_r32_imm(dst, REG_ESP, 24); // sub esp,24 - emit_mov_m32_r32(dst, MABS(&drcbe->hashstacksave), REG_ESP); // mov [hashstacksave],esp + emit_mov_m32_r32(dst, MABS(&m_hashstacksave), REG_ESP); // mov [hashstacksave],esp emit_sub_r32_imm(dst, REG_ESP, 4); // sub esp,4 - emit_mov_m32_r32(dst, MABS(&drcbe->stacksave), REG_ESP); // mov [stacksave],esp - emit_fstcw_m16(dst, MABS(&drcbe->fpumode)); // fstcw [fpumode] + emit_mov_m32_r32(dst, MABS(&m_stacksave), REG_ESP); // mov [stacksave],esp + emit_fstcw_m16(dst, MABS(&m_fpumode)); // fstcw [fpumode] emit_jmp_r32(dst, REG_EAX); // jmp eax - if (drcbe->log != NULL && !drcbe->logged_common) - x86log_disasm_code_range(drcbe->log, "entry_point", (x86code *)drcbe->entry, *dst); + if (m_log != NULL && !m_logged_common) + x86log_disasm_code_range(m_log, "entry_point", (x86code *)m_entry, dst); - /* generate an exit point */ - drcbe->exit = *dst; - emit_fldcw_m16(dst, MABS(&drcbe->fpumode)); // fldcw [fpumode] - emit_mov_r32_m32(dst, REG_ESP, MABS(&drcbe->hashstacksave)); // mov esp,[hashstacksave] + // generate an exit point + m_exit = dst; + emit_fldcw_m16(dst, MABS(&m_fpumode)); // fldcw [fpumode] + emit_mov_r32_m32(dst, REG_ESP, MABS(&m_hashstacksave)); // mov esp,[hashstacksave] emit_add_r32_imm(dst, REG_ESP, 24); // add esp,24 emit_pop_r32(dst, REG_EBP); // pop ebp emit_pop_r32(dst, REG_EDI); // pop edi emit_pop_r32(dst, REG_ESI); // pop esi emit_pop_r32(dst, REG_EBX); // pop ebx emit_ret(dst); // ret - if (drcbe->log != NULL && !drcbe->logged_common) - x86log_disasm_code_range(drcbe->log, "exit_point", drcbe->exit, *dst); + if (m_log != NULL && !m_logged_common) + x86log_disasm_code_range(m_log, "exit_point", m_exit, dst); - /* generate a no code point */ - drcbe->nocode = *dst; + // generate a no code point + m_nocode = dst; emit_ret(dst); // ret - if (drcbe->log != NULL && !drcbe->logged_common) - x86log_disasm_code_range(drcbe->log, "nocode", drcbe->nocode, *dst); + if (m_log != NULL && !m_logged_common) + x86log_disasm_code_range(m_log, "nocode", m_nocode, dst); - /* generate a save subroutine */ - drcbe->save = *dst; + // generate a save subroutine + m_save = dst; emit_pushf(dst); // pushf emit_pop_r32(dst, REG_EAX); // pop eax emit_and_r32_imm(dst, REG_EAX, 0x8c5); // and eax,0x8c5 - emit_mov_r8_m8(dst, REG_AL, MBD(REG_EAX, flags_map)); // mov al,[flags_map] + emit_mov_r8_m8(dst, REG_AL, MABSI(flags_map, REG_EAX)); // mov al,[flags_map] emit_mov_m8_r8(dst, MBD(REG_ECX, offsetof(drcuml_machine_state, flags)), REG_AL); // mov state->flags,al - emit_mov_r8_m8(dst, REG_AL, MABS(&drcbe->state.fmod)); // mov al,[fmod] + emit_mov_r8_m8(dst, REG_AL, MABS(&m_state.fmod)); // mov al,[fmod] emit_mov_m8_r8(dst, MBD(REG_ECX, offsetof(drcuml_machine_state, fmod)), REG_AL); // mov state->fmod,al - emit_mov_r32_m32(dst, REG_EAX, MABS(&drcbe->state.exp)); // mov eax,[exp] + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.exp)); // mov eax,[exp] emit_mov_m32_r32(dst, MBD(REG_ECX, offsetof(drcuml_machine_state, exp)), REG_EAX); // mov state->exp,eax - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.r); regnum++) + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.r); regnum++) { - int regoffsl = (int)&((drcuml_machine_state *)NULL)->r[regnum].w.l; - int regoffsh = (int)&((drcuml_machine_state *)NULL)->r[regnum].w.h; + FPTR regoffsl = (FPTR)&((drcuml_machine_state *)NULL)->r[regnum].w.l; + FPTR regoffsh = (FPTR)&((drcuml_machine_state *)NULL)->r[regnum].w.h; if (int_register_map[regnum] != 0) emit_mov_m32_r32(dst, MBD(REG_ECX, regoffsl), int_register_map[regnum]); else { - emit_mov_r32_m32(dst, REG_EAX, MABS(&drcbe->state.r[regnum].w.l)); + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.r[regnum].w.l)); emit_mov_m32_r32(dst, MBD(REG_ECX, regoffsl), REG_EAX); } - emit_mov_r32_m32(dst, REG_EAX, MABS(&drcbe->state.r[regnum].w.h)); + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.r[regnum].w.h)); emit_mov_m32_r32(dst, MBD(REG_ECX, regoffsh), REG_EAX); } - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.f); regnum++) + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.f); regnum++) { - int regoffsl = (int)&((drcuml_machine_state *)NULL)->f[regnum].s.l; - int regoffsh = (int)&((drcuml_machine_state *)NULL)->f[regnum].s.h; - emit_mov_r32_m32(dst, REG_EAX, MABS(&drcbe->state.f[regnum].s.l)); + FPTR regoffsl = (FPTR)&((drcuml_machine_state *)NULL)->f[regnum].s.l; + FPTR regoffsh = (FPTR)&((drcuml_machine_state *)NULL)->f[regnum].s.h; + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.f[regnum].s.l)); emit_mov_m32_r32(dst, MBD(REG_ECX, regoffsl), REG_EAX); - emit_mov_r32_m32(dst, REG_EAX, MABS(&drcbe->state.f[regnum].s.h)); + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.f[regnum].s.h)); emit_mov_m32_r32(dst, MBD(REG_ECX, regoffsh), REG_EAX); } emit_ret(dst); // ret - if (drcbe->log != NULL && !drcbe->logged_common) - x86log_disasm_code_range(drcbe->log, "save", drcbe->save, *dst); + if (m_log != NULL && !m_logged_common) + x86log_disasm_code_range(m_log, "save", m_save, dst); - /* generate a restore subroutine */ - drcbe->restore = *dst; - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.r); regnum++) + // generate a restore subroutine + m_restore = dst; + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.r); regnum++) { - int regoffsl = (int)&((drcuml_machine_state *)NULL)->r[regnum].w.l; - int regoffsh = (int)&((drcuml_machine_state *)NULL)->r[regnum].w.h; + FPTR regoffsl = (FPTR)&((drcuml_machine_state *)NULL)->r[regnum].w.l; + FPTR regoffsh = (FPTR)&((drcuml_machine_state *)NULL)->r[regnum].w.h; if (int_register_map[regnum] != 0) emit_mov_r32_m32(dst, int_register_map[regnum], MBD(REG_ECX, regoffsl)); else { emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ECX, regoffsl)); - emit_mov_m32_r32(dst, MABS(&drcbe->state.r[regnum].w.l), REG_EAX); + emit_mov_m32_r32(dst, MABS(&m_state.r[regnum].w.l), REG_EAX); } emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ECX, regoffsh)); - emit_mov_m32_r32(dst, MABS(&drcbe->state.r[regnum].w.h), REG_EAX); + emit_mov_m32_r32(dst, MABS(&m_state.r[regnum].w.h), REG_EAX); } - for (regnum = 0; regnum < ARRAY_LENGTH(drcbe->state.f); regnum++) + for (int regnum = 0; regnum < ARRAY_LENGTH(m_state.f); regnum++) { - int regoffsl = (int)&((drcuml_machine_state *)NULL)->f[regnum].s.l; - int regoffsh = (int)&((drcuml_machine_state *)NULL)->f[regnum].s.h; + FPTR regoffsl = (FPTR)&((drcuml_machine_state *)NULL)->f[regnum].s.l; + FPTR regoffsh = (FPTR)&((drcuml_machine_state *)NULL)->f[regnum].s.h; emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ECX, regoffsl)); - emit_mov_m32_r32(dst, MABS(&drcbe->state.f[regnum].s.l), REG_EAX); + emit_mov_m32_r32(dst, MABS(&m_state.f[regnum].s.l), REG_EAX); emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ECX, regoffsh)); - emit_mov_m32_r32(dst, MABS(&drcbe->state.f[regnum].s.h), REG_EAX); + emit_mov_m32_r32(dst, MABS(&m_state.f[regnum].s.h), REG_EAX); } emit_movzx_r32_m8(dst, REG_EAX, MBD(REG_ECX, offsetof(drcuml_machine_state, fmod)));// movzx eax,state->fmod emit_and_r32_imm(dst, REG_EAX, 3); // and eax,3 - emit_mov_m8_r8(dst, MABS(&drcbe->state.fmod), REG_AL); // mov [fmod],al - emit_fldcw_m16(dst, MISD(REG_EAX, 2, &fp_control[0])); // fldcw fp_control[eax] + emit_mov_m8_r8(dst, MABS(&m_state.fmod), REG_AL); // mov [fmod],al + emit_fldcw_m16(dst, MABSI(&fp_control[0], REG_EAX, 2)); // fldcw fp_control[eax] emit_mov_r32_m32(dst, REG_EAX, MBD(REG_ECX, offsetof(drcuml_machine_state, exp))); // mov eax,state->exp - emit_mov_m32_r32(dst, MABS(&drcbe->state.exp), REG_EAX); // mov [exp],eax + emit_mov_m32_r32(dst, MABS(&m_state.exp), REG_EAX); // mov [exp],eax emit_movzx_r32_m8(dst, REG_EAX, MBD(REG_ECX, offsetof(drcuml_machine_state, flags)));// movzx eax,state->flags - emit_push_m32(dst, MISD(REG_EAX, 4, flags_unmap)); // push flags_unmap[eax*4] + emit_push_m32(dst, MABSI(flags_unmap, REG_EAX, 4)); // push flags_unmap[eax*4] emit_popf(dst); // popf emit_ret(dst); // ret - if (drcbe->log != NULL && !drcbe->logged_common) - x86log_disasm_code_range(drcbe->log, "restore", drcbe->restore, *dst); + if (m_log != NULL && !m_logged_common) + x86log_disasm_code_range(m_log, "restore", m_restore, dst); - /* finish up codegen */ - drcbe->cache->end_codegen(); - drcbe->logged_common = TRUE; + // finish up codegen + *cachetop = dst; + m_cache.end_codegen(); + m_logged_common = true; - /* reset our hash tables */ - drcbe->hash->reset(); - drcbe->hash->set_default_codeptr(drcbe->nocode); + // reset our hash tables + m_hash.reset(); + m_hash.set_default_codeptr(m_nocode); } -/*------------------------------------------------- - drcbex86_execute - execute a block of code - referenced by the given handle --------------------------------------------------*/ +//------------------------------------------------- +// drcbex86_execute - execute a block of code +// referenced by the given handle +//------------------------------------------------- -static int drcbex86_execute(drcbe_state *drcbe, drcuml_codehandle *entry) +int drcbe_x86::execute(code_handle &entry) { - /* call our entry point which will jump to the destination */ - return (*drcbe->entry)((x86code *)drcuml_handle_codeptr(entry)); + // call our entry point which will jump to the destination + return (*m_entry)((x86code *)entry.codeptr()); } -/*------------------------------------------------- - drcbex86_generate - generate code --------------------------------------------------*/ +//------------------------------------------------- +// drcbex86_generate - generate code +//------------------------------------------------- -static void drcbex86_generate(drcbe_state *drcbe, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst) +void drcbe_x86::generate(drcuml_block &block, const instruction *instlist, UINT32 numinst) { - const char *blockname = NULL; - char blockbuffer[100]; - drccodeptr *cachetop; - x86code *base; - x86code *dst; - int inum; - - /* tell all of our utility objects that a block is beginning */ - drcbe->hash->block_begin(*block, instlist, numinst); - drcbe->labels->block_begin(*block); - drcbe->map->block_begin(*block); - - /* begin codegen; fail if we can't */ - cachetop = drcbe->cache->begin_codegen(numinst * 8 * 4); + // tell all of our utility objects that a block is beginning + m_hash.block_begin(block, instlist, numinst); + m_labels.block_begin(block); + m_map.block_begin(block); + + // begin codegen; fail if we can't + drccodeptr *cachetop = m_cache.begin_codegen(numinst * 8 * 4); if (cachetop == NULL) - drcuml_block_abort(block); + block.abort(); - /* compute the base by aligning the cache top to a cache line (assumed to be 64 bytes) */ - base = (x86code *)(((FPTR)*cachetop + 63) & ~63); - dst = base; + // compute the base by aligning the cache top to a cache line (assumed to be 64 bytes) + x86code *base = (x86code *)(((FPTR)*cachetop + 63) & ~63); + x86code *dst = base; - /* generate code */ - for (inum = 0; inum < numinst; inum++) + // generate code + astring tempstring; + const char *blockname = NULL; + for (int inum = 0; inum < numinst; inum++) { - const drcuml_instruction *inst = &instlist[inum]; - assert(inst->opcode < ARRAY_LENGTH(opcode_table)); + const instruction &inst = instlist[inum]; + assert(inst.opcode() < ARRAY_LENGTH(s_opcode_table)); - /* add a comment */ - if (drcbe->log != NULL) + // add a comment + if (m_log != NULL) { - char dasm[256]; - drcuml_disasm(inst, dasm, drcbe->drcuml); - x86log_add_comment(drcbe->log, dst, "%s", dasm); + astring dasm; + inst.disasm(dasm, &m_drcuml); + x86log_add_comment(m_log, dst, "%s", dasm.cstr()); } - /* extract a blockname */ + // extract a blockname if (blockname == NULL) { - if (inst->opcode == DRCUML_OP_HANDLE) - blockname = drcuml_handle_name((drcuml_codehandle *)(FPTR)inst->param[0].value); - else if (inst->opcode == DRCUML_OP_HASH) - { - sprintf(blockbuffer, "Code: mode=%d PC=%08X", (UINT32)inst->param[0].value, (offs_t)inst->param[1].value); - blockname = blockbuffer; - } + if (inst.opcode() == OP_HANDLE) + blockname = inst.param(0).handle().string(); + else if (inst.opcode() == OP_HASH) + blockname = tempstring.format("Code: mode=%d PC=%08X", (UINT32)inst.param(0).immediate(), (offs_t)inst.param(1).immediate()); } - /* generate code */ - dst = (*opcode_table[inst->opcode])(drcbe, dst, inst); + // generate code + (this->*s_opcode_table[inst.opcode()])(dst, inst); } - /* complete codegen */ + // complete codegen *cachetop = (drccodeptr)dst; - drcbe->cache->end_codegen(); + m_cache.end_codegen(); - /* log it */ - if (drcbe->log != NULL) - x86log_disasm_code_range(drcbe->log, (blockname == NULL) ? "Unknown block" : blockname, base, drcbe->cache->top()); + // log it + if (m_log != NULL) + x86log_disasm_code_range(m_log, (blockname == NULL) ? "Unknown block" : blockname, base, m_cache.top()); - /* tell all of our utility objects that the block is finished */ - drcbe->hash->block_end(*block); - drcbe->labels->block_end(*block); - drcbe->map->block_end(*block); + // tell all of our utility objects that the block is finished + m_hash.block_end(block); + m_labels.block_end(block); + m_map.block_end(block); } -/*------------------------------------------------- - drcbex86_hash_exists - return true if the - given mode/pc exists in the hash table --------------------------------------------------*/ +//------------------------------------------------- +// drcbex86_hash_exists - return true if the +// given mode/pc exists in the hash table +//------------------------------------------------- -static int drcbex86_hash_exists(drcbe_state *drcbe, UINT32 mode, UINT32 pc) +bool drcbe_x86::hash_exists(UINT32 mode, UINT32 pc) { - return drcbe->hash->code_exists(mode, pc); + return m_hash.code_exists(mode, pc); } -/*------------------------------------------------- - drcbex86_get_info - return information about - the back-end implementation --------------------------------------------------*/ +//------------------------------------------------- +// drcbex86_get_info - return information about +// the back-end implementation +//------------------------------------------------- -static void drcbex86_get_info(drcbe_state *state, drcbe_info *info) +void drcbe_x86::get_info(drcbe_info &info) { - for (info->direct_iregs = 0; info->direct_iregs < DRCUML_REG_I_END - DRCUML_REG_I0; info->direct_iregs++) - if (int_register_map[info->direct_iregs] == 0) - break; - info->direct_fregs = 0; -} - - - -/*************************************************************************** - COMPILE HELPERS -***************************************************************************/ - -/*------------------------------------------------- - param_normalize - convert a full parameter - into a reduced set --------------------------------------------------*/ - -static void param_normalize(drcbe_state *drcbe, const drcuml_parameter *src, drcuml_parameter *dest, UINT32 allowed) -{ - int regnum; - - switch (src->type) - { - /* immediates pass through */ - case DRCUML_PTYPE_IMMEDIATE: - assert(allowed & PTYPE_I); - dest->type = DRCUML_PTYPE_IMMEDIATE; - dest->value = src->value; - break; - - /* memory passes through */ - case DRCUML_PTYPE_MEMORY: - assert(allowed & PTYPE_M); - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = src->value; - break; - - /* if a register maps to a register, keep it as a register; otherwise map it to memory */ - case DRCUML_PTYPE_INT_REGISTER: - assert(allowed & PTYPE_R); - assert(allowed & PTYPE_M); - regnum = int_register_map[src->value - DRCUML_REG_I0]; - if (regnum != 0) - { - dest->type = DRCUML_PTYPE_INT_REGISTER; - dest->value = regnum; - } - else - { - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = (FPTR)&drcbe->state.r[src->value - DRCUML_REG_I0]; - } - break; - - /* all floating point registers map to memory */ - case DRCUML_PTYPE_FLOAT_REGISTER: - assert(allowed & PTYPE_F); - assert(allowed & PTYPE_M); - dest->type = DRCUML_PTYPE_MEMORY; - dest->value = (FPTR)&drcbe->state.f[src->value - DRCUML_REG_F0]; - break; - - /* everything else is unexpected */ - default: - fatalerror("Unexpected parameter type"); + for (info.direct_iregs = 0; info.direct_iregs < REG_I_COUNT; info.direct_iregs++) + if (int_register_map[info.direct_iregs] == 0) break; - } -} - - -/*------------------------------------------------- - param_normalize_1 - normalize a single - parameter instruction --------------------------------------------------*/ - -static void param_normalize_1(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0) -{ - assert(inst->numparams == 1); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); -} - - -/*------------------------------------------------- - param_normalize_2 - normalize a 2 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_2(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1) -{ - assert(inst->numparams == 2); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); -} - - -/*------------------------------------------------- - param_normalize_2_commutative - normalize a 2 - parameter instruction, shuffling the - parameters on the assumption that the two - parameters can be swapped --------------------------------------------------*/ - -static void param_normalize_2_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1) -{ - param_normalize_2(drcbe, inst, dest0, allowed0, dest1, allowed1); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest0->type == DRCUML_PTYPE_MEMORY) - { - drcuml_parameter temp = *dest0; - *dest0 = *dest1; - *dest1 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest0->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest0; - *dest0 = *dest1; - *dest1 = temp; - } + info.direct_fregs = 0; } -/*------------------------------------------------- - param_normalize_3 - normalize a 3 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_3(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2) -{ - assert(inst->numparams == 3); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); - param_normalize(drcbe, &inst->param[2], dest2, allowed2); -} +//************************************************************************** +// EMITTERS FOR 32-BIT OPERATIONS WITH PARAMETERS +//************************************************************************** -/*------------------------------------------------- - param_normalize_3_commutative - normalize a 3 - parameter instruction, shuffling the - parameters on the assumption that the last - 2 can be swapped --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r32_p32 - move a 32-bit parameter +// into a register +//------------------------------------------------- -static void param_normalize_3_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2) +void drcbe_x86::emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - param_normalize_3(drcbe, inst, dest0, allowed0, dest1, allowed1, dest2, allowed2); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest1->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest1->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } - - /* if the destination and outer parameters are equal, move the outer to the inner */ - if (dest0->type == dest2->type && dest0->value == dest2->value && dest0->type != DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest1; - *dest1 = *dest2; - *dest2 = temp; - } -} - - -/*------------------------------------------------- - param_normalize_4 - normalize a 4 - parameter instruction --------------------------------------------------*/ - -static void param_normalize_4(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2, drcuml_parameter *dest3, UINT32 allowed3) -{ - assert(inst->numparams == 4); - param_normalize(drcbe, &inst->param[0], dest0, allowed0); - param_normalize(drcbe, &inst->param[1], dest1, allowed1); - param_normalize(drcbe, &inst->param[2], dest2, allowed2); - param_normalize(drcbe, &inst->param[3], dest3, allowed3); -} - - -/*------------------------------------------------- - param_normalize_4_commutative - normalize a 4 - parameter instruction, shuffling the - parameters on the assumption that the last - 2 can be swapped --------------------------------------------------*/ - -static void param_normalize_4_commutative(drcbe_state *drcbe, const drcuml_instruction *inst, drcuml_parameter *dest0, UINT32 allowed0, drcuml_parameter *dest1, UINT32 allowed1, drcuml_parameter *dest2, UINT32 allowed2, drcuml_parameter *dest3, UINT32 allowed3) -{ - param_normalize_4(drcbe, inst, dest0, allowed0, dest1, allowed1, dest2, allowed2, dest3, allowed3); - - /* if the inner parameter is a memory operand, push it to the outer */ - if (dest2->type == DRCUML_PTYPE_MEMORY) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } - - /* if the inner parameter is an immediate, push it to the outer */ - if (dest2->type == DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } - - /* if the destination and outer parameters are equal, move the outer to the inner */ - if (dest0->type == dest3->type && dest0->value == dest3->value && dest0->type != DRCUML_PTYPE_IMMEDIATE) - { - drcuml_parameter temp = *dest2; - *dest2 = *dest3; - *dest3 = temp; - } -} - - - -/*************************************************************************** - EMITTERS FOR 32-BIT OPERATIONS WITH PARAMETERS -***************************************************************************/ - -/*------------------------------------------------- - emit_mov_r32_p32 - move a 32-bit parameter - into a register --------------------------------------------------*/ - -static void emit_mov_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) -{ - if (param->type == DRCUML_PTYPE_IMMEDIATE) - { - if (param->value == 0) + if (param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg else - emit_mov_r32_imm(dst, reg, param->value); // mov reg,param + emit_mov_r32_imm(dst, reg, param.immediate()); // mov reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_mov_r32_m32(dst, reg, MABS(param->value)); // mov reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_memory()) + emit_mov_r32_m32(dst, reg, MABS(param.memory())); // mov reg,[param] + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r32_r32(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_mov_r32_p32_keepflags - move a 32-bit - parameter into a register without affecting - any flags --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r32_p32_keepflags - move a 32-bit +// parameter into a register without affecting +// any flags +//------------------------------------------------- -static void emit_mov_r32_p32_keepflags(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param) +void drcbe_x86::emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r32_imm(dst, reg, param->value); // mov reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) + emit_mov_r32_imm(dst, reg, param.immediate()); // mov reg,param + else if (param.is_memory()) { - if (!can_skip_lower_load(drcbe, *dst, (UINT32 *)((FPTR)param->value), reg)) - emit_mov_r32_m32(dst, reg, MABS(param->value)); // mov reg,[param] + if (!can_skip_lower_load(dst, (UINT32 *)((FPTR)param.memory()), reg)) + emit_mov_r32_m32(dst, reg, MABS(param.memory())); // mov reg,[param] } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, reg, param->value); // mov reg,param + if (reg != param.ireg()) + emit_mov_r32_r32(dst, reg, param.ireg()); // mov reg,param } } -/*------------------------------------------------- - emit_mov_m32_p32 - move a 32-bit parameter - into a memory location --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_m32_p32 - move a 32-bit parameter +// into a memory location +//------------------------------------------------- -static void emit_mov_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param) +void drcbe_x86::emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_m32_imm(dst, MEMPARAMS, param->value); // mov [mem],param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) + emit_mov_m32_imm(dst, memref, param.immediate()); // mov [mem],param + else if (param.is_memory()) { - if (!can_skip_lower_load(drcbe, *dst, (UINT32 *)((FPTR)param->value), REG_EAX)) - emit_mov_r32_m32(dst, REG_EAX, MABS(param->value)); // mov eax,[param] - emit_mov_m32_r32(dst, MEMPARAMS, REG_EAX); // mov [mem],eax + if (!can_skip_lower_load(dst, (UINT32 *)((FPTR)param.memory()), REG_EAX)) + emit_mov_r32_m32(dst, REG_EAX, MABS(param.memory())); // mov eax,[param] + emit_mov_m32_r32(dst, memref, REG_EAX); // mov [mem],eax } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(dst, MEMPARAMS, param->value); // mov [mem],param + else if (param.is_int_register()) + emit_mov_m32_r32(dst, memref, param.ireg()); // mov [mem],param } -/*------------------------------------------------- - emit_mov_p32_r32 - move a register into a - 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_p32_r32 - move a register into a +// 32-bit parameter +//------------------------------------------------- -static void emit_mov_p32_r32(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reg) +void drcbe_x86::emit_mov_p32_r32(x86code *&dst, const be_parameter ¶m, UINT8 reg) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) + assert(!param.is_immediate()); + if (param.is_memory()) { - emit_mov_m32_r32(dst, MABS(param->value), reg); // mov [param],reg - set_last_lower_reg(drcbe, *dst, param, reg); + emit_mov_m32_r32(dst, MABS(param.memory()), reg); // mov [param],reg + set_last_lower_reg(dst, param, reg); } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - if (reg != param->value) - emit_mov_r32_r32(dst, param->value, reg); // mov param,reg + if (reg != param.ireg()) + emit_mov_r32_r32(dst, param.ireg(), reg); // mov param,reg } } -/*------------------------------------------------- - emit_add_r32_p32 - add operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_r32_p32 - add operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_add_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_add_r32_imm(dst, reg, param->value); // add reg,param + if (inst.flags() != 0 || param.immediate() != 0) + emit_add_r32_imm(dst, reg, param.immediate()); // add reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_add_r32_m32(dst, reg, MABS(param->value)); // add reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_add_r32_r32(dst, reg, param->value); // add reg,param + else if (param.is_memory()) + emit_add_r32_m32(dst, reg, MABS(param.memory())); // add reg,[param] + else if (param.is_int_register()) + emit_add_r32_r32(dst, reg, param.ireg()); // add reg,param } -/*------------------------------------------------- - emit_add_m32_p32 - add operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_m32_p32 - add operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_add_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_add_m32_imm(dst, MEMPARAMS, param->value); // add [dest],param + if (inst.flags() != 0 || param.immediate() != 0) + emit_add_m32_imm(dst, memref, param.immediate()); // add [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_add_m32_r32(dst, MEMPARAMS, reg); // add [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_add_m32_r32(dst, memref, reg); // add [dest],reg } } -/*------------------------------------------------- - emit_adc_r32_p32 - adc operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_r32_p32 - adc operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_adc_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_adc_r32_imm(dst, reg, param->value); // adc reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_adc_r32_m32(dst, reg, MABS(param->value)); // adc reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_adc_r32_r32(dst, reg, param->value); // adc reg,param + if (param.is_immediate()) + emit_adc_r32_imm(dst, reg, param.immediate()); // adc reg,param + else if (param.is_memory()) + emit_adc_r32_m32(dst, reg, MABS(param.memory())); // adc reg,[param] + else if (param.is_int_register()) + emit_adc_r32_r32(dst, reg, param.ireg()); // adc reg,param } -/*------------------------------------------------- - emit_adc_m32_p32 - adc operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_m32_p32 - adc operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_adc_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_adc_m32_imm(dst, MEMPARAMS, param->value); // adc [dest],param + if (param.is_immediate()) + emit_adc_m32_imm(dst, memref, param.immediate()); // adc [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_adc_m32_r32(dst, MEMPARAMS, reg); // adc [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32_keepflags(dst, reg, param); // mov reg,param + emit_adc_m32_r32(dst, memref, reg); // adc [dest],reg } } -/*------------------------------------------------- - emit_sub_r32_p32 - sub operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_r32_p32 - sub operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sub_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_sub_r32_imm(dst, reg, param->value); // sub reg,param + if (inst.flags() != 0 || param.immediate() != 0) + emit_sub_r32_imm(dst, reg, param.immediate()); // sub reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sub_r32_m32(dst, reg, MABS(param->value)); // sub reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sub_r32_r32(dst, reg, param->value); // sub reg,param + else if (param.is_memory()) + emit_sub_r32_m32(dst, reg, MABS(param.memory())); // sub reg,[param] + else if (param.is_int_register()) + emit_sub_r32_r32(dst, reg, param.ireg()); // sub reg,param } -/*------------------------------------------------- - emit_sub_m32_p32 - sub operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_m32_p32 - sub operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sub_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags != 0 || param->value != 0) - emit_sub_m32_imm(dst, MEMPARAMS, param->value); // sub [dest],param + if (inst.flags() != 0 || param.immediate() != 0) + emit_sub_m32_imm(dst, memref, param.immediate()); // sub [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_sub_m32_r32(dst, MEMPARAMS, reg); // sub [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_sub_m32_r32(dst, memref, reg); // sub [dest],reg } } -/*------------------------------------------------- - emit_sbb_r32_p32 - sbb operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_r32_p32 - sbb operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sbb_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_sbb_r32_imm(dst, reg, param->value); // sbb reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_sbb_r32_m32(dst, reg, MABS(param->value)); // sbb reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_sbb_r32_r32(dst, reg, param->value); // sbb reg,param + if (param.is_immediate()) + emit_sbb_r32_imm(dst, reg, param.immediate()); // sbb reg,param + else if (param.is_memory()) + emit_sbb_r32_m32(dst, reg, MABS(param.memory())); // sbb reg,[param] + else if (param.is_int_register()) + emit_sbb_r32_r32(dst, reg, param.ireg()); // sbb reg,param } -/*------------------------------------------------- - emit_sbb_m32_p32 - sbb operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_m32_p32 - sbb operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sbb_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_sbb_m32_imm(dst, MEMPARAMS, param->value); // sbb [dest],param + if (param.is_immediate()) + emit_sbb_m32_imm(dst, memref, param.immediate()); // sbb [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32_keepflags(drcbe, dst, reg, param); // mov reg,param - emit_sbb_m32_r32(dst, MEMPARAMS, reg); // sbb [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32_keepflags(dst, reg, param); // mov reg,param + emit_sbb_m32_r32(dst, memref, reg); // sbb [dest],reg } } -/*------------------------------------------------- - emit_cmp_r32_p32 - cmp operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_r32_p32 - cmp operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_cmp_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_cmp_r32_imm(dst, reg, param->value); // cmp reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_cmp_r32_m32(dst, reg, MABS(param->value)); // cmp reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_cmp_r32_r32(dst, reg, param->value); // cmp reg,param + if (param.is_immediate()) + emit_cmp_r32_imm(dst, reg, param.immediate()); // cmp reg,param + else if (param.is_memory()) + emit_cmp_r32_m32(dst, reg, MABS(param.memory())); // cmp reg,[param] + else if (param.is_int_register()) + emit_cmp_r32_r32(dst, reg, param.ireg()); // cmp reg,param } -/*------------------------------------------------- - emit_cmp_m32_p32 - cmp operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_m32_p32 - cmp operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_cmp_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_cmp_m32_imm(dst, MEMPARAMS, param->value); // cmp [dest],param + if (param.is_immediate()) + emit_cmp_m32_imm(dst, memref, param.immediate()); // cmp [dest],param else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_cmp_m32_r32(dst, MEMPARAMS, reg); // cmp [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_cmp_m32_r32(dst, memref, reg); // cmp [dest],reg } } -/*------------------------------------------------- - emit_and_r32_p32 - and operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_r32_p32 - and operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_and_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) emit_xor_r32_r32(dst, reg, reg); // xor reg,reg else - emit_and_r32_imm(dst, reg, param->value); // and reg,param + emit_and_r32_imm(dst, reg, param.immediate()); // and reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_and_r32_m32(dst, reg, MABS(param->value)); // and reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_and_r32_r32(dst, reg, param->value); // and reg,param + else if (param.is_memory()) + emit_and_r32_m32(dst, reg, MABS(param.memory())); // and reg,[param] + else if (param.is_int_register()) + emit_and_r32_r32(dst, reg, param.ireg()); // and reg,param } -/*------------------------------------------------- - emit_and_m32_p32 - and operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_m32_p32 - and operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_and_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) - emit_mov_m32_imm(dst, MEMPARAMS, 0); // mov [dest],0 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + emit_mov_m32_imm(dst, memref, 0); // mov [dest],0 else - emit_and_m32_imm(dst, MEMPARAMS, param->value); // and [dest],param + emit_and_m32_imm(dst, memref, param.immediate()); // and [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_and_m32_r32(dst, MEMPARAMS, reg); // and [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_and_m32_r32(dst, memref, reg); // and [dest],reg } } -/*------------------------------------------------- - emit_test_r32_p32 - test operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_r32_p32 - test operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_test_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_test_r32_imm(dst, reg, param->value); // test reg,param - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_test_m32_r32(dst, MABS(param->value), reg); // test [param],reg - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_r32_r32(dst, reg, param->value); // test reg,param + if (param.is_immediate()) + emit_test_r32_imm(dst, reg, param.immediate()); // test reg,param + else if (param.is_memory()) + emit_test_m32_r32(dst, MABS(param.memory()), reg); // test [param],reg + else if (param.is_int_register()) + emit_test_r32_r32(dst, reg, param.ireg()); // test reg,param } -/*------------------------------------------------- - emit_test_m32_p32 - test operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_m32_p32 - test operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_test_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) - emit_test_m32_imm(dst, MEMPARAMS, param->value); // test [dest],param - else if (param->type == DRCUML_PTYPE_MEMORY) + if (param.is_immediate()) + emit_test_m32_imm(dst, memref, param.immediate()); // test [dest],param + else if (param.is_memory()) { - emit_mov_r32_p32(drcbe, dst, REG_EAX, param); // mov reg,param - emit_test_m32_r32(dst, MEMPARAMS, REG_EAX); // test [dest],reg + emit_mov_r32_p32(dst, REG_EAX, param); // mov reg,param + emit_test_m32_r32(dst, memref, REG_EAX); // test [dest],reg } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_test_m32_r32(dst, MEMPARAMS, param->value); // test [dest],param + else if (param.is_int_register()) + emit_test_m32_r32(dst, memref, param.ireg()); // test [dest],param } -/*------------------------------------------------- - emit_or_r32_p32 - or operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_r32_p32 - or operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_or_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_mov_r32_imm(dst, reg, ~0); // mov reg,-1 else - emit_or_r32_imm(dst, reg, param->value); // or reg,param + emit_or_r32_imm(dst, reg, param.immediate()); // or reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_or_r32_m32(dst, reg, MABS(param->value)); // or reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_or_r32_r32(dst, reg, param->value); // or reg,param + else if (param.is_memory()) + emit_or_r32_m32(dst, reg, MABS(param.memory())); // or reg,[param] + else if (param.is_int_register()) + emit_or_r32_r32(dst, reg, param.ireg()); // or reg,param } -/*------------------------------------------------- - emit_or_m32_p32 - or operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_m32_p32 - or operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_or_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_mov_m32_imm(dst, MEMPARAMS, ~0); // mov [dest],-1 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_mov_m32_imm(dst, memref, ~0); // mov [dest],-1 else - emit_or_m32_imm(dst, MEMPARAMS, param->value); // or [dest],param + emit_or_m32_imm(dst, memref, param.immediate()); // or [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_or_m32_r32(dst, MEMPARAMS, reg); // or [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_or_m32_r32(dst, memref, reg); // or [dest],reg } } -/*------------------------------------------------- - emit_xor_r32_p32 - xor operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_r32_p32 - xor operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_xor_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_not_r32(dst, reg); // not reg else - emit_xor_r32_imm(dst, reg, param->value); // xor reg,param + emit_xor_r32_imm(dst, reg, param.immediate()); // xor reg,param } - else if (param->type == DRCUML_PTYPE_MEMORY) - emit_xor_r32_m32(dst, reg, MABS(param->value)); // xor reg,[param] - else if (param->type == DRCUML_PTYPE_INT_REGISTER) - emit_xor_r32_r32(dst, reg, param->value); // xor reg,param + else if (param.is_memory()) + emit_xor_r32_m32(dst, reg, MABS(param.memory())); // xor reg,[param] + else if (param.is_int_register()) + emit_xor_r32_r32(dst, reg, param.ireg()); // xor reg,param } -/*------------------------------------------------- - emit_xor_m32_p32 - xor operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_m32_p32 - xor operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_xor_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_not_m32(dst, MEMPARAMS); // not [dest] + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_not_m32(dst, memref); // not [dest] else - emit_xor_m32_imm(dst, MEMPARAMS, param->value); // xor [dest],param + emit_xor_m32_imm(dst, memref, param.immediate()); // xor [dest],param } else { - int reg = param_select_register(REG_EAX, param, NULL); - emit_mov_r32_p32(drcbe, dst, reg, param); // mov reg,param - emit_xor_m32_r32(dst, MEMPARAMS, reg); // xor [dest],reg + int reg = param.select_register(REG_EAX); + emit_mov_r32_p32(dst, reg, param); // mov reg,param + emit_xor_m32_r32(dst, memref, reg); // xor [dest],reg } } -/*------------------------------------------------- - emit_shl_r32_p32 - shl operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_r32_p32 - shl operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_shl_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shl_r32_imm(dst, reg, param->value); // shl reg,param + emit_shl_r32_imm(dst, reg, param.immediate()); // shl reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_shl_r32_cl(dst, reg); // shl reg,cl } } -/*------------------------------------------------- - emit_shl_m32_p32 - shl operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_m32_p32 - shl operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_shl_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shl_m32_imm(dst, MEMPARAMS, param->value); // shl [dest],param + emit_shl_m32_imm(dst, memref, param.immediate()); // shl [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_shl_m32_cl(dst, MEMPARAMS); // shl [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_shl_m32_cl(dst, memref); // shl [dest],cl } } -/*------------------------------------------------- - emit_shr_r32_p32 - shr operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_r32_p32 - shr operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_shr_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shr_r32_imm(dst, reg, param->value); // shr reg,param + emit_shr_r32_imm(dst, reg, param.immediate()); // shr reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_shr_r32_cl(dst, reg); // shr reg,cl } } -/*------------------------------------------------- - emit_shr_m32_p32 - shr operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_m32_p32 - shr operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_shr_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_shr_m32_imm(dst, MEMPARAMS, param->value); // shr [dest],param + emit_shr_m32_imm(dst, memref, param.immediate()); // shr [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_shr_m32_cl(dst, MEMPARAMS); // shr [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_shr_m32_cl(dst, memref); // shr [dest],cl } } -/*------------------------------------------------- - emit_sar_r32_p32 - sar operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_r32_p32 - sar operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_sar_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_sar_r32_imm(dst, reg, param->value); // sar reg,param + emit_sar_r32_imm(dst, reg, param.immediate()); // sar reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_sar_r32_cl(dst, reg); // sar reg,cl } } -/*------------------------------------------------- - emit_sar_m32_p32 - sar operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_m32_p32 - sar operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_sar_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_sar_m32_imm(dst, MEMPARAMS, param->value); // sar [dest],param + emit_sar_m32_imm(dst, memref, param.immediate()); // sar [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_sar_m32_cl(dst, MEMPARAMS); // sar [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_sar_m32_cl(dst, memref); // sar [dest],cl } } -/*------------------------------------------------- - emit_rol_r32_p32 - rol operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_r32_p32 - rol operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rol_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rol_r32_imm(dst, reg, param->value); // rol reg,param + emit_rol_r32_imm(dst, reg, param.immediate()); // rol reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_rol_r32_cl(dst, reg); // rol reg,cl } } -/*------------------------------------------------- - emit_rol_m32_p32 - rol operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_m32_p32 - rol operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rol_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rol_m32_imm(dst, MEMPARAMS, param->value); // rol [dest],param + emit_rol_m32_imm(dst, memref, param.immediate()); // rol [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rol_m32_cl(dst, MEMPARAMS); // rol [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_rol_m32_cl(dst, memref); // rol [dest],cl } } -/*------------------------------------------------- - emit_ror_r32_p32 - ror operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_r32_p32 - ror operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_ror_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_ror_r32_imm(dst, reg, param->value); // ror reg,param + emit_ror_r32_imm(dst, reg, param.immediate()); // ror reg,param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_ror_r32_cl(dst, reg); // ror reg,cl } } -/*------------------------------------------------- - emit_ror_m32_p32 - ror operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_m32_p32 - ror operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_ror_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_ror_m32_imm(dst, MEMPARAMS, param->value); // ror [dest],param + emit_ror_m32_imm(dst, memref, param.immediate()); // ror [dest],param } else { - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_ror_m32_cl(dst, MEMPARAMS); // ror [dest],cl + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param + emit_ror_m32_cl(dst, memref); // ror [dest],cl } } -/*------------------------------------------------- - emit_rcl_r32_p32 - rcl operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_r32_p32 - rcl operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rcl_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcl_r32_imm(dst, reg, param->value); // rcl reg,param + emit_rcl_r32_imm(dst, reg, param.immediate()); // rcl reg,param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param emit_rcl_r32_cl(dst, reg); // rcl reg,cl } } -/*------------------------------------------------- - emit_rcl_m32_p32 - rcl operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_m32_p32 - rcl operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rcl_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcl_m32_imm(dst, MEMPARAMS, param->value); // rcl [dest],param + emit_rcl_m32_imm(dst, memref, param.immediate()); // rcl [dest],param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rcl_m32_cl(dst, MEMPARAMS); // rcl [dest],cl + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param + emit_rcl_m32_cl(dst, memref); // rcl [dest],cl } } -/*------------------------------------------------- - emit_rcr_r32_p32 - rcr operation to a 32-bit - register from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_r32_p32 - rcr operation to a 32-bit +// register from a 32-bit parameter +//------------------------------------------------- -static void emit_rcr_r32_p32(drcbe_state *drcbe, x86code **dst, UINT8 reg, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcr_r32_imm(dst, reg, param->value); // rcr reg,param + emit_rcr_r32_imm(dst, reg, param.immediate()); // rcr reg,param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param emit_rcr_r32_cl(dst, reg); // rcr reg,cl } } -/*------------------------------------------------- - emit_rcr_m32_p32 - rcr operation to a 32-bit - memory location from a 32-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_m32_p32 - rcr operation to a 32-bit +// memory location from a 32-bit parameter +//------------------------------------------------- -static void emit_rcr_m32_p32(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip else - emit_rcr_m32_imm(dst, MEMPARAMS, param->value); // rcr [dest],param + emit_rcr_m32_imm(dst, memref, param.immediate()); // rcr [dest],param } else { - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param - emit_rcr_m32_cl(dst, MEMPARAMS); // rcr [dest],cl + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param + emit_rcr_m32_cl(dst, memref); // rcr [dest],cl } } -/*************************************************************************** - EMITTERS FOR 64-BIT OPERATIONS WITH PARAMETERS -***************************************************************************/ +//************************************************************************** +// EMITTERS FOR 64-BIT OPERATIONS WITH PARAMETERS +//************************************************************************** -/*------------------------------------------------- - emit_mov_r64_p64 - move a 64-bit parameter - into a pair of registers --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r64_p64 - move a 64-bit parameter +// into a pair of registers +//------------------------------------------------- -static void emit_mov_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param) +void drcbe_x86::emit_mov_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { if (reglo == REG_NONE) ; - else if ((UINT32)param->value == 0) + else if ((UINT32)param.immediate() == 0) emit_xor_r32_r32(dst, reglo, reglo); // xor reglo,reglo else - emit_mov_r32_imm(dst, reglo, param->value); // mov reglo,param + emit_mov_r32_imm(dst, reglo, param.immediate()); // mov reglo,param if (reghi == REG_NONE) ; - else if ((UINT32)(param->value >> 32) == 0) + else if ((UINT32)(param.immediate() >> 32) == 0) emit_xor_r32_r32(dst, reghi, reghi); // xor reghi,reghi else - emit_mov_r32_imm(dst, reghi, param->value >> 32); // mov reghi,param >> 32 + emit_mov_r32_imm(dst, reghi, param.immediate() >> 32); // mov reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_MEMORY) + else if (param.is_memory()) { - int skip_lower = can_skip_lower_load(drcbe, *dst, (UINT32 *)((FPTR)param->value), reglo); - int skip_upper = can_skip_upper_load(drcbe, *dst, (UINT32 *)((FPTR)param->value + 4), reghi); + int skip_lower = can_skip_lower_load(dst, (UINT32 *)((FPTR)param.memory()), reglo); + int skip_upper = can_skip_upper_load(dst, (UINT32 *)((FPTR)param.memory(4)), reghi); if (reglo != REG_NONE && !skip_lower) - emit_mov_r32_m32(dst, reglo, MABS(param->value)); // mov reglo,[param] + emit_mov_r32_m32(dst, reglo, MABS(param.memory())); // mov reglo,[param] if (reghi != REG_NONE && !skip_upper) - emit_mov_r32_m32(dst, reghi, MABS(param->value + 4)); // mov reghi,[param+4] + emit_mov_r32_m32(dst, reghi, MABS(param.memory(4))); // mov reghi,[param+4] } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - int skip_upper = can_skip_upper_load(drcbe, *dst, drcbe->reghi[param->value], reghi); - if (reglo != REG_NONE && reglo != param->value) - emit_mov_r32_r32(dst, reglo, param->value); // mov reglo,param + int skip_upper = can_skip_upper_load(dst, m_reghi[param.ireg()], reghi); + if (reglo != REG_NONE && reglo != param.ireg()) + emit_mov_r32_r32(dst, reglo, param.ireg()); // mov reglo,param if (reghi != REG_NONE && !skip_upper) - emit_mov_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // mov reghi,reghi[param] + emit_mov_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // mov reghi,reghi[param] } } -/*------------------------------------------------- - emit_mov_r64_p64_keepflags - move a 64-bit - parameter into a pair of registers without - affecting any flags --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r64_p64_keepflags - move a 64-bit +// parameter into a pair of registers without +// affecting any flags +//------------------------------------------------- -static void emit_mov_r64_p64_keepflags(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param) +void drcbe_x86::emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { if (reglo != REG_NONE) - emit_mov_r32_imm(dst, reglo, param->value); // mov reglo,param + emit_mov_r32_imm(dst, reglo, param.immediate()); // mov reglo,param if (reghi != REG_NONE) - emit_mov_r32_imm(dst, reghi, param->value >> 32); // mov reghi,param >> 32 + emit_mov_r32_imm(dst, reghi, param.immediate() >> 32); // mov reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_MEMORY) + else if (param.is_memory()) { - int skip_lower = can_skip_lower_load(drcbe, *dst, (UINT32 *)((FPTR)param->value), reglo); - int skip_upper = can_skip_upper_load(drcbe, *dst, (UINT32 *)((FPTR)param->value + 4), reghi); + int skip_lower = can_skip_lower_load(dst, (UINT32 *)((FPTR)param.memory()), reglo); + int skip_upper = can_skip_upper_load(dst, (UINT32 *)((FPTR)param.memory(4)), reghi); if (reglo != REG_NONE && !skip_lower) - emit_mov_r32_m32(dst, reglo, MABS(param->value)); // mov reglo,[param] + emit_mov_r32_m32(dst, reglo, MABS(param.memory())); // mov reglo,[param] if (reghi != REG_NONE && !skip_upper) - emit_mov_r32_m32(dst, reghi, MABS(param->value + 4)); // mov reghi,[param+4] + emit_mov_r32_m32(dst, reghi, MABS(param.memory(4))); // mov reghi,[param+4] } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - int skip_upper = can_skip_upper_load(drcbe, *dst, drcbe->reghi[param->value], reghi); - if (reglo != REG_NONE && reglo != param->value) - emit_mov_r32_r32(dst, reglo, param->value); // mov reglo,param + int skip_upper = can_skip_upper_load(dst, m_reghi[param.ireg()], reghi); + if (reglo != REG_NONE && reglo != param.ireg()) + emit_mov_r32_r32(dst, reglo, param.ireg()); // mov reglo,param if (reghi != REG_NONE && !skip_upper) - emit_mov_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // mov reghi,reghi[param] + emit_mov_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // mov reghi,reghi[param] } } -/*------------------------------------------------- - emit_mov_m64_p64 - move a 64-bit parameter - into a memory location --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_m64_p64 - move a 64-bit parameter +// into a memory location +//------------------------------------------------- -static void emit_mov_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param) +void drcbe_x86::emit_mov_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m) { - if (param->type == DRCUML_PTYPE_IMMEDIATE) + if (param.is_immediate()) { - emit_mov_m32_imm(dst, MEMPARAMS + 0, param->value); // mov [mem],param - emit_mov_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // mov [mem],param >> 32 + emit_mov_m32_imm(dst, memref + 0, param.immediate()); // mov [mem],param + emit_mov_m32_imm(dst, memref + 4, param.immediate() >> 32); // mov [mem],param >> 32 } - else if (param->type == DRCUML_PTYPE_MEMORY) + else if (param.is_memory()) { - int skip_lower = can_skip_lower_load(drcbe, *dst, (UINT32 *)((FPTR)param->value), REG_EAX); + int skip_lower = can_skip_lower_load(dst, (UINT32 *)((FPTR)param.memory()), REG_EAX); if (!skip_lower) - emit_mov_r32_m32(dst, REG_EAX, MABS(param->value)); // mov eax,[param] - emit_mov_m32_r32(dst, MEMPARAMS + 0, REG_EAX); // mov [mem],eax - emit_mov_r32_m32(dst, REG_EAX, MABS(param->value + 4)); // mov eax,[param+4] - emit_mov_m32_r32(dst, MEMPARAMS + 4, REG_EAX); // mov [mem+4],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(param.memory())); // mov eax,[param] + emit_mov_m32_r32(dst, memref + 0, REG_EAX); // mov [mem],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(param.memory(4))); // mov eax,[param+4] + emit_mov_m32_r32(dst, memref + 4, REG_EAX); // mov [mem+4],eax } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_mov_m32_r32(dst, MEMPARAMS + 0, param->value); // mov [mem],param - emit_mov_r32_m32(dst, REG_EAX, MABS(drcbe->reghi[param->value])); // mov eax,[param.hi] - emit_mov_m32_r32(dst, MEMPARAMS + 4, REG_EAX); // mov [mem+4],eax + emit_mov_m32_r32(dst, memref + 0, param.ireg()); // mov [mem],param + emit_mov_r32_m32(dst, REG_EAX, MABS(m_reghi[param.ireg()])); // mov eax,[param.hi] + emit_mov_m32_r32(dst, memref + 4, REG_EAX); // mov [mem+4],eax } } -/*------------------------------------------------- - emit_mov_p64_r64 - move a pair of registers - into a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_p64_r64 - move a pair of registers +// into a 64-bit parameter +//------------------------------------------------- -static void emit_mov_p64_r64(drcbe_state *drcbe, x86code **dst, const drcuml_parameter *param, UINT8 reglo, UINT8 reghi) +void drcbe_x86::emit_mov_p64_r64(x86code *&dst, const be_parameter ¶m, UINT8 reglo, UINT8 reghi) { - assert(param->type != DRCUML_PTYPE_IMMEDIATE); - if (param->type == DRCUML_PTYPE_MEMORY) + assert(!param.is_immediate()); + if (param.is_memory()) { - emit_mov_m32_r32(dst, MABS(param->value), reglo); // mov [param],reglo - emit_mov_m32_r32(dst, MABS(param->value + 4), reghi); // mov [param+4],reghi + emit_mov_m32_r32(dst, MABS(param.memory()), reglo); // mov [param],reglo + emit_mov_m32_r32(dst, MABS(param.memory(4)), reghi); // mov [param+4],reghi } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - if (reglo != param->value) - emit_mov_r32_r32(dst, param->value, reglo); // mov param,reglo - emit_mov_m32_r32(dst, MABS(drcbe->reghi[param->value]), reghi); // mov reghi[param],reghi + if (reglo != param.ireg()) + emit_mov_r32_r32(dst, param.ireg(), reglo); // mov param,reglo + emit_mov_m32_r32(dst, MABS(m_reghi[param.ireg()]), reghi); // mov reghi[param],reghi } - set_last_lower_reg(drcbe, *dst, param, reglo); - set_last_upper_reg(drcbe, *dst, param, reghi); + set_last_lower_reg(dst, param, reglo); + set_last_upper_reg(dst, param, reghi); } -/*------------------------------------------------- - emit_add_r64_p64 - add operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_r64_p64 - add operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_add_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_add_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_add_r32_m32(dst, reglo, MABS(param->value)); // add reglo,[param] + emit_add_r32_m32(dst, reglo, MABS(param.memory())); // add reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_m32(dst, reghi, MABS(param->value + 4)); // adc reghi,[param] + emit_adc_r32_m32(dst, reghi, MABS(param.memory(4))); // adc reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_add_r32_imm(dst, reglo, param->value); // add reglo,param + emit_add_r32_imm(dst, reglo, param.immediate()); // add reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_imm(dst, reghi, param->value >> 32); // adc reghi,param >> 32 + emit_adc_r32_imm(dst, reghi, param.immediate() >> 32); // adc reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_add_r32_r32(dst, reglo, param->value); // add reglo,param + emit_add_r32_r32(dst, reglo, param.ireg()); // add reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // adc reghi,reghi[param] + emit_adc_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // adc reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_add_m64_p64 - add operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_add_m64_p64 - add operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_add_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - emit_add_m32_imm(dst, MEMPARAMS, param->value); // add [dest],param + emit_add_m32_imm(dst, memref, param.immediate()); // add [dest],param if (saveflags) emit_pushf(dst); // pushf - emit_adc_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // adc [dest+4],param >> 32 + emit_adc_m32_imm(dst, memref + 4, param.immediate() >> 32); // adc [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_add_m32_r32(dst, MEMPARAMS, reglo); // add [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_add_m32_r32(dst, memref, reglo); // add [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_adc_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // adc [dest+4],edx + emit_adc_m32_r32(dst, memref + 4, REG_EDX); // adc [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_adc_r64_p64 - adc operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_r64_p64 - adc operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_adc_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_adc_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_adc_r32_m32(dst, reglo, MABS(param->value)); // adc reglo,[param] + emit_adc_r32_m32(dst, reglo, MABS(param.memory())); // adc reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_m32(dst, reghi, MABS(param->value + 4)); // adc reghi,[param] + emit_adc_r32_m32(dst, reghi, MABS(param.memory(4))); // adc reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_adc_r32_imm(dst, reglo, param->value); // adc reglo,param + emit_adc_r32_imm(dst, reglo, param.immediate()); // adc reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_imm(dst, reghi, param->value >> 32); // adc reghi,param >> 32 + emit_adc_r32_imm(dst, reghi, param.immediate() >> 32); // adc reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_adc_r32_r32(dst, reglo, param->value); // adc reglo,param + emit_adc_r32_r32(dst, reglo, param.ireg()); // adc reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_adc_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // adc reghi,reghi[param] + emit_adc_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // adc reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_adc_m64_p64 - adc operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_adc_m64_p64 - adc operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_adc_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - emit_adc_m32_imm(dst, MEMPARAMS, param->value); // adc [dest],param + emit_adc_m32_imm(dst, memref, param.immediate()); // adc [dest],param if (saveflags) emit_pushf(dst); // pushf - emit_adc_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // adc [dest+4],param >> 32 + emit_adc_m32_imm(dst, memref + 4, param.immediate() >> 32); // adc [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64_keepflags(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_adc_m32_r32(dst, MEMPARAMS, reglo); // adc [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64_keepflags(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_adc_m32_r32(dst, memref, reglo); // adc [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_adc_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // adc [dest+4],edx + emit_adc_m32_r32(dst, memref + 4, REG_EDX); // adc [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_sub_r64_p64 - sub operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_r64_p64 - sub operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_sub_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sub_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_sub_r32_m32(dst, reglo, MABS(param->value)); // sub reglo,[param] + emit_sub_r32_m32(dst, reglo, MABS(param.memory())); // sub reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(param->value + 4)); // sbb reghi,[param] + emit_sbb_r32_m32(dst, reghi, MABS(param.memory(4))); // sbb reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_sub_r32_imm(dst, reglo, param->value); // sub reglo,param + emit_sub_r32_imm(dst, reglo, param.immediate()); // sub reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_imm(dst, reghi, param->value >> 32); // sbb reghi,param >> 32 + emit_sbb_r32_imm(dst, reghi, param.immediate() >> 32); // sbb reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_sub_r32_r32(dst, reglo, param->value); // sub reglo,param + emit_sub_r32_r32(dst, reglo, param.ireg()); // sub reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // sbb reghi,reghi[param] + emit_sbb_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // sbb reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_sub_m64_p64 - sub operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sub_m64_p64 - sub operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_sub_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - emit_sub_m32_imm(dst, MEMPARAMS, param->value); // sub [dest],param + emit_sub_m32_imm(dst, memref, param.immediate()); // sub [dest],param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // sbb [dest+4],param >> 32 + emit_sbb_m32_imm(dst, memref + 4, param.immediate() >> 32); // sbb [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_sub_m32_r32(dst, MEMPARAMS, reglo); // sub [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_sub_m32_r32(dst, memref, reglo); // sub [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_sbb_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // sbb [dest+4],edx + emit_sbb_m32_r32(dst, memref + 4, REG_EDX); // sbb [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_sbb_r64_p64 - sbb operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_r64_p64 - sbb operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_sbb_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sbb_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_sbb_r32_m32(dst, reglo, MABS(param->value)); // sbb reglo,[param] + emit_sbb_r32_m32(dst, reglo, MABS(param.memory())); // sbb reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(param->value + 4)); // sbb reghi,[param] + emit_sbb_r32_m32(dst, reghi, MABS(param.memory(4))); // sbb reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_sbb_r32_imm(dst, reglo, param->value); // sbb reglo,param + emit_sbb_r32_imm(dst, reglo, param.immediate()); // sbb reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_imm(dst, reghi, param->value >> 32); // sbb reghi,param >> 32 + emit_sbb_r32_imm(dst, reghi, param.immediate() >> 32); // sbb reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_sbb_r32_r32(dst, reglo, param->value); // sbb reglo,param + emit_sbb_r32_r32(dst, reglo, param.ireg()); // sbb reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // sbb reghi,reghi[param] + emit_sbb_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // sbb reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_sbb_m64_p64 - sbb operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sbb_m64_p64 - sbb operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_sbb_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - emit_sbb_m32_imm(dst, MEMPARAMS, param->value); // sbb [dest],param + emit_sbb_m32_imm(dst, memref, param.immediate()); // sbb [dest],param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // sbb [dest+4],param >> 32 + emit_sbb_m32_imm(dst, memref + 4, param.immediate() >> 32); // sbb [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64_keepflags(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_sbb_m32_r32(dst, MEMPARAMS, reglo); // sbb [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64_keepflags(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_sbb_m32_r32(dst, memref, reglo); // sbb [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_sbb_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // sbb [dest+4],edx + emit_sbb_m32_r32(dst, memref + 4, REG_EDX); // sbb [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_cmp_r64_p64 - sub operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_cmp_r64_p64 - sub operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_cmp_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_cmp_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = (inst->flags != DRCUML_FLAG_Z && (inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = (inst.flags() != FLAG_Z && (inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_sub_r32_m32(dst, reglo, MABS(param->value)); // sub reglo,[param] + emit_sub_r32_m32(dst, reglo, MABS(param.memory())); // sub reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(param->value + 4)); // sbb reghi,[param] + emit_sbb_r32_m32(dst, reghi, MABS(param.memory(4))); // sbb reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_sub_r32_imm(dst, reglo, param->value); // sub reglo,param + emit_sub_r32_imm(dst, reglo, param.immediate()); // sub reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_imm(dst, reghi, param->value >> 32); // sbb reghi,param >> 32 + emit_sbb_r32_imm(dst, reghi, param.immediate() >> 32); // sbb reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_sub_r32_r32(dst, reglo, param->value); // sub reglo,param + emit_sub_r32_r32(dst, reglo, param.ireg()); // sub reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_sbb_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // sbb reghi,reghi[param] + emit_sbb_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // sbb reghi,reghi[param] } - if (inst->flags == DRCUML_FLAG_Z) + if (inst.flags() == FLAG_Z) emit_or_r32_r32(dst, reghi, reglo); // or reghi,reglo else if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_and_r64_p64 - and operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_r64_p64 - and operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_and_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_and_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_and_r32_m32(dst, reglo, MABS(param->value)); // and reglo,[param] + emit_and_r32_m32(dst, reglo, MABS(param.memory())); // and reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_and_r32_m32(dst, reghi, MABS(param->value + 4)); // and reghi,[param] + emit_and_r32_m32(dst, reghi, MABS(param.memory(4))); // and reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) emit_xor_r32_r32(dst, reglo, reglo); // xor reglo,reglo else - emit_and_r32_imm(dst, reglo, param->value); // and reglo,param + emit_and_r32_imm(dst, reglo, param.immediate()); // and reglo,param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) emit_xor_r32_r32(dst, reghi, reghi); // xor reghi,reghi else - emit_and_r32_imm(dst, reghi, param->value >> 32); // and reghi,param >> 32 + emit_and_r32_imm(dst, reghi, param.immediate() >> 32); // and reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_and_r32_r32(dst, reglo, param->value); // and reglo,param + emit_and_r32_r32(dst, reglo, param.ireg()); // and reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_and_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // and reghi,reghi[param] + emit_and_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // and reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_and_m64_p64 - and operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_and_m64_p64 - and operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_and_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0) - emit_mov_m32_imm(dst, MEMPARAMS, 0); // mov [dest],0 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + emit_mov_m32_imm(dst, memref, 0); // mov [dest],0 else - emit_and_m32_imm(dst, MEMPARAMS, param->value); // and [dest],param + emit_and_m32_imm(dst, memref, param.immediate()); // and [dest],param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) - emit_mov_m32_imm(dst, MEMPARAMS + 4, 0); // mov [dest+4],0 + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) + emit_mov_m32_imm(dst, memref + 4, 0); // mov [dest+4],0 else - emit_and_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // and [dest+4],param >> 32 + emit_and_m32_imm(dst, memref + 4, param.immediate() >> 32); // and [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_and_m32_r32(dst, MEMPARAMS, reglo); // and [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_and_m32_r32(dst, memref, reglo); // and [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_and_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // and [dest+4],edx + emit_and_m32_r32(dst, memref + 4, REG_EDX); // and [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_test_r64_p64 - test operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_r64_p64 - test operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_test_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_test_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_test_m32_r32(dst, MABS(param->value), reglo); // test [param],reglo + emit_test_m32_r32(dst, MABS(param.memory()), reglo); // test [param],reglo if (saveflags) emit_pushf(dst); // pushf - emit_test_m32_r32(dst, MABS(param->value + 4), reghi); // test [param],reghi + emit_test_m32_r32(dst, MABS(param.memory(4)), reghi); // test [param],reghi } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - emit_test_r32_imm(dst, reglo, param->value); // test reglo,param + emit_test_r32_imm(dst, reglo, param.immediate()); // test reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_test_r32_imm(dst, reghi, param->value >> 32); // test reghi,param >> 32 + emit_test_r32_imm(dst, reghi, param.immediate() >> 32); // test reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_test_r32_r32(dst, reglo, param->value); // test reglo,param + emit_test_r32_r32(dst, reglo, param.ireg()); // test reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_test_m32_r32(dst, MABS(drcbe->reghi[param->value]), reghi); // test reghi[param],reghi + emit_test_m32_r32(dst, MABS(m_reghi[param.ireg()]), reghi); // test reghi[param],reghi } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_test_m64_p64 - test operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_test_m64_p64 - test operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_test_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - emit_test_m32_imm(dst, MEMPARAMS, param->value); // test [dest],param + emit_test_m32_imm(dst, memref, param.immediate()); // test [dest],param if (saveflags) emit_pushf(dst); // pushf - emit_test_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // test [dest+4],param >> 32 + emit_test_m32_imm(dst, memref + 4, param.immediate() >> 32); // test [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_test_m32_r32(dst, MEMPARAMS, reglo); // test [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_test_m32_r32(dst, memref, reglo); // test [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_test_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // test [dest+4],edx + emit_test_m32_r32(dst, memref + 4, REG_EDX); // test [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_or_r64_p64 - or operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_r64_p64 - or operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_or_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_or_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_or_r32_m32(dst, reglo, MABS(param->value)); // or reglo,[param] + emit_or_r32_m32(dst, reglo, MABS(param.memory())); // or reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_or_r32_m32(dst, reghi, MABS(param->value + 4)); // or reghi,[param] + emit_or_r32_m32(dst, reghi, MABS(param.memory(4))); // or reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_mov_r32_imm(dst, reglo, ~0); // mov reglo,-1 else - emit_or_r32_imm(dst, reglo, param->value); // or reglo,param + emit_or_r32_imm(dst, reglo, param.immediate()); // or reglo,param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) emit_mov_r32_imm(dst, reghi, ~0); // mov reghi,-1 else - emit_or_r32_imm(dst, reghi, param->value >> 32); // or reghi,param >> 32 + emit_or_r32_imm(dst, reghi, param.immediate() >> 32); // or reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_or_r32_r32(dst, reglo, param->value); // or reglo,param + emit_or_r32_r32(dst, reglo, param.ireg()); // or reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_or_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // or reghi,reghi[param] + emit_or_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // or reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_or_m64_p64 - or operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_or_m64_p64 - or operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_or_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_mov_m32_imm(dst, MEMPARAMS, ~0); // mov [dest],-1 + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_mov_m32_imm(dst, memref, ~0); // mov [dest],-1 else - emit_or_m32_imm(dst, MEMPARAMS, param->value); // or [dest],param + emit_or_m32_imm(dst, memref, param.immediate()); // or [dest],param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) - emit_mov_m32_imm(dst, MEMPARAMS + 4, ~0); // mov [dest+4],-1 + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) + emit_mov_m32_imm(dst, memref + 4, ~0); // mov [dest+4],-1 else - emit_or_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // or [dest+4],param >> 32 + emit_or_m32_imm(dst, memref + 4, param.immediate() >> 32); // or [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_or_m32_r32(dst, MEMPARAMS, reglo); // or [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_or_m32_r32(dst, memref, reglo); // or [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_or_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // or [dest+4],edx + emit_or_m32_r32(dst, memref + 4, REG_EDX); // or [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_xor_r64_p64 - xor operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_r64_p64 - xor operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_xor_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_xor_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_MEMORY) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_memory()) { - emit_xor_r32_m32(dst, reglo, MABS(param->value)); // xor reglo,[param] + emit_xor_r32_m32(dst, reglo, MABS(param.memory())); // xor reglo,[param] if (saveflags) emit_pushf(dst); // pushf - emit_xor_r32_m32(dst, reghi, MABS(param->value + 4)); // xor reghi,[param] + emit_xor_r32_m32(dst, reghi, MABS(param.memory(4))); // xor reghi,[param] } - else if (param->type == DRCUML_PTYPE_IMMEDIATE) + else if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) emit_not_r32(dst, reglo); // not reglo else - emit_xor_r32_imm(dst, reglo, param->value); // xor reglo,param + emit_xor_r32_imm(dst, reglo, param.immediate()); // xor reglo,param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) emit_not_r32(dst, reghi); // not reghi else - emit_xor_r32_imm(dst, reghi, param->value >> 32); // xor reghi,param >> 32 + emit_xor_r32_imm(dst, reghi, param.immediate() >> 32); // xor reghi,param >> 32 } - else if (param->type == DRCUML_PTYPE_INT_REGISTER) + else if (param.is_int_register()) { - emit_xor_r32_r32(dst, reglo, param->value); // xor reglo,param + emit_xor_r32_r32(dst, reglo, param.ireg()); // xor reglo,param if (saveflags) emit_pushf(dst); // pushf - emit_xor_r32_m32(dst, reghi, MABS(drcbe->reghi[param->value])); // xor reghi,reghi[param] + emit_xor_r32_m32(dst, reghi, MABS(m_reghi[param.ireg()])); // xor reghi,reghi[param] } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_xor_m64_p64 - xor operation to a 64-bit - memory location from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_xor_m64_p64 - xor operation to a 64-bit +// memory location from a 64-bit parameter +//------------------------------------------------- -static void emit_xor_m64_p64(drcbe_state *drcbe, x86code **dst, DECLARE_MEMPARAMS, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - if (inst->flags == 0 && (UINT32)param->value == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)param->value == 0xffffffff) - emit_not_m32(dst, MEMPARAMS); // not [dest] + if (inst.flags() == 0 && (UINT32)param.immediate() == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)param.immediate() == 0xffffffff) + emit_not_m32(dst, memref); // not [dest] else - emit_xor_m32_imm(dst, MEMPARAMS, param->value); // xor [dest],param + emit_xor_m32_imm(dst, memref, param.immediate()); // xor [dest],param if (saveflags) emit_pushf(dst); // pushf - if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0) - /* skip */; - else if (inst->flags == 0 && (UINT32)(param->value >> 32) == 0xffffffff) - emit_not_m32(dst, MEMPARAMS + 4); // not [dest+4] + if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0) + ;// skip + else if (inst.flags() == 0 && (UINT32)(param.immediate() >> 32) == 0xffffffff) + emit_not_m32(dst, memref + 4); // not [dest+4] else - emit_xor_m32_imm(dst, MEMPARAMS + 4, param->value >> 32); // xor [dest+4],param >> 32 + emit_xor_m32_imm(dst, memref + 4, param.immediate() >> 32); // xor [dest+4],param >> 32 } else { - int reglo = (param->type == DRCUML_PTYPE_INT_REGISTER) ? param->value : REG_EAX; - emit_mov_r64_p64(drcbe, dst, reglo, REG_EDX, param); // mov edx:reglo,param - emit_xor_m32_r32(dst, MEMPARAMS, reglo); // xor [dest],reglo + int reglo = (param.is_int_register()) ? param.ireg() : REG_EAX; + emit_mov_r64_p64(dst, reglo, REG_EDX, param); // mov edx:reglo,param + emit_xor_m32_r32(dst, memref, reglo); // xor [dest],reglo if (saveflags) emit_pushf(dst); // pushf - emit_xor_m32_r32(dst, MEMPARAMS + 4, REG_EDX); // xor [dest+4],edx + emit_xor_m32_r32(dst, memref + 4, REG_EDX); // xor [dest+4],edx } if (saveflags) emit_combine_z_flags(dst); } -/*------------------------------------------------- - emit_shl_r64_p64 - shl operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shl_r64_p64 - shl operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_shl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = (inst->flags != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = (inst.flags() != 0); + if (param.is_immediate()) { - int count = param->value & 63; - if (inst->flags == 0 && count == 0) - /* skip */; + int count = param.immediate() & 63; + if (inst.flags() == 0 && count == 0) + ;// skip else { while (count >= 32) { - if (inst->flags != 0) + if (inst.flags() != 0) { emit_shld_r32_r32_imm(dst, reghi, reglo, 31); // shld reghi,reglo,31 emit_shl_r32_imm(dst, reglo, 31); // shl reglo,31 @@ -2667,7 +2347,7 @@ static void emit_shl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN count -= 32; } } - if (inst->flags != 0 || count > 0) + if (inst.flags() != 0 || count > 0) { emit_shld_r32_r32_imm(dst, reghi, reglo, count); // shld reghi,reglo,count if (saveflags) emit_pushf(dst); // pushf @@ -2678,27 +2358,27 @@ static void emit_shl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN else { emit_link skip1, skip2; - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 - if (inst->flags != 0) + emit_jcc_short_link(dst, x86emit::COND_Z, skip1); // jz skip1 + if (inst.flags() != 0) { emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shld_r32_r32_imm(dst, reghi, reglo, 31); // shld reghi,reglo,31 emit_shl_r32_imm(dst, reglo, 31); // shl reglo,31 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 + emit_jcc_short_link(dst, x86emit::COND_Z, skip2); // jz skip2 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shld_r32_r32_imm(dst, reghi, reglo, 31); // shld reghi,reglo,31 emit_shl_r32_imm(dst, reglo, 31); // shl reglo,31 - track_resolve_link(drcbe, dst, &skip2); // skip2: + track_resolve_link(dst, skip2); // skip2: } else { emit_mov_r32_r32(dst, reghi, reglo); // mov reghi,reglo emit_xor_r32_r32(dst, reglo, reglo); // xor reglo,reglo } - track_resolve_link(drcbe, dst, &skip1); // skip1: + track_resolve_link(dst, skip1); // skip1: emit_shld_r32_r32_cl(dst, reghi, reglo); // shld reghi,reglo,cl if (saveflags) emit_pushf(dst); // pushf emit_shl_r32_cl(dst, reglo); // shl reglo,cl @@ -2708,24 +2388,24 @@ static void emit_shl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN } -/*------------------------------------------------- - emit_shr_r64_p64 - shr operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_shr_r64_p64 - shr operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_shr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_shr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - int count = param->value & 63; - if (inst->flags == 0 && count == 0) - /* skip */; + int count = param.immediate() & 63; + if (inst.flags() == 0 && count == 0) + ;// skip else { while (count >= 32) { - if (inst->flags != 0) + if (inst.flags() != 0) { emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shr_r32_imm(dst, reghi, 31); // shr reghi,31 @@ -2738,7 +2418,7 @@ static void emit_shr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN count -= 32; } } - if (inst->flags != 0 || count > 0) + if (inst.flags() != 0 || count > 0) { emit_shrd_r32_r32_imm(dst, reglo, reghi, count); // shrd reglo,reghi,count if (saveflags) emit_pushf(dst); // pushf @@ -2749,27 +2429,27 @@ static void emit_shr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN else { emit_link skip1, skip2; - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 - if (inst->flags != 0) + emit_jcc_short_link(dst, x86emit::COND_Z, skip1); // jz skip1 + if (inst.flags() != 0) { emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shr_r32_imm(dst, reghi, 31); // shr reghi,31 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 + emit_jcc_short_link(dst, x86emit::COND_Z, skip2); // jz skip2 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shr_r32_imm(dst, reghi, 31); // shr reghi,31 - track_resolve_link(drcbe, dst, &skip2); // skip2: + track_resolve_link(dst, skip2); // skip2: } else { emit_mov_r32_r32(dst, reglo, reghi); // mov reglo,reghi emit_xor_r32_r32(dst, reghi, reghi); // xor reghi,reghi } - track_resolve_link(drcbe, dst, &skip1); // skip1: + track_resolve_link(dst, skip1); // skip1: emit_shrd_r32_r32_cl(dst, reglo, reghi); // shrd reglo,reghi,cl if (saveflags) emit_pushf(dst); // pushf emit_shr_r32_cl(dst, reghi); // shr reghi,cl @@ -2779,24 +2459,24 @@ static void emit_shr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN } -/*------------------------------------------------- - emit_sar_r64_p64 - sar operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_sar_r64_p64 - sar operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_sar_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_sar_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - int count = param->value & 63; - if (inst->flags == 0 && count == 0) - /* skip */; + int count = param.immediate() & 63; + if (inst.flags() == 0 && count == 0) + ;// skip else { while (count >= 32) { - if (inst->flags != 0) + if (inst.flags() != 0) { emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_sar_r32_imm(dst, reghi, 31); // sar reghi,31 @@ -2809,7 +2489,7 @@ static void emit_sar_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN count -= 32; } } - if (inst->flags != 0 || count > 0) + if (inst.flags() != 0 || count > 0) { emit_shrd_r32_r32_imm(dst, reglo, reghi, count); // shrd reglo,reghi,count if (saveflags) emit_pushf(dst); // pushf @@ -2820,27 +2500,27 @@ static void emit_sar_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN else { emit_link skip1, skip2; - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 - if (inst->flags != 0) + emit_jcc_short_link(dst, x86emit::COND_Z, skip1); // jz skip1 + if (inst.flags() != 0) { emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_sar_r32_imm(dst, reghi, 31); // sar reghi,31 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip + emit_jcc_short_link(dst, x86emit::COND_Z, skip2); // jz skip emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_sar_r32_imm(dst, reghi, 31); // sar reghi,31 - track_resolve_link(drcbe, dst, &skip2); // skip2: + track_resolve_link(dst, skip2); // skip2: } else { emit_mov_r32_r32(dst, reglo, reghi); // mov reglo,reghi emit_sar_r32_imm(dst, reghi, 31); // sar reghi,31 } - track_resolve_link(drcbe, dst, &skip1); // skip1: + track_resolve_link(dst, skip1); // skip1: emit_shrd_r32_r32_cl(dst, reglo, reghi); // shrd reglo,reghi,cl if (saveflags) emit_pushf(dst); // pushf emit_sar_r32_cl(dst, reghi); // sar reghi,cl @@ -2850,24 +2530,24 @@ static void emit_sar_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN } -/*------------------------------------------------- - emit_rol_r64_p64 - rol operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rol_r64_p64 - rol operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rol_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - int count = param->value & 63; - if (inst->flags == 0 && count == 0) - /* skip */; + int count = param.immediate() & 63; + if (inst.flags() == 0 && count == 0) + ;// skip else { while (count >= 32) { - if (inst->flags != 0) + if (inst.flags() != 0) { emit_mov_r32_r32(dst, REG_ECX, reglo); // mov ecx,reglo emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31 @@ -2880,7 +2560,7 @@ static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN count -= 32; } } - if (inst->flags != 0 || count > 0) + if (inst.flags() != 0 || count > 0) { emit_mov_r32_r32(dst, REG_ECX, reglo); // mov ecx,reglo emit_shld_r32_r32_imm(dst, reglo, reghi, count); // shld reglo,reghi,count @@ -2894,26 +2574,26 @@ static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN emit_link skip1, skip2; int tempreg = REG_EBX; emit_mov_m32_r32(dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 - if (inst->flags != 0) + emit_jcc_short_link(dst, x86emit::COND_Z, skip1); // jz skip1 + if (inst.flags() != 0) { emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31 emit_shld_r32_r32_imm(dst, reghi, tempreg, 31); // shld reghi,ebx,31 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 + emit_jcc_short_link(dst, x86emit::COND_Z, skip2); // jz skip2 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shld_r32_r32_imm(dst, reglo, reghi, 31); // shld reglo,reghi,31 emit_shld_r32_r32_imm(dst, reghi, tempreg, 31); // shld reghi,ebx,31 - track_resolve_link(drcbe, dst, &skip2); // skip2: + track_resolve_link(dst, skip2); // skip2: } else emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo - track_resolve_link(drcbe, dst, &skip1); // skip1: + track_resolve_link(dst, skip1); // skip1: emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shld_r32_r32_cl(dst, reglo, reghi); // shld reglo,reghi,cl if (saveflags) emit_pushf(dst); // pushf @@ -2925,24 +2605,24 @@ static void emit_rol_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN } -/*------------------------------------------------- - emit_ror_r64_p64 - ror operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_ror_r64_p64 - ror operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_ror_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); - if (param->type == DRCUML_PTYPE_IMMEDIATE) + int saveflags = ((inst.flags() & FLAG_Z) != 0); + if (param.is_immediate()) { - int count = param->value & 63; - if (inst->flags == 0 && count == 0) - /* skip */; + int count = param.immediate() & 63; + if (inst.flags() == 0 && count == 0) + ;// skip else { while (count >= 32) { - if (inst->flags != 0) + if (inst.flags() != 0) { emit_mov_r32_r32(dst, REG_ECX, reglo); // mov ecx,reglo emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 @@ -2955,7 +2635,7 @@ static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN count -= 32; } } - if (inst->flags != 0 || count > 0) + if (inst.flags() != 0 || count > 0) { emit_mov_r32_r32(dst, REG_ECX, reglo); // mov ecx,reglo emit_shrd_r32_r32_imm(dst, reglo, reghi, count); // shrd reglo,reghi,count @@ -2969,26 +2649,26 @@ static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN emit_link skip1, skip2; int tempreg = REG_EBX; emit_mov_m32_r32(dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx - emit_mov_r32_p32(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32(dst, REG_ECX, param); // mov ecx,param emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip1); // jz skip1 - if (inst->flags != 0) + emit_jcc_short_link(dst, x86emit::COND_Z, skip1); // jz skip1 + if (inst.flags() != 0) { emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shrd_r32_r32_imm(dst, reghi, tempreg, 31); // shrd reghi,ebx,31 emit_test_r32_imm(dst, REG_ECX, 0x20); // test ecx,0x20 - emit_jcc_short_link(dst, COND_Z, &skip2); // jz skip2 + emit_jcc_short_link(dst, x86emit::COND_Z, skip2); // jz skip2 emit_sub_r32_imm(dst, REG_ECX, 31); // sub ecx,31 emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shrd_r32_r32_imm(dst, reglo, reghi, 31); // shrd reglo,reghi,31 emit_shrd_r32_r32_imm(dst, reghi, tempreg, 31); // shrd reghi,ebx,31 - track_resolve_link(drcbe, dst, &skip2); // skip2: + track_resolve_link(dst, skip2); // skip2: } else emit_xchg_r32_r32(dst, reghi, reglo); // xchg reghi,reglo - track_resolve_link(drcbe, dst, &skip1); // skip1: + track_resolve_link(dst, skip1); // skip1: emit_mov_r32_r32(dst, tempreg, reglo); // mov ebx,reglo emit_shrd_r32_r32_cl(dst, reglo, reghi); // shrd reglo,reghi,cl if (saveflags) emit_pushf(dst); // pushf @@ -3000,142 +2680,142 @@ static void emit_ror_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UIN } -/*------------------------------------------------- - emit_rcl_r64_p64 - rcl operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcl_r64_p64 - rcl operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_rcl_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = ((inst->flags & DRCUML_FLAG_Z) != 0); + int saveflags = ((inst.flags() & FLAG_Z) != 0); emit_link skipall, skiploop; x86code *loop; - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param if (!saveflags) { - loop = *dst; // loop: - emit_jecxz_link(dst, &skipall); // jecxz skipall + loop = dst; // loop: + emit_jecxz_link(dst, skipall); // jecxz skipall emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] emit_rcl_r32_imm(dst, reglo, 1); // rcl reglo,1 emit_rcl_r32_imm(dst, reghi, 1); // rcl reghi,1 emit_jmp(dst, loop); // jmp loop - track_resolve_link(drcbe, dst, &skipall); // skipall: + track_resolve_link(dst, skipall); // skipall: } else { - emit_jecxz_link(dst, &skipall); // jecxz skipall + emit_jecxz_link(dst, skipall); // jecxz skipall emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] - loop = *dst; // loop: - emit_jecxz_link(dst, &skiploop); // jecxz skiploop + loop = dst; // loop: + emit_jecxz_link(dst, skiploop); // jecxz skiploop emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] emit_rcl_r32_imm(dst, reglo, 1); // rcl reglo,1 emit_rcl_r32_imm(dst, reghi, 1); // rcl reghi,1 emit_jmp(dst, loop); // jmp loop - track_resolve_link(drcbe, dst, &skiploop); // skiploop: + track_resolve_link(dst, skiploop); // skiploop: emit_rcl_r32_imm(dst, reglo, 1); // rcl reglo,1 emit_pushf(dst); // pushf emit_rcl_r32_imm(dst, reghi, 1); // rcl reghi,1 - track_resolve_link(drcbe, dst, &skipall); // skipall: + track_resolve_link(dst, skipall); // skipall: emit_combine_z_flags(dst); } } -/*------------------------------------------------- - emit_rcr_r64_p64 - rcr operation to a 64-bit - pair of registers from a 64-bit parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_rcr_r64_p64 - rcr operation to a 64-bit +// pair of registers from a 64-bit parameter +//------------------------------------------------- -static void emit_rcr_r64_p64(drcbe_state *drcbe, x86code **dst, UINT8 reglo, UINT8 reghi, const drcuml_parameter *param, const drcuml_instruction *inst) +void drcbe_x86::emit_rcr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const instruction &inst) { - int saveflags = (inst->flags != 0); + int saveflags = (inst.flags() != 0); emit_link skipall, skiploop; x86code *loop; - emit_mov_r32_p32_keepflags(drcbe, dst, REG_ECX, param); // mov ecx,param + emit_mov_r32_p32_keepflags(dst, REG_ECX, param); // mov ecx,param if (!saveflags) { - loop = *dst; // loop: - emit_jecxz_link(dst, &skipall); // jecxz skipall + loop = dst; // loop: + emit_jecxz_link(dst, skipall); // jecxz skipall emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] emit_rcr_r32_imm(dst, reghi, 1); // rcr reghi,1 emit_rcr_r32_imm(dst, reglo, 1); // rcr reglo,1 emit_jmp(dst, loop); // jmp loop - track_resolve_link(drcbe, dst, &skipall); // skipall: + track_resolve_link(dst, skipall); // skipall: } else { - emit_jecxz_link(dst, &skipall); // jecxz skipall + emit_jecxz_link(dst, skipall); // jecxz skipall emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] - loop = *dst; // loop: - emit_jecxz_link(dst, &skiploop); // jecxz skiploop + loop = dst; // loop: + emit_jecxz_link(dst, skiploop); // jecxz skiploop emit_lea_r32_m32(dst, REG_ECX, MBD(REG_ECX, -1)); // lea ecx,[ecx-1] emit_rcr_r32_imm(dst, reghi, 1); // rcr reghi,1 emit_rcr_r32_imm(dst, reglo, 1); // rcr reglo,1 emit_jmp(dst, loop); // jmp loop - track_resolve_link(drcbe, dst, &skiploop); // skiploop: + track_resolve_link(dst, skiploop); // skiploop: emit_rcr_r32_imm(dst, reghi, 1); // rcr reghi,1 emit_pushf(dst); // pushf emit_rcr_r32_imm(dst, reglo, 1); // rcr reglo,1 - track_resolve_link(drcbe, dst, &skipall); // skipall: + track_resolve_link(dst, skipall); // skipall: emit_combine_z_shl_flags(dst); } } -/*************************************************************************** - EMITTERS FOR FLOATING POINT -***************************************************************************/ +//************************************************************************** +// EMITTERS FOR FLOATING POINT +//************************************************************************** -/*------------------------------------------------- - emit_fld_p - load a floating point parameter - onto the stack --------------------------------------------------*/ +//------------------------------------------------- +// emit_fld_p - load a floating point parameter +// onto the stack +//------------------------------------------------- -static void emit_fld_p(x86code **dst, int size, const drcuml_parameter *param) +void drcbe_x86::emit_fld_p(x86code *&dst, int size, const be_parameter ¶m) { - assert(param->type == DRCUML_PTYPE_MEMORY); + assert(param.is_memory()); assert(size == 4 || size == 8); if (size == 4) - emit_fld_m32(dst, MABS(param->value)); + emit_fld_m32(dst, MABS(param.memory())); else if (size == 8) - emit_fld_m64(dst, MABS(param->value)); + emit_fld_m64(dst, MABS(param.memory())); } -/*------------------------------------------------- - emit_fstp_p - store a floating point parameter - from the stack and pop it --------------------------------------------------*/ +//------------------------------------------------- +// emit_fstp_p - store a floating point parameter +// from the stack and pop it +//------------------------------------------------- -static void emit_fstp_p(x86code **dst, int size, const drcuml_parameter *param) +void drcbe_x86::emit_fstp_p(x86code *&dst, int size, const be_parameter ¶m) { - assert(param->type == DRCUML_PTYPE_MEMORY); + assert(param.is_memory()); assert(size == 4 || size == 8); if (size == 4) - emit_fstp_m32(dst, MABS(param->value)); + emit_fstp_m32(dst, MABS(param.memory())); else if (size == 8) - emit_fstp_m64(dst, MABS(param->value)); + emit_fstp_m64(dst, MABS(param.memory())); } -/*************************************************************************** - OUT-OF-BAND CODE FIXUP CALLBACKS -***************************************************************************/ +//************************************************************************** +// OUT-OF-BAND CODE FIXUP CALLBACKS +//************************************************************************** -/*------------------------------------------------- - fixup_label - callback to fixup forward- - referenced labels --------------------------------------------------*/ +//------------------------------------------------- +// fixup_label - callback to fixup forward- +// referenced labels +//------------------------------------------------- -static void fixup_label(void *parameter, drccodeptr labelcodeptr) +void drcbe_x86::fixup_label(void *parameter, drccodeptr labelcodeptr) { drccodeptr src = (drccodeptr)parameter; - /* find the end of the instruction */ + // find the end of the instruction if (src[0] == 0xe3) { src += 1 + 1; @@ -3156,3821 +2836,3678 @@ static void fixup_label(void *parameter, drccodeptr labelcodeptr) } -/*------------------------------------------------- - fixup_exception - callback to perform cleanup - and jump to an exception handler --------------------------------------------------*/ +//------------------------------------------------- +// fixup_exception - callback to perform cleanup +// and jump to an exception handler +//------------------------------------------------- -static void fixup_exception(drccodeptr *codeptr, void *param1, void *param2, void *param3) +void drcbe_x86::fixup_exception(drccodeptr *codeptr, void *param1, void *param2) { - drcuml_parameter handp, exp; - drcbe_state *drcbe = (drcbe_state *)param1; - drccodeptr src = (drccodeptr)param2; - const drcuml_instruction *inst = (const drcuml_instruction *)param3; - drccodeptr dst = *codeptr; - drccodeptr *targetptr; + drccodeptr src = (drccodeptr)param1; + const instruction &inst = *(const instruction *)param2; - /* normalize parameters */ - param_normalize_2(drcbe, inst, &handp, PTYPE_M, &exp, PTYPE_MRI); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); + be_parameter exp(*this, inst.param(1), PTYPE_MRI); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)(FPTR)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* first fixup the jump to get us here */ + // first fixup the jump to get us here + drccodeptr dst = *codeptr; ((UINT32 *)src)[-1] = dst - src; - /* then store the exception parameter */ - emit_mov_m32_p32(drcbe, &dst, MABS(&drcbe->state.exp), &exp); // mov [exp],exp + // then store the exception parameter + emit_mov_m32_p32(dst, MABS(&m_state.exp), exp); // mov [exp],exp - /* push the original return address on the stack */ - emit_push_imm(&dst, (FPTR)src); // push <return> + // push the original return address on the stack + emit_push_imm(dst, (FPTR)src); // push <return> if (*targetptr != NULL) - emit_jmp(&dst, *targetptr); // jmp *targetptr + emit_jmp(dst, *targetptr); // jmp *targetptr else - emit_jmp_m32(&dst, MABS(targetptr)); // jmp [targetptr] + emit_jmp_m32(dst, MABS(targetptr)); // jmp [targetptr] *codeptr = dst; } -/*************************************************************************** - DEBUG HELPERS -***************************************************************************/ +//************************************************************************** +// DEBUG HELPERS +//************************************************************************** -/*------------------------------------------------- - debug_log_hashjmp - callback to handle - logging of hashjmps --------------------------------------------------*/ +//------------------------------------------------- +// debug_log_hashjmp - callback to handle +// logging of hashjmps +//------------------------------------------------- -static void debug_log_hashjmp(int mode, offs_t pc) +void drcbe_x86::debug_log_hashjmp(int mode, offs_t pc) { printf("mode=%d PC=%08X\n", mode, pc); } -/*************************************************************************** - COMPILE-TIME OPCODES -***************************************************************************/ +//************************************************************************** +// COMPILE-TIME OPCODES +//************************************************************************** -/*------------------------------------------------- - op_handle - process a HANDLE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_handle - process a HANDLE opcode +//------------------------------------------------- -static x86code *op_handle(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_handle(x86code *&dst, const instruction &inst) { - emit_link skip; - assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_MEMORY); + assert(inst.numparams() == 1); + assert(inst.param(0).is_code_handle()); - reset_last_upper_lower_reg(drcbe); + reset_last_upper_lower_reg(); - /* emit a jump around the stack adjust in case code falls through here */ - emit_jmp_short_link(&dst, &skip); // jmp skip + // emit a jump around the stack adjust in case code falls through here + emit_link skip; + emit_jmp_short_link(dst, skip); // jmp skip - /* register the current pointer for the handle */ - drcuml_handle_set_codeptr((drcuml_codehandle *)(FPTR)inst->param[0].value, dst); + // register the current pointer for the handle + inst.param(0).handle().set_codeptr(dst); - /* by default, the handle points to prolog code that moves the stack pointer */ - emit_lea_r32_m32(&dst, REG_ESP, MBD(REG_ESP, -28)); // lea rsp,[rsp-28] - track_resolve_link(drcbe, &dst, &skip); // skip: - return dst; + // by default, the handle points to prolog code that moves the stack pointer + emit_lea_r32_m32(dst, REG_ESP, MBD(REG_ESP, -28)); // lea rsp,[rsp-28] + track_resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_hash - process a HASH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_hash - process a HASH opcode +//------------------------------------------------- -static x86code *op_hash(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_hash(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 2); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); - assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 2); + assert(inst.param(0).is_immediate()); + assert(inst.param(1).is_immediate()); - /* register the current pointer for the mode/PC */ - drcbe->hash->set_codeptr(inst->param[0].value, inst->param[1].value, dst); - reset_last_upper_lower_reg(drcbe); - return dst; + // register the current pointer for the mode/PC + m_hash.set_codeptr(inst.param(0).immediate(), inst.param(1).immediate(), dst); + reset_last_upper_lower_reg(); } -/*------------------------------------------------- - op_label - process a LABEL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_label - process a LABEL opcode +//------------------------------------------------- -static x86code *op_label(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_label(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 1); + assert(inst.param(0).is_code_label()); - /* register the current pointer for the label */ - drcbe->labels->set_codeptr(inst->param[0].value, dst); - reset_last_upper_lower_reg(drcbe); - return dst; + // register the current pointer for the label + m_labels.set_codeptr(inst.param(0).label(), dst); + reset_last_upper_lower_reg(); } -/*------------------------------------------------- - op_comment - process a COMMENT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_comment - process a COMMENT opcode +//------------------------------------------------- -static x86code *op_comment(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_comment(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 1); - assert(inst->param[0].type == DRCUML_PTYPE_MEMORY); + assert(inst.numparams() == 1); + assert(inst.param(0).is_string()); - /* do nothing */ - return dst; + // do nothing } -/*------------------------------------------------- - op_mapvar - process a MAPVAR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mapvar - process a MAPVAR opcode +//------------------------------------------------- -static x86code *op_mapvar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_mapvar(x86code *&dst, const instruction &inst) { assert_no_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 2); - assert(inst->param[0].type == DRCUML_PTYPE_MAPVAR); - assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); + assert(inst.numparams() == 2); + assert(inst.param(0).is_mapvar()); + assert(inst.param(1).is_immediate()); - /* set the value of the specified mapvar */ - drcbe->map->set_value(dst, inst->param[0].value, inst->param[1].value); - return dst; + // set the value of the specified mapvar + m_map.set_value(dst, inst.param(0).mapvar(), inst.param(1).immediate()); } -/*************************************************************************** - CONTROL FLOW OPCODES -***************************************************************************/ +//************************************************************************** +// CONTROL FLOW OPCODES +//************************************************************************** -/*------------------------------------------------- - op_nop - process a NOP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_nop - process a NOP opcode +//------------------------------------------------- -static x86code *op_nop(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_nop(x86code *&dst, const instruction &inst) { - /* nothing */ - return dst; + // nothing } -/*------------------------------------------------- - op_debug - process a DEBUG opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_debug - process a DEBUG opcode +//------------------------------------------------- -static x86code *op_debug(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_debug(x86code *&dst, const instruction &inst) { - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - if ((drcbe->device->machine->debug_flags & DEBUG_FLAG_ENABLED) != 0) + if ((m_device.machine->debug_flags & DEBUG_FLAG_ENABLED) != 0) { - drcuml_parameter pcp; - - /* normalize parameters */ - param_normalize_1(drcbe, inst, &pcp, PTYPE_MRI); + // normalize parameters + be_parameter pcp(*this, inst.param(0), PTYPE_MRI); - /* test and branch */ - emit_test_m32_imm(&dst, MABS(&drcbe->device->machine->debug_flags), DEBUG_FLAG_CALL_HOOK); // test [debug_flags],DEBUG_FLAG_CALL_HOOK - emit_jcc_short_link(&dst, COND_Z, &skip); // jz skip + // test and branch + emit_test_m32_imm(dst, MABS(&m_device.machine->debug_flags), DEBUG_FLAG_CALL_HOOK); // test [debug_flags],DEBUG_FLAG_CALL_HOOK + emit_link skip = { 0 }; + emit_jcc_short_link(dst, x86emit::COND_Z, skip); // jz skip - /* push the parameter */ - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &pcp); // mov [esp+4],pcp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)drcbe->device); // mov [esp],device - emit_call(&dst, (x86code *)debugger_instruction_hook); // call debug_cpu_instruction_hook + // push the parameter + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), pcp); // mov [esp+4],pcp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_device); // mov [esp],device + emit_call(dst, (x86code *)debugger_instruction_hook); // call debug_cpu_instruction_hook - track_resolve_link(drcbe, &dst, &skip); // skip: + track_resolve_link(dst, skip); // skip: } - - return dst; } -/*------------------------------------------------- - op_exit - process an EXIT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_exit - process an EXIT opcode +//------------------------------------------------- -static x86code *op_exit(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_exit(x86code *&dst, const instruction &inst) { - drcuml_parameter retp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &retp, PTYPE_MRI); + // normalize parameters + be_parameter retp(*this, inst.param(0), PTYPE_MRI); - /* load the parameter into EAX */ - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &retp); // mov eax,retp - if (inst->condition == DRCUML_COND_ALWAYS) - emit_jmp(&dst, drcbe->exit); // jmp exit + // load the parameter into EAX + emit_mov_r32_p32(dst, REG_EAX, retp); // mov eax,retp + if (inst.condition() == uml::COND_ALWAYS) + emit_jmp(dst, m_exit); // jmp exit else - emit_jcc(&dst, X86_CONDITION(inst->condition), drcbe->exit); // jcc exit - - return dst; + emit_jcc(dst, X86_CONDITION(inst.condition()), m_exit); // jcc exit } -/*------------------------------------------------- - op_hashjmp - process a HASHJMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_hashjmp - process a HASHJMP opcode +//------------------------------------------------- -static x86code *op_hashjmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_hashjmp(x86code *&dst, const instruction &inst) { - drcuml_parameter modep, pcp, exp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &modep, PTYPE_MRI, &pcp, PTYPE_MRI, &exp, PTYPE_M); + // normalize parameters + be_parameter modep(*this, inst.param(0), PTYPE_MRI); + be_parameter pcp(*this, inst.param(1), PTYPE_MRI); + const parameter &exp = inst.param(2); + assert(exp.is_code_handle()); if (LOG_HASHJMPS) { - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &pcp); - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 0), &modep); - emit_call(&dst, (x86code *)debug_log_hashjmp); + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), pcp); + emit_mov_m32_p32(dst, MBD(REG_ESP, 0), modep); + emit_call(dst, (x86code *)debug_log_hashjmp); } - /* load the stack base one word early so we end up at the right spot after our call below */ - emit_mov_r32_m32(&dst, REG_ESP, MABS(&drcbe->hashstacksave)); // mov esp,[hashstacksave] + // load the stack base one word early so we end up at the right spot after our call below + emit_mov_r32_m32(dst, REG_ESP, MABS(&m_hashstacksave)); // mov esp,[hashstacksave] - /* fixed mode cases */ - if (modep.type == DRCUML_PTYPE_IMMEDIATE && drcbe->hash->is_mode_populated(modep.value)) + // fixed mode cases + if (modep.is_immediate() && m_hash.is_mode_populated(modep.immediate())) { - /* a straight immediate jump is direct, though we need the PC in EAX in case of failure */ - if (pcp.type == DRCUML_PTYPE_IMMEDIATE) + // a straight immediate jump is direct, though we need the PC in EAX in case of failure + if (pcp.is_immediate()) { - UINT32 l1val = (pcp.value >> drcbe->hash->l1shift()) & drcbe->hash->l1mask(); - UINT32 l2val = (pcp.value >> drcbe->hash->l2shift()) & drcbe->hash->l2mask(); - emit_call_m32(&dst, MABS(&drcbe->hash->base()[modep.value][l1val][l2val])); // call hash[modep][l1val][l2val] + UINT32 l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask(); + UINT32 l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask(); + emit_call_m32(dst, MABS(&m_hash.base()[modep.immediate()][l1val][l2val])); // call hash[modep][l1val][l2val] } - /* a fixed mode but variable PC */ + // a fixed mode but variable PC else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &pcp); // mov eax,pcp - emit_mov_r32_r32(&dst, REG_EDX, REG_EAX); // mov edx,eax - emit_shr_r32_imm(&dst, REG_EDX, drcbe->hash->l1shift()); // shr edx,l1shift - emit_and_r32_imm(&dst, REG_EAX, drcbe->hash->l2mask() << drcbe->hash->l2shift());// and eax,l2mask << l2shift - emit_mov_r32_m32(&dst, REG_EDX, MISD(REG_EDX, 4, &drcbe->hash->base()[modep.value][0])); + emit_mov_r32_p32(dst, REG_EAX, pcp); // mov eax,pcp + emit_mov_r32_r32(dst, REG_EDX, REG_EAX); // mov edx,eax + emit_shr_r32_imm(dst, REG_EDX, m_hash.l1shift()); // shr edx,l1shift + emit_and_r32_imm(dst, REG_EAX, m_hash.l2mask() << m_hash.l2shift());// and eax,l2mask << l2shift + emit_mov_r32_m32(dst, REG_EDX, MABSI(&m_hash.base()[modep.immediate()][0], REG_EDX, 4)); // mov edx,hash[modep+edx*4] - emit_call_m32(&dst, MBISD(REG_EDX, REG_EAX, 4 >> drcbe->hash->l2shift(), 0));// call [edx+eax*shift] + emit_call_m32(dst, MBISD(REG_EDX, REG_EAX, 4 >> m_hash.l2shift(), 0));// call [edx+eax*shift] } } else { - /* variable mode */ - int modereg = param_select_register(REG_ECX, &modep, NULL); - emit_mov_r32_p32(drcbe, &dst, modereg, &modep); // mov modereg,modep - emit_mov_r32_m32(&dst, REG_ECX, MISD(modereg, 4, drcbe->hash->base())); // mov ecx,hash[modereg*4] + // variable mode + int modereg = modep.select_register(REG_ECX); + emit_mov_r32_p32(dst, modereg, modep); // mov modereg,modep + emit_mov_r32_m32(dst, REG_ECX, MABSI(m_hash.base(), modereg, 4)); // mov ecx,hash[modereg*4] - /* fixed PC */ - if (pcp.type == DRCUML_PTYPE_IMMEDIATE) + // fixed PC + if (pcp.is_immediate()) { - UINT32 l1val = (pcp.value >> drcbe->hash->l1shift()) & drcbe->hash->l1mask(); - UINT32 l2val = (pcp.value >> drcbe->hash->l2shift()) & drcbe->hash->l2mask(); - emit_mov_r32_m32(&dst, REG_EDX, MBD(REG_ECX, l1val*4)); // mov edx,[ecx+l1val*4] - emit_call_m32(&dst, MBD(REG_EDX, l2val*4)); // call [l2val*4] + UINT32 l1val = (pcp.immediate() >> m_hash.l1shift()) & m_hash.l1mask(); + UINT32 l2val = (pcp.immediate() >> m_hash.l2shift()) & m_hash.l2mask(); + emit_mov_r32_m32(dst, REG_EDX, MBD(REG_ECX, l1val*4)); // mov edx,[ecx+l1val*4] + emit_call_m32(dst, MBD(REG_EDX, l2val*4)); // call [l2val*4] } - /* variable PC */ + // variable PC else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &pcp); // mov eax,pcp - emit_mov_r32_r32(&dst, REG_EDX, REG_EAX); // mov edx,eax - emit_shr_r32_imm(&dst, REG_EDX, drcbe->hash->l1shift()); // shr edx,l1shift - emit_mov_r32_m32(&dst, REG_EDX, MBISD(REG_ECX, REG_EDX, 4, 0)); // mov edx,[ecx+edx*4] - emit_and_r32_imm(&dst, REG_EAX, drcbe->hash->l2mask() << drcbe->hash->l2shift());// and eax,l2mask << l2shift - emit_call_m32(&dst, MBISD(REG_EDX, REG_EAX, 4 >> drcbe->hash->l2shift(), 0));// call [edx+eax*shift] + emit_mov_r32_p32(dst, REG_EAX, pcp); // mov eax,pcp + emit_mov_r32_r32(dst, REG_EDX, REG_EAX); // mov edx,eax + emit_shr_r32_imm(dst, REG_EDX, m_hash.l1shift()); // shr edx,l1shift + emit_mov_r32_m32(dst, REG_EDX, MBISD(REG_ECX, REG_EDX, 4, 0)); // mov edx,[ecx+edx*4] + emit_and_r32_imm(dst, REG_EAX, m_hash.l2mask() << m_hash.l2shift());// and eax,l2mask << l2shift + emit_call_m32(dst, MBISD(REG_EDX, REG_EAX, 4 >> m_hash.l2shift(), 0));// call [edx+eax*shift] } } - /* in all cases, if there is no code, we return here to generate the exception */ - emit_mov_m32_p32(drcbe, &dst, MABS(&drcbe->state.exp), &pcp); // mov [exp],param - emit_sub_r32_imm(&dst, REG_ESP, 4); // sub esp,4 - emit_call_m32(&dst, MABS(exp.value)); // call [exp] - - return dst; + // in all cases, if there is no code, we return here to generate the exception + emit_mov_m32_p32(dst, MABS(&m_state.exp), pcp); // mov [exp],param + emit_sub_r32_imm(dst, REG_ESP, 4); // sub esp,4 + emit_call_m32(dst, MABS(exp.handle().codeptr_addr())); // call [exp] } -/*------------------------------------------------- - op_jmp - process a JMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_jmp - process a JMP opcode +//------------------------------------------------- -static x86code *op_jmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_jmp(x86code *&dst, const instruction &inst) { - drcuml_parameter labelp; - x86code *jmptarget; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &labelp, PTYPE_I); + // normalize parameters + const parameter &labelp = inst.param(0); + assert(labelp.is_code_label()); - /* look up the jump target and jump there */ - jmptarget = (x86code *)drcbe->labels->get_codeptr(labelp.value, fixup_label, dst); - if (inst->condition == DRCUML_COND_ALWAYS) - emit_jmp(&dst, jmptarget); // jmp target + // look up the jump target and jump there + x86code *jmptarget = (x86code *)m_labels.get_codeptr(labelp.label(), fixup_label, dst); + if (inst.condition() == uml::COND_ALWAYS) + emit_jmp(dst, jmptarget); // jmp target else - emit_jcc(&dst, X86_CONDITION(inst->condition), jmptarget); // jcc target - - return dst; + emit_jcc(dst, X86_CONDITION(inst.condition()), jmptarget); // jcc target } -/*------------------------------------------------- - op_exh - process an EXH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_exh - process an EXH opcode +//------------------------------------------------- -static x86code *op_exh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_exh(x86code *&dst, const instruction &inst) { - drcuml_parameter handp, exp; - drccodeptr *targetptr; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &handp, PTYPE_M, &exp, PTYPE_MRI); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); + be_parameter exp(*this, inst.param(1), PTYPE_MRI); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)(FPTR)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* perform the exception processing inline if unconditional */ - if (inst->condition == DRCUML_COND_ALWAYS) + // perform the exception processing inline if unconditional + if (inst.condition() == uml::COND_ALWAYS) { - emit_mov_m32_p32(drcbe, &dst, MABS(&drcbe->state.exp), &exp); // mov [exp],exp + emit_mov_m32_p32(dst, MABS(&m_state.exp), exp); // mov [exp],exp if (*targetptr != NULL) - emit_call(&dst, *targetptr); // call *targetptr + emit_call(dst, *targetptr); // call *targetptr else - emit_call_m32(&dst, MABS(targetptr)); // call [targetptr] + emit_call_m32(dst, MABS(targetptr)); // call [targetptr] } - /* otherwise, jump to an out-of-band handler */ + // otherwise, jump to an out-of-band handler else { - emit_jcc(&dst, X86_CONDITION(inst->condition), 0); // jcc exception - drcbe->cache->request_oob_codegen(fixup_exception, drcbe, dst, (void *)inst); + emit_jcc(dst, X86_CONDITION(inst.condition()), 0); // jcc exception + m_cache.request_oob_codegen(oob_func_stub<drcbe_x86, &drcbe_x86::fixup_exception>, dst, &const_cast<instruction &>(inst), this); } - return dst; } -/*------------------------------------------------- - op_callh - process a CALLH opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_callh - process a CALLH opcode +//------------------------------------------------- -static x86code *op_callh(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_callh(x86code *&dst, const instruction &inst) { - drcuml_parameter handp; - drccodeptr *targetptr; - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &handp, PTYPE_M); + // normalize parameters + const parameter &handp = inst.param(0); + assert(handp.is_code_handle()); - /* look up the handle target */ - targetptr = drcuml_handle_codeptr_addr((drcuml_codehandle *)(FPTR)handp.value); + // look up the handle target + drccodeptr *targetptr = handp.handle().codeptr_addr(); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* jump through the handle; directly if a normal jump */ + // jump through the handle; directly if a normal jump if (*targetptr != NULL) - emit_call(&dst, *targetptr); // call *targetptr + emit_call(dst, *targetptr); // call *targetptr else - emit_call_m32(&dst, MABS(targetptr)); // call [targetptr] + emit_call_m32(dst, MABS(targetptr)); // call [targetptr] - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - track_resolve_link(drcbe, &dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + track_resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_ret - process a RET opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ret - process a RET opcode +//------------------------------------------------- -static x86code *op_ret(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_ret(x86code *&dst, const instruction &inst) { - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - assert(inst->numparams == 0); + assert(inst.numparams() == 0); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* return */ - emit_lea_r32_m32(&dst, REG_ESP, MBD(REG_ESP, 28)); // lea rsp,[rsp+28] - emit_ret(&dst); // ret + // return + emit_lea_r32_m32(dst, REG_ESP, MBD(REG_ESP, 28)); // lea rsp,[rsp+28] + emit_ret(dst); // ret - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - track_resolve_link(drcbe, &dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + track_resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_callc - process a CALLC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_callc - process a CALLC opcode +//------------------------------------------------- -static x86code *op_callc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_callc(x86code *&dst, const instruction &inst) { - drcuml_parameter funcp, paramp; - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &funcp, PTYPE_M, ¶mp, PTYPE_M); + // normalize parameters + const parameter &funcp = inst.param(0); + assert(funcp.is_c_function()); + be_parameter paramp(*this, inst.param(1), PTYPE_M); - /* skip if conditional */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // skip if conditional + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* perform the call */ - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), paramp.value); // mov [esp],paramp - emit_call(&dst, (x86code *)(FPTR)funcp.value); // call funcp + // perform the call + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)paramp.memory()); // mov [esp],paramp + emit_call(dst, (x86code *)(FPTR)funcp.cfunc()); // call funcp - /* resolve the conditional link */ - if (inst->condition != DRCUML_COND_ALWAYS) - track_resolve_link(drcbe, &dst, &skip); // skip: - return dst; + // resolve the conditional link + if (inst.condition() != uml::COND_ALWAYS) + track_resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_recover - process a RECOVER opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_recover - process a RECOVER opcode +//------------------------------------------------- -static x86code *op_recover(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_recover(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize(drcbe, &inst->param[0], &dstp, PTYPE_MR); - - /* call the recovery code */ - emit_mov_r32_m32(&dst, REG_EAX, MABS(&drcbe->stacksave)); // mov eax,stacksave - emit_mov_r32_m32(&dst, REG_EAX, MBD(REG_EAX, -4)); // mov eax,[eax-4] - emit_sub_r32_imm(&dst, REG_EAX, 1); // sub eax,1 - emit_mov_m32_imm(&dst, MBD(REG_ESP, 8), inst->param[1].value); // mov [esp+8],param1 - emit_mov_m32_r32(&dst, MBD(REG_ESP, 4), REG_EAX); // mov [esp+4],eax - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)drcbe->map); // mov [esp],drcbe->map - emit_call(&dst, (x86code *)&drc_map_variables::static_get_value); // call drcmap_get_value - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - return dst; + // call the recovery code + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_stacksave)); // mov eax,stacksave + emit_mov_r32_m32(dst, REG_EAX, MBD(REG_EAX, -4)); // mov eax,[eax-4] + emit_sub_r32_imm(dst, REG_EAX, 1); // sub eax,1 + emit_mov_m32_imm(dst, MBD(REG_ESP, 8), inst.param(1).mapvar()); // mov [esp+8],param1 + emit_mov_m32_r32(dst, MBD(REG_ESP, 4), REG_EAX); // mov [esp+4],eax + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_map); // mov [esp],m_map + emit_call(dst, (x86code *)&drc_map_variables::static_get_value); // call drcmap_get_value + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax } -/*************************************************************************** - INTERNAL REGISTER OPCODES -***************************************************************************/ +//************************************************************************** +// INTERNAL REGISTER OPCODES +//************************************************************************** -/*------------------------------------------------- - op_setfmod - process a SETFMOD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_setfmod - process a SETFMOD opcode +//------------------------------------------------- -static x86code *op_setfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_setfmod(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_MRI); - /* immediate case */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate case + if (srcp.is_immediate()) { - srcp.value &= 3; - emit_mov_m8_imm(&dst, MABS(&drcbe->state.fmod), srcp.value); // mov [fmod],srcp - emit_fldcw_m16(&dst, MABS(&fp_control[srcp.value])); // fldcw fp_control[srcp] + int value = srcp.immediate() & 3; + emit_mov_m8_imm(dst, MABS(&m_state.fmod), value); // mov [fmod],srcp + emit_fldcw_m16(dst, MABS(&fp_control[value])); // fldcw fp_control[srcp] } - /* register/memory case */ + // register/memory case else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &srcp); // mov eax,srcp - emit_and_r32_imm(&dst, REG_EAX, 3); // and eax,3 - emit_mov_m8_r8(&dst, MABS(&drcbe->state.fmod), REG_AL); // mov [fmod],al - emit_fldcw_m16(&dst, MISD(REG_EAX, 2, &fp_control[0])); // fldcw fp_control[eax] + emit_mov_r32_p32(dst, REG_EAX, srcp); // mov eax,srcp + emit_and_r32_imm(dst, REG_EAX, 3); // and eax,3 + emit_mov_m8_r8(dst, MABS(&m_state.fmod), REG_AL); // mov [fmod],al + emit_fldcw_m16(dst, MABSI(&fp_control[0], REG_EAX, 2)); // fldcw fp_control[eax] } - - return dst; } -/*------------------------------------------------- - op_getfmod - process a GETFMOD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getfmod - process a GETFMOD opcode +//------------------------------------------------- -static x86code *op_getfmod(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_getfmod(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* fetch the current mode and store to the destination */ - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_m8(&dst, dstp.value, MABS(&drcbe->state.fmod)); // movzx reg,[fmod] + // fetch the current mode and store to the destination + if (dstp.is_int_register()) + emit_movzx_r32_m8(dst, dstp.ireg(), MABS(&m_state.fmod)); // movzx reg,[fmod] else { - emit_movzx_r32_m8(&dst, REG_EAX, MABS(&drcbe->state.fmod)); // movzx eax,[fmod] - emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX); // mov [dstp],eax + emit_movzx_r32_m8(dst, REG_EAX, MABS(&m_state.fmod)); // movzx eax,[fmod] + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax } - - return dst; } -/*------------------------------------------------- - op_getexp - process a GETEXP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getexp - process a GETEXP opcode +//------------------------------------------------- -static x86code *op_getexp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_getexp(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* fetch the exception parameter and store to the destination */ - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_r32_m32(&dst, dstp.value, MABS(&drcbe->state.exp)); // mov reg,[exp] + // fetch the exception parameter and store to the destination + if (dstp.is_int_register()) + emit_mov_r32_m32(dst, dstp.ireg(), MABS(&m_state.exp)); // mov reg,[exp] else { - emit_mov_r32_m32(&dst, REG_EAX, MABS(&drcbe->state.exp)); // mov eax,[exp] - emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX); // mov [dstp],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(&m_state.exp)); // mov eax,[exp] + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax } - - return dst; } -/*------------------------------------------------- - op_getflgs - process a GETFLGS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_getflgs - process a GETFLGS opcode +//------------------------------------------------- -static x86code *op_getflgs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_getflgs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, maskp; - UINT32 flagmask = 0; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &maskp, PTYPE_I); - - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter maskp(*this, inst.param(1), PTYPE_I); - /* compute mask for flags */ - if (maskp.value & DRCUML_FLAG_C) flagmask |= 0x001; - if (maskp.value & DRCUML_FLAG_V) flagmask |= 0x800; - if (maskp.value & DRCUML_FLAG_Z) flagmask |= 0x040; - if (maskp.value & DRCUML_FLAG_S) flagmask |= 0x080; - if (maskp.value & DRCUML_FLAG_U) flagmask |= 0x004; + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - switch (maskp.value) - { - /* single flags only */ - case DRCUML_FLAG_C: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + // compute mask for flags + UINT32 flagmask = 0; + if (maskp.immediate() & FLAG_C) flagmask |= 0x001; + if (maskp.immediate() & FLAG_V) flagmask |= 0x800; + if (maskp.immediate() & FLAG_Z) flagmask |= 0x040; + if (maskp.immediate() & FLAG_S) flagmask |= 0x080; + if (maskp.immediate() & FLAG_U) flagmask |= 0x004; + + switch (maskp.immediate()) + { + // single flags only + case FLAG_C: + emit_setcc_r8(dst, x86emit::COND_C, REG_AL); // setc al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al break; - case DRCUML_FLAG_V: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + case FLAG_V: + emit_setcc_r8(dst, x86emit::COND_O, REG_AL); // seto al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - case DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_Z, REG_AL); // setz al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 2); // shl dstreg,2 + case FLAG_Z: + emit_setcc_r8(dst, x86emit::COND_Z, REG_AL); // setz al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 2); // shl dstreg,2 break; - case DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_S, REG_AL); // sets al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 3); // shl dstreg,3 + case FLAG_S: + emit_setcc_r8(dst, x86emit::COND_S, REG_AL); // sets al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 3); // shl dstreg,3 break; - case DRCUML_FLAG_U: - emit_setcc_r8(&dst, COND_P, REG_AL); // setp al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al - emit_shl_r32_imm(&dst, dstreg, 4); // shl dstreg,4 + case FLAG_U: + emit_setcc_r8(dst, x86emit::COND_P, REG_AL); // setp al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al + emit_shl_r32_imm(dst, dstreg, 4); // shl dstreg,4 break; - /* carry plus another flag */ - case DRCUML_FLAG_C | DRCUML_FLAG_V: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_O, REG_CL); // seto cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + // carry plus another flag + case FLAG_C | FLAG_V: + emit_setcc_r8(dst, x86emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x86emit::COND_O, REG_CL); // seto cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] break; - case DRCUML_FLAG_C | DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_Z, REG_CL); // setz cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] + case FLAG_C | FLAG_Z: + emit_setcc_r8(dst, x86emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x86emit::COND_Z, REG_CL); // setz cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] break; - case DRCUML_FLAG_C | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_C, REG_AL); // setc al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0)); // lea dstreg,[eax+ecx*8] + case FLAG_C | FLAG_S: + emit_setcc_r8(dst, x86emit::COND_C, REG_AL); // setc al + emit_setcc_r8(dst, x86emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 8, 0)); // lea dstreg,[eax+ecx*8] break; - /* overflow plus another flag */ - case DRCUML_FLAG_V | DRCUML_FLAG_Z: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_setcc_r8(&dst, COND_Z, REG_CL); // setz cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + // overflow plus another flag + case FLAG_V | FLAG_Z: + emit_setcc_r8(dst, x86emit::COND_O, REG_AL); // seto al + emit_setcc_r8(dst, x86emit::COND_Z, REG_CL); // setz cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - case DRCUML_FLAG_V | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_O, REG_AL); // seto al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] - emit_shl_r32_imm(&dst, dstreg, 1); // shl dstreg,1 + case FLAG_V | FLAG_S: + emit_setcc_r8(dst, x86emit::COND_O, REG_AL); // seto al + emit_setcc_r8(dst, x86emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 4, 0)); // lea dstreg,[eax+ecx*4] + emit_shl_r32_imm(dst, dstreg, 1); // shl dstreg,1 break; - /* zero plus another flag */ - case DRCUML_FLAG_Z | DRCUML_FLAG_S: - emit_setcc_r8(&dst, COND_Z, REG_AL); // setz al - emit_setcc_r8(&dst, COND_S, REG_CL); // sets cl - emit_movzx_r32_r8(&dst, REG_EAX, REG_AL); // movzx eax,al - emit_movzx_r32_r8(&dst, REG_ECX, REG_CL); // movzx ecx,al - emit_lea_r32_m32(&dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] - emit_shl_r32_imm(&dst, dstreg, 2); // shl dstreg,2 + // zero plus another flag + case FLAG_Z | FLAG_S: + emit_setcc_r8(dst, x86emit::COND_Z, REG_AL); // setz al + emit_setcc_r8(dst, x86emit::COND_S, REG_CL); // sets cl + emit_movzx_r32_r8(dst, REG_EAX, REG_AL); // movzx eax,al + emit_movzx_r32_r8(dst, REG_ECX, REG_CL); // movzx ecx,al + emit_lea_r32_m32(dst, dstreg, MBISD(REG_EAX, REG_ECX, 2, 0)); // lea dstreg,[eax+ecx*2] + emit_shl_r32_imm(dst, dstreg, 2); // shl dstreg,2 break; - /* default cases */ + // default cases default: - emit_pushf(&dst); // pushf - emit_pop_r32(&dst, REG_EAX); // pop eax - emit_and_r32_imm(&dst, REG_EAX, flagmask); // and eax,flagmask - emit_movzx_r32_m8(&dst, dstreg, MBD(REG_EAX, flags_map)); // movzx dstreg,[flags_map] + emit_pushf(dst); // pushf + emit_pop_r32(dst, REG_EAX); // pop eax + emit_and_r32_imm(dst, REG_EAX, flagmask); // and eax,flagmask + emit_movzx_r32_m8(dst, dstreg, MABSI(flags_map, REG_EAX)); // movzx dstreg,[flags_map] break; } - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - /* general case */ - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov [dstp+4],0 - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov [reghi],0 + // general case + if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov [dstp+4],0 + else if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov [reghi],0 } - return dst; } -/*------------------------------------------------- - op_save - process a SAVE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_save - process a SAVE opcode +//------------------------------------------------- -static x86code *op_save(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_save(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_M); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_M); - /* copy live state to the destination */ - emit_mov_r32_imm(&dst, REG_ECX, dstp.value); // mov ecx,dstp - emit_call(&dst, drcbe->save); // call save - return dst; + // copy live state to the destination + emit_mov_r32_imm(dst, REG_ECX, (FPTR)dstp.memory()); // mov ecx,dstp + emit_call(dst, m_save); // call save } -/*------------------------------------------------- - op_restore - process a RESTORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_restore - process a RESTORE opcode +//------------------------------------------------- -static x86code *op_restore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_restore(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - - /* validate instruction */ - assert(inst->size == 4); + // validate instruction + assert(inst.size() == 4); assert_no_condition(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_M); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_M); - /* copy live state from the destination */ - emit_mov_r32_imm(&dst, REG_ECX, dstp.value); // mov ecx,dstp - emit_call(&dst, drcbe->restore); // call restore - return dst; + // copy live state from the destination + emit_mov_r32_imm(dst, REG_ECX, (FPTR)srcp.memory()); // mov ecx,dstp + emit_call(dst, m_restore); // call restore } -/*************************************************************************** - INTEGER OPERATIONS -***************************************************************************/ +//************************************************************************** +// INTEGER OPERATIONS +//************************************************************************** -/*------------------------------------------------- - op_load - process a LOAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_load - process a LOAD opcode +//------------------------------------------------- -static x86code *op_load(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_load(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp, scalesizep; - int dstreg, scale, size; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; - - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); - - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - { - if (size == DRCUML_SIZE_BYTE) - emit_movzx_r32_m8(&dst, dstreg, MABS(basep.value + scale*indp.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movzx_r32_m16(&dst, dstreg, MABS(basep.value + scale*indp.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + scale*indp.value)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + assert(scalesizep.is_size_scale()); + int scale = 1 << scalesizep.scale(); + int size = scalesizep.size(); + + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); + + // immediate index + if (indp.is_immediate()) + { + if (size == SIZE_BYTE) + emit_movzx_r32_m8(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movzx_r32_m16(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) { - emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + scale*indp.value + 4)); // mov edx,[basep + scale*indp + 4] - emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + scale*indp.value)); // mov dstreg,[basep + scale*indp] + emit_mov_r32_m32(dst, REG_EDX, MABS(basep.memory(scale*indp.immediate() + 4))); // mov edx,[basep + scale*indp + 4] + emit_mov_r32_m32(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // mov dstreg,[basep + scale*indp] } } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); - if (size == DRCUML_SIZE_BYTE) - emit_movzx_r32_m8(&dst, dstreg, MISD(indreg, scale, basep.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movzx_r32_m16(&dst, dstreg, MISD(indreg, scale, basep.value)); // movzx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MISD(indreg, scale, basep.value)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); + if (size == SIZE_BYTE) + emit_movzx_r32_m8(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movzx_r32_m16(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // movzx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) { - emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, scale, basep.value + 4)); // mov edx,[basep + scale*indp + 4] - emit_mov_r32_m32(&dst, dstreg, MISD(indreg, scale, basep.value)); // mov dstreg,[basep + scale*indp] + emit_mov_r32_m32(dst, REG_EDX, MABSI(basep.memory(4), indreg, scale)); // mov edx,[basep + scale*indp + 4] + emit_mov_r32_m32(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // mov dstreg,[basep + scale*indp] } } - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - /* 1, 2, or 4-byte case */ - if (size != DRCUML_SIZE_QWORD) + // 1, 2, or 4-byte case + if (size != SIZE_QWORD) { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov [dstp+4],0 - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov [reghi],0 + if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov [dstp+4],0 + else if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov [reghi],0 } - /* 8-byte case */ + // 8-byte case else { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp+4],edx - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // mov [reghi],edx - set_last_upper_reg(drcbe, dst, &dstp, REG_EDX); + if (dstp.is_memory()) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx + else if (dstp.is_int_register()) + emit_mov_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // mov [reghi],edx + set_last_upper_reg(dst, dstp, REG_EDX); } } - set_last_lower_reg(drcbe, dst, &dstp, dstreg); - return dst; + set_last_lower_reg(dst, dstp, dstreg); } -/*------------------------------------------------- - op_loads - process a LOADS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_loads - process a LOADS opcode +//------------------------------------------------- -static x86code *op_loads(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_loads(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp, scalesizep; - int dstreg, scale, size; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &basep, PTYPE_M, &indp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; - - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); - - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) - { - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MABS(basep.value + scale*indp.value)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MABS(basep.value + scale*indp.value)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + scale*indp.value)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + assert(scalesizep.is_size_scale()); + int scale = 1 << scalesizep.scale(); + int size = scalesizep.size(); + + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); + + // immediate index + if (indp.is_immediate()) + { + if (size == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // movsx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // movsx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) { - emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + scale*indp.value + 4)); // mov edx,[basep + scale*indp + 4] - emit_mov_r32_m32(&dst, dstreg, MABS(basep.value + scale*indp.value)); // mov dstreg,[basep + scale*indp] + emit_mov_r32_m32(dst, REG_EDX, MABS(basep.memory(scale*indp.immediate() + 4))); // mov edx,[basep + scale*indp + 4] + emit_mov_r32_m32(dst, dstreg, MABS(basep.memory(scale*indp.immediate()))); // mov dstreg,[basep + scale*indp] } } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); - if (size == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MISD(indreg, scale, basep.value)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MISD(indreg, scale, basep.value)); // movsx dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MISD(indreg, scale, basep.value)); // mov dstreg,[basep + scale*indp] - else if (size == DRCUML_SIZE_QWORD) + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); + if (size == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // movsx dstreg,[basep + scale*indp] + else if (size == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // movsx dstreg,[basep + scale*indp] + else if (size == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // mov dstreg,[basep + scale*indp] + else if (size == SIZE_QWORD) { - emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, scale, basep.value + 4)); // mov edx,[basep + scale*indp + 4] - emit_mov_r32_m32(&dst, dstreg, MISD(indreg, scale, basep.value)); // mov dstreg,[basep + scale*indp] + emit_mov_r32_m32(dst, REG_EDX, MABSI(basep.memory(4), indreg, scale)); // mov edx,[basep + scale*indp + 4] + emit_mov_r32_m32(dst, dstreg, MABSI(basep.memory(), indreg, scale)); // mov dstreg,[basep + scale*indp] } } - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - emit_cdq(&dst); // cdq - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp+4],edx - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // mov [reghi],edx - set_last_upper_reg(drcbe, dst, &dstp, REG_EDX); + emit_cdq(dst); // cdq + if (dstp.is_memory()) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx + else if (dstp.is_int_register()) + emit_mov_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // mov [reghi],edx + set_last_upper_reg(dst, dstp, REG_EDX); } - set_last_lower_reg(drcbe, dst, &dstp, dstreg); - return dst; + set_last_lower_reg(dst, dstp, dstreg); } -/*------------------------------------------------- - op_store - process a STORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_store - process a STORE opcode +//------------------------------------------------- -static x86code *op_store(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_store(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, basep, indp, scalesizep; - int srcreg, scale, size; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MRI, &scalesizep, PTYPE_I); - scale = 1 << (scalesizep.value / 16); - size = scalesizep.value % 16; - - /* pick a source register for the general case */ - srcreg = param_select_register(REG_EAX, &srcp, NULL); - if (size == DRCUML_SIZE_BYTE && (srcreg & 4)) + // normalize parameters + be_parameter basep(*this, inst.param(0), PTYPE_M); + be_parameter indp(*this, inst.param(1), PTYPE_MRI); + be_parameter srcp(*this, inst.param(2), PTYPE_MRI); + const parameter &scalesizep = inst.param(3); + int scale = 1 << (scalesizep.scale()); + int size = scalesizep.size(); + + // pick a source register for the general case + int srcreg = srcp.select_register(REG_EAX); + if (size == SIZE_BYTE && (srcreg & 4)) srcreg = REG_EAX; - /* degenerate case: constant index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // degenerate case: constant index + if (indp.is_immediate()) { - /* immediate source */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate source + if (srcp.is_immediate()) { - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_imm(&dst, MABS(basep.value + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_imm(&dst, MABS(basep.value + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_imm(&dst, MABS(basep.value + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - else if (size == DRCUML_SIZE_QWORD) + if (size == SIZE_BYTE) + emit_mov_m8_imm(dst, MABS(basep.memory(scale*indp.immediate())), srcp.immediate()); // mov [basep + scale*indp],srcp + else if (size == SIZE_WORD) + emit_mov_m16_imm(dst, MABS(basep.memory(scale*indp.immediate())), srcp.immediate()); // mov [basep + scale*indp],srcp + else if (size == SIZE_DWORD) + emit_mov_m32_imm(dst, MABS(basep.memory(scale*indp.immediate())), srcp.immediate()); // mov [basep + scale*indp],srcp + else if (size == SIZE_QWORD) { - emit_mov_m32_imm(&dst, MABS(basep.value + scale*indp.value), srcp.value); // mov [basep + scale*indp],srcp - emit_mov_m32_imm(&dst, MABS(basep.value + scale*indp.value + 4), srcp.value >> 32); + emit_mov_m32_imm(dst, MABS(basep.memory(scale*indp.immediate())), srcp.immediate()); // mov [basep + scale*indp],srcp + emit_mov_m32_imm(dst, MABS(basep.memory(scale*indp.immediate() + 4)), srcp.immediate() >> 32); // mov [basep + scale*indp + 4],srcp >> 32 } } - /* variable source */ + // variable source else { - if (size != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp + if (size != SIZE_QWORD) + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp else - emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp); // mov edx:srcreg,srcp - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_r8(&dst, MABS(basep.value + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_r16(&dst, MABS(basep.value + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_r32(&dst, MABS(basep.value + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - else if (size == DRCUML_SIZE_QWORD) + emit_mov_r64_p64(dst, srcreg, REG_EDX, srcp); // mov edx:srcreg,srcp + if (size == SIZE_BYTE) + emit_mov_m8_r8(dst, MABS(basep.memory(scale*indp.immediate())), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_WORD) + emit_mov_m16_r16(dst, MABS(basep.memory(scale*indp.immediate())), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_DWORD) + emit_mov_m32_r32(dst, MABS(basep.memory(scale*indp.immediate())), srcreg); // mov [basep + scale*indp],srcreg + else if (size == SIZE_QWORD) { - emit_mov_m32_r32(&dst, MABS(basep.value + scale*indp.value), srcreg); // mov [basep + scale*indp],srcreg - emit_mov_m32_r32(&dst, MABS(basep.value + scale*indp.value + 4), REG_EDX); // mov [basep + scale*indp + 4],edx + emit_mov_m32_r32(dst, MABS(basep.memory(scale*indp.immediate())), srcreg); // mov [basep + scale*indp],srcreg + emit_mov_m32_r32(dst, MABS(basep.memory(scale*indp.immediate() + 4)), REG_EDX); // mov [basep + scale*indp + 4],edx } } } - /* normal case: variable index */ + // normal case: variable index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); // mov indreg,indp + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); // mov indreg,indp - /* immediate source */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate source + if (srcp.is_immediate()) { - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_imm(&dst, MISD(indreg, scale, basep.value), srcp.value); // mov [basep + 1*ecx],srcp - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_imm(&dst, MISD(indreg, scale, basep.value), srcp.value); // mov [basep + 2*ecx],srcp - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_imm(&dst, MISD(indreg, scale, basep.value), srcp.value); // mov [basep + 4*ecx],srcp - else if (size == DRCUML_SIZE_QWORD) + if (size == SIZE_BYTE) + emit_mov_m8_imm(dst, MABSI(basep.memory(), indreg, scale), srcp.immediate()); // mov [basep + 1*ecx],srcp + else if (size == SIZE_WORD) + emit_mov_m16_imm(dst, MABSI(basep.memory(), indreg, scale), srcp.immediate()); // mov [basep + 2*ecx],srcp + else if (size == SIZE_DWORD) + emit_mov_m32_imm(dst, MABSI(basep.memory(), indreg, scale), srcp.immediate()); // mov [basep + 4*ecx],srcp + else if (size == SIZE_QWORD) { - emit_mov_m32_imm(&dst, MISD(indreg, scale, basep.value), srcp.value); // mov [basep + 8*ecx],srcp - emit_mov_m32_imm(&dst, MISD(indreg, scale, basep.value + 4), srcp.value >> 32); + emit_mov_m32_imm(dst, MABSI(basep.memory(), indreg, scale), srcp.immediate()); // mov [basep + 8*ecx],srcp + emit_mov_m32_imm(dst, MABSI(basep.memory(4), indreg, scale), srcp.immediate() >> 32); // mov [basep + 8*ecx + 4],srcp >> 32 } } - /* variable source */ + // variable source else { - if (size != DRCUML_SIZE_QWORD) - emit_mov_r32_p32(drcbe, &dst, srcreg, &srcp); // mov srcreg,srcp + if (size != SIZE_QWORD) + emit_mov_r32_p32(dst, srcreg, srcp); // mov srcreg,srcp else - emit_mov_r64_p64(drcbe, &dst, srcreg, REG_EDX, &srcp); // mov edx:srcreg,srcp - if (size == DRCUML_SIZE_BYTE) - emit_mov_m8_r8(&dst, MISD(indreg, scale, basep.value), srcreg); // mov [basep + 1*ecx],srcreg - else if (size == DRCUML_SIZE_WORD) - emit_mov_m16_r16(&dst, MISD(indreg, scale, basep.value), srcreg); // mov [basep + 2*ecx],srcreg - else if (size == DRCUML_SIZE_DWORD) - emit_mov_m32_r32(&dst, MISD(indreg, scale, basep.value), srcreg); // mov [basep + 4*ecx],srcreg - else if (size == DRCUML_SIZE_QWORD) + emit_mov_r64_p64(dst, srcreg, REG_EDX, srcp); // mov edx:srcreg,srcp + if (size == SIZE_BYTE) + emit_mov_m8_r8(dst, MABSI(basep.memory(), indreg, scale), srcreg); // mov [basep + 1*ecx],srcreg + else if (size == SIZE_WORD) + emit_mov_m16_r16(dst, MABSI(basep.memory(), indreg, scale), srcreg); // mov [basep + 2*ecx],srcreg + else if (size == SIZE_DWORD) + emit_mov_m32_r32(dst, MABSI(basep.memory(), indreg, scale), srcreg); // mov [basep + 4*ecx],srcreg + else if (size == SIZE_QWORD) { - emit_mov_m32_r32(&dst, MISD(indreg, scale, basep.value), srcreg); // mov [basep + 8*ecx],srcreg - emit_mov_m32_r32(&dst, MISD(indreg, scale, basep.value + 4), REG_EDX); // mov [basep + 8*ecx],edx + emit_mov_m32_r32(dst, MABSI(basep.memory(), indreg, scale), srcreg); // mov [basep + 8*ecx],srcreg + emit_mov_m32_r32(dst, MABSI(basep.memory(4), indreg, scale), REG_EDX); // mov [basep + 8*ecx],edx } } } - return dst; } -/*------------------------------------------------- - op_read - process a READ opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_read - process a READ opcode +//------------------------------------------------- -static x86code *op_read(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_read(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, addrp, spacesizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacesizep = inst.param(2); + assert(spacesizep.is_size_space()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set up a call to the read byte handler */ - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space - if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE) + // set up a call to the read byte handler + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacesizep.space()]); // mov [esp],space + if (spacesizep.size() == SIZE_BYTE) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_byte); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_byte); // call read_byte - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al } - else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) + else if (spacesizep.size() == SIZE_WORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_word); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_word); // call read_word - emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax + emit_movzx_r32_r16(dst, dstreg, REG_AX); // movzx dstreg,ax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) + else if (spacesizep.size() == SIZE_DWORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_dword); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_dword); // call read_dword - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) + else if (spacesizep.size() == SIZE_QWORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_qword); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_qword); // call read_qword - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - /* 1, 2, or 4-byte case */ - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) + // 1, 2, or 4-byte case + if (spacesizep.size() != SIZE_QWORD) { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov [dstp+4],0 - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov [reghi],0 + if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov [dstp+4],0 + else if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov [reghi],0 } - /* 8-byte case */ + // 8-byte case else { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp+4],edx - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // mov [reghi],edx + if (dstp.is_memory()) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx + else if (dstp.is_int_register()) + emit_mov_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // mov [reghi],edx } } - return dst; } -/*------------------------------------------------- - op_readm - process a READM opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_readm - process a READM opcode +//------------------------------------------------- -static x86code *op_readm(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_readm(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, addrp, maskp, spacesizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &addrp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + be_parameter maskp(*this, inst.param(2), PTYPE_MRI); + const parameter &spacesizep = inst.param(3); + assert(spacesizep.is_size_space()); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set up a call to the read byte handler */ - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 8), &maskp); // mov [esp+8],maskp + // set up a call to the read byte handler + if (spacesizep.size() != SIZE_QWORD) + emit_mov_m32_p32(dst, MBD(REG_ESP, 8), maskp); // mov [esp+8],maskp else - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &maskp); // mov [esp+8],maskp - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space - if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), maskp); // mov [esp+8],maskp + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacesizep.space()]); // mov [esp],space + if (spacesizep.size() == SIZE_WORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_word_masked); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_word_masked); // call read_word_masked - emit_movzx_r32_r16(&dst, dstreg, REG_AX); // movzx dstreg,ax + emit_movzx_r32_r16(dst, dstreg, REG_AX); // movzx dstreg,ax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) + else if (spacesizep.size() == SIZE_DWORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_dword_masked); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_dword_masked); // call read_dword_masked - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) + else if (spacesizep.size() == SIZE_QWORD) { - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].read_qword_masked); + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].read_qword_masked); // call read_qword_masked - emit_mov_r32_r32(&dst, dstreg, REG_EAX); // mov dstreg,eax + emit_mov_r32_r32(dst, dstreg, REG_EAX); // mov dstreg,eax } - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - /* 1, 2, or 4-byte case */ - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) + // 1, 2, or 4-byte case + if (spacesizep.size() != SIZE_QWORD) { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov [dstp+4],0 - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov [reghi],0 + if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov [dstp+4],0 + else if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov [reghi],0 } - /* 8-byte case */ + // 8-byte case else { - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp+4],edx - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // mov [reghi],edx + if (dstp.is_memory()) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp+4],edx + else if (dstp.is_int_register()) + emit_mov_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // mov [reghi],edx } } - return dst; } -/*------------------------------------------------- - op_write - process a WRITE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_write - process a WRITE opcode +//------------------------------------------------- -static x86code *op_write(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_write(x86code *&dst, const instruction &inst) { - drcuml_parameter addrp, srcp, spacesizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacesizep = inst.param(2); + assert(spacesizep.is_size_space()); - /* set up a call to the write byte handler */ - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp + // set up a call to the write byte handler + if (spacesizep.size() != SIZE_QWORD) + emit_mov_m32_p32(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp else - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space - if ((spacesizep.value & 3) == DRCUML_SIZE_BYTE) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_byte); + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacesizep.space()]); // mov [esp],space + if (spacesizep.size() == SIZE_BYTE) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_byte); // call write_byte - else if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_word); + else if (spacesizep.size() == SIZE_WORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_word); // call write_word - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_dword); + else if (spacesizep.size() == SIZE_DWORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_dword); // call write_dword - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_qword); + else if (spacesizep.size() == SIZE_QWORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_qword); // call write_qword - return dst; } -/*------------------------------------------------- - op_writem - process a WRITEM opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_writem - process a WRITEM opcode +//------------------------------------------------- -static x86code *op_writem(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_writem(x86code *&dst, const instruction &inst) { - drcuml_parameter addrp, srcp, maskp, spacesizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MRI, &maskp, PTYPE_MRI, &spacesizep, PTYPE_I); + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter maskp(*this, inst.param(2), PTYPE_MRI); + const parameter &spacesizep = inst.param(3); + assert(spacesizep.is_size_space()); - /* set up a call to the write byte handler */ - if ((spacesizep.value & 3) != DRCUML_SIZE_QWORD) + // set up a call to the write byte handler + if (spacesizep.size() != SIZE_QWORD) { - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 12), &maskp); // mov [esp+12],maskp - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp + emit_mov_m32_p32(dst, MBD(REG_ESP, 12), maskp); // mov [esp+12],maskp + emit_mov_m32_p32(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp } else { - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 16), &maskp); // mov [esp+16],maskp - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp + emit_mov_m64_p64(dst, MBD(REG_ESP, 16), maskp); // mov [esp+16],maskp + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp } - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacesizep.value / 16]);// mov [esp],space - if ((spacesizep.value & 3) == DRCUML_SIZE_WORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_word_masked); + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacesizep.space()]); // mov [esp],space + if (spacesizep.size() == SIZE_WORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_word_masked); // call write_word_masked - else if ((spacesizep.value & 3) == DRCUML_SIZE_DWORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_dword_masked); + else if (spacesizep.size() == SIZE_DWORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_dword_masked); // call write_dword_masked - else if ((spacesizep.value & 3) == DRCUML_SIZE_QWORD) - emit_call(&dst, (x86code *)drcbe->accessors[spacesizep.value / 16].write_qword_masked); + else if (spacesizep.size() == SIZE_QWORD) + emit_call(dst, (x86code *)m_accessors[spacesizep.space()].write_qword_masked); // call write_qword_masked - return dst; } -/*------------------------------------------------- - op_carry - process a CARRY opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_carry - process a CARRY opcode +//------------------------------------------------- -static x86code *op_carry(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_carry(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, bitp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C); + assert_flags(inst, FLAG_C); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &srcp, PTYPE_MRI, &bitp, PTYPE_MRI); + // normalize parameters + be_parameter srcp(*this, inst.param(0), PTYPE_MRI); + be_parameter bitp(*this, inst.param(1), PTYPE_MRI); - /* degenerate case: source is immediate */ - if (srcp.type == DRCUML_PTYPE_IMMEDIATE && bitp.type == DRCUML_PTYPE_IMMEDIATE) + // degenerate case: source is immediate + if (srcp.is_immediate() && bitp.is_immediate()) { - if (srcp.value & ((UINT64)1 << bitp.value)) - emit_stc(&dst); + if (srcp.immediate() & ((UINT64)1 << bitp.immediate())) + emit_stc(dst); else - emit_clc(&dst); - return dst; - } + emit_clc(dst); + } - /* load non-immediate bit numbers into a register */ - if (bitp.type != DRCUML_PTYPE_IMMEDIATE) + // load non-immediate bit numbers into a register + if (!bitp.is_immediate()) { - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &bitp); - emit_and_r32_imm(&dst, REG_ECX, inst->size * 8 - 1); + emit_mov_r32_p32(dst, REG_ECX, bitp); + emit_and_r32_imm(dst, REG_ECX, inst.size() * 8 - 1); } - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - if (bitp.type == DRCUML_PTYPE_IMMEDIATE) + if (bitp.is_immediate()) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_imm(&dst, MABS(srcp.value), bitp.value); // bt [srcp],bitp - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r32_imm(&dst, srcp.value, bitp.value); // bt srcp,bitp + if (srcp.is_memory()) + emit_bt_m32_imm(dst, MABS(srcp.memory()), bitp.immediate()); // bt [srcp],bitp + else if (srcp.is_int_register()) + emit_bt_r32_imm(dst, srcp.ireg(), bitp.immediate()); // bt srcp,bitp } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_r32(&dst, MABS(srcp.value), REG_ECX); // bt [srcp],ecx - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_bt_r32_r32(&dst, srcp.value, REG_ECX); // bt [srcp],ecx + if (srcp.is_memory()) + emit_bt_m32_r32(dst, MABS(srcp.memory()), REG_ECX); // bt [srcp],ecx + else if (srcp.is_int_register()) + emit_bt_r32_r32(dst, srcp.ireg(), REG_ECX); // bt [srcp],ecx } } - /* 64-bit form */ + // 64-bit form else { - if (bitp.type == DRCUML_PTYPE_IMMEDIATE) + if (bitp.is_immediate()) { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_imm(&dst, MABS(srcp.value), bitp.value); // bt [srcp],bitp - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER && bitp.value < 32) - emit_bt_r32_imm(&dst, srcp.value, bitp.value); // bt srcp,bitp - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER && bitp.value >= 32) - emit_bt_m32_imm(&dst, MABS(drcbe->reghi[srcp.value]), bitp.value - 32); // bt [srcp.hi],bitp + if (srcp.is_memory()) + emit_bt_m32_imm(dst, MABS(srcp.memory()), bitp.immediate()); // bt [srcp],bitp + else if (srcp.is_int_register() && bitp.immediate() < 32) + emit_bt_r32_imm(dst, srcp.ireg(), bitp.immediate()); // bt srcp,bitp + else if (srcp.is_int_register() && bitp.immediate() >= 32) + emit_bt_m32_imm(dst, MABS(m_reghi[srcp.ireg()]), bitp.immediate() - 32); // bt [srcp.hi],bitp } else { - if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_bt_m32_r32(&dst, MABS(srcp.value), REG_ECX); // bt [srcp],ecx - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + if (srcp.is_memory()) + emit_bt_m32_r32(dst, MABS(srcp.memory()), REG_ECX); // bt [srcp],ecx + else if (srcp.is_int_register()) { - emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value); // mov [srcp.lo],srcp - emit_bt_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), REG_ECX); // bt [srcp],ecx + emit_mov_m32_r32(dst, MABS(m_reglo[srcp.ireg()]), srcp.ireg()); // mov [srcp.lo],srcp + emit_bt_m32_r32(dst, MABS(m_reglo[srcp.ireg()]), REG_ECX); // bt [srcp],ecx } } } - return dst; } -/*------------------------------------------------- - op_set - process a SET opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_set - process a SET opcode +//------------------------------------------------- -static x86code *op_set(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_set(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_1(drcbe, inst, &dstp, PTYPE_MR); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* set to AL */ - emit_setcc_r8(&dst, X86_CONDITION(inst->condition), REG_AL); // setcc al - emit_movzx_r32_r8(&dst, dstreg, REG_AL); // movzx dstreg,al + // set to AL + emit_setcc_r8(dst, X86_CONDITION(inst.condition()), REG_AL); // setcc al + emit_movzx_r32_r8(dst, dstreg, REG_AL); // movzx dstreg,al - /* store low 32 bits */ - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // store low 32 bits + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form stores upper 32 bits */ - if (inst->size == 8) + // 64-bit form stores upper 32 bits + if (inst.size() == 8) { - /* general case */ - if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov [dstp+4],0 - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov [reghi],0 + // general case + if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov [dstp+4],0 + else if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov [reghi],0 } - return dst; } -/*------------------------------------------------- - op_mov - process a MOV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mov - process a MOV opcode +//------------------------------------------------- -static x86code *op_mov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_mov(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; x86code *savedst = dst; - emit_link skip = { 0 }; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters, but only if we got here directly */ - /* other opcodes call through here with pre-normalized parameters */ - if (inst->opcode == DRCUML_OP_MOV) - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); - else - { - dstp = inst->param[0]; - srcp = inst->param[1]; - } + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* always start with a jmp */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // always start with a jmp + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* register to memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_r32(&dst, MABS(dstp.value), srcp.value); // mov [dstp],srcp + // register to memory + if (dstp.is_memory() && srcp.is_int_register()) + emit_mov_m32_r32(dst, MABS(dstp.memory()), srcp.ireg()); // mov [dstp],srcp - /* immediate to memory */ - else if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_m32_imm(&dst, MABS(dstp.value), srcp.value); // mov [dstp],srcp + // immediate to memory + else if (dstp.is_memory() && srcp.is_immediate()) + emit_mov_m32_imm(dst, MABS(dstp.memory()), srcp.immediate()); // mov [dstp],srcp - /* conditional memory to register */ - else if (inst->condition != DRCUML_COND_ALWAYS && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_MEMORY) + // conditional memory to register + else if (inst.condition() != uml::COND_ALWAYS && dstp.is_int_register() && srcp.is_memory()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r32_m32(&dst, X86_CONDITION(inst->condition), dstp.value, MABS(srcp.value)); + emit_cmovcc_r32_m32(dst, X86_CONDITION(inst.condition()), dstp.ireg(), MABS(srcp.memory())); // cmovcc dstp,[srcp] } - /* conditional register to register */ - else if (inst->condition != DRCUML_COND_ALWAYS && dstp.type == DRCUML_PTYPE_INT_REGISTER && srcp.type == DRCUML_PTYPE_INT_REGISTER) + // conditional register to register + else if (inst.condition() != uml::COND_ALWAYS && dstp.is_int_register() && srcp.is_int_register()) { dst = savedst; skip.target = NULL; - emit_cmovcc_r32_r32(&dst, X86_CONDITION(inst->condition), dstp.value, srcp.value); + emit_cmovcc_r32_r32(dst, X86_CONDITION(inst.condition()), dstp.ireg(), srcp.ireg()); // cmovcc dstp,srcp } - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, srcp); // mov dstreg,srcp + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* register to memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_INT_REGISTER) + // register to memory + if (dstp.is_memory() && srcp.is_int_register()) { - emit_mov_r32_m32(&dst, REG_EAX, MABS(drcbe->reghi[srcp.value])); // mov eax,reghi[srcp] - emit_mov_m32_r32(&dst, MABS(dstp.value), srcp.value); // mov [dstp],srcp - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EAX); // mov [dstp+4],eax + emit_mov_r32_m32(dst, REG_EAX, MABS(m_reghi[srcp.ireg()])); // mov eax,reghi[srcp] + emit_mov_m32_r32(dst, MABS(dstp.memory()), srcp.ireg()); // mov [dstp],srcp + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EAX); // mov [dstp+4],eax } - /* immediate to memory */ - else if (dstp.type == DRCUML_PTYPE_MEMORY && srcp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate to memory + else if (dstp.is_memory() && srcp.is_immediate()) { - emit_mov_m32_imm(&dst, MABS(dstp.value), srcp.value); // mov [dstp],srcp - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), srcp.value >> 32); // mov [dstp+4],srcp >> 32 + emit_mov_m32_imm(dst, MABS(dstp.memory()), srcp.immediate()); // mov [dstp],srcp + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), srcp.immediate() >> 32); // mov [dstp+4],srcp >> 32 } - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &srcp); // mov edx:dstreg,srcp - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg + emit_mov_r64_p64(dst, dstreg, REG_EDX, srcp); // mov edx:dstreg,srcp + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg } } - /* resolve the jump */ + // resolve the jump if (skip.target != NULL) - track_resolve_link(drcbe, &dst, &skip); - return dst; + track_resolve_link(dst, skip); } -/*------------------------------------------------- - op_sext - process a SEXT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sext - process a SEXT opcode +//------------------------------------------------- -static x86code *op_sext(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_sext(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &sizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - /* pick a target register for the general case */ - dstreg = (inst->size == 8) ? REG_EAX : param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = (inst.size() == 8) ? REG_EAX : dstp.select_register(REG_EAX); - /* convert 8-bit source registers to EAX */ - if (sizep.value == DRCUML_SIZE_BYTE && srcp.type == DRCUML_PTYPE_INT_REGISTER && (srcp.value & 4)) + // convert 8-bit source registers to EAX + if (sizep.size() == SIZE_BYTE && srcp.is_int_register() && (srcp.ireg() & 4)) { - emit_mov_r32_r32(&dst, REG_EAX, srcp.value); // mov eax,srcp - srcp.value = REG_EAX; + emit_mov_r32_r32(dst, REG_EAX, srcp.ireg()); // mov eax,srcp + srcp = be_parameter::make_ireg(REG_EAX); } - /* general case */ - if (srcp.type == DRCUML_PTYPE_MEMORY) + // general case + if (srcp.is_memory()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r32_m8(&dst, dstreg, MABS(srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r32_m16(&dst, dstreg, MABS(srcp.value)); // movsx dstreg,[srcp] - else if (sizep.value == DRCUML_SIZE_DWORD) - emit_mov_r32_m32(&dst, dstreg, MABS(srcp.value)); // mov dstreg,[srcp] + if (sizep.size() == SIZE_BYTE) + emit_movsx_r32_m8(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_WORD) + emit_movsx_r32_m16(dst, dstreg, MABS(srcp.memory())); // movsx dstreg,[srcp] + else if (sizep.size() == SIZE_DWORD) + emit_mov_r32_m32(dst, dstreg, MABS(srcp.memory())); // mov dstreg,[srcp] } - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + else if (srcp.is_int_register()) { - if (sizep.value == DRCUML_SIZE_BYTE) - emit_movsx_r32_r8(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_WORD) - emit_movsx_r32_r16(&dst, dstreg, srcp.value); // movsx dstreg,srcp - else if (sizep.value == DRCUML_SIZE_DWORD && dstreg != srcp.value) - emit_mov_r32_r32(&dst, dstreg, srcp.value); // mov dstreg,srcp + if (sizep.size() == SIZE_BYTE) + emit_movsx_r32_r8(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_WORD) + emit_movsx_r32_r16(dst, dstreg, srcp.ireg()); // movsx dstreg,srcp + else if (sizep.size() == SIZE_DWORD && dstreg != srcp.ireg()) + emit_mov_r32_r32(dst, dstreg, srcp.ireg()); // mov dstreg,srcp } - if (inst->flags != 0) - emit_test_r32_r32(&dst, dstreg, dstreg); // test dstreg,dstreg + if (inst.flags() != 0) + emit_test_r32_r32(dst, dstreg, dstreg); // test dstreg,dstreg - /* 32-bit form: store the low 32 bits */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + // 32-bit form: store the low 32 bits + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg - /* 64-bit form: sign extend to 64 bits and store edx:eax */ - else if (inst->size == 8) + // 64-bit form: sign extend to 64 bits and store edx:eax + else if (inst.size() == 8) { - emit_cdq(&dst); // cdq - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax + emit_cdq(dst); // cdq + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax } - return dst; } -/*------------------------------------------------- - op_roland - process an ROLAND opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_roland - process an ROLAND opcode +//------------------------------------------------- -static x86code *op_roland(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_roland(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, shiftp, maskp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &shiftp, PTYPE_MRI, &maskp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter shiftp(*this, inst.param(2), PTYPE_MRI); + be_parameter maskp(*this, inst.param(3), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register2(REG_EAX, &dstp, &shiftp, &maskp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, shiftp, maskp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,srcp - emit_rol_r32_p32(drcbe, &dst, dstreg, &shiftp, inst); // rol dstreg,shiftp - emit_and_r32_p32(drcbe, &dst, dstreg, &maskp, inst); // and dstreg,maskp - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,srcp + emit_rol_r32_p32(dst, dstreg, shiftp, inst); // rol dstreg,shiftp + emit_and_r32_p32(dst, dstreg, maskp, inst); // and dstreg,maskp + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &srcp); // mov edx:dstreg,srcp - emit_rol_r64_p64(drcbe, &dst, dstreg, REG_EDX, &shiftp, inst); // rol edx:dstreg,shiftp - emit_and_r64_p64(drcbe, &dst, dstreg, REG_EDX, &maskp, inst); // and edx:dstreg,maskp - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg + emit_mov_r64_p64(dst, dstreg, REG_EDX, srcp); // mov edx:dstreg,srcp + emit_rol_r64_p64(dst, dstreg, REG_EDX, shiftp, inst); // rol edx:dstreg,shiftp + emit_and_r64_p64(dst, dstreg, REG_EDX, maskp, inst); // and edx:dstreg,maskp + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg } - return dst; } -/*------------------------------------------------- - op_rolins - process an ROLINS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rolins - process an ROLINS opcode +//------------------------------------------------- -static x86code *op_rolins(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_rolins(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, shiftp, maskp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_S | DRCUML_FLAG_Z); + assert_flags(inst, FLAG_S | FLAG_Z); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI, &shiftp, PTYPE_MRI, &maskp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + be_parameter shiftp(*this, inst.param(2), PTYPE_MRI); + be_parameter maskp(*this, inst.param(3), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register2(REG_ECX, &dstp, &shiftp, &maskp); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_ECX, shiftp, maskp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &srcp); // mov eax,srcp - emit_rol_r32_p32(drcbe, &dst, REG_EAX, &shiftp, inst); // rol eax,shiftp - emit_mov_r32_p32(drcbe, &dst, dstreg, &dstp); // mov dstreg,dstp - if (maskp.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r32_p32(dst, REG_EAX, srcp); // mov eax,srcp + emit_rol_r32_p32(dst, REG_EAX, shiftp, inst); // rol eax,shiftp + emit_mov_r32_p32(dst, dstreg, dstp); // mov dstreg,dstp + if (maskp.is_immediate()) { - emit_and_r32_imm(&dst, REG_EAX, maskp.value); // and eax,maskp - emit_and_r32_imm(&dst, dstreg, ~maskp.value); // and dstreg,~maskp + emit_and_r32_imm(dst, REG_EAX, maskp.immediate()); // and eax,maskp + emit_and_r32_imm(dst, dstreg, ~maskp.immediate()); // and dstreg,~maskp } else { - emit_mov_r32_p32(drcbe, &dst, REG_EDX, &maskp); // mov edx,maskp - emit_and_r32_r32(&dst, REG_EAX, REG_EDX); // and eax,edx - emit_not_r32(&dst, REG_EDX); // not edx - emit_and_r32_r32(&dst, dstreg, REG_EDX); // and dstreg,edx + emit_mov_r32_p32(dst, REG_EDX, maskp); // mov edx,maskp + emit_and_r32_r32(dst, REG_EAX, REG_EDX); // and eax,edx + emit_not_r32(dst, REG_EDX); // not edx + emit_and_r32_r32(dst, dstreg, REG_EDX); // and dstreg,edx } - emit_or_r32_r32(&dst, dstreg, REG_EAX); // or dstreg,eax - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_or_r32_r32(dst, dstreg, REG_EAX); // or dstreg,eax + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, REG_EAX, REG_EDX, &srcp); // mov edx:eax,srcp - emit_rol_r64_p64(drcbe, &dst, REG_EAX, REG_EDX, &shiftp, inst); // rol edx:eax,shiftp - if (maskp.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r64_p64(dst, REG_EAX, REG_EDX, srcp); // mov edx:eax,srcp + emit_rol_r64_p64(dst, REG_EAX, REG_EDX, shiftp, inst); // rol edx:eax,shiftp + if (maskp.is_immediate()) { - emit_and_r32_imm(&dst, REG_EAX, maskp.value); // and eax,maskp - emit_and_r32_imm(&dst, REG_EDX, maskp.value >> 32); // and edx,maskp >> 32 - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) + emit_and_r32_imm(dst, REG_EAX, maskp.immediate()); // and eax,maskp + emit_and_r32_imm(dst, REG_EDX, maskp.immediate() >> 32); // and edx,maskp >> 32 + if (dstp.is_int_register()) { - emit_and_r32_imm(&dst, dstp.value, ~maskp.value); // and dstp.lo,~maskp - emit_and_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), ~maskp.value >> 32);// and dstp.hi,~maskp >> 32 - emit_or_r32_r32(&dst, dstp.value, REG_EAX); // or dstp.lo,eax - emit_or_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // or dstp.hi,edx + emit_and_r32_imm(dst, dstp.ireg(), ~maskp.immediate()); // and dstp.lo,~maskp + emit_and_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), ~maskp.immediate() >> 32);// and dstp.hi,~maskp >> 32 + emit_or_r32_r32(dst, dstp.ireg(), REG_EAX); // or dstp.lo,eax + emit_or_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // or dstp.hi,edx } else { - emit_and_m32_imm(&dst, MABS(dstp.value), ~maskp.value); // and dstp.lo,~maskp - emit_and_m32_imm(&dst, MABS(dstp.value + 4), ~maskp.value >> 32); // and dstp.hi,~maskp >> 32 - emit_or_m32_r32(&dst, MABS(dstp.value), REG_EAX); // or dstp.lo,eax - emit_or_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // or dstp.hi,edx + emit_and_m32_imm(dst, MABS(dstp.memory()), ~maskp.immediate()); // and dstp.lo,~maskp + emit_and_m32_imm(dst, MABS(dstp.memory(4)), ~maskp.immediate() >> 32); // and dstp.hi,~maskp >> 32 + emit_or_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // or dstp.lo,eax + emit_or_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // or dstp.hi,edx } } else { int tempreg = REG_EBX; - emit_mov_m32_r32(&dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx - emit_mov_r64_p64(drcbe, &dst, tempreg, REG_ECX, &maskp); // mov ecx:ebx,maskp - emit_and_r32_r32(&dst, REG_EAX, tempreg); // and eax,ebx - emit_and_r32_r32(&dst, REG_EDX, REG_ECX); // and edx,ecx - emit_not_r32(&dst, tempreg); // not ebx - emit_not_r32(&dst, REG_ECX); // not ecx - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) + emit_mov_m32_r32(dst, MBD(REG_ESP, -8), tempreg); // mov [esp-8],ebx + emit_mov_r64_p64(dst, tempreg, REG_ECX, maskp); // mov ecx:ebx,maskp + emit_and_r32_r32(dst, REG_EAX, tempreg); // and eax,ebx + emit_and_r32_r32(dst, REG_EDX, REG_ECX); // and edx,ecx + emit_not_r32(dst, tempreg); // not ebx + emit_not_r32(dst, REG_ECX); // not ecx + if (dstp.is_int_register()) { - emit_and_r32_r32(&dst, dstp.value, tempreg); // and dstp.lo,ebx - emit_and_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_ECX); // and dstp.hi,ecx - emit_or_r32_r32(&dst, dstp.value, REG_EAX); // or dstp.lo,eax - emit_or_m32_r32(&dst, MABS(drcbe->reghi[dstp.value]), REG_EDX); // or dstp.hi,edx + emit_and_r32_r32(dst, dstp.ireg(), tempreg); // and dstp.lo,ebx + emit_and_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_ECX); // and dstp.hi,ecx + emit_or_r32_r32(dst, dstp.ireg(), REG_EAX); // or dstp.lo,eax + emit_or_m32_r32(dst, MABS(m_reghi[dstp.ireg()]), REG_EDX); // or dstp.hi,edx } else { - emit_and_m32_r32(&dst, MABS(dstp.value), tempreg); // and dstp.lo,ebx - emit_and_m32_r32(&dst, MABS(dstp.value + 4), REG_ECX); // and dstp.hi,ecx - emit_or_m32_r32(&dst, MABS(dstp.value), REG_EAX); // or dstp.lo,eax - emit_or_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // or dstp.hi,edx + emit_and_m32_r32(dst, MABS(dstp.memory()), tempreg); // and dstp.lo,ebx + emit_and_m32_r32(dst, MABS(dstp.memory(4)), REG_ECX); // and dstp.hi,ecx + emit_or_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // or dstp.lo,eax + emit_or_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // or dstp.hi,edx } - emit_mov_r32_m32(&dst, tempreg, MBD(REG_ESP, -8)); // mov ebx,[esp-8] + emit_mov_r32_m32(dst, tempreg, MBD(REG_ESP, -8)); // mov ebx,[esp-8] } - if (inst->flags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EAX, REG_EDX); // or eax,edx - else if (inst->flags == DRCUML_FLAG_S) + if (inst.flags() == FLAG_Z) + emit_or_r32_r32(dst, REG_EAX, REG_EDX); // or eax,edx + else if (inst.flags() == FLAG_S) ;// do nothing -- final OR will have the right result - else if (inst->flags == (DRCUML_FLAG_Z | DRCUML_FLAG_S)) + else if (inst.flags() == (FLAG_Z | FLAG_S)) { - emit_movzx_r32_r16(&dst, REG_ECX, REG_AX); // movzx ecx,ax - emit_shr_r32_imm(&dst, REG_EAX, 16); // shr eax,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax + emit_movzx_r32_r16(dst, REG_ECX, REG_AX); // movzx ecx,ax + emit_shr_r32_imm(dst, REG_EAX, 16); // shr eax,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax } } - return dst; } -/*------------------------------------------------- - op_add - process a ADD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_add - process a ADD opcode +//------------------------------------------------- -static x86code *op_add(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_add(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_add_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // add [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_add_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // add [dstp],src2p - /* reg = reg + imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBD(src1p.value, src2p.value)); // lea dstp,[src1p+src2p] + // reg = reg + imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBD(src1p.ireg(), src2p.immediate())); // lea dstp,[src1p+src2p] - /* reg = reg + reg */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_INT_REGISTER && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBISD(src1p.value, src2p.value, 1, 0)); // lea dstp,[src1p+src2p] + // reg = reg + reg + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_int_register() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBISD(src1p.ireg(), src2p.ireg(), 1, 0)); // lea dstp,[src1p+src2p] - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_add_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // add dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_add_r32_p32(dst, dstreg, src2p, inst); // add dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_add_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // add [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_add_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // add [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_add_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // add dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_add_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // add dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_addc - process a ADDC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_addc - process a ADDC opcode +//------------------------------------------------- -static x86code *op_addc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_addc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_adc_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // adc [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_adc_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // adc [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_adc_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // adc dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_adc_r32_p32(dst, dstreg, src2p, inst); // adc dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_adc_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // adc [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_adc_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // adc [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_adc_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // adc dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64_keepflags(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_adc_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // adc dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_sub - process a SUB opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sub - process a SUB opcode +//------------------------------------------------- -static x86code *op_sub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_sub(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (dstp.type == DRCUML_PTYPE_MEMORY && src1p.type == DRCUML_PTYPE_MEMORY && src1p.value == dstp.value) - emit_sub_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // sub [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sub_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sub [dstp],src2p - /* reg = reg - imm */ - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER && src1p.type == DRCUML_PTYPE_INT_REGISTER && src2p.type == DRCUML_PTYPE_IMMEDIATE && inst->flags == 0) - emit_lea_r32_m32(&dst, dstp.value, MBD(src1p.value, -src2p.value)); // lea dstp,[src1p-src2p] + // reg = reg - imm + else if (dstp.is_int_register() && src1p.is_int_register() && src2p.is_immediate() && inst.flags() == 0) + emit_lea_r32_m32(dst, dstp.ireg(), MBD(src1p.ireg(), -src2p.immediate())); // lea dstp,[src1p-src2p] - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sub_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sub dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_sub_r32_p32(dst, dstreg, src2p, inst); // sub dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sub_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // sub [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sub_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // sub [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_sub_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // sub dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_sub_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // sub dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_subc - process a SUBC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_subc - process a SUBC opcode +//------------------------------------------------- -static x86code *op_subc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_subc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sbb_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // sbb [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sbb_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sbb [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sbb_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sbb dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_sbb_r32_p32(dst, dstreg, src2p, inst); // sbb dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sbb_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // sbb [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sbb_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // sbb [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_sbb_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // sbb dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64_keepflags(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_sbb_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // sbb dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_cmp - process a CMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_cmp - process a CMP opcode +//------------------------------------------------- -static x86code *op_cmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_cmp(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - int src1reg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MRI); + be_parameter src2p(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - src1reg = param_select_register(REG_EAX, &src1p, NULL); + // pick a target register for the general case + int src1reg = src1p.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* memory versus anything */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_cmp_m32_p32(drcbe, &dst, MABS(src1p.value), &src2p, inst); // cmp [dstp],src2p + // memory versus anything + if (src1p.is_memory()) + emit_cmp_m32_p32(dst, MABS(src1p.memory()), src2p, inst); // cmp [dstp],src2p - /* general case */ + // general case else { - if (src1p.type == DRCUML_PTYPE_IMMEDIATE) - emit_mov_r32_imm(&dst, src1reg, src1p.value); // mov src1reg,imm - emit_cmp_r32_p32(drcbe, &dst, src1reg, &src2p, inst); // cmp src1reg,src2p + if (src1p.is_immediate()) + emit_mov_r32_imm(dst, src1reg, src1p.immediate()); // mov src1reg,imm + emit_cmp_r32_p32(dst, src1reg, src2p, inst); // cmp src1reg,src2p } } - /* 64-bit form */ + // 64-bit form else { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, REG_EAX, REG_EDX, &src1p); // mov eax:dstp,[src1p] - emit_cmp_r64_p64(drcbe, &dst, REG_EAX, REG_EDX, &src2p, inst); // cmp eax:dstp,src2p + // general case + emit_mov_r64_p64(dst, REG_EAX, REG_EDX, src1p); // mov eax:dstp,[src1p] + emit_cmp_r64_p64(dst, REG_EAX, REG_EDX, src2p, inst); // cmp eax:dstp,src2p } - return dst; } -/*------------------------------------------------- - op_mulu - process a MULU opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_mulu - process a MULU opcode +//------------------------------------------------- -static x86code *op_mulu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_mulu(x86code *&dst, const instruction &inst) { - UINT8 zsflags = inst->flags & (DRCUML_FLAG_Z | DRCUML_FLAG_S); - UINT8 vflag = inst->flags & DRCUML_FLAG_V; - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_hi; + UINT8 zsflags = inst.flags() & (FLAG_Z | FLAG_S); + UINT8 vflag = inst.flags() & FLAG_V; - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); - - /* normalize parameters */ - param_normalize_4_commutative(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_hi = (dstp.type != edstp.type || dstp.value != edstp.value); - - /* 32-bit form */ - if (inst->size == 4) - { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_mul_m32(&dst, MABS(src2p.value)); // mul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_mul_r32(&dst, src2p.value); // mul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); + + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + normalize_commutative(src1p, src2p); + bool compute_hi = (dstp != edstp); + + // 32-bit form + if (inst.size() == 4) + { + // general case + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_mul_m32(dst, MABS(src2p.memory())); // mul [src2p] + else if (src2p.is_int_register()) + emit_mul_r32(dst, src2p.ireg()); // mul src2p + else if (src2p.is_immediate()) { - emit_mov_r32_imm(&dst, REG_EDX, src2p.value); // mov edx,src2p - emit_mul_r32(&dst, REG_EDX); // mul edx + emit_mov_r32_imm(dst, REG_EDX, src2p.immediate()); // mov edx,src2p + emit_mul_r32(dst, REG_EDX); // mul edx } - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_hi) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (zsflags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax - else if (zsflags == DRCUML_FLAG_S) - emit_test_r32_r32(&dst, REG_EDX, REG_EDX); // test edx,edx + if (zsflags == FLAG_Z) + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax + else if (zsflags == FLAG_S) + emit_test_r32_r32(dst, REG_EDX, REG_EDX); // test edx,edx else { - emit_movzx_r32_r16(&dst, REG_ECX, REG_AX); // movzx ecx,ax - emit_shr_r32_imm(&dst, REG_EAX, 16); // shr eax,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax + emit_movzx_r32_r16(dst, REG_ECX, REG_AX); // movzx ecx,ax + emit_shr_r32_imm(dst, REG_EAX, 16); // shr eax,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax } } else - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r32(&dst, REG_EAX); // pop eax - emit_and_m32_imm(&dst, MBD(REG_ESP, 0), ~0x84); // and [esp],~0x84 - emit_or_m32_r32(&dst, MBD(REG_ESP, 0), REG_EAX); // or [esp],eax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r32(dst, REG_EAX); // pop eax + emit_and_m32_imm(dst, MBD(REG_ESP, 0), ~0x84); // and [esp],~0x84 + emit_or_m32_r32(dst, MBD(REG_ESP, 0), REG_EAX); // or [esp],eax + emit_popf(dst); // popf } } } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_m32_imm(&dst, MBD(REG_ESP, 24), inst->flags); // mov [esp+24],flags - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 16), &src2p); // mov [esp+16],src2p - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &src1p); // mov [esp+8],src1p + // general case + emit_mov_m32_imm(dst, MBD(REG_ESP, 24), inst.flags()); // mov [esp+24],flags + emit_mov_m64_p64(dst, MBD(REG_ESP, 16), src2p); // mov [esp+16],src2p + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), src1p); // mov [esp+8],src1p if (!compute_hi) - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reslo); // mov [esp+4],&reslo + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reslo); // mov [esp+4],&reslo else - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reshi); // mov [esp+4],&reshi - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)&drcbe->reslo); // mov [esp],&reslo - emit_call(&dst, (x86code *)dmulu); // call dmulu - if (inst->flags != 0) - emit_push_m32(&dst, MISD(REG_EAX, 4, flags_unmap)); // push flags_unmap[eax*4] - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0)); // mov eax,reslo.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1)); // mov edx,reslo.hi - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reshi); // mov [esp+4],&reshi + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_reslo); // mov [esp],&reslo + emit_call(dst, (x86code *)dmulu); // call dmulu + if (inst.flags() != 0) + emit_push_m32(dst, MABSI(flags_unmap, REG_EAX, 4)); // push flags_unmap[eax*4] + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reslo + 0)); // mov eax,reslo.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reslo + 1)); // mov edx,reslo.hi + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax if (compute_hi) { - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0)); // mov eax,reshi.lo - emit_mov_r32_m32(&dst, REG_ECX, MABS((UINT32 *)&drcbe->reshi + 1)); // mov ecx,reshi.hi - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_ECX); // mov edstp,ecx:eax + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reshi + 0)); // mov eax,reshi.lo + emit_mov_r32_m32(dst, REG_ECX, MABS((UINT32 *)&m_reshi + 1)); // mov ecx,reshi.hi + emit_mov_p64_r64(dst, edstp, REG_EAX, REG_ECX); // mov edstp,ecx:eax } - if (inst->flags != 0) - emit_popf(&dst); // popf + if (inst.flags() != 0) + emit_popf(dst); // popf } - return dst; } -/*------------------------------------------------- - op_muls - process a MULS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_muls - process a MULS opcode +//------------------------------------------------- -static x86code *op_muls(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_muls(x86code *&dst, const instruction &inst) { - UINT8 zsflags = inst->flags & (DRCUML_FLAG_Z | DRCUML_FLAG_S); - UINT8 vflag = inst->flags & DRCUML_FLAG_V; - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_hi; + UINT8 zsflags = inst.flags() & (FLAG_Z | FLAG_S); + UINT8 vflag = inst.flags() & FLAG_V; - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4_commutative(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_hi = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + normalize_commutative(src1p, src2p); + bool compute_hi = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* 32-bit destination with memory/immediate or register/immediate */ - if (!compute_hi && src1p.type != DRCUML_PTYPE_IMMEDIATE && src2p.type == DRCUML_PTYPE_IMMEDIATE) + // 32-bit destination with memory/immediate or register/immediate + if (!compute_hi && !src1p.is_immediate() && src2p.is_immediate()) { - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r32_m32_imm(&dst, REG_EAX, MABS(src1p.value), src2p.value); // imul eax,[src1p],src2p - else if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32_r32_imm(&dst, REG_EAX, src1p.value, src2p.value); // imul eax,src1p,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + if (src1p.is_memory()) + emit_imul_r32_m32_imm(dst, REG_EAX, MABS(src1p.memory()), src2p.immediate()); // imul eax,[src1p],src2p + else if (src1p.is_int_register()) + emit_imul_r32_r32_imm(dst, REG_EAX, src1p.ireg(), src2p.immediate()); // imul eax,src1p,src2p + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax } - /* 32-bit destination, general case */ + // 32-bit destination, general case else if (!compute_hi) { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_r32_m32(&dst, REG_EAX, MABS(src2p.value)); // imul eax,[src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32_r32(&dst, REG_EAX, src2p.value); // imul eax,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_imul_r32_m32(dst, REG_EAX, MABS(src2p.memory())); // imul eax,[src2p] + else if (src2p.is_int_register()) + emit_imul_r32_r32(dst, REG_EAX, src2p.ireg()); // imul eax,src2p + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax } - /* 64-bit destination, general case */ + // 64-bit destination, general case else { - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - if (src2p.type == DRCUML_PTYPE_MEMORY) - emit_imul_m32(&dst, MABS(src2p.value)); // imul [src2p] - else if (src2p.type == DRCUML_PTYPE_INT_REGISTER) - emit_imul_r32(&dst, src2p.value); // imul src2p - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE) + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + if (src2p.is_memory()) + emit_imul_m32(dst, MABS(src2p.memory())); // imul [src2p] + else if (src2p.is_int_register()) + emit_imul_r32(dst, src2p.ireg()); // imul src2p + else if (src2p.is_immediate()) { - emit_mov_r32_imm(&dst, REG_EDX, src2p.value); // mov edx,src2p - emit_imul_r32(&dst, REG_EDX); // imul edx + emit_mov_r32_imm(dst, REG_EDX, src2p.immediate()); // mov edx,src2p + emit_imul_r32(dst, REG_EDX); // imul edx } - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx } - /* compute flags */ - if (inst->flags != 0) + // compute flags + if (inst.flags() != 0) { if (zsflags != 0) { if (vflag) - emit_pushf(&dst); // pushf + emit_pushf(dst); // pushf if (compute_hi) { - if (inst->flags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax - else if (inst->flags == DRCUML_FLAG_S) - emit_test_r32_r32(&dst, REG_EDX, REG_EDX); // test edx,edx + if (inst.flags() == FLAG_Z) + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax + else if (inst.flags() == FLAG_S) + emit_test_r32_r32(dst, REG_EDX, REG_EDX); // test edx,edx else { - emit_movzx_r32_r16(&dst, REG_ECX, REG_AX); // movzx ecx,ax - emit_shr_r32_imm(&dst, REG_EAX, 16); // shr eax,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_or_r32_r32(&dst, REG_EDX, REG_EAX); // or edx,eax + emit_movzx_r32_r16(dst, REG_ECX, REG_AX); // movzx ecx,ax + emit_shr_r32_imm(dst, REG_EAX, 16); // shr eax,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_or_r32_r32(dst, REG_EDX, REG_EAX); // or edx,eax } } else - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax - /* we rely on the fact that OF is cleared by all logical operations above */ + // we rely on the fact that OF is cleared by all logical operations above if (vflag) { - emit_pushf(&dst); // pushf - emit_pop_r32(&dst, REG_EAX); // pop eax - emit_and_m32_imm(&dst, MBD(REG_ESP, 0), ~0x84); // and [esp],~0x84 - emit_or_m32_r32(&dst, MBD(REG_ESP, 0), REG_EAX); // or [esp],eax - emit_popf(&dst); // popf + emit_pushf(dst); // pushf + emit_pop_r32(dst, REG_EAX); // pop eax + emit_and_m32_imm(dst, MBD(REG_ESP, 0), ~0x84); // and [esp],~0x84 + emit_or_m32_r32(dst, MBD(REG_ESP, 0), REG_EAX); // or [esp],eax + emit_popf(dst); // popf } } } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_m32_imm(&dst, MBD(REG_ESP, 24), inst->flags); // mov [esp+24],flags - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 16), &src2p); // mov [esp+16],src2p - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &src1p); // mov [esp+8],src1p + // general case + emit_mov_m32_imm(dst, MBD(REG_ESP, 24), inst.flags()); // mov [esp+24],flags + emit_mov_m64_p64(dst, MBD(REG_ESP, 16), src2p); // mov [esp+16],src2p + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), src1p); // mov [esp+8],src1p if (!compute_hi) - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reslo); // mov [esp+4],&reslo + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reslo); // mov [esp+4],&reslo else - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reshi); // push [esp+4],&reshi - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)&drcbe->reslo); // mov [esp],&reslo - emit_call(&dst, (x86code *)dmuls); // call dmuls - if (inst->flags != 0) - emit_push_m32(&dst, MISD(REG_EAX, 4, flags_unmap)); // push flags_unmap[eax*4] - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0)); // mov eax,reslo.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1)); // mov edx,reslo.hi - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reshi); // push [esp+4],&reshi + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_reslo); // mov [esp],&reslo + emit_call(dst, (x86code *)dmuls); // call dmuls + if (inst.flags() != 0) + emit_push_m32(dst, MABSI(flags_unmap, REG_EAX, 4)); // push flags_unmap[eax*4] + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reslo + 0)); // mov eax,reslo.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reslo + 1)); // mov edx,reslo.hi + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax if (compute_hi) { - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0)); // mov eax,reshi.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reshi + 1)); // mov edx,reshi.hi - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reshi + 0)); // mov eax,reshi.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reshi + 1)); // mov edx,reshi.hi + emit_mov_p64_r64(dst, edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax } - if (inst->flags != 0) - emit_popf(&dst); // popf + if (inst.flags() != 0) + emit_popf(dst); // popf } - return dst; } -/*------------------------------------------------- - op_divu - process a DIVU opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_divu - process a DIVU opcode +//------------------------------------------------- -static x86code *op_divu(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_divu(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_rem; - emit_link skip; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_rem = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + bool compute_rem = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &src2p); // mov ecx,src2p - if (inst->flags != 0) + // general case + emit_mov_r32_p32(dst, REG_ECX, src2p); // mov ecx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jecxz_link(&dst, &skip); // jecxz skip - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - emit_xor_r32_r32(&dst, REG_EDX, REG_EDX); // xor edx,edx - emit_div_r32(&dst, REG_ECX); // div ecx - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_link skip; + emit_jecxz_link(dst, skip); // jecxz skip + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + emit_xor_r32_r32(dst, REG_EDX, REG_EDX); // xor edx,edx + emit_div_r32(dst, REG_ECX); // div ecx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_rem) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx - if (inst->flags != 0) - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax - track_resolve_link(drcbe, &dst, &skip); // skip: + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx + if (inst.flags() != 0) + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax + track_resolve_link(dst, skip); // skip: } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 16), &src2p); // mov [esp+16],src2p - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &src1p); // mov [esp+8],src1p + // general case + emit_mov_m64_p64(dst, MBD(REG_ESP, 16), src2p); // mov [esp+16],src2p + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), src1p); // mov [esp+8],src1p if (!compute_rem) - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reslo); // mov [esp+4],&reslo + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reslo); // mov [esp+4],&reslo else - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reshi); // push [esp+4],&reshi - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)&drcbe->reslo); // mov [esp],&reslo - emit_call(&dst, (x86code *)ddivu); // call ddivu - if (inst->flags != 0) - emit_push_m32(&dst, MISD(REG_EAX, 4, flags_unmap)); // push flags_unmap[eax*4] - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0)); // mov eax,reslo.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1)); // mov edx,reslo.hi - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reshi); // push [esp+4],&reshi + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_reslo); // mov [esp],&reslo + emit_call(dst, (x86code *)ddivu); // call ddivu + if (inst.flags() != 0) + emit_push_m32(dst, MABSI(flags_unmap, REG_EAX, 4)); // push flags_unmap[eax*4] + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reslo + 0)); // mov eax,reslo.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reslo + 1)); // mov edx,reslo.hi + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax if (compute_rem) { - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0)); // mov eax,reshi.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reshi + 1)); // mov edx,reshi.hi - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reshi + 0)); // mov eax,reshi.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reshi + 1)); // mov edx,reshi.hi + emit_mov_p64_r64(dst, edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax } - if (inst->flags != 0) - emit_popf(&dst); // popf + if (inst.flags() != 0) + emit_popf(dst); // popf } - return dst; } -/*------------------------------------------------- - op_divs - process a DIVS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_divs - process a DIVS opcode +//------------------------------------------------- -static x86code *op_divs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_divs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, edstp, src1p, src2p; - int compute_rem; - emit_link skip; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_V | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &edstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); - compute_rem = (dstp.type != edstp.type || dstp.value != edstp.value); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter edstp(*this, inst.param(1), PTYPE_MR); + be_parameter src1p(*this, inst.param(2), PTYPE_MRI); + be_parameter src2p(*this, inst.param(3), PTYPE_MRI); + bool compute_rem = (dstp != edstp); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* general case */ - emit_mov_r32_p32(drcbe, &dst, REG_ECX, &src2p); // mov ecx,src2p - if (inst->flags != 0) + // general case + emit_mov_r32_p32(dst, REG_ECX, src2p); // mov ecx,src2p + if (inst.flags() != 0) { - emit_mov_r32_imm(&dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 - emit_add_r32_r32(&dst, REG_EAX, REG_EAX); // add eax,eax + emit_mov_r32_imm(dst, REG_EAX, 0xa0000000); // mov eax,0xa0000000 + emit_add_r32_r32(dst, REG_EAX, REG_EAX); // add eax,eax } - emit_jecxz_link(&dst, &skip); // jecxz skip - emit_mov_r32_p32(drcbe, &dst, REG_EAX, &src1p); // mov eax,src1p - emit_cdq(&dst); // cdq - emit_idiv_r32(&dst, REG_ECX); // idiv ecx - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax + emit_link skip; + emit_jecxz_link(dst, skip); // jecxz skip + emit_mov_r32_p32(dst, REG_EAX, src1p); // mov eax,src1p + emit_cdq(dst); // cdq + emit_idiv_r32(dst, REG_ECX); // idiv ecx + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax if (compute_rem) - emit_mov_p32_r32(drcbe, &dst, &edstp, REG_EDX); // mov edstp,edx - if (inst->flags != 0) - emit_test_r32_r32(&dst, REG_EAX, REG_EAX); // test eax,eax - track_resolve_link(drcbe, &dst, &skip); // skip: + emit_mov_p32_r32(dst, edstp, REG_EDX); // mov edstp,edx + if (inst.flags() != 0) + emit_test_r32_r32(dst, REG_EAX, REG_EAX); // test eax,eax + track_resolve_link(dst, skip); // skip: } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 16), &src2p); // mov [esp+16],src2p - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &src1p); // mov [esp+8],src1p + // general case + emit_mov_m64_p64(dst, MBD(REG_ESP, 16), src2p); // mov [esp+16],src2p + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), src1p); // mov [esp+8],src1p if (!compute_rem) - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reslo); // mov [esp+4],&reslo + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reslo); // mov [esp+4],&reslo else - emit_mov_m32_imm(&dst, MBD(REG_ESP, 4), (FPTR)&drcbe->reshi); // push [esp+4],&reshi - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (FPTR)&drcbe->reslo); // mov [esp],&reslo - emit_call(&dst, (x86code *)ddivs); // call ddivs - if (inst->flags != 0) - emit_push_m32(&dst, MISD(REG_EAX, 4, flags_unmap)); // push flags_unmap[eax*4] - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reslo + 0)); // mov eax,reslo.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reslo + 1)); // mov edx,reslo.hi - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax + emit_mov_m32_imm(dst, MBD(REG_ESP, 4), (FPTR)&m_reshi); // push [esp+4],&reshi + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)&m_reslo); // mov [esp],&reslo + emit_call(dst, (x86code *)ddivs); // call ddivs + if (inst.flags() != 0) + emit_push_m32(dst, MABSI(flags_unmap, REG_EAX, 4)); // push flags_unmap[eax*4] + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reslo + 0)); // mov eax,reslo.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reslo + 1)); // mov edx,reslo.hi + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax if (compute_rem) { - emit_mov_r32_m32(&dst, REG_EAX, MABS((UINT32 *)&drcbe->reshi + 0)); // mov eax,reshi.lo - emit_mov_r32_m32(&dst, REG_EDX, MABS((UINT32 *)&drcbe->reshi + 1)); // mov edx,reshi.hi - emit_mov_p64_r64(drcbe, &dst, &edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax + emit_mov_r32_m32(dst, REG_EAX, MABS((UINT32 *)&m_reshi + 0)); // mov eax,reshi.lo + emit_mov_r32_m32(dst, REG_EDX, MABS((UINT32 *)&m_reshi + 1)); // mov edx,reshi.hi + emit_mov_p64_r64(dst, edstp, REG_EAX, REG_EDX); // mov edstp,edx:eax } - if (inst->flags != 0) - emit_popf(&dst); // popf + if (inst.flags() != 0) + emit_popf(dst); // popf } - return dst; } -/*------------------------------------------------- - op_and - process a AND opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_and - process a AND opcode +//------------------------------------------------- -static x86code *op_and(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_and(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_and_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // and [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_and_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // and [dstp],src2p - /* AND with immediate 0xff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xff && inst->flags == 0) + // AND with immediate 0xff + else if (src2p.is_immediate_value(0xff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r8(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m8(&dst, dstreg, MABS(src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r8(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m8(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* AND with immediate 0xffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffff && inst->flags == 0) + // AND with immediate 0xffff + else if (src2p.is_immediate_value(0xffff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r16(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m16(&dst, dstreg, MABS(src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + if (src1p.is_int_register()) + emit_movzx_r32_r16(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m16(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_and_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // and dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_and_r32_p32(dst, dstreg, src2p, inst); // and dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_and_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // and [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_and_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // and [dstp],src2p - /* AND with immediate 0xff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xff && inst->flags == 0) + // AND with immediate 0xff + else if (src2p.is_immediate_value(0xff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r8(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m8(&dst, dstreg, MABS(src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov dsthi,0 - else if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov dsthi,0 + if (src1p.is_int_register()) + emit_movzx_r32_r8(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m8(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg + if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov dsthi,0 + else if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov dsthi,0 } - /* AND with immediate 0xffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffff && inst->flags == 0) + // AND with immediate 0xffff + else if (src2p.is_immediate_value(0xffff) && inst.flags() == 0) { - if (src1p.type == DRCUML_PTYPE_INT_REGISTER) - emit_movzx_r32_r16(&dst, dstreg, src1p.value); // movzx dstreg,src1p - else if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_movzx_r32_m16(&dst, dstreg, MABS(src1p.value)); // movzx dstreg,[src1p] - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov dsthi,0 - else if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov dsthi,0 + if (src1p.is_int_register()) + emit_movzx_r32_r16(dst, dstreg, src1p.ireg()); // movzx dstreg,src1p + else if (src1p.is_memory()) + emit_movzx_r32_m16(dst, dstreg, MABS(src1p.memory())); // movzx dstreg,[src1p] + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg + if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov dsthi,0 + else if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov dsthi,0 } - /* AND with immediate 0xffffffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == 0xffffffff && inst->flags == 0) + // AND with immediate 0xffffffff + else if (src2p.is_immediate_value(0xffffffff) && inst.flags() == 0) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov dsthi,0 - else if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov dsthi,0 + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg + if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov dsthi,0 + else if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov dsthi,0 } - /* AND with immediate 0xffffffff00000000 */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value == U64(0xffffffff00000000) && inst->flags == 0) + // AND with immediate 0xffffffff00000000 + else if (src2p.is_immediate_value(U64(0xffffffff00000000)) && inst.flags() == 0) { - if (src1p.type != dstp.type || src1p.value != dstp.value) + if (src1p != dstp) { - emit_mov_r64_p64(drcbe, &dst, REG_NONE, REG_EDX, &src1p); // mov dstreg,src1p - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_NONE, REG_EDX); // mov dstp,dstreg + emit_mov_r64_p64(dst, REG_NONE, REG_EDX, src1p); // mov dstreg,src1p + emit_mov_p64_r64(dst, dstp, REG_NONE, REG_EDX); // mov dstp,dstreg } - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_xor_r32_r32(&dst, dstp.value, dstp.value); // xor dstlo,dstlo - else if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value), 0); // mov dstlo,0 + if (dstp.is_int_register()) + emit_xor_r32_r32(dst, dstp.ireg(), dstp.ireg()); // xor dstlo,dstlo + else if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory()), 0); // mov dstlo,0 } - /* AND with immediate <= 0xffffffff */ - else if (src2p.type == DRCUML_PTYPE_IMMEDIATE && src2p.value <= 0xffffffff && inst->flags == 0) + // AND with immediate <= 0xffffffff + else if (src2p.is_immediate() && src2p.immediate() <= 0xffffffff && inst.flags() == 0) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_and_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // and dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg - if (dstp.type == DRCUML_PTYPE_INT_REGISTER) - emit_mov_m32_imm(&dst, MABS(drcbe->reghi[dstp.value]), 0); // mov dsthi,0 - else if (dstp.type == DRCUML_PTYPE_MEMORY) - emit_mov_m32_imm(&dst, MABS(dstp.value + 4), 0); // mov dsthi,0 + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_and_r32_p32(dst, dstreg, src2p, inst); // and dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg + if (dstp.is_int_register()) + emit_mov_m32_imm(dst, MABS(m_reghi[dstp.ireg()]), 0); // mov dsthi,0 + else if (dstp.is_memory()) + emit_mov_m32_imm(dst, MABS(dstp.memory(4)), 0); // mov dsthi,0 } - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_and_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // and dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_and_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // and dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_test - process a TEST opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_test - process a TEST opcode +//------------------------------------------------- -static x86code *op_test(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_test(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - int src1reg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2_commutative(drcbe, inst, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MRI); + be_parameter src2p(*this, inst.param(1), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - src1reg = param_select_register(REG_EAX, &src1p, NULL); + // pick a target register for the general case + int src1reg = src1p.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* src1p in memory */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_test_m32_p32(drcbe, &dst, MABS(src1p.value), &src2p, inst); // test [src1p],src2p + // src1p in memory + if (src1p.is_memory()) + emit_test_m32_p32(dst, MABS(src1p.memory()), src2p, inst); // test [src1p],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, src1reg, &src1p); // mov src1reg,src1p - emit_test_r32_p32(drcbe, &dst, src1reg, &src2p, inst); // test src1reg,src2p + emit_mov_r32_p32(dst, src1reg, src1p); // mov src1reg,src1p + emit_test_r32_p32(dst, src1reg, src2p, inst); // test src1reg,src2p } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* src1p in memory */ - if (src1p.type == DRCUML_PTYPE_MEMORY) - emit_test_m64_p64(drcbe, &dst, MABS(src1p.value), &src2p, inst); // test [dstp],src2p + // src1p in memory + if (src1p.is_memory()) + emit_test_m64_p64(dst, MABS(src1p.memory()), src2p, inst); // test [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, src1reg, REG_EDX, &src1p); // mov src1reg:dstp,[src1p] - emit_test_r64_p64(drcbe, &dst, src1reg, REG_EDX, &src2p, inst); // test src1reg:dstp,src2p + emit_mov_r64_p64(dst, src1reg, REG_EDX, src1p); // mov src1reg:dstp,[src1p] + emit_test_r64_p64(dst, src1reg, REG_EDX, src2p, inst); // test src1reg:dstp,src2p } } - return dst; } -/*------------------------------------------------- - op_or - process a OR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_or - process a OR opcode +//------------------------------------------------- -static x86code *op_or(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_or(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_or_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // or [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_or_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // or [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_or_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // or dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_or_r32_p32(dst, dstreg, src2p, inst); // or dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_or_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // or [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_or_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // or [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_or_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // or dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_or_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // or dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_xor - process a XOR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_xor - process a XOR opcode +//------------------------------------------------- -static x86code *op_xor(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_xor(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3_commutative(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); + normalize_commutative(src1p, src2p); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_xor_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // xor [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_xor_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // xor [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_xor_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // xor dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_xor_r32_p32(dst, dstreg, src2p, inst); // xor dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_xor_m64_p64(drcbe, &dst, MABS(dstp.value), &src2p, inst); // xor [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_xor_m64_p64(dst, MABS(dstp.memory()), src2p, inst); // xor [dstp],src2p - /* general case */ + // general case else { - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_xor_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // xor dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_xor_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // xor dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } } - return dst; } -/*------------------------------------------------- - op_lzcnt - process a LZCNT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_lzcnt - process a LZCNT opcode +//------------------------------------------------- -static x86code *op_lzcnt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_lzcnt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_mov_r32_imm(&dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 - emit_bsr_r32_r32(&dst, dstreg, dstreg); // bsr dstreg,dstreg - emit_cmovcc_r32_r32(&dst, COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx - emit_xor_r32_imm(&dst, dstreg, 31); // xor dstreg,31 - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,src1p + emit_mov_r32_imm(dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 + emit_bsr_r32_r32(dst, dstreg, dstreg); // bsr dstreg,dstreg + emit_cmovcc_r32_r32(dst, x86emit::COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx + emit_xor_r32_imm(dst, dstreg, 31); // xor dstreg,31 + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { + emit_mov_r64_p64(dst, REG_EDX, dstreg, srcp); // mov dstreg:edx,srcp + emit_bsr_r32_r32(dst, dstreg, dstreg); // bsr dstreg,dstreg emit_link skip; - - emit_mov_r64_p64(drcbe, &dst, REG_EDX, dstreg, &srcp); // mov dstreg:edx,srcp - emit_bsr_r32_r32(&dst, dstreg, dstreg); // bsr dstreg,dstreg - emit_jcc_short_link(&dst, COND_NZ, &skip); // jnz skip - emit_mov_r32_imm(&dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 - emit_bsr_r32_r32(&dst, dstreg, REG_EDX); // bsr dstreg,edx - emit_cmovcc_r32_r32(&dst, COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx - emit_add_r32_imm(&dst, REG_ECX, 32); // add ecx,32 - track_resolve_link(drcbe, &dst, &skip); // skip: - emit_xor_r32_r32(&dst, REG_EDX, REG_EDX); // xor edx,edx - emit_xor_r32_imm(&dst, dstreg, 31); // xor dstreg,31 - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg + emit_jcc_short_link(dst, x86emit::COND_NZ, skip); // jnz skip + emit_mov_r32_imm(dst, REG_ECX, 32 ^ 31); // mov ecx,32 ^ 31 + emit_bsr_r32_r32(dst, dstreg, REG_EDX); // bsr dstreg,edx + emit_cmovcc_r32_r32(dst, x86emit::COND_Z, dstreg, REG_ECX); // cmovz dstreg,ecx + emit_add_r32_imm(dst, REG_ECX, 32); // add ecx,32 + track_resolve_link(dst, skip); // skip: + emit_xor_r32_r32(dst, REG_EDX, REG_EDX); // xor edx,edx + emit_xor_r32_imm(dst, dstreg, 31); // xor dstreg,31 + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg } - return dst; } -/*------------------------------------------------- - op_bswap - process a BSWAP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_bswap - process a BSWAP opcode +//------------------------------------------------- -static x86code *op_bswap(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_bswap(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, NULL); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - emit_mov_r32_p32(drcbe, &dst, dstreg, &srcp); // mov dstreg,src1p - emit_bswap_r32(&dst, dstreg); // bswap dstreg - if (inst->flags != 0) - emit_test_r32_r32(&dst, dstreg, dstreg); // test dstreg,dstreg - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, srcp); // mov dstreg,src1p + emit_bswap_r32(dst, dstreg); // bswap dstreg + if (inst.flags() != 0) + emit_test_r32_r32(dst, dstreg, dstreg); // test dstreg,dstreg + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - emit_mov_r64_p64(drcbe, &dst, REG_EDX, dstreg, &srcp); // mov dstreg:edx,srcp - emit_bswap_r32(&dst, dstreg); // bswap dstreg - emit_bswap_r32(&dst, REG_EDX); // bswap edx - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg - if (inst->flags == DRCUML_FLAG_Z) - emit_or_r32_r32(&dst, REG_EDX, dstreg); // or edx,eax - else if (inst->flags == DRCUML_FLAG_S) - emit_test_r32_r32(&dst, REG_EDX, REG_EDX); // test edx,edx + emit_mov_r64_p64(dst, REG_EDX, dstreg, srcp); // mov dstreg:edx,srcp + emit_bswap_r32(dst, dstreg); // bswap dstreg + emit_bswap_r32(dst, REG_EDX); // bswap edx + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,edx:dstreg + if (inst.flags() == FLAG_Z) + emit_or_r32_r32(dst, REG_EDX, dstreg); // or edx,eax + else if (inst.flags() == FLAG_S) + emit_test_r32_r32(dst, REG_EDX, REG_EDX); // test edx,edx else { - emit_movzx_r32_r16(&dst, REG_ECX, dstreg); // movzx ecx,dstreg - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx - emit_mov_r32_r32(&dst, REG_ECX, dstreg); // mov ecx,dstreg - emit_shr_r32_imm(&dst, REG_ECX, 16); // shr ecx,16 - emit_or_r32_r32(&dst, REG_EDX, REG_ECX); // or edx,ecx + emit_movzx_r32_r16(dst, REG_ECX, dstreg); // movzx ecx,dstreg + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx + emit_mov_r32_r32(dst, REG_ECX, dstreg); // mov ecx,dstreg + emit_shr_r32_imm(dst, REG_ECX, 16); // shr ecx,16 + emit_or_r32_r32(dst, REG_EDX, REG_ECX); // or edx,ecx } } - return dst; } -/*------------------------------------------------- - op_shl - process a SHL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_shl - process a SHL opcode +//------------------------------------------------- -static x86code *op_shl(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_shl(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shl_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // shl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shl_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // shl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shl_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // shl dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_shl_r32_p32(dst, dstreg, src2p, inst); // shl dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_shl_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // shl dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_shl_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // shl dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_shr - process a SHR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_shr - process a SHR opcode +//------------------------------------------------- -static x86code *op_shr(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_shr(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_shr_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // shr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_shr_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // shr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_shr_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // shr dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_shr_r32_p32(dst, dstreg, src2p, inst); // shr dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_shr_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // shr dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_shr_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // shr dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_sar - process a SAR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_sar - process a SAR opcode +//------------------------------------------------- -static x86code *op_sar(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_sar(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_sar_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // sar [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_sar_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // sar [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_sar_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // sar dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_sar_r32_p32(dst, dstreg, src2p, inst); // sar dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_sar_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // sar dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_sar_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // sar dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_rol - process a rol opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rol - process a rol opcode +//------------------------------------------------- -static x86code *op_rol(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_rol(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rol_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // rol [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rol_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rol [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rol_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rol dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_rol_r32_p32(dst, dstreg, src2p, inst); // rol dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_rol_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // rol dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_rol_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // rol dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_ror - process a ROR opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ror - process a ROR opcode +//------------------------------------------------- -static x86code *op_ror(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_ror(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_ror_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // ror [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_ror_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // ror [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_ror_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // ror dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32(dst, dstreg, src1p); // mov dstreg,src1p + emit_ror_r32_p32(dst, dstreg, src2p, inst); // ror dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_ror_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // ror dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_ror_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // ror dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_rolc - process a ROLC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rolc - process a ROLC opcode +//------------------------------------------------- -static x86code *op_rolc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_rolc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcl_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // rcl [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcl_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rcl [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcl_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rcl dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcl_r32_p32(dst, dstreg, src2p, inst); // rcl dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_rcl_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // rcl dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64_keepflags(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_rcl_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // rcl dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*------------------------------------------------- - op_rorc - process a RORC opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_rorc - process a RORC opcode +//------------------------------------------------- -static x86code *op_rorc(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_rorc(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - int dstreg; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_S); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_S); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MR, &src1p, PTYPE_MRI, &src2p, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter src1p(*this, inst.param(1), PTYPE_MRI); + be_parameter src2p(*this, inst.param(2), PTYPE_MRI); - /* pick a target register for the general case */ - dstreg = param_select_register(REG_EAX, &dstp, &src2p); + // pick a target register for the general case + int dstreg = dstp.select_register(REG_EAX, src2p); - /* 32-bit form */ - if (inst->size == 4) + // 32-bit form + if (inst.size() == 4) { - /* dstp == src1p in memory */ - if (src1p.type == dstp.type && src1p.value == dstp.value && dstp.type == DRCUML_PTYPE_MEMORY) - emit_rcr_m32_p32(drcbe, &dst, MABS(dstp.value), &src2p, inst); // rcr [dstp],src2p + // dstp == src1p in memory + if (dstp.is_memory() && dstp == src1p) + emit_rcr_m32_p32(dst, MABS(dstp.memory()), src2p, inst); // rcr [dstp],src2p - /* general case */ + // general case else { - emit_mov_r32_p32_keepflags(drcbe, &dst, dstreg, &src1p); // mov dstreg,src1p - emit_rcr_r32_p32(drcbe, &dst, dstreg, &src2p, inst); // rcr dstreg,src2p - emit_mov_p32_r32(drcbe, &dst, &dstp, dstreg); // mov dstp,dstreg + emit_mov_r32_p32_keepflags(dst, dstreg, src1p); // mov dstreg,src1p + emit_rcr_r32_p32(dst, dstreg, src2p, inst); // rcr dstreg,src2p + emit_mov_p32_r32(dst, dstp, dstreg); // mov dstp,dstreg } } - /* 64-bit form */ - else if (inst->size == 8) + // 64-bit form + else if (inst.size() == 8) { - /* general case */ - emit_mov_r64_p64_keepflags(drcbe, &dst, dstreg, REG_EDX, &src1p); // mov dstreg:dstp,[src1p] - emit_rcr_r64_p64(drcbe, &dst, dstreg, REG_EDX, &src2p, inst); // rcr dstreg:dstp,src2p - emit_mov_p64_r64(drcbe, &dst, &dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax + // general case + emit_mov_r64_p64_keepflags(dst, dstreg, REG_EDX, src1p); // mov dstreg:dstp,[src1p] + emit_rcr_r64_p64(dst, dstreg, REG_EDX, src2p, inst); // rcr dstreg:dstp,src2p + emit_mov_p64_r64(dst, dstp, dstreg, REG_EDX); // mov dstp,dstreg:eax } - return dst; } -/*************************************************************************** - FLOATING POINT OPERATIONS -***************************************************************************/ +//************************************************************************** +// FLOATING POINT OPERATIONS +//************************************************************************** -/*------------------------------------------------- - op_fload - process a FLOAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fload - process a FLOAD opcode +//------------------------------------------------- -static x86code *op_fload(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fload(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, basep, indp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &basep, PTYPE_M, &indp, PTYPE_MRI); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter basep(*this, inst.param(1), PTYPE_M); + be_parameter indp(*this, inst.param(2), PTYPE_MRI); - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate index + if (indp.is_immediate()) { - emit_mov_r32_m32(&dst, REG_EAX, MABS(basep.value + 4*indp.value)); // mov eax,[basep + 4*indp] - if (inst->size == 8) - emit_mov_r32_m32(&dst, REG_EDX, MABS(basep.value + 4 + 4*indp.value)); // mov edx,[basep + 4*indp + 4] + emit_mov_r32_m32(dst, REG_EAX, MABS(basep.memory(4*indp.immediate()))); // mov eax,[basep + 4*indp] + if (inst.size() == 8) + emit_mov_r32_m32(dst, REG_EDX, MABS(basep.memory(4 + 4*indp.immediate()))); // mov edx,[basep + 4*indp + 4] } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); - emit_mov_r32_m32(&dst, REG_EAX, MISD(indreg, 4, basep.value)); // mov eax,[basep + 4*indp] - if (inst->size == 8) - emit_mov_r32_m32(&dst, REG_EDX, MISD(indreg, 4, basep.value + 4)); // mov edx,[basep + 4*indp + 4] + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); + emit_mov_r32_m32(dst, REG_EAX, MABSI(basep.memory(), indreg, 4)); // mov eax,[basep + 4*indp] + if (inst.size() == 8) + emit_mov_r32_m32(dst, REG_EDX, MABSI(basep.memory(4), indreg, 4)); // mov edx,[basep + 4*indp + 4] } - /* general case */ - emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX); // mov [dstp],eax - if (inst->size == 8) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp + 4],edx - return dst; + // general case + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax + if (inst.size() == 8) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp + 4],edx } -/*------------------------------------------------- - op_fstore - process a FSTORE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fstore - process a FSTORE opcode +//------------------------------------------------- -static x86code *op_fstore(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fstore(x86code *&dst, const instruction &inst) { - drcuml_parameter srcp, basep, indp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &basep, PTYPE_M, &indp, PTYPE_MRI, &srcp, PTYPE_MF); + // normalize parameters + be_parameter basep(*this, inst.param(0), PTYPE_M); + be_parameter indp(*this, inst.param(1), PTYPE_MRI); + be_parameter srcp(*this, inst.param(2), PTYPE_MF); - /* general case */ - emit_mov_r32_m32(&dst, REG_EAX, MABS(srcp.value)); // mov eax,[srcp] - if (inst->size == 8) - emit_mov_r32_m32(&dst, REG_EDX, MABS(srcp.value + 4)); // mov edx,[srcp + 4] + // general case + emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp] + if (inst.size() == 8) + emit_mov_r32_m32(dst, REG_EDX, MABS(srcp.memory(4))); // mov edx,[srcp + 4] - /* immediate index */ - if (indp.type == DRCUML_PTYPE_IMMEDIATE) + // immediate index + if (indp.is_immediate()) { - emit_mov_m32_r32(&dst, MABS(basep.value + 4*indp.value), REG_EAX); // mov [basep + 4*indp],eax - if (inst->size == 8) - emit_mov_m32_r32(&dst, MABS(basep.value + 4 + 4*indp.value), REG_EDX); // mov [basep + 4*indp + 4],edx + emit_mov_m32_r32(dst, MABS(basep.memory(4*indp.immediate())), REG_EAX); // mov [basep + 4*indp],eax + if (inst.size() == 8) + emit_mov_m32_r32(dst, MABS(basep.memory(4 + 4*indp.immediate())), REG_EDX); // mov [basep + 4*indp + 4],edx } - /* other index */ + // other index else { - int indreg = param_select_register(REG_ECX, &indp, NULL); - emit_mov_r32_p32(drcbe, &dst, indreg, &indp); - emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value), REG_EAX); // mov [basep + 4*indp],eax - if (inst->size == 8) - emit_mov_m32_r32(&dst, MISD(indreg, 4, basep.value + 4), REG_EDX); // mov [basep + 4*indp + 4],edx + int indreg = indp.select_register(REG_ECX); + emit_mov_r32_p32(dst, indreg, indp); + emit_mov_m32_r32(dst, MABSI(basep.memory(), indreg, 4), REG_EAX); // mov [basep + 4*indp],eax + if (inst.size() == 8) + emit_mov_m32_r32(dst, MABSI(basep.memory(4), indreg, 4), REG_EDX); // mov [basep + 4*indp + 4],edx } - return dst; } -/*------------------------------------------------- - op_fread - process a FREAD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fread - process a FREAD opcode +//------------------------------------------------- -static x86code *op_fread(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fread(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, spacep, addrp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &addrp, PTYPE_MRI, &spacep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter addrp(*this, inst.param(1), PTYPE_MRI); + const parameter &spacep = inst.param(2); + assert(spacep.is_size_space()); + assert((1 << spacep.size()) == inst.size()); - /* set up a call to the read dword/qword handler */ - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacep.value]); // mov [esp],space - if (inst->size == 4) - emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].read_dword); // call read_dword - else if (inst->size == 8) - emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].read_qword); // call read_qword + // set up a call to the read dword/qword handler + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacep.space()]); // mov [esp],space + if (inst.size() == 4) + emit_call(dst, (x86code *)m_accessors[spacep.space()].read_dword); // call read_dword + else if (inst.size() == 8) + emit_call(dst, (x86code *)m_accessors[spacep.space()].read_qword); // call read_qword - /* store result */ - if (inst->size == 4) - emit_mov_p32_r32(drcbe, &dst, &dstp, REG_EAX); // mov dstp,eax - else if (inst->size == 8) - emit_mov_p64_r64(drcbe, &dst, &dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax - - return dst; + // store result + if (inst.size() == 4) + emit_mov_p32_r32(dst, dstp, REG_EAX); // mov dstp,eax + else if (inst.size() == 8) + emit_mov_p64_r64(dst, dstp, REG_EAX, REG_EDX); // mov dstp,edx:eax } -/*------------------------------------------------- - op_fwrite - process a FWRITE opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fwrite - process a FWRITE opcode +//------------------------------------------------- -static x86code *op_fwrite(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fwrite(x86code *&dst, const instruction &inst) { - drcuml_parameter spacep, addrp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &addrp, PTYPE_MRI, &srcp, PTYPE_MF, &spacep, PTYPE_I); - - /* set up a call to the write dword/qword handler */ - if (inst->size == 4) - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp - else if (inst->size == 8) - emit_mov_m64_p64(drcbe, &dst, MBD(REG_ESP, 8), &srcp); // mov [esp+8],srcp - emit_mov_m32_p32(drcbe, &dst, MBD(REG_ESP, 4), &addrp); // mov [esp+4],addrp - emit_mov_m32_imm(&dst, MBD(REG_ESP, 0), (UINT32)drcbe->space[spacep.value]); // mov [esp],space - if (inst->size == 4) - emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].write_dword); // call write_dword - else if (inst->size == 8) - emit_call(&dst, (x86code *)drcbe->accessors[spacep.value].write_qword); // call write_qword + // normalize parameters + be_parameter addrp(*this, inst.param(0), PTYPE_MRI); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &spacep = inst.param(2); + assert(spacep.is_size_space()); + assert((1 << spacep.size()) == inst.size()); - return dst; + // set up a call to the write dword/qword handler + if (inst.size() == 4) + emit_mov_m32_p32(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp + else if (inst.size() == 8) + emit_mov_m64_p64(dst, MBD(REG_ESP, 8), srcp); // mov [esp+8],srcp + emit_mov_m32_p32(dst, MBD(REG_ESP, 4), addrp); // mov [esp+4],addrp + emit_mov_m32_imm(dst, MBD(REG_ESP, 0), (FPTR)m_space[spacep.space()]); // mov [esp],space + if (inst.size() == 4) + emit_call(dst, (x86code *)m_accessors[spacep.space()].write_dword); // call write_dword + else if (inst.size() == 8) + emit_call(dst, (x86code *)m_accessors[spacep.space()].write_qword); // call write_qword } -/*------------------------------------------------- - op_fmov - process a FMOV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fmov - process a FMOV opcode +//------------------------------------------------- -static x86code *op_fmov(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fmov(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - emit_link skip = { 0 }; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_any_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); - - /* always start with a jmp */ - if (inst->condition != DRCUML_COND_ALWAYS) - emit_jcc_short_link(&dst, X86_NOT_CONDITION(inst->condition), &skip); // jcc skip + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* general case */ - emit_mov_r32_m32(&dst, REG_EAX, MABS(srcp.value)); // mov eax,[srcp] - if (inst->size == 8) - emit_mov_r32_m32(&dst, REG_EDX, MABS(srcp.value + 4)); // mov edx,[srcp + 4] - emit_mov_m32_r32(&dst, MABS(dstp.value), REG_EAX); // mov [dstp],eax - if (inst->size == 8) - emit_mov_m32_r32(&dst, MABS(dstp.value + 4), REG_EDX); // mov [dstp + 4],edx - - /* resolve the jump */ + // always start with a jmp + emit_link skip = { 0 }; + if (inst.condition() != uml::COND_ALWAYS) + emit_jcc_short_link(dst, X86_NOT_CONDITION(inst.condition()), skip); // jcc skip + + // general case + emit_mov_r32_m32(dst, REG_EAX, MABS(srcp.memory())); // mov eax,[srcp] + if (inst.size() == 8) + emit_mov_r32_m32(dst, REG_EDX, MABS(srcp.memory(4))); // mov edx,[srcp + 4] + emit_mov_m32_r32(dst, MABS(dstp.memory()), REG_EAX); // mov [dstp],eax + if (inst.size() == 8) + emit_mov_m32_r32(dst, MABS(dstp.memory(4)), REG_EDX); // mov [dstp + 4],edx + + // resolve the jump if (skip.target != NULL) - track_resolve_link(drcbe, &dst, &skip); // skip: - return dst; + track_resolve_link(dst, skip); // skip: } -/*------------------------------------------------- - op_ftoint - process a FTOINT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ftoint - process a FTOINT opcode +//------------------------------------------------- -static x86code *op_ftoint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_ftoint(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep, roundp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_4(drcbe, inst, &dstp, PTYPE_MR, &srcp, PTYPE_MF, &sizep, PTYPE_I, &roundp, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MR); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); + const parameter &roundp = inst.param(3); + assert(roundp.is_rounding()); - /* set rounding mode if necessary */ - if (roundp.value != DRCUML_FMOD_DEFAULT && (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)) + // set rounding mode if necessary + if (roundp.rounding() != ROUND_DEFAULT && (!m_sse3 || roundp.rounding() != ROUND_TRUNC)) { - emit_fstcw_m16(&dst, MABS(&drcbe->fmodesave)); // fstcw [fmodesave] - emit_fldcw_m16(&dst, MABS(&fp_control[roundp.value])); // fldcw fpcontrol[roundp] + emit_fstcw_m16(dst, MABS(&m_fmodesave)); // fstcw [fmodesave] + emit_fldcw_m16(dst, MABS(&fp_control[roundp.rounding()])); // fldcw fpcontrol[roundp] } - /* general case */ - emit_fld_p(&dst, inst->size, &srcp); // fld srcp + // general case + emit_fld_p(dst, inst.size(), srcp); // fld srcp - /* 4-byte integer case */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 4-byte integer case + if (sizep.size() == SIZE_DWORD) { - if (dstp.type == DRCUML_PTYPE_MEMORY) + if (dstp.is_memory()) { - if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC) - emit_fistp_m32(&dst, MABS(dstp.value)); // fistp [dstp] + if (!m_sse3 || roundp.rounding() != ROUND_TRUNC) + emit_fistp_m32(dst, MABS(dstp.memory())); // fistp [dstp] else - emit_fisttp_m32(&dst, MABS(dstp.value)); // fisttp [dstp] + emit_fisttp_m32(dst, MABS(dstp.memory())); // fisttp [dstp] } - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) + else if (dstp.is_int_register()) { - if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC) - emit_fistp_m32(&dst, MABS(drcbe->reglo[dstp.value])); // fistp reglo[dstp] + if (!m_sse3 || roundp.rounding() != ROUND_TRUNC) + emit_fistp_m32(dst, MABS(m_reglo[dstp.ireg()])); // fistp reglo[dstp] else - emit_fisttp_m32(&dst, MABS(drcbe->reglo[dstp.value])); // fisttp reglo[dstp] - emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value])); // mov dstp,reglo[dstp] + emit_fisttp_m32(dst, MABS(m_reglo[dstp.ireg()])); // fisttp reglo[dstp] + emit_mov_r32_m32(dst, dstp.ireg(), MABS(m_reglo[dstp.ireg()])); // mov dstp,reglo[dstp] } } - /* 8-byte integer case */ - else if (sizep.value == DRCUML_SIZE_QWORD) + // 8-byte integer case + else if (sizep.size() == SIZE_QWORD) { - if (dstp.type == DRCUML_PTYPE_MEMORY) + if (dstp.is_memory()) { - if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC) - emit_fistp_m64(&dst, MABS(dstp.value)); // fistp [dstp] + if (!m_sse3 || roundp.rounding() != ROUND_TRUNC) + emit_fistp_m64(dst, MABS(dstp.memory())); // fistp [dstp] else - emit_fisttp_m64(&dst, MABS(dstp.value)); // fisttp [dstp] + emit_fisttp_m64(dst, MABS(dstp.memory())); // fisttp [dstp] } - else if (dstp.type == DRCUML_PTYPE_INT_REGISTER) + else if (dstp.is_int_register()) { - if (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC) - emit_fistp_m64(&dst, MABS(drcbe->reglo[dstp.value])); // fistp reglo[dstp] + if (!m_sse3 || roundp.rounding() != ROUND_TRUNC) + emit_fistp_m64(dst, MABS(m_reglo[dstp.ireg()])); // fistp reglo[dstp] else - emit_fisttp_m64(&dst, MABS(drcbe->reglo[dstp.value])); // fisttp reglo[dstp] - emit_mov_r32_m32(&dst, dstp.value, MABS(drcbe->reglo[dstp.value])); // mov dstp,reglo[dstp] + emit_fisttp_m64(dst, MABS(m_reglo[dstp.ireg()])); // fisttp reglo[dstp] + emit_mov_r32_m32(dst, dstp.ireg(), MABS(m_reglo[dstp.ireg()])); // mov dstp,reglo[dstp] } } - /* restore control word and proceed */ - if (roundp.value != DRCUML_FMOD_DEFAULT && (!drcbe->sse3 || roundp.value != DRCUML_FMOD_TRUNC)) - emit_fldcw_m16(&dst, MABS(&drcbe->fmodesave)); // fldcw [fmodesave] - - return dst; + // restore control word and proceed + if (roundp.rounding() != ROUND_DEFAULT && (!m_sse3 || roundp.rounding() != ROUND_TRUNC)) + emit_fldcw_m16(dst, MABS(&m_fmodesave)); // fldcw [fmodesave] } -/*------------------------------------------------- - op_ffrint - process a FFRINT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ffrint - process a FFRINT opcode +//------------------------------------------------- -static x86code *op_ffrint(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_ffrint(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MRI, &sizep, PTYPE_I); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MRI); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - /* 4-byte integer case */ - if (sizep.value == DRCUML_SIZE_DWORD) + // 4-byte integer case + if (sizep.size() == SIZE_DWORD) { - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + if (srcp.is_immediate()) { - emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value); // mov [fptemp],srcp - emit_fild_m32(&dst, MABS(&drcbe->fptemp)); // fild [fptemp] + emit_mov_m32_imm(dst, MABS(&m_fptemp), srcp.immediate()); // mov [fptemp],srcp + emit_fild_m32(dst, MABS(&m_fptemp)); // fild [fptemp] } - else if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_fild_m32(&dst, MABS(srcp.value)); // fild [srcp] - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + else if (srcp.is_memory()) + emit_fild_m32(dst, MABS(srcp.memory())); // fild [srcp] + else if (srcp.is_int_register()) { - emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value); // mov reglo[srcp],srcp - emit_fild_m32(&dst, MABS(drcbe->reglo[srcp.value])); // fild reglo[srcp] + emit_mov_m32_r32(dst, MABS(m_reglo[srcp.ireg()]), srcp.ireg()); // mov reglo[srcp],srcp + emit_fild_m32(dst, MABS(m_reglo[srcp.ireg()])); // fild reglo[srcp] } } - /* 8-bit integer case */ - else if (sizep.value == DRCUML_SIZE_QWORD) + // 8-bit integer case + else if (sizep.size() == SIZE_QWORD) { - if (srcp.type == DRCUML_PTYPE_IMMEDIATE) + if (srcp.is_immediate()) { - emit_mov_m32_imm(&dst, MABS(&drcbe->fptemp), srcp.value); // mov [fptemp],srcp - emit_mov_m32_imm(&dst, MABS((UINT8 *)&drcbe->fptemp + 4), srcp.value); // mov [fptemp+4],srcp - emit_fild_m64(&dst, MABS(&drcbe->fptemp)); // fild [fptemp] + emit_mov_m32_imm(dst, MABS(&m_fptemp), srcp.immediate()); // mov [fptemp],srcp + emit_mov_m32_imm(dst, MABS((UINT8 *)&m_fptemp + 4), srcp.immediate()); // mov [fptemp+4],srcp + emit_fild_m64(dst, MABS(&m_fptemp)); // fild [fptemp] } - else if (srcp.type == DRCUML_PTYPE_MEMORY) - emit_fild_m64(&dst, MABS(srcp.value)); // fild [srcp] - else if (srcp.type == DRCUML_PTYPE_INT_REGISTER) + else if (srcp.is_memory()) + emit_fild_m64(dst, MABS(srcp.memory())); // fild [srcp] + else if (srcp.is_int_register()) { - emit_mov_m32_r32(&dst, MABS(drcbe->reglo[srcp.value]), srcp.value); // mov reglo[srcp],srcp - emit_fild_m64(&dst, MABS(drcbe->reglo[srcp.value])); // fild reglo[srcp] + emit_mov_m32_r32(dst, MABS(m_reglo[srcp.ireg()]), srcp.ireg()); // mov reglo[srcp],srcp + emit_fild_m64(dst, MABS(m_reglo[srcp.ireg()])); // fild reglo[srcp] } } - /* store the result and be done */ - emit_fstp_p(&dst, inst->size, &dstp); // fstp [dstp] - return dst; + // store the result and be done + emit_fstp_p(dst, inst.size(), dstp); // fstp [dstp] } -/*------------------------------------------------- - op_ffrflt - process a FFRFLT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_ffrflt - process a FFRFLT opcode +//------------------------------------------------- -static x86code *op_ffrflt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_ffrflt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp, sizep; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF, &sizep, PTYPE_I); - - /* general case */ - if (sizep.value == DRCUML_SIZE_DWORD) - emit_fld_m32(&dst, MABS(srcp.value)); // fld [srcp] - else if (sizep.value == DRCUML_SIZE_QWORD) - emit_fld_m64(&dst, MABS(srcp.value)); // fld [srcp] - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); + const parameter &sizep = inst.param(2); + assert(sizep.is_size()); - return dst; + // general case + if (sizep.size() == SIZE_DWORD) + emit_fld_m32(dst, MABS(srcp.memory())); // fld [srcp] + else if (sizep.size() == SIZE_QWORD) + emit_fld_m64(dst, MABS(srcp.memory())); // fld [srcp] + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_frnds - process a FRNDS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frnds - process a FRNDS opcode +//------------------------------------------------- -static x86code *op_frnds(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_frnds(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 8); + // validate instruction + assert(inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* general case */ - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fstp_m32(&dst, MABS(&drcbe->fptemp)); // fstp [fptemp] - emit_fld_m32(&dst, MABS(&drcbe->fptemp)); // fld [fptemp] - emit_fstp_p(&dst, inst->size, &dstp); // fstp [dstp] - return dst; + // general case + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fstp_m32(dst, MABS(&m_fptemp)); // fstp [fptemp] + emit_fld_m32(dst, MABS(&m_fptemp)); // fld [fptemp] + emit_fstp_p(dst, inst.size(), dstp); // fstp [dstp] } -/*------------------------------------------------- - op_fadd - process a FADD opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fadd - process a FADD opcode +//------------------------------------------------- -static x86code *op_fadd(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fadd(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); - - /* general case */ - emit_fld_p(&dst, inst->size, &src1p); // fld src1p - emit_fld_p(&dst, inst->size, &src2p); // fld src2p - emit_faddp(&dst); // faddp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); + normalize_commutative(src1p, src2p); - return dst; + // general case + emit_fld_p(dst, inst.size(), src1p); // fld src1p + emit_fld_p(dst, inst.size(), src2p); // fld src2p + emit_faddp(dst); // faddp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fsub - process a FSUB opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fsub - process a FSUB opcode +//------------------------------------------------- -static x86code *op_fsub(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fsub(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); - - /* general case */ - emit_fld_p(&dst, inst->size, &src1p); // fld src1p - emit_fld_p(&dst, inst->size, &src2p); // fld src2p - emit_fsubp(&dst); // fsubp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); - return dst; + // general case + emit_fld_p(dst, inst.size(), src1p); // fld src1p + emit_fld_p(dst, inst.size(), src2p); // fld src2p + emit_fsubp(dst); // fsubp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fcmp - process a FCMP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fcmp - process a FCMP opcode +//------------------------------------------------- -static x86code *op_fcmp(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fcmp(x86code *&dst, const instruction &inst) { - drcuml_parameter src1p, src2p; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); - assert_flags(inst, DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U); + assert_flags(inst, FLAG_C | FLAG_Z | FLAG_U); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter src1p(*this, inst.param(0), PTYPE_MF); + be_parameter src2p(*this, inst.param(1), PTYPE_MF); - /* general case */ - emit_fld_p(&dst, inst->size, &src2p); // fld src2p - emit_fld_p(&dst, inst->size, &src1p); // fld src1p - emit_fcompp(&dst); // fcompp - emit_fstsw_ax(&dst); // fnstsw ax - emit_sahf(&dst); // sahf - - return dst; + // general case + emit_fld_p(dst, inst.size(), src2p); // fld src2p + emit_fld_p(dst, inst.size(), src1p); // fld src1p + emit_fcompp(dst); // fcompp + emit_fstsw_ax(dst); // fnstsw ax + emit_sahf(dst); // sahf } -/*------------------------------------------------- - op_fmul - process a FMUL opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fmul - process a FMUL opcode +//------------------------------------------------- -static x86code *op_fmul(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fmul(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); + normalize_commutative(src1p, src2p); - /* general case */ - emit_fld_p(&dst, inst->size, &src1p); // fld src1p - emit_fld_p(&dst, inst->size, &src2p); // fld src2p - emit_fmulp(&dst); // fmulp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp - - return dst; + // general case + emit_fld_p(dst, inst.size(), src1p); // fld src1p + emit_fld_p(dst, inst.size(), src2p); // fld src2p + emit_fmulp(dst); // fmulp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fdiv - process a FDIV opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fdiv - process a FDIV opcode +//------------------------------------------------- -static x86code *op_fdiv(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fdiv(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, src1p, src2p; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_3(drcbe, inst, &dstp, PTYPE_MF, &src1p, PTYPE_MF, &src2p, PTYPE_MF); - - /* general case */ - emit_fld_p(&dst, inst->size, &src1p); // fld src1p - emit_fld_p(&dst, inst->size, &src2p); // fld src2p - emit_fdivp(&dst); // fdivp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter src1p(*this, inst.param(1), PTYPE_MF); + be_parameter src2p(*this, inst.param(2), PTYPE_MF); - return dst; + // general case + emit_fld_p(dst, inst.size(), src1p); // fld src1p + emit_fld_p(dst, inst.size(), src2p); // fld src2p + emit_fdivp(dst); // fdivp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fneg - process a FNEG opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fneg - process a FNEG opcode +//------------------------------------------------- -static x86code *op_fneg(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fneg(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); - - /* general case */ - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fchs(&dst); // fchs - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - return dst; + // general case + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fchs(dst); // fchs + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fabs - process a FABS opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fabs - process a FABS opcode +//------------------------------------------------- -static x86code *op_fabs(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fabs(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - /* general case */ - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fabs(&dst); // fabs - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp - - return dst; + // general case + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fabs(dst); // fabs + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_fsqrt - process a FSQRT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_fsqrt - process a FSQRT opcode +//------------------------------------------------- -static x86code *op_fsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_fsqrt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); - - /* general case */ - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fsqrt(&dst); // fsqrt - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - return dst; + // general case + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fsqrt(dst); // fsqrt + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_frecip - process a FRECIP opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frecip - process a FRECIP opcode +//------------------------------------------------- -static x86code *op_frecip(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_frecip(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); - - /* general case */ - emit_fld1(&dst); // fld1 - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fdivp(&dst); // fdivp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - return dst; + // general case + emit_fld1(dst); // fld1 + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fdivp(dst); // fdivp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*------------------------------------------------- - op_frsqrt - process a FRSQRT opcode --------------------------------------------------*/ +//------------------------------------------------- +// op_frsqrt - process a FRSQRT opcode +//------------------------------------------------- -static x86code *op_frsqrt(drcbe_state *drcbe, x86code *dst, const drcuml_instruction *inst) +void drcbe_x86::op_frsqrt(x86code *&dst, const instruction &inst) { - drcuml_parameter dstp, srcp; - - /* validate instruction */ - assert(inst->size == 4 || inst->size == 8); + // validate instruction + assert(inst.size() == 4 || inst.size() == 8); assert_no_condition(inst); assert_no_flags(inst); - /* normalize parameters */ - param_normalize_2(drcbe, inst, &dstp, PTYPE_MF, &srcp, PTYPE_MF); - - /* general case */ - emit_fld1(&dst); // fld1 - emit_fld_p(&dst, inst->size, &srcp); // fld srcp - emit_fsqrt(&dst); // fsqrt - emit_fdivp(&dst); // fdivp - emit_fstp_p(&dst, inst->size, &dstp); // fstp dstp + // normalize parameters + be_parameter dstp(*this, inst.param(0), PTYPE_MF); + be_parameter srcp(*this, inst.param(1), PTYPE_MF); - return dst; + // general case + emit_fld1(dst); // fld1 + emit_fld_p(dst, inst.size(), srcp); // fld srcp + emit_fsqrt(dst); // fsqrt + emit_fdivp(dst); // fdivp + emit_fstp_p(dst, inst.size(), dstp); // fstp dstp } -/*************************************************************************** - MISCELLAENOUS FUNCTIONS -***************************************************************************/ +//************************************************************************** +// MISCELLAENOUS FUNCTIONS +//************************************************************************** -/*------------------------------------------------- - dmulu - perform a double-wide unsigned multiply --------------------------------------------------*/ +//------------------------------------------------- +// dmulu - perform a double-wide unsigned multiply +//------------------------------------------------- -static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int flags) +int drcbe_x86::dmulu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2, int flags) { - UINT64 lo, hi, prevlo; - UINT64 a, b, temp; - - /* shortcut if we don't care about the high bits or the flags */ - if (dstlo == dsthi && flags == 0) + // shortcut if we don't care about the high bits or the flags + if (&dstlo == &dsthi && flags == 0) { - *dstlo = src1 * src2; + dstlo = src1 * src2; return 0; } - /* fetch source values */ - a = src1; - b = src2; + // fetch source values + UINT64 a = src1; + UINT64 b = src2; if (a == 0 || b == 0) { - *dsthi = *dstlo = 0; - return DRCUML_FLAG_Z; + dsthi = dstlo = 0; + return FLAG_Z; } - /* compute high and low parts first */ - lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); - hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); + // compute high and low parts first + UINT64 lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); + UINT64 hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); - /* compute middle parts */ - prevlo = lo; - temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); + // compute middle parts + UINT64 prevlo = lo; + UINT64 temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); @@ -6979,43 +6516,43 @@ static int dmulu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2, int fla lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); - /* store the results */ - *dsthi = hi; - *dstlo = lo; - return ((hi >> 60) & DRCUML_FLAG_S) | ((*dsthi != 0) << 1); + // store the results + dsthi = hi; + dstlo = lo; + return ((hi >> 60) & FLAG_S) | ((dsthi != 0) << 1); } -/*------------------------------------------------- - dmuls - perform a double-wide signed multiply --------------------------------------------------*/ +//------------------------------------------------- +// dmuls - perform a double-wide signed multiply +//------------------------------------------------- -static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags) +int drcbe_x86::dmuls(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2, int flags) { UINT64 lo, hi, prevlo; UINT64 a, b, temp; - /* shortcut if we don't care about the high bits or the flags */ - if (dstlo == dsthi && flags == 0) + // shortcut if we don't care about the high bits or the flags + if (&dstlo == &dsthi && flags == 0) { - *dstlo = src1 * src2; + dstlo = src1 * src2; return 0; } - /* fetch absolute source values */ + // fetch absolute source values a = src1; if ((INT64)a < 0) a = -a; b = src2; if ((INT64)b < 0) b = -b; if (a == 0 || b == 0) { - *dsthi = *dstlo = 0; - return DRCUML_FLAG_Z; + dsthi = dstlo = 0; + return FLAG_Z; } - /* compute high and low parts first */ + // compute high and low parts first lo = (UINT64)(UINT32)(a >> 0) * (UINT64)(UINT32)(b >> 0); hi = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 32); - /* compute middle parts */ + // compute middle parts prevlo = lo; temp = (UINT64)(UINT32)(a >> 32) * (UINT64)(UINT32)(b >> 0); lo += temp << 32; @@ -7026,51 +6563,51 @@ static int dmuls(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2, int flags lo += temp << 32; hi += (temp >> 32) + (lo < prevlo); - /* adjust for signage */ + // adjust for signage if ((INT64)(src1 ^ src2) < 0) { hi = ~hi + (lo == 0); lo = ~lo + 1; } - /* store the results */ - *dsthi = hi; - *dstlo = lo; - return ((hi >> 60) & DRCUML_FLAG_S) | ((*dsthi != ((INT64)lo >> 63)) << 1); + // store the results + dsthi = hi; + dstlo = lo; + return ((hi >> 60) & FLAG_S) | ((dsthi != ((INT64)lo >> 63)) << 1); } -/*------------------------------------------------- - ddivu - perform a double-wide unsigned divide --------------------------------------------------*/ +//------------------------------------------------- +// ddivu - perform a double-wide unsigned divide +//------------------------------------------------- -static int ddivu(UINT64 *dstlo, UINT64 *dsthi, UINT64 src1, UINT64 src2) +int drcbe_x86::ddivu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2) { - /* do nothing if src2 == 0 */ + // do nothing if src2 == 0 if (src2 == 0) - return DRCUML_FLAG_V; + return FLAG_V; - /* shortcut if no remainder */ - *dstlo = src1 / src2; + // shortcut if no remainder + dstlo = src1 / src2; if (dstlo != dsthi) - *dsthi = src1 % src2; - return ((*dstlo == 0) << 2) | ((*dstlo >> 60) & DRCUML_FLAG_S); + dsthi = src1 % src2; + return ((dstlo == 0) << 2) | ((dstlo >> 60) & FLAG_S); } -/*------------------------------------------------- - ddivs - perform a double-wide signed divide --------------------------------------------------*/ +//------------------------------------------------- +// ddivs - perform a double-wide signed divide +//------------------------------------------------- -static int ddivs(UINT64 *dstlo, UINT64 *dsthi, INT64 src1, INT64 src2) +int drcbe_x86::ddivs(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2) { - /* do nothing if src2 == 0 */ + // do nothing if src2 == 0 if (src2 == 0) - return DRCUML_FLAG_V; + return FLAG_V; - /* shortcut if no remainder */ - *dstlo = src1 / src2; + // shortcut if no remainder + dstlo = src1 / src2; if (dstlo != dsthi) - *dsthi = src1 % src2; - return ((*dstlo == 0) << 2) | ((*dstlo >> 60) & DRCUML_FLAG_S); + dsthi = src1 % src2; + return ((dstlo == 0) << 2) | ((dstlo >> 60) & FLAG_S); } diff --git a/src/emu/cpu/drcbex86.h b/src/emu/cpu/drcbex86.h new file mode 100644 index 00000000000..96617cfe164 --- /dev/null +++ b/src/emu/cpu/drcbex86.h @@ -0,0 +1,371 @@ +/*************************************************************************** + + drcbex86.h + + 32-bit x86 back-end for the universal machine language. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#pragma once + +#ifndef __DRCBEX86_H__ +#define __DRCBEX86_H__ + +#include "drcuml.h" +#include "drcbeut.h" +#include "x86log.h" + +#define X86EMIT_SIZE 32 +#include "x86emit.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class drcbe_x86 : public drcbe_interface +{ + typedef UINT32 (*x86_entry_point_func)(x86code *entry); + +public: + // construction/destruction + drcbe_x86(drcuml_state &drcuml, device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits); + virtual ~drcbe_x86(); + + // required overrides + virtual void reset(); + virtual int execute(uml::code_handle &entry); + virtual void generate(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst); + virtual bool hash_exists(UINT32 mode, UINT32 pc); + virtual void get_info(drcbe_info &info); + +private: + // a be_parameter is similar to a uml::parameter but maps to native registers/memory + class be_parameter + { + public: + // parameter types + enum be_parameter_type + { + PTYPE_NONE = 0, // invalid + PTYPE_IMMEDIATE, // immediate; value = sign-extended to 64 bits + PTYPE_INT_REGISTER, // integer register; value = 0-REG_MAX + PTYPE_FLOAT_REGISTER, // floating point register; value = 0-REG_MAX + PTYPE_VECTOR_REGISTER, // vector register; value = 0-REG_MAX + PTYPE_MEMORY, // memory; value = pointer to memory + PTYPE_MAX + }; + + // represents the value of a parameter + typedef UINT64 be_parameter_value; + + // construction + be_parameter() : m_type(PTYPE_NONE), m_value(0) { } + be_parameter(const be_parameter ¶m) : m_type(param.m_type), m_value(param.m_value) { } + be_parameter(UINT64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } + be_parameter(drcbe_x86 &drcbe, const uml::parameter ¶m, UINT32 allowed); + + // creators for types that don't safely default + static inline be_parameter make_ireg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_INT_REGISTER, regnum); } + static inline be_parameter make_freg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_FLOAT_REGISTER, regnum); } + static inline be_parameter make_vreg(int regnum) { assert(regnum >= 0 && regnum < x86emit::REG_MAX); return be_parameter(PTYPE_VECTOR_REGISTER, regnum); } + static inline be_parameter make_memory(void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(base)); } + static inline be_parameter make_memory(const void *base) { return be_parameter(PTYPE_MEMORY, reinterpret_cast<be_parameter_value>(const_cast<void *>(base))); } + + // operators + bool operator==(const be_parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); } + bool operator!=(const be_parameter &rhs) const { return (m_type != rhs.m_type || m_value != rhs.m_value); } + + // getters + be_parameter_type type() const { return m_type; } + UINT64 immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } + int ireg() const { assert(m_type == PTYPE_INT_REGISTER); assert(m_value >= 0 && m_value < x86emit::REG_MAX); return m_value; } + int freg() const { assert(m_type == PTYPE_FLOAT_REGISTER); assert(m_value >= 0 && m_value < x86emit::REG_MAX); return m_value; } + int vreg() const { assert(m_type == PTYPE_VECTOR_REGISTER); assert(m_value >= 0 && m_value < x86emit::REG_MAX); return m_value; } + void *memory(UINT32 offset = 0) const { assert(m_type == PTYPE_MEMORY); return reinterpret_cast<void *>(m_value + offset); } + + // type queries + bool is_immediate() const { return (m_type == PTYPE_IMMEDIATE); } + bool is_int_register() const { return (m_type == PTYPE_INT_REGISTER); } + bool is_float_register() const { return (m_type == PTYPE_FLOAT_REGISTER); } + bool is_vector_register() const { return (m_type == PTYPE_VECTOR_REGISTER); } + bool is_memory() const { return (m_type == PTYPE_MEMORY); } + + // other queries + bool is_immediate_value(UINT64 value) const { return (m_type == PTYPE_IMMEDIATE && m_value == value); } + + // helpers + int select_register(int defreg) const; + int select_register(int defreg, const be_parameter &checkparam) const; + int select_register(int defreg, const be_parameter &checkparam, const be_parameter &checkparam2) const; + + private: + // private constructor + be_parameter(be_parameter_type type, be_parameter_value value) : m_type(type), m_value(value) { } + + // internals + be_parameter_type m_type; // parameter type + be_parameter_value m_value; // parameter value + }; + + // helpers + void normalize_commutative(be_parameter &inner, be_parameter &outer); + void emit_combine_z_flags(x86code *&dst); + void emit_combine_z_shl_flags(x86code *&dst); + void reset_last_upper_lower_reg(); + void set_last_lower_reg(x86code *&dst, const be_parameter ¶m, UINT8 reglo); + void set_last_upper_reg(x86code *&dst, const be_parameter ¶m, UINT8 reghi); + bool can_skip_lower_load(x86code *&dst, UINT32 *memref, UINT8 reglo); + bool can_skip_upper_load(x86code *&dst, UINT32 *memref, UINT8 reghi); + void track_resolve_link(x86code *&destptr, const emit_link &linkinfo); + + static void fixup_label(void *parameter, drccodeptr labelcodeptr); + void fixup_exception(drccodeptr *codeptr, void *param1, void *param2); + + static void debug_log_hashjmp(int mode, offs_t pc); + static void debug_log_hashjmp_fail(); + + // code generators + void op_handle(x86code *&dst, const uml::instruction &inst); + void op_hash(x86code *&dst, const uml::instruction &inst); + void op_label(x86code *&dst, const uml::instruction &inst); + void op_comment(x86code *&dst, const uml::instruction &inst); + void op_mapvar(x86code *&dst, const uml::instruction &inst); + + void op_nop(x86code *&dst, const uml::instruction &inst); + void op_debug(x86code *&dst, const uml::instruction &inst); + void op_exit(x86code *&dst, const uml::instruction &inst); + void op_hashjmp(x86code *&dst, const uml::instruction &inst); + void op_jmp(x86code *&dst, const uml::instruction &inst); + void op_exh(x86code *&dst, const uml::instruction &inst); + void op_callh(x86code *&dst, const uml::instruction &inst); + void op_ret(x86code *&dst, const uml::instruction &inst); + void op_callc(x86code *&dst, const uml::instruction &inst); + void op_recover(x86code *&dst, const uml::instruction &inst); + + void op_setfmod(x86code *&dst, const uml::instruction &inst); + void op_getfmod(x86code *&dst, const uml::instruction &inst); + void op_getexp(x86code *&dst, const uml::instruction &inst); + void op_getflgs(x86code *&dst, const uml::instruction &inst); + void op_save(x86code *&dst, const uml::instruction &inst); + void op_restore(x86code *&dst, const uml::instruction &inst); + + void op_load(x86code *&dst, const uml::instruction &inst); + void op_loads(x86code *&dst, const uml::instruction &inst); + void op_store(x86code *&dst, const uml::instruction &inst); + void op_read(x86code *&dst, const uml::instruction &inst); + void op_readm(x86code *&dst, const uml::instruction &inst); + void op_write(x86code *&dst, const uml::instruction &inst); + void op_writem(x86code *&dst, const uml::instruction &inst); + void op_carry(x86code *&dst, const uml::instruction &inst); + void op_set(x86code *&dst, const uml::instruction &inst); + void op_mov(x86code *&dst, const uml::instruction &inst); + void op_sext(x86code *&dst, const uml::instruction &inst); + void op_roland(x86code *&dst, const uml::instruction &inst); + void op_rolins(x86code *&dst, const uml::instruction &inst); + void op_add(x86code *&dst, const uml::instruction &inst); + void op_addc(x86code *&dst, const uml::instruction &inst); + void op_sub(x86code *&dst, const uml::instruction &inst); + void op_subc(x86code *&dst, const uml::instruction &inst); + void op_cmp(x86code *&dst, const uml::instruction &inst); + void op_mulu(x86code *&dst, const uml::instruction &inst); + void op_muls(x86code *&dst, const uml::instruction &inst); + void op_divu(x86code *&dst, const uml::instruction &inst); + void op_divs(x86code *&dst, const uml::instruction &inst); + void op_and(x86code *&dst, const uml::instruction &inst); + void op_test(x86code *&dst, const uml::instruction &inst); + void op_or(x86code *&dst, const uml::instruction &inst); + void op_xor(x86code *&dst, const uml::instruction &inst); + void op_lzcnt(x86code *&dst, const uml::instruction &inst); + void op_bswap(x86code *&dst, const uml::instruction &inst); + void op_shl(x86code *&dst, const uml::instruction &inst); + void op_shr(x86code *&dst, const uml::instruction &inst); + void op_sar(x86code *&dst, const uml::instruction &inst); + void op_ror(x86code *&dst, const uml::instruction &inst); + void op_rol(x86code *&dst, const uml::instruction &inst); + void op_rorc(x86code *&dst, const uml::instruction &inst); + void op_rolc(x86code *&dst, const uml::instruction &inst); + + void op_fload(x86code *&dst, const uml::instruction &inst); + void op_fstore(x86code *&dst, const uml::instruction &inst); + void op_fread(x86code *&dst, const uml::instruction &inst); + void op_fwrite(x86code *&dst, const uml::instruction &inst); + void op_fmov(x86code *&dst, const uml::instruction &inst); + void op_ftoint(x86code *&dst, const uml::instruction &inst); + void op_ffrint(x86code *&dst, const uml::instruction &inst); + void op_ffrflt(x86code *&dst, const uml::instruction &inst); + void op_frnds(x86code *&dst, const uml::instruction &inst); + void op_fadd(x86code *&dst, const uml::instruction &inst); + void op_fsub(x86code *&dst, const uml::instruction &inst); + void op_fcmp(x86code *&dst, const uml::instruction &inst); + void op_fmul(x86code *&dst, const uml::instruction &inst); + void op_fdiv(x86code *&dst, const uml::instruction &inst); + void op_fneg(x86code *&dst, const uml::instruction &inst); + void op_fabs(x86code *&dst, const uml::instruction &inst); + void op_fsqrt(x86code *&dst, const uml::instruction &inst); + void op_frecip(x86code *&dst, const uml::instruction &inst); + void op_frsqrt(x86code *&dst, const uml::instruction &inst); + + // 32-bit code emission helpers + void emit_mov_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter ¶m); + void emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m); + void emit_mov_p32_r32(x86code *&dst, const be_parameter ¶m, UINT8 reg); + void emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + + // 64-bit code emission helpers + void emit_mov_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m); + void emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m); + void emit_mov_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m); + void emit_mov_p64_r64(x86code *&dst, const be_parameter ¶m, UINT8 reglo, UINT8 reghi); + void emit_add_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_cmp_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_shl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_shr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_sar_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_rol_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_ror_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter ¶m, const uml::instruction &inst); + void emit_rcr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter ¶m, const uml::instruction &inst); + + // floating-point code emission helpers + void emit_fld_p(x86code *&dst, int size, const be_parameter ¶m); + void emit_fstp_p(x86code *&dst, int size, const be_parameter ¶m); + + // callback helpers + static int dmulu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2, int flags); + static int dmuls(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2, int flags); + static int ddivu(UINT64 &dstlo, UINT64 &dsthi, UINT64 src1, UINT64 src2); + static int ddivs(UINT64 &dstlo, UINT64 &dsthi, INT64 src1, INT64 src2); + + // internal state + drc_hash_table m_hash; // hash table state + drc_map_variables m_map; // code map + drc_label_list m_labels; // label list + x86log_context * m_log; // logging + bool m_logged_common; // logged common code already? + bool m_sse3; // do we have SSE3 support? + + x86_entry_point_func m_entry; // entry point + x86code * m_exit; // exit point + x86code * m_nocode; // nocode handler + x86code * m_save; // save handler + x86code * m_restore; // restore handler + + UINT32 * m_reglo[x86emit::REG_MAX];// pointer to low part of data for each register + UINT32 * m_reghi[x86emit::REG_MAX];// pointer to high part of data for each register + UINT8 m_last_lower_reg; // last register we stored a lower from + x86code * m_last_lower_pc; // PC after instruction where we last stored a lower register + UINT32 * m_last_lower_addr; // address where we last stored an lower register + UINT8 m_last_upper_reg; // last register we stored an upper from + x86code * m_last_upper_pc; // PC after instruction where we last stored an upper register + UINT32 * m_last_upper_addr; // address where we last stored an upper register + double m_fptemp; // temporary storage for floating point + + UINT16 m_fpumode; // saved FPU mode + UINT16 m_fmodesave; // temporary location for saving + + void * m_stacksave; // saved stack pointer + void * m_hashstacksave; // saved stack pointer for hashjmp + UINT64 m_reslo; // extended low result + UINT64 m_reshi; // extended high result + + // globals + typedef void (drcbe_x86::*opcode_generate_func)(x86code *&dst, const uml::instruction &inst); + struct opcode_table_entry + { + uml::opcode_t opcode; // opcode in question + opcode_generate_func func; // function pointer to the work + }; + static const opcode_table_entry s_opcode_table_source[]; + static opcode_generate_func s_opcode_table[uml::OP_MAX]; +}; + + +#endif /* __DRCBEC_H__ */ diff --git a/src/emu/cpu/drccache.h b/src/emu/cpu/drccache.h index fe2475c272d..efafef09ed6 100644 --- a/src/emu/cpu/drccache.h +++ b/src/emu/cpu/drccache.h @@ -49,8 +49,8 @@ //************************************************************************** // ensure that a given pointer is within the cache boundaries -#define assert_in_cache(c,p) assert((c)->contains_pointer(p)) -#define assert_in_near_cache(c,p) assert((c)->contains_near_pointer(p)) +#define assert_in_cache(c,p) assert((c).contains_pointer(p)) +#define assert_in_near_cache(c,p) assert((c).contains_near_pointer(p)) @@ -61,6 +61,16 @@ // generic code pointer typedef UINT8 *drccodeptr; + +// helper template for oob codegen +template<class T, void (T::*func)(drccodeptr *codeptr, void *param1, void *param2)> +void oob_func_stub(drccodeptr *codeptr, void *param1, void *param2, void *param3) +{ + T *target = reinterpret_cast<T *>(param3); + (target->*func)(codeptr, param1, param2); +} + + // drc_cache class drc_cache { diff --git a/src/emu/cpu/drcuml.c b/src/emu/cpu/drcuml.c index 27f50bb121d..01616e26e4e 100644 --- a/src/emu/cpu/drcuml.c +++ b/src/emu/cpu/drcuml.c @@ -4,9 +4,36 @@ Universal machine language for dynamic recompiling CPU cores. +**************************************************************************** + Copyright Aaron Giles - Released for general non-commercial use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. **************************************************************************** @@ -38,143 +65,31 @@ #include "emu.h" #include "drcuml.h" -#include "drcumlsh.h" -#include <setjmp.h> - - -/*************************************************************************** - DEBUGGING -***************************************************************************/ - -#define VALIDATE_BACKEND (0) -#define LOG_SIMPLIFICATIONS (0) - - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* opcode validation condition/flag valid bitmasks */ -#define OPFLAGS_NONE 0x00 -#define OPFLAGS_C DRCUML_FLAG_C -#define OPFLAGS_SZ (DRCUML_FLAG_S | DRCUML_FLAG_Z) -#define OPFLAGS_SZC (DRCUML_FLAG_S | DRCUML_FLAG_Z | DRCUML_FLAG_C) -#define OPFLAGS_SZV (DRCUML_FLAG_S | DRCUML_FLAG_Z | DRCUML_FLAG_V) -#define OPFLAGS_SZVC (DRCUML_FLAG_S | DRCUML_FLAG_Z | DRCUML_FLAG_V | DRCUML_FLAG_C) -#define OPFLAGS_UZC (DRCUML_FLAG_U | DRCUML_FLAG_Z | DRCUML_FLAG_C) -#define OPFLAGS_ALL 0x1f -#define OPFLAGS_P1 0x81 -#define OPFLAGS_P2 0x82 -#define OPFLAGS_P3 0x83 -#define OPFLAGS_P4 0x84 - -/* parameter input/output states */ -#define PIO_IN 0x01 -#define PIO_OUT 0x02 -#define PIO_INOUT (PIO_IN | PIO_OUT) - -/* parameter sizes */ -#define PSIZE_4 DRCUML_SIZE_DWORD -#define PSIZE_8 DRCUML_SIZE_QWORD -#define PSIZE_OP 0x80 -#define PSIZE_P1 0x81 -#define PSIZE_P2 0x82 -#define PSIZE_P3 0x83 -#define PSIZE_P4 0x84 - -/* basic parameter types */ -#define PTYPES_NONE 0 -#define PTYPES_IMM (1 << DRCUML_PTYPE_IMMEDIATE) -#define PTYPES_IREG (1 << DRCUML_PTYPE_INT_REGISTER) -#define PTYPES_FREG (1 << DRCUML_PTYPE_FLOAT_REGISTER) -#define PTYPES_MVAR (1 << DRCUML_PTYPE_MAPVAR) -#define PTYPES_MEM (1 << DRCUML_PTYPE_MEMORY) - -/* special parameter types */ -#define PTYPES_PTR (PTYPES_MEM | 0x1000) -#define PTYPES_STATE (PTYPES_MEM | 0x2000) -#define PTYPES_STR (PTYPES_MEM | 0x3000) -#define PTYPES_CFUNC (PTYPES_MEM | 0x4000) -#define PTYPES_HAND (PTYPES_MEM | 0x5000) -#define PTYPES_SIZE (PTYPES_IMM | 0x8000) -#define PTYPES_SCSZ (PTYPES_IMM | 0x9000) -#define PTYPES_SPACE (PTYPES_IMM | 0xa000) -#define PTYPES_SPSZ (PTYPES_IMM | 0xb000) -#define PTYPES_FMOD (PTYPES_IMM | 0xc000) -#define PTYPES_LAB (PTYPES_IMM | 0xd000) - -/* combinations of types */ -#define PTYPES_IRM (PTYPES_IREG | PTYPES_MEM) -#define PTYPES_FRM (PTYPES_FREG | PTYPES_MEM) -#define PTYPES_IMV (PTYPES_IMM | PTYPES_MVAR) -#define PTYPES_IANY (PTYPES_IRM | PTYPES_IMV) -#define PTYPES_FANY (PTYPES_FRM) - -/* test result undefined */ -#define UNDEFINED 0x19bb7a1005fde439 -#define UNDEFINED_U64 U64(0x19bb7a1005fde439) - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ +#include "drcbec.h" +#include "drcbex86.h" +#include "drcbex64.h" -/* structure describing a UML symbol */ -typedef struct _drcuml_symbol drcuml_symbol; -struct _drcuml_symbol -{ - drcuml_symbol * next; /* link to the next symbol */ - drccodeptr base; /* base of the symbol */ - UINT32 length; /* length of the symbol */ - char symname[1]; /* name of the symbol */ -}; +using namespace uml; -/* structure describing UML generation state */ -struct _drcuml_state -{ - device_t * device; /* CPU device we are associated with */ - drc_cache * cache; /* pointer to the codegen cache */ - drcuml_block * blocklist; /* list of active blocks */ - const drcbe_interface * beintf; /* backend interface pointer */ - drcbe_state * bestate; /* pointer to the back-end state */ - drcuml_codehandle * handlelist; /* head of linked list of handles */ - FILE * umllog; /* handle to the UML logfile */ - drcuml_symbol * symlist; /* head of linked list of symbols */ - drcuml_symbol ** symtailptr; /* pointer to tail of linked list of symbols */ -}; +//************************************************************************** +// DEBUGGING +//************************************************************************** -/* structure describing UML codegen block */ -struct _drcuml_block -{ - drcuml_state * drcuml; /* pointer back to the owning UML */ - drcuml_block * next; /* pointer to next block */ - drcuml_instruction * inst; /* pointer to the instruction list */ - UINT8 inuse; /* this block is in use */ - UINT32 maxinst; /* maximum number of instructions */ - UINT32 nextinst; /* next instruction to fill in the cache */ - jmp_buf * errorbuf; /* setjmp buffer for deep error handling */ -}; +#define VALIDATE_BACKEND (0) +#define LOG_SIMPLIFICATIONS (0) -/* structure describing a global handle */ -struct _drcuml_codehandle -{ - drccodeptr code; /* pointer to the associated code */ - char * string; /* pointer to string attached to handle */ - drcuml_codehandle * next; /* link to next handle in the list */ - drcuml_state * drcuml; /* pointer to owning object */ -}; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/* structure describing back-end validation test */ -typedef struct _bevalidate_test bevalidate_test; -struct _bevalidate_test +// structure describing back-end validation test +struct bevalidate_test { - drcuml_opcode opcode; + opcode_t opcode; UINT8 size; UINT8 iflags; UINT8 flags; @@ -183,1842 +98,628 @@ struct _bevalidate_test -/*************************************************************************** - TABLES -***************************************************************************/ - -/* macro to simplify the table */ -#define PINFO(inout, size, types) { PIO_##inout, PSIZE_##size, PTYPES_##types } -#define OPINFO0(op,str,sizes,cond,iflag,oflag,mflag) { DRCUML_OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { { 0 } } }, -#define OPINFO1(op,str,sizes,cond,iflag,oflag,mflag,p0) { DRCUML_OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0 } }, -#define OPINFO2(op,str,sizes,cond,iflag,oflag,mflag,p0,p1) { DRCUML_OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1 } }, -#define OPINFO3(op,str,sizes,cond,iflag,oflag,mflag,p0,p1,p2) { DRCUML_OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1, p2 } }, -#define OPINFO4(op,str,sizes,cond,iflag,oflag,mflag,p0,p1,p2,p3) { DRCUML_OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1, p2, p3 } }, - -/* opcode validation table */ -static const drcuml_opcode_info opcode_info_source[] = -{ - /* Compile-time opcodes */ - OPINFO1(HANDLE, "handle", 4, FALSE, NONE, NONE, NONE, PINFO(IN, OP, HAND)) - OPINFO2(HASH, "hash", 4, FALSE, NONE, NONE, NONE, PINFO(IN, OP, IMV), PINFO(IN, OP, IMV)) - OPINFO1(LABEL, "label", 4, FALSE, NONE, NONE, NONE, PINFO(IN, OP, LAB)) - OPINFO1(COMMENT, "comment", 4, FALSE, NONE, NONE, NONE, PINFO(IN, OP, STR)) - OPINFO2(MAPVAR, "mapvar", 4, FALSE, NONE, NONE, NONE, PINFO(OUT, OP, MVAR), PINFO(IN, OP, IMV)) - - /* Control Flow Operations */ - OPINFO0(NOP, "nop", 4, FALSE, NONE, NONE, NONE) - OPINFO1(DEBUG, "debug", 4, FALSE, NONE, NONE, ALL, PINFO(IN, OP, IANY)) - OPINFO1(EXIT, "exit", 4, TRUE, NONE, NONE, ALL, PINFO(IN, OP, IANY)) - OPINFO3(HASHJMP, "hashjmp", 4, FALSE, NONE, NONE, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, HAND)) - OPINFO1(JMP, "jmp", 4, TRUE, NONE, NONE, NONE, PINFO(IN, OP, LAB)) - OPINFO2(EXH, "exh", 4, TRUE, NONE, NONE, ALL, PINFO(IN, OP, HAND), PINFO(IN, OP, IANY)) - OPINFO1(CALLH, "callh", 4, TRUE, NONE, NONE, ALL, PINFO(IN, OP, HAND)) - OPINFO0(RET, "ret", 4, TRUE, NONE, NONE, ALL) - OPINFO2(CALLC, "callc", 4, TRUE, NONE, NONE, ALL, PINFO(IN, OP, CFUNC), PINFO(IN, OP, PTR)) - OPINFO2(RECOVER, "recover", 4, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, MVAR)) - - /* Internal Register Operations */ - OPINFO1(SETFMOD, "setfmod", 4, FALSE, NONE, NONE, ALL, PINFO(IN, OP, IANY)) - OPINFO1(GETFMOD, "getfmod", 4, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) - OPINFO1(GETEXP, "getexp", 4, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) - OPINFO2(GETFLGS, "getflgs", 4, FALSE, P2, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IMV)) - OPINFO1(SAVE, "save", 4, FALSE, ALL, NONE, ALL, PINFO(OUT, OP, STATE)) - OPINFO1(RESTORE, "restore", 4, FALSE, NONE, ALL, ALL, PINFO(IN, OP, STATE)) - - /* Integer Operations */ - OPINFO4(LOAD, "!load", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, SCSZ)) - OPINFO4(LOADS, "!loads", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, SCSZ)) - OPINFO4(STORE, "!store", 4|8, FALSE, NONE, NONE, ALL, PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SCSZ)) - OPINFO3(READ, "!read", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, 4, IANY), PINFO(IN, OP, SPSZ)) - OPINFO4(READM, "!readm", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSZ)) - OPINFO3(WRITE, "!write", 4|8, FALSE, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSZ)) - OPINFO4(WRITEM, "!writem", 4|8, FALSE, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSZ)) - OPINFO2(CARRY, "!carry", 4|8, FALSE, NONE, C, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO2(MOV, "!mov", 4|8, TRUE, NONE, NONE, NONE, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) - OPINFO1(SET, "!set", 4|8, TRUE, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) - OPINFO3(SEXT, "!sext", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, P3, IANY), PINFO(IN, OP, SIZE)) - OPINFO4(ROLAND, "!roland", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO4(ROLINS, "!rolins", 4|8, FALSE, NONE, SZ, ALL, PINFO(INOUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(ADD, "!add", 4|8, FALSE, NONE, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(ADDC, "!addc", 4|8, FALSE, C, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(SUB, "!sub", 4|8, FALSE, NONE, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(SUBB, "!subb", 4|8, FALSE, C, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO2(CMP, "!cmp", 4|8, FALSE, NONE, SZVC, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO4(MULU, "!mulu", 4|8, FALSE, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO4(MULS, "!muls", 4|8, FALSE, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO4(DIVU, "!divu", 4|8, FALSE, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO4(DIVS, "!divs", 4|8, FALSE, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(AND, "!and", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO2(TEST, "!test", 4|8, FALSE, NONE, SZ, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(OR, "!or", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(XOR, "!xor", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO2(LZCNT, "!lzcnt", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) - OPINFO2(BSWAP, "!bswap", 4|8, FALSE, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) - OPINFO3(SHL, "!shl", 4|8, FALSE, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(SHR, "!shr", 4|8, FALSE, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(SAR, "!sar", 4|8, FALSE, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(ROL, "!rol", 4|8, FALSE, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(ROLC, "!rolc", 4|8, FALSE, C, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(ROR, "!ror", 4|8, FALSE, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - OPINFO3(RORC, "!rorc", 4|8, FALSE, C, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) - - /* Floating Point Operations */ - OPINFO3(FLOAD, "f#load", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY)) - OPINFO3(FSTORE, "f#store", 4|8, FALSE, NONE, NONE, ALL, PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, FRM)) - OPINFO3(FREAD, "f#read", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, 4, IANY), PINFO(IN, OP, SPACE)) - OPINFO3(FWRITE, "f#write", 4|8, FALSE, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, FANY), PINFO(IN, OP, SPACE)) - OPINFO2(FMOV, "f#mov", 4|8, TRUE, NONE, NONE, NONE, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) - OPINFO4(FTOINT, "f#toint", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, P3, IRM), PINFO(IN, OP, FANY), PINFO(IN, OP, SIZE), PINFO(IN, OP, FMOD)) - OPINFO3(FFRINT, "f#frint", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, IANY), PINFO(IN, OP, SIZE)) - OPINFO3(FFRFLT, "f#frflt", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, FANY), PINFO(IN, OP, SIZE)) - OPINFO2(FRNDS, "f#rnds", 8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, FANY)) - OPINFO3(FADD, "f#add", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) - OPINFO3(FSUB, "f#sub", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) - OPINFO2(FCMP, "f#cmp", 4|8, FALSE, NONE, UZC, ALL, PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) - OPINFO3(FMUL, "f#mul", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) - OPINFO3(FDIV, "f#div", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) - OPINFO2(FNEG, "f#neg", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) - OPINFO2(FABS, "f#abs", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) - OPINFO2(FSQRT, "f#sqrt", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) - OPINFO2(FRECIP, "f#recip", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) - OPINFO2(FRSQRT, "f#rsqrt", 4|8, FALSE, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) -}; - - - -/*************************************************************************** - GLOBAL VARIABLES -***************************************************************************/ - -/* we presume the existence of a C back-end interface */ -extern const drcbe_interface drcbe_c_be_interface; - -/* extern a reference to the native DRC interface if it exists */ -#ifndef NATIVE_DRC -#define NATIVE_DRC drcbe_c_be_interface -#else -extern const drcbe_interface NATIVE_DRC; -#endif - -/* table that is built up on first alloc which looks up via opcode */ -static const drcuml_opcode_info *opcode_info_table[DRCUML_OP_MAX]; - - - -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -static void optimize_block(drcuml_block *block); -static void simplify_instruction_with_no_flags(drcuml_block *block, drcuml_instruction *inst); - -static void disassemble_block(drcuml_block *block); -static const char *get_comment_text(const drcuml_instruction *inst); - -static void validate_instruction(drcuml_block *block, const drcuml_instruction *inst); - -static void validate_backend(drcuml_state *drcuml); -static void bevalidate_iterate_over_params(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, drcuml_parameter *paramlist, int pnum); -static void bevalidate_iterate_over_flags(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, drcuml_parameter *paramlist); -static void bevalidate_execute(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, const drcuml_parameter *paramlist, UINT8 flagmask); -static void bevalidate_initialize_random_state(drcuml_state *drcuml, drcuml_block *block, drcuml_machine_state *state); -static int bevalidate_populate_state(drcuml_block *block, drcuml_machine_state *state, const bevalidate_test *test, const drcuml_parameter *paramlist, drcuml_parameter *params, UINT64 *parammem); -static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_state *istate, drcuml_machine_state *state, const bevalidate_test *test, UINT32 flags, const drcuml_parameter *params, const drcuml_instruction *testinst, drccodeptr codestart, drccodeptr codeend, UINT8 flagmask); - - - -/*************************************************************************** - INLINE FUNCTIONS -***************************************************************************/ - -/*------------------------------------------------- - rol32 - perform a 32-bit left rotate --------------------------------------------------*/ - -INLINE UINT32 rol32(UINT32 source, UINT8 count) -{ - count &= 31; - return (source << count) | (source >> (32 - count)); -} - - -/*------------------------------------------------- - rol64 - perform a 64-bit left rotate --------------------------------------------------*/ - -INLINE UINT64 rol64(UINT64 source, UINT8 count) -{ - count &= 63; - return (source << count) | (source >> (64 - count)); -} - - -/*------------------------------------------------- - effective_inflags - return the effective - input flags based on any conditions encoded - in an instruction --------------------------------------------------*/ - -INLINE UINT8 effective_inflags(const drcuml_instruction *inst, const drcuml_opcode_info *opinfo) -{ - static const UINT8 flags_for_condition[] = - { - /* DRCUML_COND_Z */ DRCUML_FLAG_Z, - /* DRCUML_COND_NZ */ DRCUML_FLAG_Z, - /* DRCUML_COND_S */ DRCUML_FLAG_S, - /* DRCUML_COND_NS */ DRCUML_FLAG_S, - /* DRCUML_COND_C */ DRCUML_FLAG_C, - /* DRCUML_COND_NC */ DRCUML_FLAG_C, - /* DRCUML_COND_V */ DRCUML_FLAG_V, - /* DRCUML_COND_NV */ DRCUML_FLAG_V, - /* DRCUML_COND_U */ DRCUML_FLAG_U, - /* DRCUML_COND_NU */ DRCUML_FLAG_U, - /* DRCUML_COND_A */ DRCUML_FLAG_C | DRCUML_FLAG_Z, - /* DRCUML_COND_BE */ DRCUML_FLAG_C | DRCUML_FLAG_Z, - /* DRCUML_COND_G */ DRCUML_FLAG_S | DRCUML_FLAG_V | DRCUML_FLAG_Z, - /* DRCUML_COND_LE */ DRCUML_FLAG_S | DRCUML_FLAG_V | DRCUML_FLAG_Z, - /* DRCUML_COND_L */ DRCUML_FLAG_S | DRCUML_FLAG_V, - /* DRCUML_COND_GE */ DRCUML_FLAG_S | DRCUML_FLAG_V - }; - UINT8 flags = opinfo->inflags; - if (flags & 0x80) - flags = inst->param[flags - OPFLAGS_P1].value & OPFLAGS_ALL; - if (inst->condition != DRCUML_COND_ALWAYS) - flags |= flags_for_condition[inst->condition & 0x0f]; - return flags; -} - - -/*------------------------------------------------- - effective_outflags - return the effective - output flags based on any conditions encoded - in an instruction --------------------------------------------------*/ - -INLINE UINT8 effective_outflags(const drcuml_instruction *inst, const drcuml_opcode_info *opinfo) -{ - UINT8 flags = opinfo->outflags; - if (flags & 0x80) - flags = inst->param[flags - OPFLAGS_P1].value & OPFLAGS_ALL; - return flags; -} - - -/*------------------------------------------------- - effective_psize - return the effective - parameter size based on the instruction and - parameters passed --------------------------------------------------*/ - -INLINE UINT8 effective_psize(const drcuml_instruction *inst, const drcuml_opcode_info *opinfo, int pnum) -{ - switch (opinfo->param[pnum].size) - { - case PSIZE_4: return 4; - case PSIZE_8: return 8; - case PSIZE_OP: return inst->size; - case PSIZE_P1: assert(inst->param[0].type == DRCUML_PTYPE_IMMEDIATE); return 1 << (inst->param[0].value & 3); - case PSIZE_P2: assert(inst->param[1].type == DRCUML_PTYPE_IMMEDIATE); return 1 << (inst->param[1].value & 3); - case PSIZE_P3: assert(inst->param[2].type == DRCUML_PTYPE_IMMEDIATE); return 1 << (inst->param[2].value & 3); - case PSIZE_P4: assert(inst->param[3].type == DRCUML_PTYPE_IMMEDIATE); return 1 << (inst->param[3].value & 3); - } - return inst->size; -} - +//************************************************************************** +// DRC BACKEND INTERFACE +//************************************************************************** -/*------------------------------------------------- - effective_test_psize - return the effective - parameter size based on the size and fixed - array of parameter values --------------------------------------------------*/ +//------------------------------------------------- +// drcbe_interface - constructor +//------------------------------------------------- -INLINE UINT8 effective_test_psize(const drcuml_opcode_info *opinfo, int pnum, int instsize, const UINT64 *params) +drcbe_interface::drcbe_interface(drcuml_state &drcuml, drc_cache &cache, device_t &device) + : m_drcuml(drcuml), + m_cache(cache), + m_device(device), + m_state(*(drcuml_machine_state *)cache.alloc_near(sizeof(m_state))) { - switch (opinfo->param[pnum].size) - { - case PSIZE_4: return 4; - case PSIZE_8: return 8; - case PSIZE_OP: return instsize; - case PSIZE_P1: return 1 << (params[0] & 3); - case PSIZE_P2: return 1 << (params[1] & 3); - case PSIZE_P3: return 1 << (params[2] & 3); - case PSIZE_P4: return 1 << (params[3] & 3); - } - return instsize; -} - + // reset the machine state + memset(&m_state, 0, sizeof(m_state)); -/*------------------------------------------------- - param_is_immediate - return TRUE if the - given instruction parameter is an immediate --------------------------------------------------*/ - -INLINE int param_is_immediate(const drcuml_instruction *inst, int pnum) -{ - return (inst->param[pnum].type == DRCUML_PTYPE_IMMEDIATE); + // find the spaces and fetch memory accessors + device_memory_interface *memory; + if (device.interface(memory)) + for (int spacenum = 0; spacenum < ARRAY_LENGTH(m_space); spacenum++) + { + m_space[spacenum] = memory->space(spacenum); + if (m_space[spacenum] != NULL) + m_space[spacenum]->accessors(m_accessors[spacenum]); + } } + +//------------------------------------------------- +// ~drcbe_interface - destructor +//------------------------------------------------- -/*------------------------------------------------- - param_is_immediate_value - return TRUE if the - given instruction parameter is an immediate - with the provided value --------------------------------------------------*/ - -INLINE int param_is_immediate_value(const drcuml_instruction *inst, int pnum, UINT64 value) +drcbe_interface::~drcbe_interface() { - return (inst->param[pnum].type == DRCUML_PTYPE_IMMEDIATE && inst->param[pnum].value == value); } -/*------------------------------------------------- - param_equal - return TRUE if the two provided - parameters are equal --------------------------------------------------*/ - -INLINE int param_equal(const drcuml_instruction *inst, int pnum1, int pnum2) -{ - return (inst->param[pnum1].type == inst->param[pnum2].type && inst->param[pnum1].value == inst->param[pnum2].value); -} +//************************************************************************** +// DRCUML STATE +//************************************************************************** -/*------------------------------------------------- - convert_to_nop - convert an instruction - inline to a NOP --------------------------------------------------*/ +//------------------------------------------------- +// drcuml_state - constructor +//------------------------------------------------- -INLINE void convert_to_nop(drcuml_instruction *inst) +drcuml_state::drcuml_state(device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits) + : m_device(device), + m_cache(cache), + m_beintf((flags & DRCUML_OPTION_USE_C) ? + *static_cast<drcbe_interface *>(auto_alloc(device.machine, drcbe_c(*this, device, cache, flags, modes, addrbits, ignorebits))) : + *static_cast<drcbe_interface *>(auto_alloc(device.machine, drcbe_native(*this, device, cache, flags, modes, addrbits, ignorebits)))), + m_umllog(NULL), + m_blocklist(device.machine->m_respool), + m_symlist(device.machine->m_respool) { - inst->opcode = DRCUML_OP_NOP; - inst->size = 4; - inst->condition = DRCUML_COND_ALWAYS; - inst->numparams = 0; + // if we're to log, create the logfile + if (flags & DRCUML_OPTION_LOG_UML) + m_umllog = fopen("drcuml.asm", "w"); } -/*------------------------------------------------- - convert_to_mov_immediate - convert an - instruction inline to a MOV immediate --------------------------------------------------*/ +//------------------------------------------------- +// ~drcuml_state - destructor +//------------------------------------------------- -INLINE void convert_to_mov_immediate(drcuml_instruction *inst, UINT64 immediate) +drcuml_state::~drcuml_state() { - inst->opcode = DRCUML_OP_MOV; - inst->condition = DRCUML_COND_ALWAYS; - inst->numparams = 2; - inst->param[1].type = DRCUML_PTYPE_IMMEDIATE; - inst->param[1].value = immediate; -} - - -/*------------------------------------------------- - convert_to_mov_param - convert an - instruction inline to a MOV with a source - parameter given by the existing parameter - index pnum --------------------------------------------------*/ + // free the back-end + auto_free(m_device.machine, &m_beintf); -INLINE void convert_to_mov_param(drcuml_instruction *inst, int pnum) -{ - inst->opcode = DRCUML_OP_MOV; - inst->condition = DRCUML_COND_ALWAYS; - inst->numparams = 2; - if (pnum != 1) - inst->param[1] = inst->param[pnum]; + // close any files + if (m_umllog != NULL) + fclose(m_umllog); } +//------------------------------------------------- +// reset - reset the state completely, flushing +// the cache and all information +//------------------------------------------------- -/*************************************************************************** - INITIALIZATION/TEARDOWN -***************************************************************************/ - -/*------------------------------------------------- - drcuml_alloc - allocate state for the code - generator and initialize the back-end --------------------------------------------------*/ - -drcuml_state *drcuml_alloc(device_t *device, drc_cache *cache, UINT32 flags, int modes, int addrbits, int ignorebits) +void drcuml_state::reset() { - drcuml_state *drcuml; - int opnum; - - /* allocate state */ - drcuml = (drcuml_state *)cache->alloc(sizeof(*drcuml)); - if (drcuml == NULL) - return NULL; - memset(drcuml, 0, sizeof(*drcuml)); - - /* initialize the state */ - drcuml->device = device; - drcuml->cache = cache; - drcuml->beintf = (flags & DRCUML_OPTION_USE_C) ? &drcbe_c_be_interface : &NATIVE_DRC; - drcuml->symtailptr = &drcuml->symlist; - - /* if we're to log, create the logfile */ - if (flags & DRCUML_OPTION_LOG_UML) - drcuml->umllog = fopen("drcuml.asm", "w"); - - /* allocate the back-end */ - drcuml->bestate = (*drcuml->beintf->be_alloc)(drcuml, cache, device, flags, modes, addrbits, ignorebits); - if (drcuml->bestate == NULL) + // if we error here, we are screwed + try { - drcuml_free(drcuml); - return NULL; - } - - /* update the valid opcode table */ - for (opnum = 0; opnum < ARRAY_LENGTH(opcode_info_source); opnum++) - opcode_info_table[opcode_info_source[opnum].opcode] = &opcode_info_source[opnum]; - - return drcuml; -} - - -/*------------------------------------------------- - drcuml_get_backend_info - return information - about the back-end --------------------------------------------------*/ - -void drcuml_get_backend_info(drcuml_state *drcuml, drcbe_info *info) -{ - (*drcuml->beintf->be_get_info)(drcuml->bestate, info); -} - - -/*------------------------------------------------- - drcuml_reset - reset the state completely, - flushing the cache and all information --------------------------------------------------*/ - -void drcuml_reset(drcuml_state *drcuml) -{ - drcuml_codehandle *handle; - jmp_buf errorbuf; - - /* flush the cache */ - drcuml->cache->flush(); - - /* if we error here, we are screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Out of cache space in drcuml_reset"); + // flush the cache + m_cache.flush(); - /* reset all handle code pointers */ - for (handle = drcuml->handlelist; handle != NULL; handle = handle->next) - handle->code = NULL; + // reset all handle code pointers + for (code_handle *handle = m_handlelist.first(); handle != NULL; handle = handle->next()) + *handle->m_code = NULL; - /* call the backend to reset */ - (*drcuml->beintf->be_reset)(drcuml->bestate); + // call the backend to reset + m_beintf.reset(); - /* do a one-time validation if requested */ - if (VALIDATE_BACKEND) - { - static int validated = FALSE; - if (!validated) + // do a one-time validation if requested +/* if (VALIDATE_BACKEND) { - validated = TRUE; - validate_backend(drcuml); - } - } -} - - -/*------------------------------------------------- - drcuml_free - free state for the code generator - and the back-end --------------------------------------------------*/ - -void drcuml_free(drcuml_state *drcuml) -{ - /* free the back-end */ - if (drcuml->bestate != NULL) - (*drcuml->beintf->be_free)(drcuml->bestate); - - /* free all the blocks */ - while (drcuml->blocklist != NULL) - { - drcuml_block *block = drcuml->blocklist; - - /* remove the item from the list */ - drcuml->blocklist = block->next; - - /* free memory */ - if (block->inst != NULL) - auto_free(drcuml->device->machine, block->inst); - auto_free(drcuml->device->machine, block); + static bool validated = false; + if (!validated) + { + validated = true; + validate_backend(this); + } + }*/ } - - /* free all the symbols */ - while (drcuml->symlist != NULL) + catch (drcuml_block::abort_compilation &) { - drcuml_symbol *sym = drcuml->symlist; - drcuml->symlist = sym->next; - auto_free(drcuml->device->machine, sym); + fatalerror("Out of cache space in drcuml_state::reset"); } - - /* close any files */ - if (drcuml->umllog != NULL) - fclose(drcuml->umllog); } +//------------------------------------------------- +// begin_block - begin a new code block +//------------------------------------------------- -/*************************************************************************** - CODE BLOCK GENERATION -***************************************************************************/ - -/*------------------------------------------------- - drcuml_block_begin - begin a new code block --------------------------------------------------*/ - -drcuml_block *drcuml_block_begin(drcuml_state *drcuml, UINT32 maxinst, jmp_buf *errorbuf) +drcuml_block *drcuml_state::begin_block(UINT32 maxinst) { + // find an inactive block that matches our qualifications drcuml_block *bestblock = NULL; - drcuml_block *block; - - /* find an inactive block that matches our qualifications */ - for (block = drcuml->blocklist; block != NULL; block = block->next) - if (!block->inuse && block->maxinst >= maxinst && (bestblock == NULL || block->maxinst < bestblock->maxinst)) + for (drcuml_block *block = m_blocklist.first(); block != NULL; block = block->next()) + if (!block->inuse() && block->maxinst() >= maxinst && (bestblock == NULL || block->maxinst() < bestblock->maxinst())) bestblock = block; - /* if we failed to find one, allocate a new one */ + // if we failed to find one, allocate a new one if (bestblock == NULL) - { - /* allocate the block structure itself */ - bestblock = auto_alloc_clear(drcuml->device->machine, drcuml_block); - - /* fill in the structure */ - bestblock->drcuml = drcuml; - bestblock->next = drcuml->blocklist; - bestblock->maxinst = maxinst * 3 / 2; - bestblock->inst = auto_alloc_array(drcuml->device->machine, drcuml_instruction, bestblock->maxinst); - - /* hook us into the list */ - drcuml->blocklist = bestblock; - } - - /* set up the block information and return it */ - bestblock->inuse = TRUE; - bestblock->nextinst = 0; - bestblock->errorbuf = errorbuf; + bestblock = &m_blocklist.append(*auto_alloc(m_device.machine, drcuml_block(*this, maxinst * 3/2))); + // start the block + bestblock->begin(); return bestblock; } -/*------------------------------------------------- - drcuml_block_append_0 - append an opcode with - 0 parameters to the block --------------------------------------------------*/ +//------------------------------------------------- +// handle_alloc - allocate a new handle +//------------------------------------------------- -void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition) +code_handle *drcuml_state::handle_alloc(const char *name) { - drcuml_instruction *inst = &block->inst[block->nextinst++]; - - assert(block->inuse); - - /* get a pointer to the next instruction */ - if (block->nextinst > block->maxinst) - fatalerror("Overran maxinst in drcuml_block_append"); - - /* fill in the instruction */ - inst->opcode = (drcuml_opcode)(UINT8)op; - inst->size = size; - inst->condition = condition; - inst->flags = 0; - inst->numparams = 0; - - /* validation */ - validate_instruction(block, inst); + // allocate the handle, add it to our list, and return it + return &m_handlelist.append(*auto_alloc(m_device.machine, code_handle(*this, name))); } -/*------------------------------------------------- - drcuml_block_append_1 - append an opcode with - 1 parameter to the block --------------------------------------------------*/ +//------------------------------------------------- +// symbol_add - add a symbol to the internal +// symbol table +//------------------------------------------------- -void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value) +void drcuml_state::symbol_add(void *base, UINT32 length, const char *name) { - drcuml_instruction *inst = &block->inst[block->nextinst++]; - - assert(block->inuse); - - /* get a pointer to the next instruction */ - if (block->nextinst > block->maxinst) - fatalerror("Overran maxinst in drcuml_block_append"); - - /* fill in the instruction */ - inst->opcode = (drcuml_opcode)(UINT8)op; - inst->size = size; - inst->condition = condition; - inst->flags = 0; - inst->numparams = 1; - inst->param[0].type = p0type; - inst->param[0].value = p0value; - - /* validation */ - validate_instruction(block, inst); + m_symlist.append(*auto_alloc(m_device.machine, symbol(base, length, name))); } -/*------------------------------------------------- - drcuml_block_append_2 - append an opcode with - 2 parameters to the block --------------------------------------------------*/ +//------------------------------------------------- +// symbol_find - look up a symbol from the +// internal symbol table or return NULL if not +// found +//------------------------------------------------- -void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value) +const char *drcuml_state::symbol_find(void *base, UINT32 *offset) { - drcuml_instruction *inst = &block->inst[block->nextinst++]; - - assert(block->inuse); - - /* get a pointer to the next instruction */ - if (block->nextinst > block->maxinst) - fatalerror("Overran maxinst in drcuml_block_append"); - - /* fill in the instruction */ - inst->opcode = (drcuml_opcode)(UINT8)op; - inst->size = size; - inst->condition = condition; - inst->flags = 0; - inst->numparams = 2; - inst->param[0].type = p0type; - inst->param[0].value = p0value; - inst->param[1].type = p1type; - inst->param[1].value = p1value; - - /* validation */ - validate_instruction(block, inst); -} + drccodeptr search = drccodeptr(base); + // simple linear search + for (symbol *cursym = m_symlist.first(); cursym != NULL; cursym = cursym->next()) + if (search >= cursym->m_base && search < cursym->m_base + cursym->m_length) + { + // if no offset pointer, only match perfectly + if (offset == NULL && search != cursym->m_base) + continue; -/*------------------------------------------------- - drcuml_block_append_3 - append an opcode with - 3 parameters to the block --------------------------------------------------*/ - -void drcuml_block_append_3(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value) -{ - drcuml_instruction *inst = &block->inst[block->nextinst++]; - - assert(block->inuse); - - /* get a pointer to the next instruction */ - if (block->nextinst > block->maxinst) - fatalerror("Overran maxinst in drcuml_block_append"); - - /* fill in the instruction */ - inst->opcode = (drcuml_opcode)(UINT8)op; - inst->size = size; - inst->condition = condition; - inst->flags = 0; - inst->numparams = 3; - inst->param[0].type = p0type; - inst->param[0].value = p0value; - inst->param[1].type = p1type; - inst->param[1].value = p1value; - inst->param[2].type = p2type; - inst->param[2].value = p2value; - - /* validation */ - validate_instruction(block, inst); -} - - -/*------------------------------------------------- - drcuml_block_append_4 - append an opcode with - 4 parameters to the block --------------------------------------------------*/ - -void drcuml_block_append_4(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value, drcuml_ptype p3type, drcuml_pvalue p3value) -{ - drcuml_instruction *inst = &block->inst[block->nextinst++]; - - assert(block->inuse); - - /* get a pointer to the next instruction */ - if (block->nextinst > block->maxinst) - fatalerror("Overran maxinst in drcuml_block_append"); - - /* fill in the instruction */ - inst->opcode = (drcuml_opcode)(UINT8)op; - inst->size = size; - inst->condition = condition; - inst->flags = 0; - inst->numparams = 4; - inst->param[0].type = p0type; - inst->param[0].value = p0value; - inst->param[1].type = p1type; - inst->param[1].value = p1value; - inst->param[2].type = p2type; - inst->param[2].value = p2value; - inst->param[3].type = p3type; - inst->param[3].value = p3value; - - /* validation */ - validate_instruction(block, inst); -} - - -/*------------------------------------------------- - drcuml_block_end - complete a code block and - commit it to the cache via the back-end --------------------------------------------------*/ - -void drcuml_block_end(drcuml_block *block) -{ - drcuml_state *drcuml = block->drcuml; - - assert(block->inuse); - - /* optimize the resulting code first */ - optimize_block(block); - - /* if we have a logfile, generate a disassembly of the block */ - if (drcuml->umllog != NULL) - disassemble_block(block); - - /* generate the code via the back-end */ - (*drcuml->beintf->be_generate)(drcuml->bestate, block, block->inst, block->nextinst); - - /* block is no longer in use */ - block->inuse = FALSE; -} - - -/*------------------------------------------------- - drcuml_block_abort - abort a code block in - progress --------------------------------------------------*/ - -void drcuml_block_abort(drcuml_block *block) -{ - assert(block->inuse); - - /* block is no longer in use */ - block->inuse = FALSE; - - /* unwind */ - longjmp(*block->errorbuf, 1); -} - - -/*------------------------------------------------- - drcuml_hash_exists - return true if a hash - entry exists for the given mode/pc --------------------------------------------------*/ - -int drcuml_hash_exists(drcuml_state *drcuml, UINT32 mode, UINT32 pc) -{ - return (*drcuml->beintf->be_hash_exists)(drcuml->bestate, mode, pc); -} - - - -/*************************************************************************** - CODE EXECUTION -***************************************************************************/ - -/*------------------------------------------------- - drcuml_execute - execute at the given PC/mode - for the specified cycles --------------------------------------------------*/ + // return the offset and name + if (offset != NULL) + *offset = search - cursym->m_base; + return cursym->m_name; + } -int drcuml_execute(drcuml_state *drcuml, drcuml_codehandle *entry) -{ - return (*drcuml->beintf->be_execute)(drcuml->bestate, entry); + // not found; return NULL + return NULL; } +//------------------------------------------------- +// log_printf - directly printf to the UML log +// if generated +//------------------------------------------------- -/*************************************************************************** - CODE HANDLES -***************************************************************************/ - -/*------------------------------------------------- - drcuml_handle_alloc - allocate a new handle --------------------------------------------------*/ - -drcuml_codehandle *drcuml_handle_alloc(drcuml_state *drcuml, const char *name) +void drcuml_state::log_printf(const char *format, ...) { - drcuml_codehandle *handle; - char *string; - - /* allocate space for a copy of the string */ - string = (char *)drcuml->cache->alloc(strlen(name) + 1); - if (string == NULL) - return NULL; - strcpy(string, name); - - /* allocate a new handle info */ - handle = (drcuml_codehandle *)drcuml->cache->alloc_near(sizeof(*handle)); - if (handle == NULL) + // if we have a file, print to it + if (m_umllog != NULL) { - drcuml->cache->dealloc(string, strlen(name) + 1); - return NULL; - } - memset(handle, 0, sizeof(*handle)); - - /* fill in the rest of the info and add to the list of handles */ - handle->drcuml = drcuml; - handle->string = string; - handle->next = drcuml->handlelist; - drcuml->handlelist = handle; + va_list va; - return handle; + // do the printf + va_start(va, format); + vfprintf(m_umllog, format, va); + va_end(va); + } } -/*------------------------------------------------- - drcuml_handle_set_codeptr - set a codeptr - associated with a handle --------------------------------------------------*/ -void drcuml_handle_set_codeptr(drcuml_codehandle *handle, drccodeptr code) -{ - assert(handle->code == NULL); - assert_in_cache(handle->drcuml->cache, code); - handle->code = code; -} +//************************************************************************** +// DRCUML BLOCK +//************************************************************************** +//------------------------------------------------- +// drcuml_block - constructor +//------------------------------------------------- -/*------------------------------------------------- - drcuml_handle_codeptr - get the pointer from - a handle --------------------------------------------------*/ - -drccodeptr drcuml_handle_codeptr(const drcuml_codehandle *handle) +drcuml_block::drcuml_block(drcuml_state &drcuml, UINT32 maxinst) + : m_drcuml(drcuml), + m_next(NULL), + m_nextinst(0), + m_maxinst(maxinst * 3/2), + m_inst(auto_alloc_array(drcuml.device().machine, instruction, m_maxinst)), + m_inuse(false) { - return handle->code; } -/*------------------------------------------------- - drcuml_handle_codeptr_addr - get the address - of the pointer from a handle --------------------------------------------------*/ +//------------------------------------------------- +// ~drcuml_block - destructor +//------------------------------------------------- -drccodeptr *drcuml_handle_codeptr_addr(drcuml_codehandle *handle) +drcuml_block::~drcuml_block() { - return &handle->code; + // free the instruction list + auto_free(m_drcuml.device().machine, m_inst); } -/*------------------------------------------------- - drcuml_handle_name - get the name of a handle --------------------------------------------------*/ +//------------------------------------------------- +// begin - begin code generation +//------------------------------------------------- -const char *drcuml_handle_name(const drcuml_codehandle *handle) +void drcuml_block::begin() { - return handle->string; + // set up the block information and return it + m_inuse = true; + m_nextinst = 0; } +//------------------------------------------------- +// end - complete a code block and commit it to +// the cache via the back-end +//------------------------------------------------- -/*************************************************************************** - CODE LOGGING -***************************************************************************/ - -/*------------------------------------------------- - drcuml_symbol_add - add a symbol to the - internal symbol table --------------------------------------------------*/ - -void drcuml_symbol_add(drcuml_state *drcuml, void *base, UINT32 length, const char *name) +void drcuml_block::end() { - drcuml_symbol *symbol; + assert(m_inuse); + + // optimize the resulting code first + optimize(); - /* allocate memory to hold the symbol */ - symbol = (drcuml_symbol *)auto_alloc_array(drcuml->device->machine, UINT8, sizeof(*symbol) + strlen(name)); + // if we have a logfile, generate a disassembly of the block + if (m_drcuml.logging()) + disassemble(); - /* fill in the structure */ - symbol->next = NULL; - symbol->base = (drccodeptr)base; - symbol->length = length; - strcpy(symbol->symname, name); + // generate the code via the back-end + m_drcuml.generate(*this, m_inst, m_nextinst); - /* add to the tail of the list */ - *drcuml->symtailptr = symbol; - drcuml->symtailptr = &symbol->next; + // block is no longer in use + m_inuse = false; } -/*------------------------------------------------- - drcuml_symbol_find - look up a symbol from the - internal symbol table or return NULL if not - found --------------------------------------------------*/ +//------------------------------------------------- +// abort - abort a code block in progress +//------------------------------------------------- -const char *drcuml_symbol_find(drcuml_state *drcuml, void *base, UINT32 *offset) +void drcuml_block::abort() { - drccodeptr search = (drccodeptr)base; - drcuml_symbol *symbol; + assert(m_inuse); - /* simple linear search */ - for (symbol = drcuml->symlist; symbol != NULL; symbol = symbol->next) - if (search >= symbol->base && search < symbol->base + symbol->length) - { - /* if no offset pointer, only match perfectly */ - if (offset == NULL && search != symbol->base) - continue; - - /* return the offset and name */ - if (offset != NULL) - *offset = search - symbol->base; - return symbol->symname; - } + // block is no longer in use + m_inuse = false; - /* not found; return NULL */ - return NULL; + // unwind + throw abort_compilation(); } -/*------------------------------------------------- - drcuml_log_printf - directly printf to the UML - log if generated --------------------------------------------------*/ +//------------------------------------------------- +// append - append an opcode to the block +//------------------------------------------------- -void drcuml_log_printf(drcuml_state *drcuml, const char *format, ...) +uml::instruction &drcuml_block::append() { - /* if we have a file, print to it */ - if (drcuml->umllog != NULL) - { - va_list va; - - /* do the printf */ - va_start(va, format); - vfprintf(drcuml->umllog, format, va); - va_end(va); - } + // get a pointer to the next instruction + instruction &curinst = m_inst[m_nextinst++]; + if (m_nextinst > m_maxinst) + fatalerror("Overran maxinst in drcuml_block_append"); + + return curinst; } -/*------------------------------------------------- - drcuml_add_comment - attach a comment to the - current output location in the specified block --------------------------------------------------*/ +//------------------------------------------------- +// comment - attach a comment to the current +// output location in the specified block +//------------------------------------------------- -void drcuml_add_comment(drcuml_block *block, const char *format, ...) +void drcuml_block::append_comment(const char *format, ...) { - char buffer[512]; - char *comment; + // do the printf + astring temp; va_list va; - - assert(block->inuse); - - /* do the printf */ va_start(va, format); - vsprintf(buffer, format, va); + temp.vprintf(format, va); va_end(va); - /* allocate space in the cache to hold the comment */ - comment = (char *)block->drcuml->cache->alloc_temporary(strlen(buffer) + 1); + // allocate space in the cache to hold the comment + char *comment = (char *)m_drcuml.cache().alloc_temporary(temp.len() + 1); if (comment == NULL) return; - strcpy(comment, buffer); + strcpy(comment, temp); - /* add an instruction with a pointer */ - drcuml_block_append_1(block, DRCUML_OP_COMMENT, 4, DRCUML_COND_ALWAYS, MEM(comment)); + // add an instruction with a pointer + append().comment(comment); } -/*------------------------------------------------- - drcuml_disasm - disassemble an - instruction to the given buffer --------------------------------------------------*/ +//------------------------------------------------- +// optimize - apply various optimizations to a +// block of code +//------------------------------------------------- -void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drcuml_state *drcuml) +void drcuml_block::optimize() { - static const char *const conditions[] = { "z", "nz", "s", "ns", "c", "nc", "v", "nv", "u", "nu", "a", "be", "g", "le", "l", "ge" }; - static const char *const pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" }; - static const char *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" }; - static const char *const fmods[] = { "trunc", "round", "ceil", "floor", "default" }; - static const char *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" }; - static const char *const sizes[] = { "byte", "word", "dword", "qword" }; - const drcuml_opcode_info *opinfo = opcode_info_table[inst->opcode]; - char *dest = buffer; - const char *opsrc; - int pnum; + UINT32 mapvar[MAPVAR_COUNT] = { 0 }; - assert(inst->opcode != DRCUML_OP_INVALID && inst->opcode < DRCUML_OP_MAX); - - /* start with the raw mnemonic and substitute sizes */ - for (opsrc = opinfo->mnemonic; *opsrc != 0; opsrc++) - if (*opsrc == '!') - dest += sprintf(dest, "%s", bang_size[inst->size]); - else if (*opsrc == '#') - dest += sprintf(dest, "%s", pound_size[inst->size]); - else - *dest++ = *opsrc; - - /* pad to 8 spaces */ - while (dest < &buffer[8]) - *dest++ = ' '; - - /* iterate through parameters */ - for (pnum = 0; pnum < inst->numparams; pnum++) + // iterate over instructions + for (int instnum = 0; instnum < m_nextinst; instnum++) { - const drcuml_parameter *param = &inst->param[pnum]; - UINT16 typemask = opinfo->param[pnum].typemask; - const char *symbol; - UINT32 symoffset; + instruction &inst = m_inst[instnum]; - /* start with a comma for all except the first parameter */ - if (pnum != 0) - *dest++ = ','; + // first compute what flags we need + UINT8 accumflags = 0; + UINT8 remainingflags = inst.output_flags(); - /* ouput based on type */ - switch (param->type) + // scan ahead until we run out of possible remaining flags + for (int scannum = instnum + 1; remainingflags != 0 && scannum < m_nextinst; scannum++) { - /* immediates have several special cases */ - case DRCUML_PTYPE_IMMEDIATE: - - /* size immediate */ - if (typemask == PTYPES_SIZE) - dest += sprintf(dest, "%s", sizes[param->value]); - - /* address space immediate */ - else if (typemask == PTYPES_SPACE) - dest += sprintf(dest, "%s", spaces[param->value]); - - /* size + address space immediate */ - else if (typemask == PTYPES_SPSZ) - dest += sprintf(dest, "%s_%s", spaces[param->value / 16], sizes[param->value % 16]); - - /* size + scale immediate */ - else if (typemask == PTYPES_SCSZ) - { - int scale = param->value / 16; - int size = param->value % 16; - if (scale == size) - dest += sprintf(dest, "%s", sizes[size]); - else - dest += sprintf(dest, "%s_x%d", sizes[size], 1 << scale); - } - - /* fmod immediate */ - else if (typemask == PTYPES_FMOD) - dest += sprintf(dest, "%s", fmods[param->value]); - - /* general immediate */ - else - { - int size = effective_psize(inst, opinfo, pnum); - UINT64 value = param->value; - - /* truncate to size */ - if (size == 1) value = (UINT8)value; - if (size == 2) value = (UINT16)value; - if (size == 4) value = (UINT32)value; - if ((UINT32)value == value) - dest += sprintf(dest, "$%X", (UINT32)value); - else - dest += sprintf(dest, "$%X%08X", (UINT32)(value >> 32), (UINT32)value); - } - break; - - /* integer registers */ - case DRCUML_PTYPE_INT_REGISTER: - if (param->value >= DRCUML_REG_I0 && param->value < DRCUML_REG_I_END) - dest += sprintf(dest, "i%d", (UINT32)(param->value - DRCUML_REG_I0)); - else - dest += sprintf(dest, "i(%X?)", (UINT32)param->value); - break; - - /* floating point registers */ - case DRCUML_PTYPE_FLOAT_REGISTER: - if (param->value >= DRCUML_REG_F0 && param->value < DRCUML_REG_F_END) - dest += sprintf(dest, "f%d", (UINT32)(param->value - DRCUML_REG_F0)); - else - dest += sprintf(dest, "f(%X?)", (UINT32)param->value); - break; - - /* map variables */ - case DRCUML_PTYPE_MAPVAR: - if (param->value >= DRCUML_MAPVAR_M0 && param->value < DRCUML_MAPVAR_END) - dest += sprintf(dest, "m%d", (UINT32)(param->value - DRCUML_MAPVAR_M0)); - else - dest += sprintf(dest, "m(%X?)", (UINT32)param->value); - break; + // any input flags are required + const instruction &scan = m_inst[scannum]; + accumflags |= scan.input_flags(); - /* memory */ - case DRCUML_PTYPE_MEMORY: - - /* handle pointer */ - if (typemask == PTYPES_HAND) - dest += sprintf(dest, "%s", drcuml_handle_name((const drcuml_codehandle *)(FPTR)param->value)); - - /* string pointer */ - else if (typemask == PTYPES_STR) - dest += sprintf(dest, "%s", (const char *)(FPTR)param->value); - - /* symbol */ - else if (drcuml != NULL && (symbol = drcuml_symbol_find(drcuml, (drccodeptr)(FPTR)param->value, &symoffset)) != NULL) - { - if (symoffset == 0) - dest += sprintf(dest, "[%s]", symbol); - else - dest += sprintf(dest, "[%s+$%X]", symbol, symoffset); - } - - /* cache memory */ - else if (drcuml != NULL && drcuml->cache->contains_pointer((void *)(FPTR)param->value)) - dest += sprintf(dest, "[+$%X]", (UINT32)(FPTR)((drccodeptr)(FPTR)param->value - drcuml->cache->near())); - - /* general memory */ - else - dest += sprintf(dest, "[[$%p]]", (void *)(FPTR)param->value); - break; - - default: - dest += sprintf(dest, "???"); - break; + // if the scanahead instruction is unconditional, assume his flags are modified + if (scan.condition() == COND_ALWAYS) + remainingflags &= ~scan.modified_flags(); } - } - - /* if there's a condition, append it */ - if (inst->condition != DRCUML_COND_ALWAYS) - dest += sprintf(dest, ",%s", conditions[inst->condition & 0x0f]); - - /* if there are flags, append them */ - if (inst->flags != 0) - { - *dest++ = ','; - if (inst->flags & DRCUML_FLAG_U) - *dest++ = 'U'; - if (inst->flags & DRCUML_FLAG_S) - *dest++ = 'S'; - if (inst->flags & DRCUML_FLAG_Z) - *dest++ = 'Z'; - if (inst->flags & DRCUML_FLAG_V) - *dest++ = 'V'; - if (inst->flags & DRCUML_FLAG_C) - *dest++ = 'C'; - } - - /* ensure we are NULL-terminated */ - *dest = 0; -} - - - -/*************************************************************************** - CODE BLOCK OPTIMIZATION -***************************************************************************/ - -/*------------------------------------------------- - optimize_block - apply various optimizations - to a block of code --------------------------------------------------*/ - -static void optimize_block(drcuml_block *block) -{ - UINT32 mapvar[DRCUML_MAPVAR_END - DRCUML_MAPVAR_M0] = { 0 }; - int instnum; - - /* iterate over instructions */ - for (instnum = 0; instnum < block->nextinst; instnum++) - { - drcuml_instruction *inst = &block->inst[instnum]; - const drcuml_opcode_info *opinfo = opcode_info_table[inst->opcode]; - UINT8 remainingflags; - int scannum, pnum; - - /* first compute what flags we need */ - inst->flags = 0; - remainingflags = effective_outflags(inst, opinfo); - - /* scan ahead until we run out of possible remaining flags */ - for (scannum = instnum + 1; remainingflags != 0 && scannum < block->nextinst; scannum++) - { - const drcuml_instruction *scan = &block->inst[scannum]; - const drcuml_opcode_info *scaninfo = opcode_info_table[scan->opcode]; - - /* any input flags are required */ - inst->flags |= effective_inflags(scan, scaninfo); - - /* if the scanahead instruction is unconditional, assume his flags are modified */ - if (scan->condition == DRCUML_COND_ALWAYS) - remainingflags &= ~scaninfo->modflags; - } - - /* track mapvars */ - if (inst->opcode == DRCUML_OP_MAPVAR) - mapvar[inst->param[0].value - DRCUML_MAPVAR_M0] = inst->param[1].value; - - /* convert all mapvar parameters to immediates */ - else if (inst->opcode != DRCUML_OP_RECOVER) - for (pnum = 0; pnum < inst->numparams; pnum++) - if (inst->param[pnum].type == DRCUML_PTYPE_MAPVAR) - { - inst->param[pnum].type = DRCUML_PTYPE_IMMEDIATE; - inst->param[pnum].value = mapvar[inst->param[pnum].value - DRCUML_MAPVAR_M0]; - } - - /* if we don't need any flags, then we can eliminate a lot of dumb operations */ - if (inst->flags == 0) - simplify_instruction_with_no_flags(block, inst); - } -} - - -/*------------------------------------------------- - simplify_instruction_with_no_flags - simplify - instructions that have immediate values we - can evaluate at compile time --------------------------------------------------*/ - -static void simplify_instruction_with_no_flags(drcuml_block *block, drcuml_instruction *inst) -{ - static const UINT64 instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, U64(0xffffffffffffffff) }; - static const UINT64 paramsizemask[] = { 0xff, 0xffff, 0xffffffff, U64(0xffffffffffffffff) }; - drcuml_opcode origop = inst->opcode; - drcuml_instruction orig = *inst; - - switch (inst->opcode) - { - /* READM: convert to READ if the mask is wide open */ - case DRCUML_OP_READM: - if (param_is_immediate_value(inst, 2, paramsizemask[inst->param[3].value] & 3)) - { - inst->opcode = DRCUML_OP_READ; - inst->numparams = 3; - inst->param[2] = inst->param[3]; - } - break; - - /* WRITEM: convert to WRITE if the mask is wide open */ - case DRCUML_OP_WRITEM: - if (param_is_immediate_value(inst, 2, paramsizemask[inst->param[3].value] & 3)) - { - inst->opcode = DRCUML_OP_WRITE; - inst->numparams = 3; - inst->param[2] = inst->param[3]; - } - break; - - /* SET: convert to MOV if constant condition */ - case DRCUML_OP_SET: - if (inst->condition == DRCUML_COND_ALWAYS) - convert_to_mov_immediate(inst, 1); - break; - - /* MOV: convert to NOP if move-to-self */ - case DRCUML_OP_MOV: - if (param_equal(inst, 0, 1)) - convert_to_nop(inst); - break; - - /* SEXT: convert immediates to MOV */ - case DRCUML_OP_SEXT: - if (param_is_immediate(inst, 1)) - switch (inst->param[2].value) - { - case DRCUML_SIZE_BYTE: convert_to_mov_immediate(inst, (INT8)inst->param[1].value); break; - case DRCUML_SIZE_WORD: convert_to_mov_immediate(inst, (INT16)inst->param[1].value); break; - case DRCUML_SIZE_DWORD: convert_to_mov_immediate(inst, (INT32)inst->param[1].value); break; - case DRCUML_SIZE_QWORD: convert_to_mov_immediate(inst, (INT64)inst->param[1].value); break; - } - break; - - /* ROLAND: convert to MOV if all immediate, or to ROL or AND if one is not needed, or to SHL/SHR if the mask is right */ - case DRCUML_OP_ROLAND: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2) && param_is_immediate(inst, 3)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, rol32(inst->param[1].value, inst->param[2].value) & inst->param[3].value); - else - convert_to_mov_immediate(inst, rol64(inst->param[1].value, inst->param[2].value) & inst->param[3].value); - } - else if (param_is_immediate_value(inst, 2, 0)) - { - inst->opcode = DRCUML_OP_AND; - inst->numparams = 3; - inst->param[2] = inst->param[3]; - } - else if (param_is_immediate_value(inst, 3, instsizemask[inst->size])) - { - inst->opcode = DRCUML_OP_ROL; - inst->numparams = 3; - } - else if (param_is_immediate(inst, 2) && param_is_immediate_value(inst, 3, ((U64(0xffffffffffffffff) << inst->param[2].value) & instsizemask[inst->size]))) - { - inst->opcode = DRCUML_OP_SHL; - inst->numparams = 3; - } - else if (param_is_immediate(inst, 2) && param_is_immediate_value(inst, 3, instsizemask[inst->size] >> (8 * inst->size - inst->param[2].value))) - { - inst->opcode = DRCUML_OP_SHR; - inst->numparams = 3; - inst->param[2].value = 8 * inst->size - inst->param[2].value; - } - break; - - /* ROLINS: convert to ROLAND if the mask is full */ - case DRCUML_OP_ROLINS: - if (param_is_immediate_value(inst, 3, instsizemask[inst->size])) - inst->opcode = DRCUML_OP_ROLAND; - break; - - /* ADD: convert to MOV if immediate, or if adding 0 */ - case DRCUML_OP_ADD: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value + inst->param[2].value); - else if (param_is_immediate_value(inst, 1, 0)) - convert_to_mov_param(inst, 2); - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* SUB: convert to MOV if immediate, or if subtracting 0 */ - case DRCUML_OP_SUB: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value - inst->param[2].value); - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* CMP: no-op if no flags needed, compare i0 to i0 if the parameters are equal */ - case DRCUML_OP_CMP: - if (inst->flags == 0) - convert_to_nop(inst); - else if (param_equal(inst, 1, 2)) - { - inst->param[1].type = inst->param[2].type = DRCUML_PTYPE_INT_REGISTER; - inst->param[1].value = inst->param[2].value = DRCUML_REG_I0; - } - break; - - /* MULU: convert simple form to MOV if immediate, or if multiplying by 0 */ - case DRCUML_OP_MULU: - if (param_equal(inst, 0, 1)) - { - if (param_is_immediate_value(inst, 2, 0) || param_is_immediate_value(inst, 3, 0)) - convert_to_mov_immediate(inst, 0); - else if (param_is_immediate(inst, 2) && param_is_immediate(inst, 3)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (UINT32)((UINT32)inst->param[1].value * (UINT32)inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (UINT64)((UINT64)inst->param[1].value * (UINT64)inst->param[2].value)); - } - } - break; - - /* MULS: convert simple form to MOV if immediate, or if multiplying by 0 */ - case DRCUML_OP_MULS: - if (param_equal(inst, 0, 1)) - { - if (param_is_immediate_value(inst, 2, 0) || param_is_immediate_value(inst, 3, 0)) - convert_to_mov_immediate(inst, 0); - else if (param_is_immediate(inst, 2) && param_is_immediate(inst, 3)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (INT32)((INT32)inst->param[1].value * (INT32)inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (INT64)((INT64)inst->param[1].value * (INT64)inst->param[2].value)); - } - } - break; - - /* DIVU: convert simple form to MOV if immediate, or if dividing with 0 */ - case DRCUML_OP_DIVU: - if (param_equal(inst, 0, 1) && !param_is_immediate_value(inst, 3, 0)) - { - if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_immediate(inst, 0); - else if (param_is_immediate(inst, 2) && param_is_immediate(inst, 3)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (UINT32)((UINT32)inst->param[1].value / (UINT32)inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (UINT64)((UINT64)inst->param[1].value / (UINT64)inst->param[2].value)); - } - } - break; - - /* DIVS: convert simple form to MOV if immediate, or if dividing with 0 */ - case DRCUML_OP_DIVS: - if (param_equal(inst, 0, 1) && !param_is_immediate_value(inst, 3, 0)) - { - if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_immediate(inst, 0); - else if (param_is_immediate(inst, 2) && param_is_immediate(inst, 3)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (INT32)((INT32)inst->param[1].value / (INT32)inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (INT64)((INT64)inst->param[1].value / (INT64)inst->param[2].value)); - } - } - break; - - /* AND: convert to MOV if immediate, or if anding against 0 or 0xffffffff */ - case DRCUML_OP_AND: - if (param_is_immediate_value(inst, 1, 0) || param_is_immediate_value(inst, 2, 0)) - convert_to_mov_immediate(inst, 0); - else if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value & inst->param[2].value); - else if (param_is_immediate_value(inst, 1, instsizemask[inst->size])) - convert_to_mov_param(inst, 2); - else if (param_is_immediate_value(inst, 2, instsizemask[inst->size])) - convert_to_mov_param(inst, 1); - break; - - /* TEST: no-op if no flags needed */ - case DRCUML_OP_TEST: - if (inst->flags == 0) - convert_to_nop(inst); - break; - - /* OR: convert to MOV if immediate, or if oring against 0 or 0xffffffff */ - case DRCUML_OP_OR: - if (param_is_immediate_value(inst, 1, instsizemask[inst->size]) || param_is_immediate_value(inst, 2, instsizemask[inst->size])) - convert_to_mov_immediate(inst, instsizemask[inst->size]); - else if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value | inst->param[2].value); - else if (param_is_immediate_value(inst, 1, 0)) - convert_to_mov_param(inst, 2); - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* XOR: convert to MOV if immediate, or if xoring against 0 */ - case DRCUML_OP_XOR: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value ^ inst->param[2].value); - else if (param_is_immediate_value(inst, 1, 0)) - convert_to_mov_param(inst, 2); - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* LZCNT: convert to MOV if immediate */ - case DRCUML_OP_LZCNT: - if (param_is_immediate(inst, 1)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, count_leading_zeros(inst->param[1].value)); - else if (inst->size == 8) - { - if ((inst->param[1].value >> 32) == 0) - convert_to_mov_immediate(inst, 32 + count_leading_zeros(inst->param[1].value)); - else - convert_to_mov_immediate(inst, count_leading_zeros(inst->param[1].value >> 32)); - } - } - break; - - /* BSWAP: convert to MOV if immediate */ - case DRCUML_OP_BSWAP: - if (param_is_immediate(inst, 1)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, FLIPENDIAN_INT32(inst->param[1].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, FLIPENDIAN_INT64(inst->param[1].value)); - } - break; + inst.set_flags(accumflags); - /* SHL: convert to MOV if immediate or shifting by 0 */ - case DRCUML_OP_SHL: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - convert_to_mov_immediate(inst, inst->param[1].value << inst->param[2].value); - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; + // track mapvars + if (inst.opcode() == OP_MAPVAR) + mapvar[inst.param(0).mapvar() - MAPVAR_M0] = inst.param(1).immediate(); - /* SHR: convert to MOV if immediate or shifting by 0 */ - case DRCUML_OP_SHR: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (UINT32)inst->param[1].value >> inst->param[2].value); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (UINT64)inst->param[1].value >> inst->param[2].value); - } - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; + // convert all mapvar parameters to immediates + else if (inst.opcode() != OP_RECOVER) + for (int pnum = 0; pnum < inst.numparams(); pnum++) + if (inst.param(pnum).is_mapvar()) + inst.set_mapvar(pnum, mapvar[inst.param(pnum).mapvar() - MAPVAR_M0]); - /* SAR: convert to MOV if immediate or shifting by 0 */ - case DRCUML_OP_SAR: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, (INT32)inst->param[1].value >> inst->param[2].value); - else if (inst->size == 8) - convert_to_mov_immediate(inst, (INT64)inst->param[1].value >> inst->param[2].value); - } - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* ROL: convert to NOP if immediate or rotating by 0 */ - case DRCUML_OP_ROL: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, rol32(inst->param[1].value, inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, rol64(inst->param[1].value, inst->param[2].value)); - } - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* ROR: convert to NOP if immediate or rotating by 0 */ - case DRCUML_OP_ROR: - if (param_is_immediate(inst, 1) && param_is_immediate(inst, 2)) - { - if (inst->size == 4) - convert_to_mov_immediate(inst, rol32(inst->param[1].value, 32 - inst->param[2].value)); - else if (inst->size == 8) - convert_to_mov_immediate(inst, rol64(inst->param[1].value, 64 - inst->param[2].value)); - } - else if (param_is_immediate_value(inst, 2, 0)) - convert_to_mov_param(inst, 1); - break; - - /* FMOV: convert to NOP if move-to-self */ - case DRCUML_OP_FMOV: - if (param_equal(inst, 0, 1)) - convert_to_nop(inst); - break; - - default: - break; - } - - if (LOG_SIMPLIFICATIONS && memcmp(&orig, inst, sizeof(orig)) != 0) - { - char disasm1[256], disasm2[256]; - drcuml_disasm(&orig, disasm1, block->drcuml); - drcuml_disasm(inst, disasm2, block->drcuml); - mame_printf_debug("Simplified: %-50.50s -> %s\n", disasm1, disasm2); - } - - /* if the opcode changed, validate and reoptimize */ - if (inst->opcode != origop) - { - validate_instruction(block, inst); - simplify_instruction_with_no_flags(block, inst); + // now that flags are correct, simplify the instruction + inst.simplify(); } } +//------------------------------------------------- +// disassemble - disassemble a block of +// instructions to the log +//------------------------------------------------- -/*************************************************************************** - LOGGING HELPERS -***************************************************************************/ - -/*------------------------------------------------- - disassemble_block - disassemble a block of - instructions to the log --------------------------------------------------*/ - -static void disassemble_block(drcuml_block *block) +void drcuml_block::disassemble() { + astring comment; + astring dasm; + + // iterate over instructions and output int firstcomment = -1; - int instnum; - - /* iterate over instructions and output */ - for (instnum = 0; instnum < block->nextinst; instnum++) + for (int instnum = 0; instnum < m_nextinst; instnum++) { - const drcuml_instruction *inst = &block->inst[instnum]; - int flushcomments = FALSE; + const instruction &inst = m_inst[instnum]; + bool flushcomments = false; - /* remember comments and mapvars for later */ - if (inst->opcode == DRCUML_OP_COMMENT || inst->opcode == DRCUML_OP_MAPVAR) + // remember comments and mapvars for later + if (inst.opcode() == OP_COMMENT || inst.opcode() == OP_MAPVAR) { if (firstcomment == -1) firstcomment = instnum; } - /* print labels, handles, and hashes left justified */ - else if (inst->opcode == DRCUML_OP_LABEL) - drcuml_log_printf(block->drcuml, "$%X:\n", (UINT32)inst->param[0].value); - else if (inst->opcode == DRCUML_OP_HANDLE) - drcuml_log_printf(block->drcuml, "%s:\n", drcuml_handle_name((const drcuml_codehandle *)(FPTR)inst->param[0].value)); - else if (inst->opcode == DRCUML_OP_HASH) - drcuml_log_printf(block->drcuml, "(%X,%X):\n", (UINT32)inst->param[0].value, (UINT32)inst->param[1].value); + // print labels, handles, and hashes left justified + else if (inst.opcode() == OP_LABEL) + m_drcuml.log_printf("$%X:\n", UINT32(inst.param(0).label())); + else if (inst.opcode() == OP_HANDLE) + m_drcuml.log_printf("%s:\n", inst.param(0).handle().string()); + else if (inst.opcode() == OP_HASH) + m_drcuml.log_printf("(%X,%X):\n", UINT32(inst.param(0).immediate()), UINT32(inst.param(1).immediate())); - /* indent everything else with a tab */ + // indent everything else with a tab else { - char dasm[256]; - drcuml_disasm(&block->inst[instnum], dasm, block->drcuml); + m_inst[instnum].disasm(dasm, &m_drcuml); - /* include the first accumulated comment with this line */ + // include the first accumulated comment with this line if (firstcomment != -1) { - drcuml_log_printf(block->drcuml, "\t%-50.50s; %s\n", dasm, get_comment_text(&block->inst[firstcomment])); + m_drcuml.log_printf("\t%-50.50s; %s\n", dasm.cstr(), get_comment_text(m_inst[firstcomment], comment)); firstcomment++; flushcomments = TRUE; } else - drcuml_log_printf(block->drcuml, "\t%s\n", dasm); + m_drcuml.log_printf("\t%s\n", dasm.cstr()); } - /* flush any comments pending */ - if (firstcomment != -1 && (flushcomments || instnum == block->nextinst - 1)) + // flush any comments pending + if (firstcomment != -1 && (flushcomments || instnum == m_nextinst - 1)) { while (firstcomment <= instnum) { - const char *text = get_comment_text(&block->inst[firstcomment++]); + const char *text = get_comment_text(m_inst[firstcomment++], comment); if (text != NULL) - drcuml_log_printf(block->drcuml, "\t%50s; %s\n", "", text); + m_drcuml.log_printf("\t%50s; %s\n", "", text); } firstcomment = -1; } } - drcuml_log_printf(block->drcuml, "\n\n"); - fflush(block->drcuml->umllog); + m_drcuml.log_printf("\n\n"); + m_drcuml.log_flush(); } -/*------------------------------------------------- - get_comment_text - determine the text - associated with a comment or mapvar --------------------------------------------------*/ +//------------------------------------------------- +// get_comment_text - determine the text +// associated with a comment or mapvar +//------------------------------------------------- -static const char *get_comment_text(const drcuml_instruction *inst) +const char *drcuml_block::get_comment_text(const instruction &inst, astring &comment) { - static char tempbuf[100]; + // comments return their strings + if (inst.opcode() == OP_COMMENT) + return comment.cpy(inst.param(0).string()); - /* comments return their strings */ - if (inst->opcode == DRCUML_OP_COMMENT) - return (char *)(FPTR)inst->param[0].value; - - /* mapvars comment about their values */ - else if (inst->opcode == DRCUML_OP_MAPVAR) - { - sprintf(tempbuf, "m%d = $%X", (int)inst->param[0].value - DRCUML_MAPVAR_M0, (UINT32)inst->param[1].value); - return tempbuf; - } + // mapvars comment about their values + else if (inst.opcode() == OP_MAPVAR) + return comment.format("m%d = $%X", (int)inst.param(0).mapvar() - MAPVAR_M0, (UINT32)inst.param(1).immediate()); - /* everything else is NULL */ + // everything else is NULL return NULL; } +#if 0 + /*************************************************************************** - OPCODE VALIDATION + BACK-END VALIDATION ***************************************************************************/ -/*------------------------------------------------- - validate_instruction - verify that the - instruction created meets all requirements --------------------------------------------------*/ +//------------------------------------------------- +// effective_test_psize - return the effective +// parameter size based on the size and fixed +// array of parameter values +//------------------------------------------------- -static void validate_instruction(drcuml_block *block, const drcuml_instruction *inst) +inline UINT8 effective_test_psize(const opcode_info &opinfo, int pnum, int instsize, const UINT64 *params) { - const drcuml_opcode_info *opinfo = opcode_info_table[inst->opcode]; - int pnum; - - /* validate raw information */ - assert(inst->opcode != DRCUML_OP_INVALID && inst->opcode < DRCUML_OP_MAX); - assert(inst->size == 1 || inst->size == 2 || inst->size == 4 || inst->size == 8); - - /* validate against opcode limits */ - assert((opinfo->sizes & inst->size) != 0); - assert(inst->condition == DRCUML_COND_ALWAYS || opinfo->condition); - - /* validate each parameter */ - for (pnum = 0; pnum < inst->numparams; pnum++) + switch (opinfo.param[pnum].size) { - const drcuml_parameter *param = &inst->param[pnum]; - UINT16 typemask = opinfo->param[pnum].typemask; - - /* ensure the type is correct */ - assert(param->type > DRCUML_PTYPE_NONE && param->type < DRCUML_PTYPE_MAX); - assert((typemask >> param->type) & 1); - - /* validate various parameter types */ - switch (param->type) - { - case DRCUML_PTYPE_MEMORY: - /* most memory parameters must be in the near cache */ - if (typemask != PTYPES_PTR && typemask != PTYPES_STATE && typemask != PTYPES_STR && typemask != PTYPES_CFUNC) - assert_in_near_cache(block->drcuml->cache, (void *)(FPTR)param->value); - break; - - case DRCUML_PTYPE_IMMEDIATE: - /* many special parameter types are encoded as immediately; ensure they are in range */ - if (typemask == PTYPES_SIZE) - assert(param->value >= DRCUML_SIZE_BYTE && param->value <= DRCUML_SIZE_QWORD); - else if (typemask == PTYPES_SPACE) - assert(param->value >= ADDRESS_SPACE_PROGRAM && param->value <= ADDRESS_SPACE_IO); - else if (typemask == PTYPES_SPSZ) - { - assert(param->value % 16 >= DRCUML_SIZE_BYTE && param->value % 16 <= DRCUML_SIZE_QWORD); - assert(param->value / 16 >= ADDRESS_SPACE_PROGRAM && param->value / 16 <= ADDRESS_SPACE_IO); - } - else if (typemask == PTYPES_FMOD) - assert(param->value >= DRCUML_FMOD_TRUNC && param->value <= DRCUML_FMOD_DEFAULT); - break; - - case DRCUML_PTYPE_MAPVAR: - assert(param->value >= DRCUML_MAPVAR_M0 && param->value < DRCUML_MAPVAR_END); - break; - - case DRCUML_PTYPE_INT_REGISTER: - assert(param->value >= DRCUML_REG_I0 && param->value < DRCUML_REG_I_END); - break; - - case DRCUML_PTYPE_FLOAT_REGISTER: - assert(param->value >= DRCUML_REG_F0 && param->value < DRCUML_REG_F_END); - break; - - default: - assert(FALSE); - break; - } + case PSIZE_4: return 4; + case PSIZE_8: return 8; + case PSIZE_OP: return instsize; + case PSIZE_P1: return 1 << (params[0] & 3); + case PSIZE_P2: return 1 << (params[1] & 3); + case PSIZE_P3: return 1 << (params[2] & 3); + case PSIZE_P4: return 1 << (params[3] & 3); } - - /* make sure we aren't missing any parameters */ - if (inst->numparams < ARRAY_LENGTH(opinfo->param)) - assert(opinfo->param[inst->numparams].typemask == 0); + return instsize; } - - -/*************************************************************************** - BACK-END VALIDATION -***************************************************************************/ - -#define TEST_ENTRY_2(op, size, p1, p2, flags) { DRCUML_OP_##op, size, 0, flags, { U64(p1), U64(p2) } }, -#define TEST_ENTRY_2F(op, size, p1, p2, iflags, flags) { DRCUML_OP_##op, size, iflags, flags, { U64(p1), U64(p2) } }, -#define TEST_ENTRY_3(op, size, p1, p2, p3, flags) { DRCUML_OP_##op, size, 0, flags, { U64(p1), U64(p2), U64(p3) } }, -#define TEST_ENTRY_3F(op, size, p1, p2, p3, iflags, flags) { DRCUML_OP_##op, size, iflags, flags, { U64(p1), U64(p2), U64(p3) } }, -#define TEST_ENTRY_4(op, size, p1, p2, p3, p4, flags) { DRCUML_OP_##op, size, 0, flags, { U64(p1), U64(p2), U64(p3), U64(p4) } }, -#define TEST_ENTRY_4F(op, size, p1, p2, p3, p4, iflags, flags) { DRCUML_OP_##op, size, iflags, flags, { U64(p1), U64(p2), U64(p3), U64(p4) } }, +#define TEST_ENTRY_2(op, size, p1, p2, flags) { OP_##op, size, 0, flags, { U64(p1), U64(p2) } }, +#define TEST_ENTRY_2F(op, size, p1, p2, iflags, flags) { OP_##op, size, iflags, flags, { U64(p1), U64(p2) } }, +#define TEST_ENTRY_3(op, size, p1, p2, p3, flags) { OP_##op, size, 0, flags, { U64(p1), U64(p2), U64(p3) } }, +#define TEST_ENTRY_3F(op, size, p1, p2, p3, iflags, flags) { OP_##op, size, iflags, flags, { U64(p1), U64(p2), U64(p3) } }, +#define TEST_ENTRY_4(op, size, p1, p2, p3, p4, flags) { OP_##op, size, 0, flags, { U64(p1), U64(p2), U64(p3), U64(p4) } }, +#define TEST_ENTRY_4F(op, size, p1, p2, p3, p4, iflags, flags) { OP_##op, size, iflags, flags, { U64(p1), U64(p2), U64(p3), U64(p4) } }, static const bevalidate_test bevalidate_test_list[] = { TEST_ENTRY_3(ADD, 4, 0x7fffffff, 0x12345678, 0x6dcba987, 0) - TEST_ENTRY_3(ADD, 4, 0x80000000, 0x12345678, 0x6dcba988, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3(ADD, 4, 0xffffffff, 0x92345678, 0x6dcba987, DRCUML_FLAG_S) - TEST_ENTRY_3(ADD, 4, 0x00000000, 0x92345678, 0x6dcba988, DRCUML_FLAG_C | DRCUML_FLAG_Z) + TEST_ENTRY_3(ADD, 4, 0x80000000, 0x12345678, 0x6dcba988, FLAG_V | FLAG_S) + TEST_ENTRY_3(ADD, 4, 0xffffffff, 0x92345678, 0x6dcba987, FLAG_S) + TEST_ENTRY_3(ADD, 4, 0x00000000, 0x92345678, 0x6dcba988, FLAG_C | FLAG_Z) TEST_ENTRY_3(ADD, 8, 0x7fffffffffffffff, 0x0123456789abcdef, 0x7edcba9876543210, 0) - TEST_ENTRY_3(ADD, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543211, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3(ADD, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba9876543210, DRCUML_FLAG_S) - TEST_ENTRY_3(ADD, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543211, DRCUML_FLAG_C | DRCUML_FLAG_Z) + TEST_ENTRY_3(ADD, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543211, FLAG_V | FLAG_S) + TEST_ENTRY_3(ADD, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba9876543210, FLAG_S) + TEST_ENTRY_3(ADD, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543211, FLAG_C | FLAG_Z) TEST_ENTRY_3F(ADDC, 4, 0x7fffffff, 0x12345678, 0x6dcba987, 0, 0) - TEST_ENTRY_3F(ADDC, 4, 0x7fffffff, 0x12345678, 0x6dcba986, DRCUML_FLAG_C, 0) - TEST_ENTRY_3F(ADDC, 4, 0x80000000, 0x12345678, 0x6dcba988, 0, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 4, 0x80000000, 0x12345678, 0x6dcba987, DRCUML_FLAG_C, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 4, 0xffffffff, 0x92345678, 0x6dcba987, 0, DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 4, 0xffffffff, 0x92345678, 0x6dcba986, DRCUML_FLAG_C, DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 4, 0x00000000, 0x92345678, 0x6dcba988, 0, DRCUML_FLAG_C | DRCUML_FLAG_Z) - TEST_ENTRY_3F(ADDC, 4, 0x00000000, 0x92345678, 0x6dcba987, DRCUML_FLAG_C, DRCUML_FLAG_C | DRCUML_FLAG_Z) - TEST_ENTRY_3F(ADDC, 4, 0x12345678, 0x12345678, 0xffffffff, DRCUML_FLAG_C, DRCUML_FLAG_C) + TEST_ENTRY_3F(ADDC, 4, 0x7fffffff, 0x12345678, 0x6dcba986, FLAG_C, 0) + TEST_ENTRY_3F(ADDC, 4, 0x80000000, 0x12345678, 0x6dcba988, 0, FLAG_V | FLAG_S) + TEST_ENTRY_3F(ADDC, 4, 0x80000000, 0x12345678, 0x6dcba987, FLAG_C, FLAG_V | FLAG_S) + TEST_ENTRY_3F(ADDC, 4, 0xffffffff, 0x92345678, 0x6dcba987, 0, FLAG_S) + TEST_ENTRY_3F(ADDC, 4, 0xffffffff, 0x92345678, 0x6dcba986, FLAG_C, FLAG_S) + TEST_ENTRY_3F(ADDC, 4, 0x00000000, 0x92345678, 0x6dcba988, 0, FLAG_C | FLAG_Z) + TEST_ENTRY_3F(ADDC, 4, 0x00000000, 0x92345678, 0x6dcba987, FLAG_C, FLAG_C | FLAG_Z) + TEST_ENTRY_3F(ADDC, 4, 0x12345678, 0x12345678, 0xffffffff, FLAG_C, FLAG_C) TEST_ENTRY_3F(ADDC, 8, 0x7fffffffffffffff, 0x0123456789abcdef, 0x7edcba9876543210, 0, 0) - TEST_ENTRY_3F(ADDC, 8, 0x7fffffffffffffff, 0x0123456789abcdef, 0x7edcba987654320f, DRCUML_FLAG_C, 0) - TEST_ENTRY_3F(ADDC, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543211, 0, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543210, DRCUML_FLAG_C, DRCUML_FLAG_V | DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba9876543210, 0, DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba987654320f, DRCUML_FLAG_C, DRCUML_FLAG_S) - TEST_ENTRY_3F(ADDC, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543211, 0, DRCUML_FLAG_C | DRCUML_FLAG_Z) - TEST_ENTRY_3F(ADDC, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543210, DRCUML_FLAG_C, DRCUML_FLAG_C | DRCUML_FLAG_Z) - TEST_ENTRY_3F(ADDC, 8, 0x123456789abcdef0, 0x123456789abcdef0, 0xffffffffffffffff, DRCUML_FLAG_C, DRCUML_FLAG_C) + TEST_ENTRY_3F(ADDC, 8, 0x7fffffffffffffff, 0x0123456789abcdef, 0x7edcba987654320f, FLAG_C, 0) + TEST_ENTRY_3F(ADDC, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543211, 0, FLAG_V | FLAG_S) + TEST_ENTRY_3F(ADDC, 8, 0x8000000000000000, 0x0123456789abcdef, 0x7edcba9876543210, FLAG_C, FLAG_V | FLAG_S) + TEST_ENTRY_3F(ADDC, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba9876543210, 0, FLAG_S) + TEST_ENTRY_3F(ADDC, 8, 0xffffffffffffffff, 0x8123456789abcdef, 0x7edcba987654320f, FLAG_C, FLAG_S) + TEST_ENTRY_3F(ADDC, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543211, 0, FLAG_C | FLAG_Z) + TEST_ENTRY_3F(ADDC, 8, 0x0000000000000000, 0x8123456789abcdef, 0x7edcba9876543210, FLAG_C, FLAG_C | FLAG_Z) + TEST_ENTRY_3F(ADDC, 8, 0x123456789abcdef0, 0x123456789abcdef0, 0xffffffffffffffff, FLAG_C, FLAG_C) TEST_ENTRY_3(SUB, 4, 0x12345678, 0x7fffffff, 0x6dcba987, 0) - TEST_ENTRY_3(SUB, 4, 0x12345678, 0x80000000, 0x6dcba988, DRCUML_FLAG_V) - TEST_ENTRY_3(SUB, 4, 0x92345678, 0xffffffff, 0x6dcba987, DRCUML_FLAG_S) - TEST_ENTRY_3(SUB, 4, 0x92345678, 0x00000000, 0x6dcba988, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3(SUB, 4, 0x00000000, 0x12345678, 0x12345678, DRCUML_FLAG_Z) + TEST_ENTRY_3(SUB, 4, 0x12345678, 0x80000000, 0x6dcba988, FLAG_V) + TEST_ENTRY_3(SUB, 4, 0x92345678, 0xffffffff, 0x6dcba987, FLAG_S) + TEST_ENTRY_3(SUB, 4, 0x92345678, 0x00000000, 0x6dcba988, FLAG_C | FLAG_S) + TEST_ENTRY_3(SUB, 4, 0x00000000, 0x12345678, 0x12345678, FLAG_Z) TEST_ENTRY_3(SUB, 8, 0x0123456789abcdef, 0x7fffffffffffffff, 0x7edcba9876543210, 0) - TEST_ENTRY_3(SUB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543211, DRCUML_FLAG_V) - TEST_ENTRY_3(SUB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba9876543210, DRCUML_FLAG_S) - TEST_ENTRY_3(SUB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543211, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3(SUB, 8, 0x0000000000000000, 0x0123456789abcdef, 0x0123456789abcdef, DRCUML_FLAG_Z) + TEST_ENTRY_3(SUB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543211, FLAG_V) + TEST_ENTRY_3(SUB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba9876543210, FLAG_S) + TEST_ENTRY_3(SUB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543211, FLAG_C | FLAG_S) + TEST_ENTRY_3(SUB, 8, 0x0000000000000000, 0x0123456789abcdef, 0x0123456789abcdef, FLAG_Z) TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x7fffffff, 0x6dcba987, 0, 0) - TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x7fffffff, 0x6dcba986, DRCUML_FLAG_C, 0) - TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x80000000, 0x6dcba988, 0, DRCUML_FLAG_V) - TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x80000000, 0x6dcba987, DRCUML_FLAG_C, DRCUML_FLAG_V) - TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0xffffffff, 0x6dcba987, 0, DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0xffffffff, 0x6dcba986, DRCUML_FLAG_C, DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0x00000000, 0x6dcba988, 0, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0x00000000, 0x6dcba987, DRCUML_FLAG_C, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x12345678, 0xffffffff, DRCUML_FLAG_C, DRCUML_FLAG_C) - TEST_ENTRY_3F(SUBB, 4, 0x00000000, 0x12345678, 0x12345677, DRCUML_FLAG_C, DRCUML_FLAG_Z) + TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x7fffffff, 0x6dcba986, FLAG_C, 0) + TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x80000000, 0x6dcba988, 0, FLAG_V) + TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x80000000, 0x6dcba987, FLAG_C, FLAG_V) + TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0xffffffff, 0x6dcba987, 0, FLAG_S) + TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0xffffffff, 0x6dcba986, FLAG_C, FLAG_S) + TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0x00000000, 0x6dcba988, 0, FLAG_C | FLAG_S) + TEST_ENTRY_3F(SUBB, 4, 0x92345678, 0x00000000, 0x6dcba987, FLAG_C, FLAG_C | FLAG_S) + TEST_ENTRY_3F(SUBB, 4, 0x12345678, 0x12345678, 0xffffffff, FLAG_C, FLAG_C) + TEST_ENTRY_3F(SUBB, 4, 0x00000000, 0x12345678, 0x12345677, FLAG_C, FLAG_Z) TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x7fffffffffffffff, 0x7edcba9876543210, 0, 0) - TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x7fffffffffffffff, 0x7edcba987654320f, DRCUML_FLAG_C, 0) - TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543211, 0, DRCUML_FLAG_V) - TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543210, DRCUML_FLAG_C, DRCUML_FLAG_V) - TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba9876543210, 0, DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba987654320f, DRCUML_FLAG_C, DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543211, 0, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543210, DRCUML_FLAG_C, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_3F(SUBB, 8, 0x123456789abcdef0, 0x123456789abcdef0, 0xffffffffffffffff, DRCUML_FLAG_C, DRCUML_FLAG_C) - TEST_ENTRY_3F(SUBB, 8, 0x0000000000000000, 0x123456789abcdef0, 0x123456789abcdeef, DRCUML_FLAG_C, DRCUML_FLAG_Z) + TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x7fffffffffffffff, 0x7edcba987654320f, FLAG_C, 0) + TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543211, 0, FLAG_V) + TEST_ENTRY_3F(SUBB, 8, 0x0123456789abcdef, 0x8000000000000000, 0x7edcba9876543210, FLAG_C, FLAG_V) + TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba9876543210, 0, FLAG_S) + TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0xffffffffffffffff, 0x7edcba987654320f, FLAG_C, FLAG_S) + TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543211, 0, FLAG_C | FLAG_S) + TEST_ENTRY_3F(SUBB, 8, 0x8123456789abcdef, 0x0000000000000000, 0x7edcba9876543210, FLAG_C, FLAG_C | FLAG_S) + TEST_ENTRY_3F(SUBB, 8, 0x123456789abcdef0, 0x123456789abcdef0, 0xffffffffffffffff, FLAG_C, FLAG_C) + TEST_ENTRY_3F(SUBB, 8, 0x0000000000000000, 0x123456789abcdef0, 0x123456789abcdeef, FLAG_C, FLAG_Z) TEST_ENTRY_2(CMP, 4, 0x7fffffff, 0x6dcba987, 0) - TEST_ENTRY_2(CMP, 4, 0x80000000, 0x6dcba988, DRCUML_FLAG_V) - TEST_ENTRY_2(CMP, 4, 0xffffffff, 0x6dcba987, DRCUML_FLAG_S) - TEST_ENTRY_2(CMP, 4, 0x00000000, 0x6dcba988, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_2(CMP, 4, 0x12345678, 0x12345678, DRCUML_FLAG_Z) + TEST_ENTRY_2(CMP, 4, 0x80000000, 0x6dcba988, FLAG_V) + TEST_ENTRY_2(CMP, 4, 0xffffffff, 0x6dcba987, FLAG_S) + TEST_ENTRY_2(CMP, 4, 0x00000000, 0x6dcba988, FLAG_C | FLAG_S) + TEST_ENTRY_2(CMP, 4, 0x12345678, 0x12345678, FLAG_Z) TEST_ENTRY_2(CMP, 8, 0x7fffffffffffffff, 0x7edcba9876543210, 0) - TEST_ENTRY_2(CMP, 8, 0x8000000000000000, 0x7edcba9876543211, DRCUML_FLAG_V) - TEST_ENTRY_2(CMP, 8, 0xffffffffffffffff, 0x7edcba9876543210, DRCUML_FLAG_S) - TEST_ENTRY_2(CMP, 8, 0x0000000000000000, 0x7edcba9876543211, DRCUML_FLAG_C | DRCUML_FLAG_S) - TEST_ENTRY_2(CMP, 8, 0x0123456789abcdef, 0x0123456789abcdef, DRCUML_FLAG_Z) + TEST_ENTRY_2(CMP, 8, 0x8000000000000000, 0x7edcba9876543211, FLAG_V) + TEST_ENTRY_2(CMP, 8, 0xffffffffffffffff, 0x7edcba9876543210, FLAG_S) + TEST_ENTRY_2(CMP, 8, 0x0000000000000000, 0x7edcba9876543211, FLAG_C | FLAG_S) + TEST_ENTRY_2(CMP, 8, 0x0123456789abcdef, 0x0123456789abcdef, FLAG_Z) TEST_ENTRY_4(MULU, 4, 0x77777777, 0x00000000, 0x11111111, 0x00000007, 0) TEST_ENTRY_4(MULU, 4, 0xffffffff, 0x00000000, 0x11111111, 0x0000000f, 0) - TEST_ENTRY_4(MULU, 4, 0x00000000, 0x00000000, 0x11111111, 0x00000000, DRCUML_FLAG_Z) - TEST_ENTRY_4(MULU, 4, 0xea61d951, 0x37c048d0, 0x77777777, 0x77777777, DRCUML_FLAG_V) - TEST_ENTRY_4(MULU, 4, 0x32323233, 0xcdcdcdcc, 0xcdcdcdcd, 0xffffffff, DRCUML_FLAG_V | DRCUML_FLAG_S) + TEST_ENTRY_4(MULU, 4, 0x00000000, 0x00000000, 0x11111111, 0x00000000, FLAG_Z) + TEST_ENTRY_4(MULU, 4, 0xea61d951, 0x37c048d0, 0x77777777, 0x77777777, FLAG_V) + TEST_ENTRY_4(MULU, 4, 0x32323233, 0xcdcdcdcc, 0xcdcdcdcd, 0xffffffff, FLAG_V | FLAG_S) TEST_ENTRY_4(MULU, 8, 0x7777777777777777, 0x0000000000000000, 0x1111111111111111, 0x0000000000000007, 0) TEST_ENTRY_4(MULU, 8, 0xffffffffffffffff, 0x0000000000000000, 0x1111111111111111, 0x000000000000000f, 0) - TEST_ENTRY_4(MULU, 8, 0x0000000000000000, 0x0000000000000000, 0x1111111111111111, 0x0000000000000000, DRCUML_FLAG_Z) - TEST_ENTRY_4(MULU, 8, 0x0c83fb72ea61d951, 0x37c048d159e26af3, 0x7777777777777777, 0x7777777777777777, DRCUML_FLAG_V) - TEST_ENTRY_4(MULU, 8, 0x3232323232323233, 0xcdcdcdcdcdcdcdcc, 0xcdcdcdcdcdcdcdcd, 0xffffffffffffffff, DRCUML_FLAG_V | DRCUML_FLAG_S) + TEST_ENTRY_4(MULU, 8, 0x0000000000000000, 0x0000000000000000, 0x1111111111111111, 0x0000000000000000, FLAG_Z) + TEST_ENTRY_4(MULU, 8, 0x0c83fb72ea61d951, 0x37c048d159e26af3, 0x7777777777777777, 0x7777777777777777, FLAG_V) + TEST_ENTRY_4(MULU, 8, 0x3232323232323233, 0xcdcdcdcdcdcdcdcc, 0xcdcdcdcdcdcdcdcd, 0xffffffffffffffff, FLAG_V | FLAG_S) TEST_ENTRY_4(MULS, 4, 0x77777777, 0x00000000, 0x11111111, 0x00000007, 0) - TEST_ENTRY_4(MULS, 4, 0xffffffff, 0x00000000, 0x11111111, 0x0000000f, DRCUML_FLAG_V) - TEST_ENTRY_4(MULS, 4, 0x00000000, 0x00000000, 0x11111111, 0x00000000, DRCUML_FLAG_Z) - TEST_ENTRY_4(MULS, 4, 0x9e26af38, 0xc83fb72e, 0x77777777, 0x88888888, DRCUML_FLAG_V | DRCUML_FLAG_S) + TEST_ENTRY_4(MULS, 4, 0xffffffff, 0x00000000, 0x11111111, 0x0000000f, FLAG_V) + TEST_ENTRY_4(MULS, 4, 0x00000000, 0x00000000, 0x11111111, 0x00000000, FLAG_Z) + TEST_ENTRY_4(MULS, 4, 0x9e26af38, 0xc83fb72e, 0x77777777, 0x88888888, FLAG_V | FLAG_S) TEST_ENTRY_4(MULS, 4, 0x32323233, 0x00000000, 0xcdcdcdcd, 0xffffffff, 0) TEST_ENTRY_4(MULS, 8, 0x7777777777777777, 0x0000000000000000, 0x1111111111111111, 0x0000000000000007, 0) - TEST_ENTRY_4(MULS, 8, 0xffffffffffffffff, 0x0000000000000000, 0x1111111111111111, 0x000000000000000f, DRCUML_FLAG_V) - TEST_ENTRY_4(MULS, 8, 0x0000000000000000, 0x0000000000000000, 0x1111111111111111, 0x0000000000000000, DRCUML_FLAG_Z) - TEST_ENTRY_4(MULS, 8, 0x7c048d159e26af38, 0xc83fb72ea61d950c, 0x7777777777777777, 0x8888888888888888, DRCUML_FLAG_V | DRCUML_FLAG_S) + TEST_ENTRY_4(MULS, 8, 0xffffffffffffffff, 0x0000000000000000, 0x1111111111111111, 0x000000000000000f, FLAG_V) + TEST_ENTRY_4(MULS, 8, 0x0000000000000000, 0x0000000000000000, 0x1111111111111111, 0x0000000000000000, FLAG_Z) + TEST_ENTRY_4(MULS, 8, 0x7c048d159e26af38, 0xc83fb72ea61d950c, 0x7777777777777777, 0x8888888888888888, FLAG_V | FLAG_S) TEST_ENTRY_4(MULS, 8, 0x3232323232323233, 0x0000000000000000, 0xcdcdcdcdcdcdcdcd, 0xffffffffffffffff, 0) TEST_ENTRY_4(DIVU, 4, 0x02702702, 0x00000003, 0x11111111, 0x00000007, 0) - TEST_ENTRY_4(DIVU, 4, 0x00000000, 0x11111111, 0x11111111, 0x11111112, DRCUML_FLAG_Z) + TEST_ENTRY_4(DIVU, 4, 0x00000000, 0x11111111, 0x11111111, 0x11111112, FLAG_Z) TEST_ENTRY_4(DIVU, 4, 0x7fffffff, 0x00000000, 0xfffffffe, 0x00000002, 0) - TEST_ENTRY_4(DIVU, 4, 0xfffffffe, 0x00000000, 0xfffffffe, 0x00000001, DRCUML_FLAG_S) - TEST_ENTRY_4(DIVU, 4, UNDEFINED, UNDEFINED, 0xffffffff, 0x00000000, DRCUML_FLAG_V) + TEST_ENTRY_4(DIVU, 4, 0xfffffffe, 0x00000000, 0xfffffffe, 0x00000001, FLAG_S) + TEST_ENTRY_4(DIVU, 4, UNDEFINED, UNDEFINED, 0xffffffff, 0x00000000, FLAG_V) TEST_ENTRY_4(DIVU, 8, 0x0270270270270270, 0x0000000000000001, 0x1111111111111111, 0x0000000000000007, 0) - TEST_ENTRY_4(DIVU, 8, 0x0000000000000000, 0x1111111111111111, 0x1111111111111111, 0x1111111111111112, DRCUML_FLAG_Z) + TEST_ENTRY_4(DIVU, 8, 0x0000000000000000, 0x1111111111111111, 0x1111111111111111, 0x1111111111111112, FLAG_Z) TEST_ENTRY_4(DIVU, 8, 0x7fffffffffffffff, 0x0000000000000000, 0xfffffffffffffffe, 0x0000000000000002, 0) - TEST_ENTRY_4(DIVU, 8, 0xfffffffffffffffe, 0x0000000000000000, 0xfffffffffffffffe, 0x0000000000000001, DRCUML_FLAG_S) - TEST_ENTRY_4(DIVU, 8, UNDEFINED, UNDEFINED, 0xffffffffffffffff, 0x0000000000000000, DRCUML_FLAG_V) + TEST_ENTRY_4(DIVU, 8, 0xfffffffffffffffe, 0x0000000000000000, 0xfffffffffffffffe, 0x0000000000000001, FLAG_S) + TEST_ENTRY_4(DIVU, 8, UNDEFINED, UNDEFINED, 0xffffffffffffffff, 0x0000000000000000, FLAG_V) TEST_ENTRY_4(DIVS, 4, 0x02702702, 0x00000003, 0x11111111, 0x00000007, 0) - TEST_ENTRY_4(DIVS, 4, 0x00000000, 0x11111111, 0x11111111, 0x11111112, DRCUML_FLAG_Z) - TEST_ENTRY_4(DIVS, 4, 0xffffffff, 0x00000000, 0xfffffffe, 0x00000002, DRCUML_FLAG_S) - TEST_ENTRY_4(DIVS, 4, UNDEFINED, UNDEFINED, 0xffffffff, 0x00000000, DRCUML_FLAG_V) + TEST_ENTRY_4(DIVS, 4, 0x00000000, 0x11111111, 0x11111111, 0x11111112, FLAG_Z) + TEST_ENTRY_4(DIVS, 4, 0xffffffff, 0x00000000, 0xfffffffe, 0x00000002, FLAG_S) + TEST_ENTRY_4(DIVS, 4, UNDEFINED, UNDEFINED, 0xffffffff, 0x00000000, FLAG_V) TEST_ENTRY_4(DIVS, 8, 0x0270270270270270, 0x0000000000000001, 0x1111111111111111, 0x0000000000000007, 0) - TEST_ENTRY_4(DIVS, 8, 0x0000000000000000, 0x1111111111111111, 0x1111111111111111, 0x1111111111111112, DRCUML_FLAG_Z) - TEST_ENTRY_4(DIVS, 8, 0xffffffffffffffff, 0x0000000000000000, 0xfffffffffffffffe, 0x0000000000000002, DRCUML_FLAG_S) - TEST_ENTRY_4(DIVS, 8, UNDEFINED, UNDEFINED, 0xffffffffffffffff, 0x0000000000000000, DRCUML_FLAG_V) + TEST_ENTRY_4(DIVS, 8, 0x0000000000000000, 0x1111111111111111, 0x1111111111111111, 0x1111111111111112, FLAG_Z) + TEST_ENTRY_4(DIVS, 8, 0xffffffffffffffff, 0x0000000000000000, 0xfffffffffffffffe, 0x0000000000000002, FLAG_S) + TEST_ENTRY_4(DIVS, 8, UNDEFINED, UNDEFINED, 0xffffffffffffffff, 0x0000000000000000, FLAG_V) }; @@ -2029,26 +730,26 @@ static const bevalidate_test bevalidate_test_list[] = static void validate_backend(drcuml_state *drcuml) { - drcuml_codehandle *handles[3]; + code_handle *handles[3]; int tnum; - /* allocate handles for the code */ - handles[0] = drcuml_handle_alloc(drcuml, "test_entry"); - handles[1] = drcuml_handle_alloc(drcuml, "code_start"); - handles[2] = drcuml_handle_alloc(drcuml, "code_end"); + // allocate handles for the code + handles[0] = drcuml->handle_alloc("test_entry"); + handles[1] = drcuml->handle_alloc("code_start"); + handles[2] = drcuml->handle_alloc("code_end"); - /* iterate over test entries */ + // iterate over test entries printf("Backend validation....\n"); for (tnum = 31; tnum < ARRAY_LENGTH(bevalidate_test_list); tnum++) { const bevalidate_test *test = &bevalidate_test_list[tnum]; - drcuml_parameter param[ARRAY_LENGTH(test->param)]; + parameter param[ARRAY_LENGTH(test->param)]; char mnemonic[20], *dst; const char *src; - /* progress */ + // progress dst = mnemonic; - for (src = opcode_info_table[test->opcode]->mnemonic; *src != 0; src++) + for (src = opcode_info_table[test->opcode()]->mnemonic; *src != 0; src++) { if (*src == '!') { @@ -2063,7 +764,7 @@ static void validate_backend(drcuml_state *drcuml) *dst = 0; printf("Executing test %d/%d (%s)", tnum + 1, (int)ARRAY_LENGTH(bevalidate_test_list), mnemonic); - /* reset parameter list and iterate */ + // reset parameter list and iterate memset(param, 0, sizeof(param)); bevalidate_iterate_over_params(drcuml, handles, test, param, 0); printf("\n"); @@ -2079,63 +780,63 @@ static void validate_backend(drcuml_state *drcuml) or else move on to iterate over the flags -------------------------------------------------*/ -static void bevalidate_iterate_over_params(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, drcuml_parameter *paramlist, int pnum) +static void bevalidate_iterate_over_params(drcuml_state *drcuml, code_handle **handles, const bevalidate_test *test, parameter *paramlist, int pnum) { - const drcuml_opcode_info *opinfo = opcode_info_table[test->opcode]; + const opcode_info *opinfo = opcode_info_table[test->opcode()]; drcuml_ptype ptype; - /* if no parameters, execute now */ + // if no parameters, execute now if (pnum >= ARRAY_LENGTH(opinfo->param) || opinfo->param[pnum].typemask == PTYPES_NONE) { bevalidate_iterate_over_flags(drcuml, handles, test, paramlist); return; } - /* iterate over valid parameter types */ - for (ptype = DRCUML_PTYPE_IMMEDIATE; ptype < DRCUML_PTYPE_MAX; ptype++) + // iterate over valid parameter types + for (ptype = parameter::PTYPE_IMMEDIATE; ptype < parameter::PTYPE_MAX; ptype++) if (opinfo->param[pnum].typemask & (1 << ptype)) { int pindex, pcount; - /* mapvars can only do 32-bit tests */ - if (ptype == DRCUML_PTYPE_MAPVAR && effective_test_psize(opinfo, pnum, test->size, test->param) == 8) + // mapvars can only do 32-bit tests + if (ptype == parameter::PTYPE_MAPVAR && effective_test_psize(opinfo, pnum, test->size, test->param) == 8) continue; - /* for some parameter types, we wish to iterate over all possibilities */ + // for some parameter types, we wish to iterate over all possibilities switch (ptype) { - case DRCUML_PTYPE_INT_REGISTER: pcount = DRCUML_REG_I_END - DRCUML_REG_I0; break; - case DRCUML_PTYPE_FLOAT_REGISTER: pcount = DRCUML_REG_F_END - DRCUML_REG_F0; break; + case parameter::PTYPE_INT_REGISTER: pcount = REG_I_END - REG_I0; break; + case parameter::PTYPE_FLOAT_REGISTER: pcount = REG_F_END - REG_F0; break; default: pcount = 1; break; } - /* iterate over possibilities */ + // iterate over possibilities for (pindex = 0; pindex < pcount; pindex++) { int skip = FALSE; int pscannum; - /* for param 0, print a dot */ + // for param 0, print a dot if (pnum == 0) printf("."); - /* can't duplicate multiple source parameters unless they are immediates */ - if (ptype != DRCUML_PTYPE_IMMEDIATE && (opinfo->param[pnum].output & PIO_IN)) + // can't duplicate multiple source parameters unless they are immediates + if (ptype != parameter::PTYPE_IMMEDIATE && (opinfo->param[pnum].output & PIO_IN)) - /* loop over all parameters we've done before; if the parameter is a source and matches us, skip this case */ + // loop over all parameters we've done before; if the parameter is a source and matches us, skip this case for (pscannum = 0; pscannum < pnum; pscannum++) if ((opinfo->param[pscannum].output & PIO_IN) && ptype == paramlist[pscannum].type && pindex == paramlist[pscannum].value) skip = TRUE; - /* can't duplicate multiple dest parameters */ + // can't duplicate multiple dest parameters if (opinfo->param[pnum].output & PIO_OUT) - /* loop over all parameters we've done before; if the parameter is a source and matches us, skip this case */ + // loop over all parameters we've done before; if the parameter is a source and matches us, skip this case for (pscannum = 0; pscannum < pnum; pscannum++) if ((opinfo->param[pscannum].output & PIO_OUT) && ptype == paramlist[pscannum].type && pindex == paramlist[pscannum].value) skip = TRUE; - /* iterate over the next parameter in line */ + // iterate over the next parameter in line if (!skip) { paramlist[pnum].type = ptype; @@ -2152,13 +853,13 @@ static void bevalidate_iterate_over_params(drcuml_state *drcuml, drcuml_codehand all supported flag masks -------------------------------------------------*/ -static void bevalidate_iterate_over_flags(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, drcuml_parameter *paramlist) +static void bevalidate_iterate_over_flags(drcuml_state *drcuml, code_handle **handles, const bevalidate_test *test, parameter *paramlist) { - const drcuml_opcode_info *opinfo = opcode_info_table[test->opcode]; + const opcode_info *opinfo = opcode_info_table[test->opcode()]; UINT8 flagmask = opinfo->outflags; UINT8 curmask; - /* iterate over all possible flag combinations */ + // iterate over all possible flag combinations for (curmask = 0; curmask <= flagmask; curmask++) if ((curmask & flagmask) == curmask) bevalidate_execute(drcuml, handles, test, paramlist, curmask); @@ -2171,54 +872,54 @@ static void bevalidate_iterate_over_flags(drcuml_state *drcuml, drcuml_codehandl results -------------------------------------------------*/ -static void bevalidate_execute(drcuml_state *drcuml, drcuml_codehandle **handles, const bevalidate_test *test, const drcuml_parameter *paramlist, UINT8 flagmask) +static void bevalidate_execute(drcuml_state *drcuml, code_handle **handles, const bevalidate_test *test, const parameter *paramlist, UINT8 flagmask) { - drcuml_parameter params[ARRAY_LENGTH(test->param)]; + parameter params[ARRAY_LENGTH(test->param)]; drcuml_machine_state istate, fstate; - drcuml_instruction testinst; + instruction testinst; drcuml_block *block; UINT64 *parammem; int numparams; - /* allocate memory for parameters */ + // allocate memory for parameters parammem = (UINT64 *)drcuml->cache->alloc_near(sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1)); - /* flush the cache */ - drcuml_reset(drcuml); + // flush the cache + drcuml->reset(); - /* start a new block */ - block = drcuml_block_begin(drcuml, 30, NULL); + // start a new block + block = drcuml->block_begin(30); UML_HANDLE(block, handles[0]); - /* set up a random initial state */ + // set up a random initial state bevalidate_initialize_random_state(drcuml, block, &istate); - /* then populate the state with the parameters */ + // then populate the state with the parameters numparams = bevalidate_populate_state(block, &istate, test, paramlist, params, parammem); - /* generate the code */ + // generate the code UML_RESTORE(block, &istate); UML_HANDLE(block, handles[1]); switch (numparams) { case 0: - drcuml_block_append_0(block, test->opcode, test->size, DRCUML_COND_ALWAYS); + block->append(test->opcode(), test->size); break; case 1: - drcuml_block_append_1(block, test->opcode, test->size, DRCUML_COND_ALWAYS, params[0].type, params[0].value); + block->append(test->opcode(), test->size, params[0]); break; case 2: - drcuml_block_append_2(block, test->opcode, test->size, DRCUML_COND_ALWAYS, params[0].type, params[0].value, params[1].type, params[1].value); + block->append(test->opcode(), test->size, params[0], params[1]); break; case 3: - drcuml_block_append_3(block, test->opcode, test->size, DRCUML_COND_ALWAYS, params[0].type, params[0].value, params[1].type, params[1].value, params[2].type, params[2].value); + block->append(test->opcode(), test->size, params[0], params[1], params[2]); break; case 4: - drcuml_block_append_4(block, test->opcode, test->size, DRCUML_COND_ALWAYS, params[0].type, params[0].value, params[1].type, params[1].value, params[2].type, params[2].value, params[3].type, params[3].value); + block->append(test->opcode(), test->size, params[0], params[1], params[2], params[3]); break; } testinst = block->inst[block->nextinst - 1]; @@ -2227,16 +928,16 @@ static void bevalidate_execute(drcuml_state *drcuml, drcuml_codehandle **handles UML_SAVE(block, &fstate); UML_EXIT(block, IMM(0)); - /* end the block */ - drcuml_block_end(block); + // end the block + block->end(); - /* execute */ - drcuml_execute(drcuml, handles[0]); + // execute + drcuml->execute(*handles[0]); - /* verify the results */ + // verify the results bevalidate_verify_state(drcuml, &istate, &fstate, test, *(UINT32 *)¶mmem[ARRAY_LENGTH(test->param)], params, &testinst, handles[1]->code, handles[2]->code, flagmask); - /* free memory */ + // free memory drcuml->cache->dealloc(parammem, sizeof(UINT64) * (ARRAY_LENGTH(test->param) + 1)); } @@ -2251,27 +952,27 @@ static void bevalidate_initialize_random_state(drcuml_state *drcuml, drcuml_bloc running_machine *machine = drcuml->device->machine; int regnum; - /* initialize core state to random values */ + // initialize core state to random values state->fmod = machine->rand() & 0x03; state->flags = machine->rand() & 0x1f; state->exp = machine->rand(); - /* initialize integer registers to random values */ + // initialize integer registers to random values for (regnum = 0; regnum < ARRAY_LENGTH(state->r); regnum++) { state->r[regnum].w.h = machine->rand(); state->r[regnum].w.l = machine->rand(); } - /* initialize float registers to random values */ + // initialize float registers to random values for (regnum = 0; regnum < ARRAY_LENGTH(state->f); regnum++) { *(UINT32 *)&state->f[regnum].s.h = machine->rand(); *(UINT32 *)&state->f[regnum].s.l = machine->rand(); } - /* initialize map variables to random values */ - for (regnum = 0; regnum < DRCUML_MAPVAR_END - DRCUML_MAPVAR_M0; regnum++) + // initialize map variables to random values + for (regnum = 0; regnum < MAPVAR_COUNT; regnum++) UML_MAPVAR(block, MVAR(regnum), machine->rand()); } @@ -2282,46 +983,46 @@ static void bevalidate_initialize_random_state(drcuml_state *drcuml, drcuml_bloc to executing a test -------------------------------------------------*/ -static int bevalidate_populate_state(drcuml_block *block, drcuml_machine_state *state, const bevalidate_test *test, const drcuml_parameter *paramlist, drcuml_parameter *params, UINT64 *parammem) +static int bevalidate_populate_state(drcuml_block *block, drcuml_machine_state *state, const bevalidate_test *test, const parameter *paramlist, parameter *params, UINT64 *parammem) { - const drcuml_opcode_info *opinfo = opcode_info_table[test->opcode]; + const opcode_info *opinfo = opcode_info_table[test->opcode()]; int numparams = ARRAY_LENGTH(test->param); int pnum; - /* copy flags as-is */ + // copy flags as-is state->flags = test->iflags; - /* iterate over parameters */ + // iterate over parameters for (pnum = 0; pnum < ARRAY_LENGTH(test->param); pnum++) { int psize = effective_test_psize(opinfo, pnum, test->size, test->param); - drcuml_parameter *curparam = ¶ms[pnum]; + parameter *curparam = ¶ms[pnum]; - /* start with a copy of the parameter from the list */ + // start with a copy of the parameter from the list *curparam = paramlist[pnum]; - /* switch off the type */ + // switch off the type switch (curparam->type) { - /* immediate parameters: take the value from the test entry */ - case DRCUML_PTYPE_IMMEDIATE: + // immediate parameters: take the value from the test entry + case parameter::PTYPE_IMMEDIATE: curparam->value = test->param[pnum]; break; - /* register parameters: set the register value in the state and set the parameter value to the register index */ - case DRCUML_PTYPE_INT_REGISTER: + // register parameters: set the register value in the state and set the parameter value to the register index + case parameter::PTYPE_INT_REGISTER: state->r[curparam->value].d = test->param[pnum]; - curparam->value += DRCUML_REG_I0; + curparam->value += REG_I0; break; - /* register parameters: set the register value in the state and set the parameter value to the register index */ - case DRCUML_PTYPE_FLOAT_REGISTER: + // register parameters: set the register value in the state and set the parameter value to the register index + case parameter::PTYPE_FLOAT_REGISTER: state->f[curparam->value].d = test->param[pnum]; - curparam->value += DRCUML_REG_F0; + curparam->value += REG_F0; break; - /* memory parameters: set the memory value in the parameter space and set the parameter value to point to it */ - case DRCUML_PTYPE_MEMORY: + // memory parameters: set the memory value in the parameter space and set the parameter value to point to it + case parameter::PTYPE_MEMORY: curparam->value = (FPTR)¶mmem[pnum]; if (psize == 4) *(UINT32 *)(FPTR)curparam->value = test->param[pnum]; @@ -2329,20 +1030,20 @@ static int bevalidate_populate_state(drcuml_block *block, drcuml_machine_state * *(UINT64 *)(FPTR)curparam->value = test->param[pnum]; break; - /* map variables: issue a MAPVAR instruction to set the value and set the parameter value to the mapvar index */ - case DRCUML_PTYPE_MAPVAR: + // map variables: issue a MAPVAR instruction to set the value and set the parameter value to the mapvar index + case parameter::PTYPE_MAPVAR: UML_MAPVAR(block, MVAR(curparam->value), test->param[pnum]); - curparam->value += DRCUML_MAPVAR_M0; + curparam->value += MAPVAR_M0; break; - /* use anything else to count the number of parameters */ + // use anything else to count the number of parameters default: numparams = MIN(numparams, pnum); break; } } - /* return the total number of parameters */ + // return the total number of parameters return numparams; } @@ -2353,34 +1054,34 @@ static int bevalidate_populate_state(drcuml_block *block, drcuml_machine_state * discrepancies -------------------------------------------------*/ -static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_state *istate, drcuml_machine_state *state, const bevalidate_test *test, UINT32 flags, const drcuml_parameter *params, const drcuml_instruction *testinst, drccodeptr codestart, drccodeptr codeend, UINT8 flagmask) +static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_state *istate, drcuml_machine_state *state, const bevalidate_test *test, UINT32 flags, const parameter *params, const instruction *testinst, drccodeptr codestart, drccodeptr codeend, UINT8 flagmask) { - const drcuml_opcode_info *opinfo = opcode_info_table[test->opcode]; - UINT8 ireg[DRCUML_REG_I_END - DRCUML_REG_I0] = { 0 }; - UINT8 freg[DRCUML_REG_F_END - DRCUML_REG_F0] = { 0 }; + const opcode_info *opinfo = opcode_info_table[test->opcode()]; + UINT8 ireg[REG_I_END - REG_I0] = { 0 }; + UINT8 freg[REG_F_END - REG_F0] = { 0 }; char errorbuf[1024]; char *errend = errorbuf; int pnum, regnum; *errend = 0; - /* check flags */ + // check flags if (flags != (test->flags & flagmask)) { errend += sprintf(errend, " Flags ... result:%c%c%c%c%c expected:%c%c%c%c%c\n", - (flagmask & DRCUML_FLAG_U) ? ((flags & DRCUML_FLAG_U) ? 'U' : '.') : '-', - (flagmask & DRCUML_FLAG_S) ? ((flags & DRCUML_FLAG_S) ? 'S' : '.') : '-', - (flagmask & DRCUML_FLAG_Z) ? ((flags & DRCUML_FLAG_Z) ? 'Z' : '.') : '-', - (flagmask & DRCUML_FLAG_V) ? ((flags & DRCUML_FLAG_V) ? 'V' : '.') : '-', - (flagmask & DRCUML_FLAG_C) ? ((flags & DRCUML_FLAG_C) ? 'C' : '.') : '-', - (flagmask & DRCUML_FLAG_U) ? ((test->flags & DRCUML_FLAG_U) ? 'U' : '.') : '-', - (flagmask & DRCUML_FLAG_S) ? ((test->flags & DRCUML_FLAG_S) ? 'S' : '.') : '-', - (flagmask & DRCUML_FLAG_Z) ? ((test->flags & DRCUML_FLAG_Z) ? 'Z' : '.') : '-', - (flagmask & DRCUML_FLAG_V) ? ((test->flags & DRCUML_FLAG_V) ? 'V' : '.') : '-', - (flagmask & DRCUML_FLAG_C) ? ((test->flags & DRCUML_FLAG_C) ? 'C' : '.') : '-'); + (flagmask & FLAG_U) ? ((flags & FLAG_U) ? 'U' : '.') : '-', + (flagmask & FLAG_S) ? ((flags & FLAG_S) ? 'S' : '.') : '-', + (flagmask & FLAG_Z) ? ((flags & FLAG_Z) ? 'Z' : '.') : '-', + (flagmask & FLAG_V) ? ((flags & FLAG_V) ? 'V' : '.') : '-', + (flagmask & FLAG_C) ? ((flags & FLAG_C) ? 'C' : '.') : '-', + (flagmask & FLAG_U) ? ((test->flags & FLAG_U) ? 'U' : '.') : '-', + (flagmask & FLAG_S) ? ((test->flags & FLAG_S) ? 'S' : '.') : '-', + (flagmask & FLAG_Z) ? ((test->flags & FLAG_Z) ? 'Z' : '.') : '-', + (flagmask & FLAG_V) ? ((test->flags & FLAG_V) ? 'V' : '.') : '-', + (flagmask & FLAG_C) ? ((test->flags & FLAG_C) ? 'C' : '.') : '-'); } - /* check destination parameters */ + // check destination parameters for (pnum = 0; pnum < ARRAY_LENGTH(test->param); pnum++) if (opinfo->param[pnum].output & PIO_OUT) { @@ -2388,23 +1089,23 @@ static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_st UINT64 mask = U64(0xffffffffffffffff) >> (64 - 8 * psize); UINT64 result = 0; - /* fetch the result from the parameters */ + // fetch the result from the parameters switch (params[pnum].type) { - /* integer registers fetch from the state */ - case DRCUML_PTYPE_INT_REGISTER: - ireg[params[pnum].value - DRCUML_REG_I0] = 1; - result = state->r[params[pnum].value - DRCUML_REG_I0].d; + // integer registers fetch from the state + case parameter::PTYPE_INT_REGISTER: + ireg[params[pnum].value - REG_I0] = 1; + result = state->r[params[pnum].value - REG_I0].d; break; - /* float registers fetch from the state */ - case DRCUML_PTYPE_FLOAT_REGISTER: - freg[params[pnum].value - DRCUML_REG_I0] = 1; - result = state->f[params[pnum].value - DRCUML_REG_F0].d; + // float registers fetch from the state + case parameter::PTYPE_FLOAT_REGISTER: + freg[params[pnum].value - REG_I0] = 1; + result = state->f[params[pnum].value - REG_F0].d; break; - /* memory registers fetch from the memory address */ - case DRCUML_PTYPE_MEMORY: + // memory registers fetch from the memory address + case parameter::PTYPE_MEMORY: if (psize == 4) result = *(UINT32 *)(FPTR)params[pnum].value; else @@ -2415,7 +1116,7 @@ static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_st break; } - /* check against the mask */ + // check against the mask if (test->param[pnum] != UNDEFINED_U64 && (result & mask) != (test->param[pnum] & mask)) { if ((UINT32)mask == mask) @@ -2428,29 +1129,29 @@ static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_st } } - /* check source integer parameters for unexpected alterations */ + // check source integer parameters for unexpected alterations for (regnum = 0; regnum < ARRAY_LENGTH(state->r); regnum++) if (ireg[regnum] == 0 && istate->r[regnum].d != state->r[regnum].d) errend += sprintf(errend, " Register i%d ... result:%08X%08X originally:%08X%08X\n", regnum, (UINT32)(state->r[regnum].d >> 32), (UINT32)state->r[regnum].d, (UINT32)(istate->r[regnum].d >> 32), (UINT32)istate->r[regnum].d); - /* check source float parameters for unexpected alterations */ + // check source float parameters for unexpected alterations for (regnum = 0; regnum < ARRAY_LENGTH(state->f); regnum++) if (freg[regnum] == 0 && *(UINT64 *)&istate->f[regnum].d != *(UINT64 *)&state->f[regnum].d) errend += sprintf(errend, " Register f%d ... result:%08X%08X originally:%08X%08X\n", regnum, (UINT32)(*(UINT64 *)&state->f[regnum].d >> 32), (UINT32)*(UINT64 *)&state->f[regnum].d, (UINT32)(*(UINT64 *)&istate->f[regnum].d >> 32), (UINT32)*(UINT64 *)&istate->f[regnum].d); - /* output the error if we have one */ + // output the error if we have one if (errend != errorbuf) { char disasm[256]; - /* disassemble the test instruction */ - drcuml_disasm(testinst, disasm, drcuml); + // disassemble the test instruction + testinst->disasm(disasm, drcuml); - /* output a description of what went wrong */ + // output a description of what went wrong printf("\n"); printf("----------------------------------------------\n"); printf("Backend validation error:\n"); @@ -2462,3 +1163,5 @@ static int bevalidate_verify_state(drcuml_state *drcuml, const drcuml_machine_st } return errend != errorbuf; } + +#endif diff --git a/src/emu/cpu/drcuml.h b/src/emu/cpu/drcuml.h index 9e2d5bc9ac4..25517cbcd27 100644 --- a/src/emu/cpu/drcuml.h +++ b/src/emu/cpu/drcuml.h @@ -4,9 +4,36 @@ Universal machine language for dynamic recompiling CPU cores. +**************************************************************************** + Copyright Aaron Giles - Released for general non-commercial use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. ***************************************************************************/ @@ -16,516 +43,225 @@ #define __DRCUML_H__ #include "drccache.h" -#include <setjmp.h> - - -/*************************************************************************** - CONSTANTS -***************************************************************************/ - -/* these options are passed into drcuml_alloc() and control global behaviors */ -#define DRCUML_OPTION_USE_C 0x0001 /* always use the C back-end */ -#define DRCUML_OPTION_LOG_UML 0x0002 /* generate a UML disassembly of each block */ -#define DRCUML_OPTION_LOG_NATIVE 0x0004 /* tell the back-end to generate a native disassembly of each block */ - - -/* opcode parameter types */ -enum _drcuml_ptype -{ - DRCUML_PTYPE_NONE = 0, - DRCUML_PTYPE_IMMEDIATE, - DRCUML_PTYPE_INT_REGISTER, - DRCUML_PTYPE_FLOAT_REGISTER, - DRCUML_PTYPE_MAPVAR, - DRCUML_PTYPE_MEMORY, - DRCUML_PTYPE_MAX -}; -typedef enum _drcuml_ptype drcuml_ptype; -DECLARE_ENUM_OPERATORS(drcuml_ptype) - - -/* these define the registers for the UML */ -enum -{ - DRCUML_REG_INVALID = 0, /* 0 is invalid */ - - /* integer registers */ - DRCUML_REG_I0 = 0x400, - DRCUML_REG_I1, - DRCUML_REG_I2, - DRCUML_REG_I3, - DRCUML_REG_I4, - DRCUML_REG_I5, - DRCUML_REG_I6, - DRCUML_REG_I7, - DRCUML_REG_I8, - DRCUML_REG_I9, - DRCUML_REG_I_END, - - /* floating point registers */ - DRCUML_REG_F0 = 0x800, - DRCUML_REG_F1, - DRCUML_REG_F2, - DRCUML_REG_F3, - DRCUML_REG_F4, - DRCUML_REG_F5, - DRCUML_REG_F6, - DRCUML_REG_F7, - DRCUML_REG_F8, - DRCUML_REG_F9, - DRCUML_REG_F_END, - - /* map variables */ - DRCUML_MAPVAR_M0 = 0xc00, - DRCUML_MAPVAR_M1, - DRCUML_MAPVAR_M2, - DRCUML_MAPVAR_M3, - DRCUML_MAPVAR_M4, - DRCUML_MAPVAR_M5, - DRCUML_MAPVAR_M6, - DRCUML_MAPVAR_M7, - DRCUML_MAPVAR_M8, - DRCUML_MAPVAR_M9, - DRCUML_MAPVAR_END -}; - - -/* UML flag definitions */ -enum -{ - DRCUML_FLAG_C = 1, /* carry flag */ - DRCUML_FLAG_V = 2, /* overflow flag (defined for integer only) */ - DRCUML_FLAG_Z = 4, /* zero flag */ - DRCUML_FLAG_S = 8, /* sign flag (defined for integer only) */ - DRCUML_FLAG_U = 16 /* unordered flag (defined for FP only) */ -}; - - -/* these define the conditions for the UML */ -/* note that these are defined such that (condition ^ 1) is always the opposite */ -/* they are also defined so as not to conflict with the flag bits above */ -enum -{ - DRCUML_COND_ALWAYS = 0, - - DRCUML_COND_Z = 0x80, /* requires Z */ - DRCUML_COND_NZ, /* requires Z */ - DRCUML_COND_S, /* requires S */ - DRCUML_COND_NS, /* requires S */ - DRCUML_COND_C, /* requires C */ - DRCUML_COND_NC, /* requires C */ - DRCUML_COND_V, /* requires V */ - DRCUML_COND_NV, /* requires V */ - DRCUML_COND_U, /* requires U */ - DRCUML_COND_NU, /* requires U */ - DRCUML_COND_A, /* requires CZ */ - DRCUML_COND_BE, /* requires CZ */ - DRCUML_COND_G, /* requires SVZ */ - DRCUML_COND_LE, /* requires SVZ */ - DRCUML_COND_L, /* requires SV */ - DRCUML_COND_GE, /* requires SV */ - - DRCUML_COND_MAX -}; - - -/* basic condition code aliases */ -enum -{ - DRCUML_COND_E = DRCUML_COND_Z, - DRCUML_COND_NE = DRCUML_COND_NZ, - DRCUML_COND_B = DRCUML_COND_C, - DRCUML_COND_AE = DRCUML_COND_NC -}; - - -/* floating point modes */ -enum -{ - DRCUML_FMOD_TRUNC = 0, /* truncate */ - DRCUML_FMOD_ROUND, /* round */ - DRCUML_FMOD_CEIL, /* round up */ - DRCUML_FMOD_FLOOR, /* round down */ - DRCUML_FMOD_DEFAULT -}; - - -/* sizes */ -enum -{ - DRCUML_SIZE_BYTE = 0, /* 1-byte */ - DRCUML_SIZE_WORD, /* 2-byte */ - DRCUML_SIZE_DWORD, /* 4-byte */ - DRCUML_SIZE_QWORD, /* 8-byte */ - DRCUML_SIZE_SHORT = DRCUML_SIZE_DWORD, - DRCUML_SIZE_DOUBLE = DRCUML_SIZE_QWORD -}; - - -/* scale/space combinations */ -enum -{ - DRCUML_SCSIZE_BYTE = (0 * 16) + DRCUML_SIZE_BYTE, - DRCUML_SCSIZE_BYTE_x2 = (1 * 16) + DRCUML_SIZE_BYTE, - DRCUML_SCSIZE_BYTE_x4 = (2 * 16) + DRCUML_SIZE_BYTE, - DRCUML_SCSIZE_BYTE_x8 = (3 * 16) + DRCUML_SIZE_BYTE, - DRCUML_SCSIZE_WORD_x1 = (0 * 16) + DRCUML_SIZE_WORD, - DRCUML_SCSIZE_WORD = (1 * 16) + DRCUML_SIZE_WORD, - DRCUML_SCSIZE_WORD_x4 = (2 * 16) + DRCUML_SIZE_WORD, - DRCUML_SCSIZE_WORD_x8 = (3 * 16) + DRCUML_SIZE_WORD, - DRCUML_SCSIZE_DWORD_x1 = (0 * 16) + DRCUML_SIZE_DWORD, - DRCUML_SCSIZE_DWORD_x2 = (1 * 16) + DRCUML_SIZE_DWORD, - DRCUML_SCSIZE_DWORD = (2 * 16) + DRCUML_SIZE_DWORD, - DRCUML_SCSIZE_DWORD_x8 = (3 * 16) + DRCUML_SIZE_DWORD, - DRCUML_SCSIZE_QWORD_x1 = (0 * 16) + DRCUML_SIZE_QWORD, - DRCUML_SCSIZE_QWORD_x2 = (1 * 16) + DRCUML_SIZE_QWORD, - DRCUML_SCSIZE_QWORD_x4 = (2 * 16) + DRCUML_SIZE_QWORD, - DRCUML_SCSIZE_QWORD = (3 * 16) + DRCUML_SIZE_QWORD -}; - - -/* size/space combinations */ -enum -{ - DRCUML_SPSIZE_PROGRAM_BYTE = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_BYTE, - DRCUML_SPSIZE_PROGRAM_WORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_WORD, - DRCUML_SPSIZE_PROGRAM_DWORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_DWORD, - DRCUML_SPSIZE_PROGRAM_QWORD = (ADDRESS_SPACE_PROGRAM * 16) + DRCUML_SIZE_QWORD, - DRCUML_SPSIZE_DATA_BYTE = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_BYTE, - DRCUML_SPSIZE_DATA_WORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_WORD, - DRCUML_SPSIZE_DATA_DWORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_DWORD, - DRCUML_SPSIZE_DATA_QWORD = (ADDRESS_SPACE_DATA * 16) + DRCUML_SIZE_QWORD, - DRCUML_SPSIZE_IO_BYTE = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_BYTE, - DRCUML_SPSIZE_IO_WORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_WORD, - DRCUML_SPSIZE_IO_DWORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_DWORD, - DRCUML_SPSIZE_IO_QWORD = (ADDRESS_SPACE_IO * 16) + DRCUML_SIZE_QWORD -}; - - -/* these define the opcodes for the UML */ -enum _drcuml_opcode -{ - DRCUML_OP_INVALID, - - /* Compile-time opcodes */ - DRCUML_OP_HANDLE, /* HANDLE handle */ - DRCUML_OP_HASH, /* HASH mode,pc */ - DRCUML_OP_LABEL, /* LABEL imm */ - DRCUML_OP_COMMENT, /* COMMENT string */ - DRCUML_OP_MAPVAR, /* MAPVAR mapvar,value */ - - /* Control Flow Operations */ - DRCUML_OP_NOP, /* NOP */ - DRCUML_OP_DEBUG, /* DEBUG pc */ - DRCUML_OP_EXIT, /* EXIT src1[,c] */ - DRCUML_OP_HASHJMP, /* HASHJMP mode,pc,handle */ - DRCUML_OP_JMP, /* JMP imm[,c] */ - DRCUML_OP_EXH, /* EXH handle,param[,c] */ - DRCUML_OP_CALLH, /* CALLH handle[,c] */ - DRCUML_OP_RET, /* RET [c] */ - DRCUML_OP_CALLC, /* CALLC func,ptr[,c] */ - DRCUML_OP_RECOVER, /* RECOVER dst,mapvar */ - - /* Internal Register Operations */ - DRCUML_OP_SETFMOD, /* SETFMOD src */ - DRCUML_OP_GETFMOD, /* GETFMOD dst */ - DRCUML_OP_GETEXP, /* GETEXP dst */ - DRCUML_OP_GETFLGS, /* GETFLGS dst[,f] */ - DRCUML_OP_SAVE, /* SAVE mem */ - DRCUML_OP_RESTORE, /* RESTORE mem */ - - /* Integer Operations */ - DRCUML_OP_LOAD, /* LOAD dst,base,index,size */ - DRCUML_OP_LOADS, /* LOADS dst,base,index,size */ - DRCUML_OP_STORE, /* STORE base,index,src,size */ - DRCUML_OP_READ, /* READ dst,src1,space/size */ - DRCUML_OP_READM, /* READM dst,src1,mask,space/size */ - DRCUML_OP_WRITE, /* WRITE dst,src1,space/size */ - DRCUML_OP_WRITEM, /* WRITEM dst,mask,src1,space/size */ - DRCUML_OP_CARRY, /* CARRY src,bitnum */ - DRCUML_OP_SET, /* SET dst,c */ - DRCUML_OP_MOV, /* MOV dst,src[,c] */ - DRCUML_OP_SEXT, /* SEXT dst,src,size */ - DRCUML_OP_ROLAND, /* ROLAND dst,src,shift,mask */ - DRCUML_OP_ROLINS, /* ROLINS dst,src,shift,mask */ - DRCUML_OP_ADD, /* ADD dst,src1,src2[,f] */ - DRCUML_OP_ADDC, /* ADDC dst,src1,src2[,f] */ - DRCUML_OP_SUB, /* SUB dst,src1,src2[,f] */ - DRCUML_OP_SUBB, /* SUBB dst,src1,src2[,f] */ - DRCUML_OP_CMP, /* CMP src1,src2[,f] */ - DRCUML_OP_MULU, /* MULU dst,edst,src1,src2[,f] */ - DRCUML_OP_MULS, /* MULS dst,edst,src1,src2[,f] */ - DRCUML_OP_DIVU, /* DIVU dst,edst,src1,src2[,f] */ - DRCUML_OP_DIVS, /* DIVS dst,edst,src1,src2[,f] */ - DRCUML_OP_AND, /* AND dst,src1,src2[,f] */ - DRCUML_OP_TEST, /* TEST src1,src2[,f] */ - DRCUML_OP_OR, /* OR dst,src1,src2[,f] */ - DRCUML_OP_XOR, /* XOR dst,src1,src2[,f] */ - DRCUML_OP_LZCNT, /* LZCNT dst,src */ - DRCUML_OP_BSWAP, /* BSWAP dst,src */ - DRCUML_OP_SHL, /* SHL dst,src,count[,f] */ - DRCUML_OP_SHR, /* SHR dst,src,count[,f] */ - DRCUML_OP_SAR, /* SAR dst,src,count[,f] */ - DRCUML_OP_ROL, /* ROL dst,src,count[,f] */ - DRCUML_OP_ROLC, /* ROLC dst,src,count[,f] */ - DRCUML_OP_ROR, /* ROL dst,src,count[,f] */ - DRCUML_OP_RORC, /* ROLC dst,src,count[,f] */ - - /* Floating Point Operations */ - DRCUML_OP_FLOAD, /* FLOAD dst,base,index */ - DRCUML_OP_FSTORE, /* FSTORE base,index,src */ - DRCUML_OP_FREAD, /* FREAD dst,space,src1 */ - DRCUML_OP_FWRITE, /* FWRITE space,dst,src1 */ - DRCUML_OP_FMOV, /* FMOV dst,src1[,c] */ - DRCUML_OP_FTOINT, /* FTOINT dst,src1,size,round */ - DRCUML_OP_FFRINT, /* FFRINT dst,src1,size */ - DRCUML_OP_FFRFLT, /* FFRFLT dst,src1,size */ - DRCUML_OP_FRNDS, /* FRNDS dst,src1 */ - DRCUML_OP_FADD, /* FADD dst,src1,src2 */ - DRCUML_OP_FSUB, /* FSUB dst,src1,src2 */ - DRCUML_OP_FCMP, /* FCMP src1,src2 */ - DRCUML_OP_FMUL, /* FMUL dst,src1,src2 */ - DRCUML_OP_FDIV, /* FDIV dst,src1,src2 */ - DRCUML_OP_FNEG, /* FNEG dst,src1 */ - DRCUML_OP_FABS, /* FABS dst,src1 */ - DRCUML_OP_FSQRT, /* FSQRT dst,src1 */ - DRCUML_OP_FRECIP, /* FRECIP dst,src1 */ - DRCUML_OP_FRSQRT, /* FRSQRT dst,src1 */ - - DRCUML_OP_MAX -}; -typedef enum _drcuml_opcode drcuml_opcode; - - - -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* represents a reference to a local label in the code */ -typedef UINT32 drcuml_codelabel; - -/* represents the value of an opcode parameter */ -typedef UINT64 drcuml_pvalue; +#include "uml.h" -/* opaque structure describing UML generation state */ -typedef struct _drcuml_state drcuml_state; +//************************************************************************** +// CONSTANTS +//************************************************************************** -/* opaque structure describing UML codegen block */ -typedef struct _drcuml_block drcuml_block; +// these options are passed into drcuml_alloc() and control global behaviors +const UINT32 DRCUML_OPTION_USE_C = 0x0001; // always use the C back-end +const UINT32 DRCUML_OPTION_LOG_UML = 0x0002; // generate a UML disassembly of each block +const UINT32 DRCUML_OPTION_LOG_NATIVE = 0x0004; // tell the back-end to generate a native disassembly of each block -/* opaque structure describing back-end state */ -typedef struct _drcbe_state drcbe_state; -/* opaque structure describing a code handle */ -typedef struct _drcuml_codehandle drcuml_codehandle; +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** -/* a parameter for a UML instructon is encoded like this */ -typedef struct _drcuml_parameter drcuml_parameter; -struct _drcuml_parameter -{ - drcuml_ptype type; /* parameter type */ - drcuml_pvalue value; /* parameter value */ -}; - - -/* a single UML instructon is encoded like this */ -typedef struct _drcuml_instruction drcuml_instruction; -struct _drcuml_instruction -{ - drcuml_opcode opcode; /* opcode */ - UINT8 condition; /* condition */ - UINT8 flags; /* flags */ - UINT8 size; /* operation size */ - UINT8 numparams; /* number of parameters */ - drcuml_parameter param[4]; /* up to 4 parameters */ -}; - - -/* structure describing rules for parameter encoding */ -typedef struct _drcuml_parameter_info drcuml_parameter_info; -struct _drcuml_parameter_info -{ - UINT8 output; /* input or output? */ - UINT8 size; /* size of the parameter */ - UINT16 typemask; /* types allowed */ -}; +// determine the type of the native DRC, falling back to C +#ifndef NATIVE_DRC +typedef drcbe_c drcbe_native; +#else +class NATIVE_DRC; +typedef NATIVE_DRC drcbe_native; +#endif -/* structure describing rules for opcode encoding */ -typedef struct _drcuml_opcode_info drcuml_opcode_info; -struct _drcuml_opcode_info -{ - drcuml_opcode opcode; /* the opcode itself */ - const char * mnemonic; /* mnemonic string */ - UINT8 sizes; /* allowed sizes */ - UINT8 condition; /* conditions allowed? */ - UINT8 inflags; /* input flags */ - UINT8 outflags; /* output flags */ - UINT8 modflags; /* modified flags */ - drcuml_parameter_info param[4]; /* information about parameters */ -}; +// opaque structure describing UML generation state +class drcuml_state; -/* an integer register, with low/high parts */ -typedef union _drcuml_ireg drcuml_ireg; -union _drcuml_ireg +// an integer register, with low/high parts +union drcuml_ireg { #ifdef LSB_FIRST - struct { UINT32 l,h; } w; /* 32-bit low, high parts of the register */ + struct { UINT32 l,h; } w; // 32-bit low, high parts of the register #else - struct { UINT32 h,l; } w; /* 32-bit low, high parts of the register */ + struct { UINT32 h,l; } w; // 32-bit low, high parts of the register #endif - UINT64 d; /* 64-bit full register */ + UINT64 d; // 64-bit full register }; -/* a floating-point register, with low/high parts */ -typedef union _drcuml_freg drcuml_freg; -union _drcuml_freg +// a floating-point register, with low/high parts +union drcuml_freg { #ifdef LSB_FIRST - struct { float l,h; } s; /* 32-bit low, high parts of the register */ + struct { float l,h; } s; // 32-bit low, high parts of the register #else - struct { float h,l; } s; /* 32-bit low, high parts of the register */ + struct { float h,l; } s; // 32-bit low, high parts of the register #endif - double d; /* 64-bit full register */ + double d; // 64-bit full register }; -/* the collected machine state of a system */ -typedef struct _drcuml_machine_state drcuml_machine_state; -struct _drcuml_machine_state +// the collected machine state of a system +struct drcuml_machine_state { - drcuml_ireg r[DRCUML_REG_I_END - DRCUML_REG_I0]; /* integer registers */ - drcuml_freg f[DRCUML_REG_F_END - DRCUML_REG_F0]; /* floating-point registers */ - UINT32 exp; /* exception parameter register */ - UINT8 fmod; /* fmod (floating-point mode) register */ - UINT8 flags; /* flags state */ + drcuml_ireg r[uml::REG_I_COUNT]; // integer registers + drcuml_freg f[uml::REG_F_COUNT]; // floating-point registers + UINT32 exp; // exception parameter register + UINT8 fmod; // fmod (floating-point mode) register + UINT8 flags; // flags state }; -/* hints and information about the back-end */ -typedef struct _drcbe_info drcbe_info; -struct _drcbe_info +// hints and information about the back-end +struct drcbe_info { - UINT8 direct_iregs; /* number of direct-mapped integer registers */ - UINT8 direct_fregs; /* number of direct-mapped floating point registers */ + UINT8 direct_iregs; // number of direct-mapped integer registers + UINT8 direct_fregs; // number of direct-mapped floating point registers }; -/* typedefs for back-end callback functions */ -typedef drcbe_state *(*drcbe_alloc_func)(drcuml_state *drcuml, drc_cache *cache, device_t *device, UINT32 flags, int modes, int addrbits, int ignorebits); -typedef void (*drcbe_free_func)(drcbe_state *state); -typedef void (*drcbe_reset_func)(drcbe_state *state); -typedef int (*drcbe_execute_func)(drcbe_state *state, drcuml_codehandle *entry); -typedef void (*drcbe_generate_func)(drcbe_state *state, drcuml_block *block, const drcuml_instruction *instlist, UINT32 numinst); -typedef int (*drcbe_hash_exists)(drcbe_state *state, UINT32 mode, UINT32 pc); -typedef void (*drcbe_get_info)(drcbe_state *state, drcbe_info *info); - - -/* interface structure for a back-end */ -typedef struct _drcbe_interface drcbe_interface; -struct _drcbe_interface +// a drcuml_block describes a basic block of instructions +class drcuml_block { - drcbe_alloc_func be_alloc; - drcbe_free_func be_free; - drcbe_reset_func be_reset; - drcbe_execute_func be_execute; - drcbe_generate_func be_generate; - drcbe_hash_exists be_hash_exists; - drcbe_get_info be_get_info; + template<class T> friend class simple_list; + +public: + // construction/destruction + drcuml_block(drcuml_state &drcuml, UINT32 maxinst); + ~drcuml_block(); + + // getters + drcuml_block *next() const { return m_next; } + bool inuse() const { return m_inuse; } + UINT32 maxinst() const { return m_maxinst; } + + // code generation + void begin(); + void end(); + void abort(); + + // instruction appending + uml::instruction &append(); + void append_comment(const char *format, ...); + + // this class is thrown if abort() is called + class abort_compilation : public emu_exception + { + friend class drcuml_block; + abort_compilation() { } + }; + +private: + // internal helpers + void optimize(); + void disassemble(); + const char *get_comment_text(const uml::instruction &inst, astring &comment); + + // internal state + drcuml_state & m_drcuml; // pointer back to the owning UML + drcuml_block * m_next; // pointer to next block + UINT32 m_nextinst; // next instruction to fill in the cache + UINT32 m_maxinst; // maximum number of instructions + uml::instruction * m_inst; // pointer to the instruction list + bool m_inuse; // this block is in use }; +// interface structure for a back-end +class drcbe_interface +{ +public: + // construction/destruction + drcbe_interface(drcuml_state &drcuml, drc_cache &cache, device_t &device); + virtual ~drcbe_interface(); + + // required overrides + virtual void reset() = 0; + virtual int execute(uml::code_handle &entry) = 0; + virtual void generate(drcuml_block &block, const uml::instruction *instlist, UINT32 numinst) = 0; + virtual bool hash_exists(UINT32 mode, UINT32 pc) = 0; + virtual void get_info(drcbe_info &info) = 0; + +protected: + // internal state + drcuml_state & m_drcuml; // pointer back to our owner + drc_cache & m_cache; // pointer to the cache + device_t & m_device; // CPU device we are associated with + address_space * m_space[ADDRESS_SPACES];// pointers to CPU's address space + data_accessors m_accessors[ADDRESS_SPACES];// memory accessors + drcuml_machine_state & m_state; // state of the machine (in near cache) +}; -/*************************************************************************** - FUNCTION PROTOTYPES -***************************************************************************/ - -/* ----- initialization/teardown ----- */ - -/* allocate state for the code generator and initialize the back-end */ -drcuml_state *drcuml_alloc(device_t *device, drc_cache *cache, UINT32 flags, int modes, int addrbits, int ignorebits); - -/* return information about the back-end */ -void drcuml_get_backend_info(drcuml_state *drcuml, drcbe_info *info); - -/* reset the state completely, flushing the cache and all information */ -void drcuml_reset(drcuml_state *drcuml); - -/* free state for the code generator and the back-end */ -void drcuml_free(drcuml_state *drcuml); - - - -/* ----- code block generation ----- */ - -/* begin a new code block */ -drcuml_block *drcuml_block_begin(drcuml_state *drcuml, UINT32 maxinst, jmp_buf *errorbuf); - -/* append an opcode to the block, with 0-4 parameters */ -void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition); -void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value); -void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value); -void drcuml_block_append_3(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value); -void drcuml_block_append_4(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value, drcuml_ptype p3type, drcuml_pvalue p3value); - -/* complete a code block and commit it to the cache via the back-end */ -void drcuml_block_end(drcuml_block *block); - -/* abort a code block in progress due to cache allocation failure */ -void drcuml_block_abort(drcuml_block *block); - -/* return true if a hash entry exists for the given mode/pc */ -int drcuml_hash_exists(drcuml_state *drcuml, UINT32 mode, UINT32 pc); - - - -/* ----- code execution ----- */ - -/* execute at the given PC/mode for the specified cycles */ -int drcuml_execute(drcuml_state *drcuml, drcuml_codehandle *entry); - - - -/* ----- code handles ----- */ - -/* allocate a new handle */ -drcuml_codehandle *drcuml_handle_alloc(drcuml_state *drcuml, const char *name); - -/* set the handle pointer */ -void drcuml_handle_set_codeptr(drcuml_codehandle *handle, drccodeptr code); - -/* get the pointer from a handle */ -drccodeptr drcuml_handle_codeptr(const drcuml_codehandle *handle); - -/* get the address of the pointer from a handle */ -drccodeptr *drcuml_handle_codeptr_addr(drcuml_codehandle *handle); - -/* get the name of a handle */ -const char *drcuml_handle_name(const drcuml_codehandle *handle); - - - -/* ----- code logging ----- */ - -/* directly printf to the UML log if generated */ -void drcuml_log_printf(drcuml_state *drcuml, const char *format, ...) ATTR_PRINTF(2,3); - -/* add a symbol to the internal symbol table */ -void drcuml_symbol_add(drcuml_state *drcuml, void *base, UINT32 length, const char *name); - -/* look up a symbol from the internal symbol table or return NULL if not found */ -const char *drcuml_symbol_find(drcuml_state *drcuml, void *base, UINT32 *offset); -/* attach a comment to the current output location in the specified block */ -void drcuml_add_comment(drcuml_block *block, const char *format, ...) ATTR_PRINTF(2,3); +// structure describing UML generation state +class drcuml_state +{ +public: + // construction/destruction + drcuml_state(device_t &device, drc_cache &cache, UINT32 flags, int modes, int addrbits, int ignorebits); + ~drcuml_state(); + + // getters + device_t &device() const { return m_device; } + drc_cache &cache() const { return m_cache; } + + // reset the state + void reset(); + int execute(uml::code_handle &entry) { return m_beintf.execute(entry); } + + // code generation + drcuml_block *begin_block(UINT32 maxinst); + + // back-end interface + void get_backend_info(drcbe_info &info) { m_beintf.get_info(info); } + bool hash_exists(UINT32 mode, UINT32 pc) { return m_beintf.hash_exists(mode, pc); } + void generate(drcuml_block &block, uml::instruction *instructions, UINT32 count) { m_beintf.generate(block, instructions, count); } + + // handle management + uml::code_handle *handle_alloc(const char *name); + + // symbol management + void symbol_add(void *base, UINT32 length, const char *name); + const char *symbol_find(void *base, UINT32 *offset = NULL); + + // logging + bool logging() const { return (m_umllog != NULL); } + void log_printf(const char *format, ...); + void log_flush() { if (logging()) fflush(m_umllog); } + +private: + // symbol class + class symbol + { + friend class drcuml_state; + template<class T> friend class simple_list; + + // construction/destruction + symbol(void *base, UINT32 length, const char *name) + : m_next(NULL), + m_base(drccodeptr(base)), + m_length(length), + m_name(name) { } + + public: + // getters + symbol *next() const { return m_next; } + + private: + // internal state + symbol * m_next; // link to the next symbol + drccodeptr m_base; // base of the symbol + UINT32 m_length; // length of the region covered + astring m_name; // name of the symbol + }; + + // internal state + device_t & m_device; // CPU device we are associated with + drc_cache & m_cache; // pointer to the codegen cache + drcbe_interface & m_beintf; // backend interface pointer + FILE * m_umllog; // handle to the UML logfile + simple_list<drcuml_block> m_blocklist; // list of active blocks + simple_list<uml::code_handle> m_handlelist; // list of active handles + simple_list<symbol> m_symlist; // list of symbols +}; -/* disassemble a UML instruction to the given buffer */ -void drcuml_disasm(const drcuml_instruction *inst, char *buffer, drcuml_state *state); #endif /* __DRCUML_H__ */ diff --git a/src/emu/cpu/drcumlsh.h b/src/emu/cpu/drcumlsh.h index f83ca6b7cfc..f64d0fec83d 100644 --- a/src/emu/cpu/drcumlsh.h +++ b/src/emu/cpu/drcumlsh.h @@ -24,27 +24,27 @@ ***************************************************************************/ /* shorthand for conditions */ -#define IF_Z DRCUML_COND_Z -#define IF_NZ DRCUML_COND_NZ -#define IF_S DRCUML_COND_S -#define IF_NS DRCUML_COND_NS -#define IF_C DRCUML_COND_C -#define IF_NC DRCUML_COND_NC -#define IF_V DRCUML_COND_V -#define IF_NV DRCUML_COND_NV -#define IF_U DRCUML_COND_U -#define IF_NU DRCUML_COND_NU -#define IF_E DRCUML_COND_E -#define IF_NE DRCUML_COND_NE -#define IF_A DRCUML_COND_A -#define IF_AE DRCUML_COND_AE -#define IF_B DRCUML_COND_B -#define IF_BE DRCUML_COND_BE -#define IF_G DRCUML_COND_G -#define IF_GE DRCUML_COND_GE -#define IF_L DRCUML_COND_L -#define IF_LE DRCUML_COND_LE -#define IF_ALWAYS DRCUML_COND_ALWAYS +#define IF_Z uml::COND_Z +#define IF_NZ uml::COND_NZ +#define IF_S uml::COND_S +#define IF_NS uml::COND_NS +#define IF_C uml::COND_C +#define IF_NC uml::COND_NC +#define IF_V uml::COND_V +#define IF_NV uml::COND_NV +#define IF_U uml::COND_U +#define IF_NU uml::COND_NU +#define IF_E uml::COND_E +#define IF_NE uml::COND_NE +#define IF_A uml::COND_A +#define IF_AE uml::COND_AE +#define IF_B uml::COND_B +#define IF_BE uml::COND_BE +#define IF_G uml::COND_G +#define IF_GE uml::COND_GE +#define IF_L uml::COND_L +#define IF_LE uml::COND_LE +#define IF_ALWAYS uml::COND_ALWAYS @@ -53,13 +53,13 @@ ***************************************************************************/ /* macros for wrapping parameters */ -#define NONE DRCUML_PTYPE_NONE, 0 -#define IMM(x) DRCUML_PTYPE_IMMEDIATE, (x) -#define IREG(x) DRCUML_PTYPE_INT_REGISTER, (DRCUML_REG_I0 + (x)) -#define FREG(x) DRCUML_PTYPE_FLOAT_REGISTER, (DRCUML_REG_F0 + (x)) -#define MVAR(x) DRCUML_PTYPE_MAPVAR, (DRCUML_MAPVAR_M0 + (x)) -#define MEM(x) DRCUML_PTYPE_MEMORY, (FPTR)(x) -#define PARAM(t,v) (t), (v) +#define NONE uml::parameter() +#define IMM(x) (x) +#define IREG(x) uml::ireg(x) +#define FREG(x) uml::freg(x) +#define VREG(x) uml::vreg(x) +#define MVAR(x) uml::mapvar(x) +#define MEM(x) uml::parameter::make_memory((void *)(x)) @@ -68,162 +68,163 @@ ***************************************************************************/ /* ----- Compile-time Opcodes ----- */ -#define UML_HANDLE(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_HANDLE, 4, IF_ALWAYS, MEM(handle)); } while (0) -#define UML_HASH(block, mode, pc) do { drcuml_block_append_2(block, DRCUML_OP_HASH, 4, IF_ALWAYS, IMM(mode), IMM(pc)); } while (0) -#define UML_LABEL(block, label) do { drcuml_block_append_1(block, DRCUML_OP_LABEL, 4, IF_ALWAYS, IMM(label)); } while (0) -#define UML_COMMENT/*(block, format, ...)*/ drcuml_add_comment -#define UML_MAPVAR(block, mapvar, value) do { drcuml_block_append_2(block, DRCUML_OP_MAPVAR, 4, IF_ALWAYS, mapvar, IMM(value)); } while (0) +#define UML_HANDLE(block, _handle) do { block->append().handle(_handle); } while (0) +#define UML_HASH(block, mode, pc) do { block->append().hash(mode, pc); } while (0) +#define UML_LABEL(block, _label) do { block->append().label(_label); } while (0) +#define UML_MAPVAR(block, _mapvar, _value) do { block->append().mapvar(_mapvar, _value); } while (0) /* ----- Control Flow Operations ----- */ -#define UML_NOP(block) do { drcuml_block_append_0(block, DRCUML_OP_NOP, 4, IF_ALWAYS); } while (0) -#define UML_DEBUG(block, pc) do { drcuml_block_append_1(block, DRCUML_OP_DEBUG, 4, IF_ALWAYS, pc); } while (0) -#define UML_EXIT(block, param) do { drcuml_block_append_1(block, DRCUML_OP_EXIT, 4, IF_ALWAYS, param); } while (0) -#define UML_EXITc(block, cond, param) do { drcuml_block_append_1(block, DRCUML_OP_EXIT, 4, cond, param); } while (0) -#define UML_HASHJMP(block, mode, pc, handle) do { drcuml_block_append_3(block, DRCUML_OP_HASHJMP, 4, IF_ALWAYS, mode, pc, MEM(handle)); } while (0) -#define UML_JMP(block, label) do { drcuml_block_append_1(block, DRCUML_OP_JMP, 4, IF_ALWAYS, IMM(label)); } while (0) -#define UML_JMPc(block, cond, label) do { drcuml_block_append_1(block, DRCUML_OP_JMP, 4, cond, IMM(label)); } while (0) -#define UML_JMPH(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_JMPH, 4, IF_ALWAYS, MEM(handle)); } while (0) -#define UML_JMPHc(block, cond, handle) do { drcuml_block_append_1(block, DRCUML_OP_JMPH, 4, cond, MEM(handle)); } while (0) -#define UML_EXH(block, handle, param) do { drcuml_block_append_2(block, DRCUML_OP_EXH, 4, IF_ALWAYS, MEM(handle), param); } while (0) -#define UML_EXHc(block, cond, handle, param) do { drcuml_block_append_2(block, DRCUML_OP_EXH, 4, cond, MEM(handle), param); } while (0) -#define UML_CALLH(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_CALLH, 4, IF_ALWAYS, MEM(handle)); } while (0) -#define UML_CALLHc(block, cond, handle) do { drcuml_block_append_1(block, DRCUML_OP_CALLH, 4, cond, MEM(handle)); } while (0) -#define UML_RET(block) do { drcuml_block_append_0(block, DRCUML_OP_RET, 4, IF_ALWAYS); } while (0) -#define UML_RETc(block, cond) do { drcuml_block_append_0(block, DRCUML_OP_RET, 4, cond); } while (0) -#define UML_CALLC(block, func, ptr) do { drcuml_block_append_2(block, DRCUML_OP_CALLC, 4, IF_ALWAYS, MEM(func), MEM(ptr)); } while (0) -#define UML_CALLCc(block, cond, func, ptr) do { drcuml_block_append_2(block, DRCUML_OP_CALLC, 4, cond, MEM(func), MEM(ptr)); } while (0) -#define UML_RECOVER(block, dst, mapvar) do { drcuml_block_append_2(block, DRCUML_OP_RECOVER, 4, IF_ALWAYS, dst, mapvar); } while (0) +#define UML_NOP(block) do { block->append().nop(); } while (0) +#define UML_DEBUG(block, pc) do { block->append().debug(pc); } while (0) +#define UML_EXIT(block, param) do { block->append().exit(param); } while (0) +#define UML_EXITc(block, cond, param) do { block->append().exit(param, cond); } while (0) +#define UML_HASHJMP(block, mode, pc, handle) do { block->append().hashjmp(mode, pc, handle); } while (0) +#define UML_JMP(block, label) do { block->append().jmp(label); } while (0) +#define UML_JMPc(block, cond, label) do { block->append().jmp(cond, label); } while (0) +#define UML_JMPH(block, handle) do { block->append().jmph(handle); } while (0) +#define UML_JMPHc(block, cond, handle) do { block->append().jmph(cond, handle); } while (0) +#define UML_EXH(block, handle, param) do { block->append().exh(handle, param); } while (0) +#define UML_EXHc(block, cond, handle, param) do { block->append().exh(cond, handle, param); } while (0) +#define UML_CALLH(block, handle) do { block->append().callh(handle); } while (0) +#define UML_CALLHc(block, cond, handle) do { block->append().callh(cond, handle); } while (0) +#define UML_RET(block) do { block->append().ret(); } while (0) +#define UML_RETc(block, cond) do { block->append().ret(cond); } while (0) +#define UML_CALLC(block, func, ptr) do { block->append().callc(func, ptr); } while (0) +#define UML_CALLCc(block, cond, func, ptr) do { block->append().callc(cond, func, ptr); } while (0) +#define UML_RECOVER(block, dst, mapvar) do { block->append().recover(dst, mapvar); } while (0) /* ----- Internal Register Operations ----- */ -#define UML_SETFMOD(block, mode) do { drcuml_block_append_1(block, DRCUML_OP_SETFMOD, 4, IF_ALWAYS, mode); } while (0) -#define UML_GETFMOD(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_GETFMOD, 4, IF_ALWAYS, dst); } while (0) -#define UML_GETEXP(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_GETEXP, 4, IF_ALWAYS, dst); } while (0) -#define UML_GETFLGS(block, dst, flags) do { drcuml_block_append_2(block, DRCUML_OP_GETFLGS, 4, IF_ALWAYS, dst, IMM(flags)); } while (0) -#define UML_SAVE(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_SAVE, 4, IF_ALWAYS, MEM(dst)); } while (0) -#define UML_RESTORE(block, src) do { drcuml_block_append_1(block, DRCUML_OP_RESTORE, 4, IF_ALWAYS, MEM(src)); } while (0) +#define UML_SETFMOD(block, mode) do { block->append().setfmod(mode); } while (0) +#define UML_GETFMOD(block, dst) do { block->append().getfmod(dst); } while (0) +#define UML_GETEXP(block, dst) do { block->append().getexp(dst); } while (0) +#define UML_GETFLGS(block, dst, flags) do { block->append().getflgs(dst, flags); } while (0) +#define UML_SAVE(block, dst) do { block->append().save(dst); } while (0) +#define UML_RESTORE(block, src) do { block->append().restore(src); } while (0) /* ----- 32-Bit Integer Operations ----- */ -#define UML_LOAD(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOAD, 4, IF_ALWAYS, dst, MEM(base), index, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_LOADS(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOADS, 4, IF_ALWAYS, dst, MEM(base), index, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_STORE(block, base, index, src1, size) do { drcuml_block_append_4(block, DRCUML_OP_STORE, 4, IF_ALWAYS, MEM(base), index, src1, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_READ(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_READ, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_READM(block, dst, src1, mask, spsize) do { drcuml_block_append_4(block, DRCUML_OP_READM, 4, IF_ALWAYS, dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_WRITE(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_WRITE, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_WRITEM(block, dst, src1, mask, spsize) do { drcuml_block_append_4(block, DRCUML_OP_WRITEM, 4, IF_ALWAYS, dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_CARRY(block, src, bitnum) do { drcuml_block_append_2(block, DRCUML_OP_CARRY, 4, IF_ALWAYS, src, bitnum); } while (0) -#define UML_SETc(block, cond, dst) do { drcuml_block_append_1(block, DRCUML_OP_SET, 4, cond, dst); } while (0) -#define UML_MOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_MOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 4, cond, dst, src1); } while (0) -#define UML_SEXT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_SEXT, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_ROLAND(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLAND, 4, IF_ALWAYS, dst, src, shift, mask); } while (0) -#define UML_ROLINS(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLINS, 4, IF_ALWAYS, dst, src, shift, mask); } while (0) -#define UML_ADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_ADDC(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_SUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_SUBB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_CMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 4, IF_ALWAYS, src1, src2); } while (0) -#define UML_MULU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 4, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_MULS(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULS, 4, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DIVU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_DIVU, 4, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DIVS(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_DIVS, 4, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_AND(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_AND, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_TEST(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 4, IF_ALWAYS, src1, src2); } while (0) -#define UML_OR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_OR, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_XOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_LZCNT(block, dst, src) do { drcuml_block_append_2(block, DRCUML_OP_LZCNT, 4, IF_ALWAYS, dst, src); } while (0) -#define UML_BSWAP(block, dst, src) do { drcuml_block_append_2(block, DRCUML_OP_BSWAP, 4, IF_ALWAYS, dst, src); } while (0) -#define UML_SHL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_SHR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_SAR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_ROL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_ROLC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_ROR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 4, IF_ALWAYS, dst, src, count); } while (0) -#define UML_RORC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 4, IF_ALWAYS, dst, src, count); } while (0) +#define UML_LOAD(block, dst, base, index, size, scale) do { block->append().load(dst, base, index, size, scale); } while (0) +#define UML_LOADS(block, dst, base, index, size, scale) do { block->append().loads(dst, base, index, size, scale); } while (0) +#define UML_STORE(block, base, index, src1, size, scale) do { block->append().store(base, index, src1, size, scale); } while (0) +#define UML_READ(block, dst, src1, size, space) do { block->append().read(dst, src1, size, space); } while (0) +#define UML_READM(block, dst, src1, mask, size, space) do { block->append().readm(dst, src1, mask, size, space); } while (0) +#define UML_WRITE(block, dst, src1, size, space) do { block->append().write(dst, src1, size, space); } while (0) +#define UML_WRITEM(block, dst, src1, mask, size, space) do { block->append().writem(dst, src1, mask, size, space); } while (0) +#define UML_CARRY(block, src, bitnum) do { block->append().carry(src, bitnum); } while (0) +#define UML_SETc(block, cond, dst) do { block->append().set(cond, dst); } while (0) +#define UML_MOV(block, dst, src1) do { block->append().mov(dst, src1); } while (0) +#define UML_MOVc(block, cond, dst, src1) do { block->append().mov(cond, dst, src1); } while (0) +#define UML_SEXT(block, dst, src1, size) do { block->append().sext(dst, src1, size); } while (0) +#define UML_ROLAND(block, dst, src, shift, mask) do { block->append().roland(dst, src, shift, mask); } while (0) +#define UML_ROLINS(block, dst, src, shift, mask) do { block->append().rolins(dst, src, shift, mask); } while (0) +#define UML_ADD(block, dst, src1, src2) do { block->append().add(dst, src1, src2); } while (0) +#define UML_ADDC(block, dst, src1, src2) do { block->append().addc(dst, src1, src2); } while (0) +#define UML_SUB(block, dst, src1, src2) do { block->append().sub(dst, src1, src2); } while (0) +#define UML_SUBB(block, dst, src1, src2) do { block->append().subb(dst, src1, src2); } while (0) +#define UML_CMP(block, src1, src2) do { block->append().cmp(src1, src2); } while (0) +#define UML_MULU(block, dst, edst, src1, src2) do { block->append().mulu(dst, edst, src1, src2); } while (0) +#define UML_MULS(block, dst, edst, src1, src2) do { block->append().muls(dst, edst, src1, src2); } while (0) +#define UML_DIVU(block, dst, edst, src1, src2) do { block->append().divu(dst, edst, src1, src2); } while (0) +#define UML_DIVS(block, dst, edst, src1, src2) do { block->append().divs(dst, edst, src1, src2); } while (0) +#define UML_AND(block, dst, src1, src2) do { block->append()._and(dst, src1, src2); } while (0) +#define UML_TEST(block, src1, src2) do { block->append().test(src1, src2); } while (0) +#define UML_OR(block, dst, src1, src2) do { block->append()._or(dst, src1, src2); } while (0) +#define UML_XOR(block, dst, src1, src2) do { block->append()._xor(dst, src1, src2); } while (0) +#define UML_LZCNT(block, dst, src) do { block->append().lzcnt(dst, src); } while (0) +#define UML_BSWAP(block, dst, src) do { block->append().bswap(dst, src); } while (0) +#define UML_SHL(block, dst, src, count) do { block->append().shl(dst, src, count); } while (0) +#define UML_SHR(block, dst, src, count) do { block->append().shr(dst, src, count); } while (0) +#define UML_SAR(block, dst, src, count) do { block->append().sar(dst, src, count); } while (0) +#define UML_ROL(block, dst, src, count) do { block->append().rol(dst, src, count); } while (0) +#define UML_ROLC(block, dst, src, count) do { block->append().rolc(dst, src, count); } while (0) +#define UML_ROR(block, dst, src, count) do { block->append().ror(dst, src, count); } while (0) +#define UML_RORC(block, dst, src, count) do { block->append().rorc(dst, src, count); } while (0) /* ----- 64-Bit Integer Operations ----- */ -#define UML_DLOAD(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOAD, 8, IF_ALWAYS, dst, MEM(base), index, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_DLOADS(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOADS, 8, IF_ALWAYS, dst, MEM(base), index, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_DSTORE(block, base, index, src1, size) do { drcuml_block_append_4(block, DRCUML_OP_STORE, 8, IF_ALWAYS, MEM(base), index, src1, IMM(DRCUML_SCSIZE_##size)); } while (0) -#define UML_DREAD(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_READ, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_DREADM(block, dst, src1, mask, spsize) do { drcuml_block_append_4(block, DRCUML_OP_READM, 8, IF_ALWAYS, dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_DWRITE(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_WRITE, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_DWRITEM(block, dst, src1, mask, spsize) do { drcuml_block_append_4(block, DRCUML_OP_WRITEM, 8, IF_ALWAYS, dst, src1, mask, IMM(DRCUML_SPSIZE_##spsize)); } while (0) -#define UML_DCARRY(block, src, bitnum) do { drcuml_block_append_2(block, DRCUML_OP_CARRY, 8, IF_ALWAYS, src, bitnum); } while (0) -#define UML_DSETc(block, cond, dst) do { drcuml_block_append_1(block, DRCUML_OP_SET, 8, cond, dst); } while (0) -#define UML_DMOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_DMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 8, cond, dst, src1); } while (0) -#define UML_DSEXT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_SEXT, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_DROLAND(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLAND, 8, IF_ALWAYS, dst, src, shift, mask); } while (0) -#define UML_DROLINS(block, dst, src, shift, mask) do { drcuml_block_append_4(block, DRCUML_OP_ROLINS, 8, IF_ALWAYS, dst, src, shift, mask); } while (0) -#define UML_DADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DADDC(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DSUBB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 8, IF_ALWAYS, src1, src2); } while (0) -#define UML_DMULU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 8, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DMULS(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULS, 8, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DDIVU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_DIVU, 8, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DDIVS(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_DIVS, 8, IF_ALWAYS, dst, edst, src1, src2); } while (0) -#define UML_DAND(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_AND, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DTEST(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 8, IF_ALWAYS, src1, src2); } while (0) -#define UML_DOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_OR, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DXOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_DSHL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DSHR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DSAR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DROL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DROLC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DROR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 8, IF_ALWAYS, dst, src, count); } while (0) -#define UML_DRORC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 8, IF_ALWAYS, dst, src, count); } while (0) +#define UML_DLOAD(block, dst, base, index, size, scale) do { block->append().dload(dst, base, index, size, scale); } while (0) +#define UML_DLOADS(block, dst, base, index, size, scale) do { block->append().dloads(dst, base, index, size, scale); } while (0) +#define UML_DSTORE(block, base, index, src1, size, scale) do { block->append().dstore(base, index, src1, size, scale); } while (0) +#define UML_DREAD(block, dst, src1, size, space) do { block->append().dread(dst, src1, size, space); } while (0) +#define UML_DREADM(block, dst, src1, mask, size, space) do { block->append().dreadm(dst, src1, mask, size, space); } while (0) +#define UML_DWRITE(block, dst, src1, size, space) do { block->append().dwrite(dst, src1, size, space); } while (0) +#define UML_DWRITEM(block, dst, src1, mask, size, space) do { block->append().dwritem(dst, src1, mask, size, space); } while (0) +#define UML_DCARRY(block, src, bitnum) do { block->append().dcarry(src, bitnum); } while (0) +#define UML_DSETc(block, cond, dst) do { block->append().dset(cond, dst); } while (0) +#define UML_DMOV(block, dst, src1) do { block->append().dmov(dst, src1); } while (0) +#define UML_DMOVc(block, cond, dst, src1) do { block->append().dmov(cond, dst, src1); } while (0) +#define UML_DSEXT(block, dst, src1, size) do { block->append().dsext(dst, src1, size); } while (0) +#define UML_DROLAND(block, dst, src, shift, mask) do { block->append().droland(dst, src, shift, mask); } while (0) +#define UML_DROLINS(block, dst, src, shift, mask) do { block->append().drolins(dst, src, shift, mask); } while (0) +#define UML_DADD(block, dst, src1, src2) do { block->append().dadd(dst, src1, src2); } while (0) +#define UML_DADDC(block, dst, src1, src2) do { block->append().daddc(dst, src1, src2); } while (0) +#define UML_DSUB(block, dst, src1, src2) do { block->append().dsub(dst, src1, src2); } while (0) +#define UML_DSUBB(block, dst, src1, src2) do { block->append().dsubb(dst, src1, src2); } while (0) +#define UML_DCMP(block, src1, src2) do { block->append().dcmp(src1, src2); } while (0) +#define UML_DMULU(block, dst, edst, src1, src2) do { block->append().dmulu(dst, edst, src1, src2); } while (0) +#define UML_DMULS(block, dst, edst, src1, src2) do { block->append().dmuls(dst, edst, src1, src2); } while (0) +#define UML_DDIVU(block, dst, edst, src1, src2) do { block->append().ddivu(dst, edst, src1, src2); } while (0) +#define UML_DDIVS(block, dst, edst, src1, src2) do { block->append().ddivs(dst, edst, src1, src2); } while (0) +#define UML_DAND(block, dst, src1, src2) do { block->append().dand(dst, src1, src2); } while (0) +#define UML_DTEST(block, src1, src2) do { block->append().dtest(src1, src2); } while (0) +#define UML_DOR(block, dst, src1, src2) do { block->append().dor(dst, src1, src2); } while (0) +#define UML_DXOR(block, dst, src1, src2) do { block->append().dxor(dst, src1, src2); } while (0) +#define UML_DLZCNT(block, dst, src) do { block->append().dlzcnt(dst, src); } while (0) +#define UML_DBSWAP(block, dst, src) do { block->append().dbswap(dst, src); } while (0) +#define UML_DSHL(block, dst, src, count) do { block->append().dshl(dst, src, count); } while (0) +#define UML_DSHR(block, dst, src, count) do { block->append().dshr(dst, src, count); } while (0) +#define UML_DSAR(block, dst, src, count) do { block->append().dsar(dst, src, count); } while (0) +#define UML_DROL(block, dst, src, count) do { block->append().drol(dst, src, count); } while (0) +#define UML_DROLC(block, dst, src, count) do { block->append().drolc(dst, src, count); } while (0) +#define UML_DROR(block, dst, src, count) do { block->append().dror(dst, src, count); } while (0) +#define UML_DRORC(block, dst, src, count) do { block->append().drorc(dst, src, count); } while (0) /* ----- 32-bit Floating Point Arithmetic Operations ----- */ -#define UML_FSLOAD(block, dst, base, index) do { drcuml_block_append_3(block, DRCUML_OP_FLOAD, 4, IF_ALWAYS, dst, MEM(base), index); } while (0) -#define UML_FSSTORE(block, base, index, src1) do { drcuml_block_append_3(block, DRCUML_OP_FSTORE, 4, IF_ALWAYS, MEM(base), index, src1); } while (0) -#define UML_FSREAD(block, dst, src1, space) do { drcuml_block_append_3(block, DRCUML_OP_FREAD, 4, IF_ALWAYS, dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0) -#define UML_FSWRITE(block, dst, src1, space) do { drcuml_block_append_3(block, DRCUML_OP_FWRITE, 4, IF_ALWAYS, dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0) -#define UML_FSMOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_FSMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 4, cond, dst, src1); } while (0) -#define UML_FSTOINT(block, dst, src1, size, round) do { drcuml_block_append_4(block, DRCUML_OP_FTOINT, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size), IMM(DRCUML_FMOD_##round)); } while (0) -#define UML_FSFRINT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_FFRINT, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_FSFRFLT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_FFRFLT, 4, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_FSADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FADD, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FSSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FSUB, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FSCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_FCMP, 4, IF_ALWAYS, src1, src2); } while (0) -#define UML_FSMUL(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FMUL, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FSDIV(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FDIV, 4, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FSNEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FNEG, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_FSABS(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FABS, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_FSSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FSQRT, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_FSRECIP(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRECIP, 4, IF_ALWAYS, dst, src1); } while (0) -#define UML_FSRSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRSQRT, 4, IF_ALWAYS, dst, src1); } while (0) +#define UML_FSLOAD(block, dst, base, index) do { block->append().fsload(dst, base, index); } while (0) +#define UML_FSSTORE(block, base, index, src1) do { block->append().fsstore(base, index, src1); } while (0) +#define UML_FSREAD(block, dst, src1, space) do { block->append().fsread(dst, src1, ADDRESS_SPACE_##space); } while (0) +#define UML_FSWRITE(block, dst, src1, space) do { block->append().fswrite(dst, src1, ADDRESS_SPACE_##space); } while (0) +#define UML_FSMOV(block, dst, src1) do { block->append().fsmov(dst, src1); } while (0) +#define UML_FSMOVc(block, cond, dst, src1) do { block->append().fsmov(cond, dst, src1); } while (0) +#define UML_FSTOINT(block, dst, src1, size, round) do { block->append().fstoint(dst, src1, size, round); } while (0) +#define UML_FSFRINT(block, dst, src1, size) do { block->append().fsfrint(dst, src1, size); } while (0) +#define UML_FSFRFLT(block, dst, src1, size) do { block->append().fsfrflt(dst, src1, size); } while (0) +#define UML_FSADD(block, dst, src1, src2) do { block->append().fsadd(dst, src1, src2); } while (0) +#define UML_FSSUB(block, dst, src1, src2) do { block->append().fssub(dst, src1, src2); } while (0) +#define UML_FSCMP(block, src1, src2) do { block->append().fscmp(src1, src2); } while (0) +#define UML_FSMUL(block, dst, src1, src2) do { block->append().fsmul(dst, src1, src2); } while (0) +#define UML_FSDIV(block, dst, src1, src2) do { block->append().fsdiv(dst, src1, src2); } while (0) +#define UML_FSNEG(block, dst, src1) do { block->append().fsneg(dst, src1); } while (0) +#define UML_FSABS(block, dst, src1) do { block->append().fsabs(dst, src1); } while (0) +#define UML_FSSQRT(block, dst, src1) do { block->append().fssqrt(dst, src1); } while (0) +#define UML_FSRECIP(block, dst, src1) do { block->append().fsrecip(dst, src1); } while (0) +#define UML_FSRSQRT(block, dst, src1) do { block->append().fsrsqrt(dst, src1); } while (0) /* ----- 64-bit Floating Point Arithmetic Operations ----- */ -#define UML_FDLOAD(block, dst, base, index) do { drcuml_block_append_3(block, DRCUML_OP_FLOAD, 8, IF_ALWAYS, dst, MEM(base), index); } while (0) -#define UML_FDSTORE(block, base, index, src1) do { drcuml_block_append_3(block, DRCUML_OP_FSTORE, 8, IF_ALWAYS, MEM(base), index, src1); } while (0) -#define UML_FDREAD(block, dst, src1, space) do { drcuml_block_append_3(block, DRCUML_OP_FREAD, 8, IF_ALWAYS, dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0) -#define UML_FDWRITE(block, dst, src1, space) do { drcuml_block_append_3(block, DRCUML_OP_FWRITE, 8, IF_ALWAYS, dst, src1, IMM(ADDRESS_SPACE_##space)); } while (0) -#define UML_FDMOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 8, cond, dst, src1); } while (0) -#define UML_FDTOINT(block, dst, src1, size, round) do { drcuml_block_append_4(block, DRCUML_OP_FTOINT, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size), IMM(DRCUML_FMOD_##round)); } while (0) -#define UML_FDFRINT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_FFRINT, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_FDFRFLT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_FFRFLT, 8, IF_ALWAYS, dst, src1, IMM(DRCUML_SIZE_##size)); } while (0) -#define UML_FDRNDS(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRNDS, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FADD, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FDSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FSUB, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FDCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_FCMP, 8, IF_ALWAYS, src1, src2); } while (0) -#define UML_FDMUL(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FMUL, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FDDIV(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FDIV, 8, IF_ALWAYS, dst, src1, src2); } while (0) -#define UML_FDNEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FNEG, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDABS(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FABS, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FSQRT, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDRECIP(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRECIP, 8, IF_ALWAYS, dst, src1); } while (0) -#define UML_FDRSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRSQRT, 8, IF_ALWAYS, dst, src1); } while (0) +#define UML_FDLOAD(block, dst, base, index) do { block->append().fdload(dst, base, index); } while (0) +#define UML_FDSTORE(block, base, index, src1) do { block->append().fdstore(base, index, src1); } while (0) +#define UML_FDREAD(block, dst, src1, space) do { block->append().fdread(dst, src1, ADDRESS_SPACE_##space); } while (0) +#define UML_FDWRITE(block, dst, src1, space) do { block->append().fdwrite(dst, src1, ADDRESS_SPACE_##space); } while (0) +#define UML_FDMOV(block, dst, src1) do { block->append().fdmov(dst, src1); } while (0) +#define UML_FDMOVc(block, cond, dst, src1) do { block->append().fdmov(cond, dst, src1); } while (0) +#define UML_FDTOINT(block, dst, src1, size, round) do { block->append().fdtoint(dst, src1, size, round); } while (0) +#define UML_FDFRINT(block, dst, src1, size) do { block->append().fdfrint(dst, src1, size); } while (0) +#define UML_FDFRFLT(block, dst, src1, size) do { block->append().fdfrflt(dst, src1, size); } while (0) +#define UML_FDRNDS(block, dst, src1) do { block->append().fdrnds(dst, src1); } while (0) +#define UML_FDADD(block, dst, src1, src2) do { block->append().fdadd(dst, src1, src2); } while (0) +#define UML_FDSUB(block, dst, src1, src2) do { block->append().fdsub(dst, src1, src2); } while (0) +#define UML_FDCMP(block, src1, src2) do { block->append().fdcmp(src1, src2); } while (0) +#define UML_FDMUL(block, dst, src1, src2) do { block->append().fdmul(dst, src1, src2); } while (0) +#define UML_FDDIV(block, dst, src1, src2) do { block->append().fddiv(dst, src1, src2); } while (0) +#define UML_FDNEG(block, dst, src1) do { block->append().fdneg(dst, src1); } while (0) +#define UML_FDABS(block, dst, src1) do { block->append().fdabs(dst, src1); } while (0) +#define UML_FDSQRT(block, dst, src1) do { block->append().fdsqrt(dst, src1); } while (0) +#define UML_FDRECIP(block, dst, src1) do { block->append().fdrecip(dst, src1); } while (0) +#define UML_FDRSQRT(block, dst, src1) do { block->append().fdrsqrt(dst, src1); } while (0) #endif /* __DRCUMLSH_H__ */ diff --git a/src/emu/cpu/mips/mips3drc.c b/src/emu/cpu/mips/mips3drc.c index 7b84f95aee5..8cfebe39855 100644 --- a/src/emu/cpu/mips/mips3drc.c +++ b/src/emu/cpu/mips/mips3drc.c @@ -65,6 +65,8 @@ extern unsigned dasmmips3(char *buffer, unsigned pc, UINT32 op); #ifdef MIPS3_USE_DRC +using namespace uml; + /*************************************************************************** DEBUGGING ***************************************************************************/ @@ -119,7 +121,7 @@ extern unsigned dasmmips3(char *buffer, unsigned pc, UINT32 op); #define LOPTR(x) ((UINT32 *)(x) + NATIVE_ENDIAN_VALUE_LE_BE(0,1)) -#define R32(reg) mips3->impstate->regmaplo[reg].type, mips3->impstate->regmaplo[reg].value +#define R32(reg) mips3->impstate->regmaplo[reg] #define LO32 R32(REG_LO) #define HI32 R32(REG_HI) #define CPR032(reg) MEM(LOPTR(&mips3->cpr[0][reg])) @@ -129,7 +131,7 @@ extern unsigned dasmmips3(char *buffer, unsigned pc, UINT32 op); #define CPR232(reg) MEM(LOPTR(&mips3->cpr[2][reg])) #define CCR232(reg) MEM(LOPTR(&mips3->ccr[2][reg])) -#define R64(reg) mips3->impstate->regmap[reg].type, mips3->impstate->regmap[reg].value +#define R64(reg) mips3->impstate->regmap[reg] #define LO64 R64(REG_LO) #define HI64 R64(REG_HI) #define CPR064(reg) MEM(&mips3->cpr[0][reg]) @@ -176,7 +178,7 @@ struct _compiler_state UINT32 cycles; /* accumulated cycles */ UINT8 checkints; /* need to check interrupts before next instruction */ UINT8 checksoftints; /* need to check software interrupts before next instruction */ - drcuml_codelabel labelnum; /* index for local labels */ + code_label labelnum; /* index for local labels */ }; @@ -204,28 +206,28 @@ struct _mips3imp_state UINT8 fpmode[4]; /* FPU mode table */ /* register mappings */ - drcuml_parameter regmap[34]; /* parameter to register mappings for all 32 integer registers */ - drcuml_parameter regmaplo[34]; /* parameter to register mappings for all 32 integer registers */ + parameter regmap[34]; /* parameter to register mappings for all 32 integer registers */ + parameter regmaplo[34]; /* parameter to register mappings for all 32 integer registers */ /* subroutines */ - drcuml_codehandle * entry; /* entry point */ - drcuml_codehandle * nocode; /* nocode exception handler */ - drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */ - drcuml_codehandle * tlb_mismatch; /* tlb mismatch handler */ - drcuml_codehandle * read8[3]; /* read byte */ - drcuml_codehandle * write8[3]; /* write byte */ - drcuml_codehandle * read16[3]; /* read half */ - drcuml_codehandle * write16[3]; /* write half */ - drcuml_codehandle * read32[3]; /* read word */ - drcuml_codehandle * read32mask[3]; /* read word masked */ - drcuml_codehandle * write32[3]; /* write word */ - drcuml_codehandle * write32mask[3]; /* write word masked */ - drcuml_codehandle * read64[3]; /* read double */ - drcuml_codehandle * read64mask[3]; /* read double masked */ - drcuml_codehandle * write64[3]; /* write double */ - drcuml_codehandle * write64mask[3]; /* write double masked */ - drcuml_codehandle * exception[EXCEPTION_COUNT]; /* array of exception handlers */ - drcuml_codehandle * exception_norecover[EXCEPTION_COUNT]; /* array of no-recover exception handlers */ + code_handle * entry; /* entry point */ + code_handle * nocode; /* nocode exception handler */ + code_handle * out_of_cycles; /* out of cycles exception handler */ + code_handle * tlb_mismatch; /* tlb mismatch handler */ + code_handle * read8[3]; /* read byte */ + code_handle * write8[3]; /* write byte */ + code_handle * read16[3]; /* read half */ + code_handle * write16[3]; /* write half */ + code_handle * read32[3]; /* read word */ + code_handle * read32mask[3]; /* read word masked */ + code_handle * write32[3]; /* write word */ + code_handle * write32mask[3]; /* write word masked */ + code_handle * read64[3]; /* read double */ + code_handle * read64mask[3]; /* read double masked */ + code_handle * write64[3]; /* write double */ + code_handle * write64mask[3]; /* write double masked */ + code_handle * exception[EXCEPTION_COUNT]; /* array of exception handlers */ + code_handle * exception_norecover[EXCEPTION_COUNT]; /* array of no-recover exception handlers */ /* fast RAM */ UINT32 fastram_select; @@ -254,10 +256,10 @@ static void static_generate_nocode_handler(mips3_state *mips3); static void static_generate_out_of_cycles(mips3_state *mips3); static void static_generate_tlb_mismatch(mips3_state *mips3); static void static_generate_exception(mips3_state *mips3, UINT8 exception, int recover, const char *name); -static void static_generate_memory_accessor(mips3_state *mips3, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr); +static void static_generate_memory_accessor(mips3_state *mips3, int mode, int size, int iswrite, int ismasked, const char *name, code_handle **handleptr); static void generate_update_mode(mips3_state *mips3, drcuml_block *block); -static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception); +static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception); static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); static void generate_delay_slot_and_branch(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg); @@ -288,10 +290,10 @@ static const UINT8 fcc_shift[8] = { 23, 25, 26, 27, 28, 29, 30, 31 }; /* lookup table for FP modes */ static const UINT8 fpmode_source[4] = { - DRCUML_FMOD_ROUND, - DRCUML_FMOD_TRUNC, - DRCUML_FMOD_CEIL, - DRCUML_FMOD_FLOOR + ROUND_ROUND, + ROUND_TRUNC, + ROUND_CEIL, + ROUND_FLOOR }; @@ -339,10 +341,10 @@ INLINE UINT32 epc(const opcode_desc *desc) already allocated -------------------------------------------------*/ -INLINE void alloc_handle(drcuml_state *drcuml, drcuml_codehandle **handleptr, const char *name) +INLINE void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) { if (*handleptr == NULL) - *handleptr = drcuml_handle_alloc(drcuml, name); + *handleptr = drcuml->handle_alloc(name); } @@ -356,8 +358,8 @@ INLINE void load_fast_iregs(mips3_state *mips3, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(mips3->impstate->regmap); regnum++) - if (mips3->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_DMOV(block, IREG(mips3->impstate->regmap[regnum].value - DRCUML_REG_I0), MEM(&mips3->r[regnum])); + if (mips3->impstate->regmap[regnum].is_int_register()) + UML_DMOV(block, IREG(mips3->impstate->regmap[regnum].ireg() - REG_I0), MEM(&mips3->r[regnum])); } @@ -371,8 +373,8 @@ INLINE void save_fast_iregs(mips3_state *mips3, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(mips3->impstate->regmap); regnum++) - if (mips3->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_DMOV(block, MEM(&mips3->r[regnum]), IREG(mips3->impstate->regmap[regnum].value - DRCUML_REG_I0)); + if (mips3->impstate->regmap[regnum].is_int_register()) + UML_DMOV(block, MEM(&mips3->r[regnum]), IREG(mips3->impstate->regmap[regnum].ireg() - REG_I0)); } @@ -417,52 +419,50 @@ static void mips3_init(mips3_flavor flavor, int bigendian, legacy_cpu_device *de flags |= DRCUML_OPTION_LOG_UML; if (LOG_NATIVE) flags |= DRCUML_OPTION_LOG_NATIVE; - mips3->impstate->drcuml = drcuml_alloc(device, cache, flags, 8, 32, 2); - if (mips3->impstate->drcuml == NULL) - fatalerror("Error initializing the UML"); + mips3->impstate->drcuml = auto_alloc(device->machine, drcuml_state(*device, *cache, flags, 8, 32, 2)); /* add symbols for our stuff */ - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->pc, sizeof(mips3->pc), "pc"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->icount, sizeof(mips3->icount), "icount"); + mips3->impstate->drcuml->symbol_add(&mips3->pc, sizeof(mips3->pc), "pc"); + mips3->impstate->drcuml->symbol_add(&mips3->icount, sizeof(mips3->icount), "icount"); for (regnum = 0; regnum < 32; regnum++) { char buf[10]; sprintf(buf, "r%d", regnum); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[regnum], sizeof(mips3->r[regnum]), buf); + mips3->impstate->drcuml->symbol_add(&mips3->r[regnum], sizeof(mips3->r[regnum]), buf); sprintf(buf, "f%d", regnum); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[1][regnum], sizeof(mips3->cpr[1][regnum]), buf); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[1][regnum], sizeof(mips3->cpr[1][regnum]), buf); } - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[REG_LO], sizeof(mips3->r[REG_LO]), "lo"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->r[REG_HI], sizeof(mips3->r[REG_LO]), "hi"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Index], sizeof(mips3->cpr[0][COP0_Index]), "Index"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Random], sizeof(mips3->cpr[0][COP0_Random]), "Random"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryLo0], sizeof(mips3->cpr[0][COP0_EntryLo0]), "EntryLo0"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryLo1], sizeof(mips3->cpr[0][COP0_EntryLo1]), "EntryLo1"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Context], sizeof(mips3->cpr[0][COP0_Context]), "Context"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_PageMask], sizeof(mips3->cpr[0][COP0_PageMask]), "PageMask"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Wired], sizeof(mips3->cpr[0][COP0_Wired]), "Wired"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_BadVAddr], sizeof(mips3->cpr[0][COP0_BadVAddr]), "BadVAddr"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Count], sizeof(mips3->cpr[0][COP0_Count]), "Count"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EntryHi], sizeof(mips3->cpr[0][COP0_EntryHi]), "EntryHi"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Compare], sizeof(mips3->cpr[0][COP0_Compare]), "Compare"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Status], sizeof(mips3->cpr[0][COP0_Status]), "Status"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Cause], sizeof(mips3->cpr[0][COP0_Cause]), "Cause"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_EPC], sizeof(mips3->cpr[0][COP0_EPC]), "EPC"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_PRId], sizeof(mips3->cpr[0][COP0_PRId]), "PRId"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_Config], sizeof(mips3->cpr[0][COP0_Config]), "Config"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_LLAddr], sizeof(mips3->cpr[0][COP0_LLAddr]), "LLAddr"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_XContext], sizeof(mips3->cpr[0][COP0_XContext]), "XContext"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_ECC], sizeof(mips3->cpr[0][COP0_ECC]), "ECC"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_CacheErr], sizeof(mips3->cpr[0][COP0_CacheErr]), "CacheErr"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_TagLo], sizeof(mips3->cpr[0][COP0_TagLo]), "TagLo"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_TagHi], sizeof(mips3->cpr[0][COP0_TagHi]), "TagHi"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->cpr[0][COP0_ErrorPC], sizeof(mips3->cpr[0][COP0_ErrorPC]), "ErrorPC"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->ccr[1][31], sizeof(mips3->cpr[1][31]), "fcr31"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->mode, sizeof(mips3->impstate->mode), "mode"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->arg0, sizeof(mips3->impstate->arg0), "arg0"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->arg1, sizeof(mips3->impstate->arg1), "arg1"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->numcycles, sizeof(mips3->impstate->numcycles), "numcycles"); - drcuml_symbol_add(mips3->impstate->drcuml, &mips3->impstate->fpmode, sizeof(mips3->impstate->fpmode), "fpmode"); + mips3->impstate->drcuml->symbol_add(&mips3->r[REG_LO], sizeof(mips3->r[REG_LO]), "lo"); + mips3->impstate->drcuml->symbol_add(&mips3->r[REG_HI], sizeof(mips3->r[REG_LO]), "hi"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Index], sizeof(mips3->cpr[0][COP0_Index]), "Index"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Random], sizeof(mips3->cpr[0][COP0_Random]), "Random"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_EntryLo0], sizeof(mips3->cpr[0][COP0_EntryLo0]), "EntryLo0"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_EntryLo1], sizeof(mips3->cpr[0][COP0_EntryLo1]), "EntryLo1"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Context], sizeof(mips3->cpr[0][COP0_Context]), "Context"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_PageMask], sizeof(mips3->cpr[0][COP0_PageMask]), "PageMask"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Wired], sizeof(mips3->cpr[0][COP0_Wired]), "Wired"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_BadVAddr], sizeof(mips3->cpr[0][COP0_BadVAddr]), "BadVAddr"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Count], sizeof(mips3->cpr[0][COP0_Count]), "Count"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_EntryHi], sizeof(mips3->cpr[0][COP0_EntryHi]), "EntryHi"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Compare], sizeof(mips3->cpr[0][COP0_Compare]), "Compare"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Status], sizeof(mips3->cpr[0][COP0_Status]), "Status"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Cause], sizeof(mips3->cpr[0][COP0_Cause]), "Cause"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_EPC], sizeof(mips3->cpr[0][COP0_EPC]), "EPC"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_PRId], sizeof(mips3->cpr[0][COP0_PRId]), "PRId"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_Config], sizeof(mips3->cpr[0][COP0_Config]), "Config"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_LLAddr], sizeof(mips3->cpr[0][COP0_LLAddr]), "LLAddr"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_XContext], sizeof(mips3->cpr[0][COP0_XContext]), "XContext"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_ECC], sizeof(mips3->cpr[0][COP0_ECC]), "ECC"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_CacheErr], sizeof(mips3->cpr[0][COP0_CacheErr]), "CacheErr"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_TagLo], sizeof(mips3->cpr[0][COP0_TagLo]), "TagLo"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_TagHi], sizeof(mips3->cpr[0][COP0_TagHi]), "TagHi"); + mips3->impstate->drcuml->symbol_add(&mips3->cpr[0][COP0_ErrorPC], sizeof(mips3->cpr[0][COP0_ErrorPC]), "ErrorPC"); + mips3->impstate->drcuml->symbol_add(&mips3->ccr[1][31], sizeof(mips3->cpr[1][31]), "fcr31"); + mips3->impstate->drcuml->symbol_add(&mips3->impstate->mode, sizeof(mips3->impstate->mode), "mode"); + mips3->impstate->drcuml->symbol_add(&mips3->impstate->arg0, sizeof(mips3->impstate->arg0), "arg0"); + mips3->impstate->drcuml->symbol_add(&mips3->impstate->arg1, sizeof(mips3->impstate->arg1), "arg1"); + mips3->impstate->drcuml->symbol_add(&mips3->impstate->numcycles, sizeof(mips3->impstate->numcycles), "numcycles"); + mips3->impstate->drcuml->symbol_add(&mips3->impstate->fpmode, sizeof(mips3->impstate->fpmode), "fpmode"); /* initialize the front-end helper */ mips3->impstate->drcfe = auto_alloc(device->machine, mips3_frontend(*mips3, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE)); @@ -473,30 +473,28 @@ static void mips3_init(mips3_flavor flavor, int bigendian, legacy_cpu_device *de /* compute the register parameters */ for (regnum = 0; regnum < 34; regnum++) { - mips3->impstate->regmap[regnum].type = (regnum == 0) ? DRCUML_PTYPE_IMMEDIATE : DRCUML_PTYPE_MEMORY; - mips3->impstate->regmap[regnum].value = (regnum == 0) ? 0 : (FPTR)&mips3->r[regnum]; - mips3->impstate->regmaplo[regnum].type = (regnum == 0) ? DRCUML_PTYPE_IMMEDIATE : DRCUML_PTYPE_MEMORY; - mips3->impstate->regmaplo[regnum].value = (regnum == 0) ? 0 : (FPTR)LOPTR(&mips3->r[regnum]); + mips3->impstate->regmap[regnum] = (regnum == 0) ? parameter(0) : parameter::make_memory(&mips3->r[regnum]); + mips3->impstate->regmaplo[regnum] = (regnum == 0) ? parameter(0) : parameter::make_memory(LOPTR(&mips3->r[regnum])); } /* if we have registers to spare, assign r2, r3, r4 to leftovers */ if (!DISABLE_FAST_REGISTERS) { - drcuml_get_backend_info(mips3->impstate->drcuml, &beinfo); + mips3->impstate->drcuml->get_backend_info(beinfo); if (beinfo.direct_iregs > 4) { - mips3->impstate->regmap[2].type = mips3->impstate->regmaplo[2].type = DRCUML_PTYPE_INT_REGISTER; - mips3->impstate->regmap[2].value = mips3->impstate->regmaplo[2].value = DRCUML_REG_I4; + mips3->impstate->regmap[2] = IREG(4); + mips3->impstate->regmaplo[2] = IREG(4); } if (beinfo.direct_iregs > 5) { - mips3->impstate->regmap[3].type = mips3->impstate->regmaplo[3].type = DRCUML_PTYPE_INT_REGISTER; - mips3->impstate->regmap[3].value = mips3->impstate->regmaplo[3].value = DRCUML_REG_I5; + mips3->impstate->regmap[3] = IREG(5); + mips3->impstate->regmaplo[3] = IREG(5); } if (beinfo.direct_iregs > 6) { - mips3->impstate->regmap[4].type = mips3->impstate->regmaplo[4].type = DRCUML_PTYPE_INT_REGISTER; - mips3->impstate->regmap[4].value = mips3->impstate->regmaplo[4].value = DRCUML_REG_I6; + mips3->impstate->regmap[4] = IREG(6); + mips3->impstate->regmaplo[4] = IREG(6); } } @@ -540,7 +538,7 @@ static CPU_EXECUTE( mips3 ) do { /* run as much as we can */ - execute_result = drcuml_execute(drcuml, mips3->impstate->entry); + execute_result = drcuml->execute(*mips3->impstate->entry); /* if we need to recompile, do it */ if (execute_result == EXECUTE_MISSING_CODE) @@ -565,7 +563,7 @@ static CPU_EXIT( mips3 ) /* clean up the DRC */ auto_free(device->machine, mips3->impstate->drcfe); - drcuml_free(mips3->impstate->drcuml); + auto_free(device->machine, mips3->impstate->drcuml); auto_free(device->machine, mips3->impstate->cache); } @@ -701,46 +699,53 @@ static void code_flush_cache(mips3_state *mips3) int mode; /* empty the transient cache contents */ - drcuml_reset(mips3->impstate->drcuml); - - /* generate the entry point and out-of-cycles handlers */ - static_generate_entry_point(mips3); - static_generate_nocode_handler(mips3); - static_generate_out_of_cycles(mips3); - static_generate_tlb_mismatch(mips3); - - /* append exception handlers for various types */ - static_generate_exception(mips3, EXCEPTION_INTERRUPT, TRUE, "exception_interrupt"); - static_generate_exception(mips3, EXCEPTION_INTERRUPT, FALSE, "exception_interrupt_norecover"); - static_generate_exception(mips3, EXCEPTION_TLBMOD, TRUE, "exception_tlbmod"); - static_generate_exception(mips3, EXCEPTION_TLBLOAD, TRUE, "exception_tlbload"); - static_generate_exception(mips3, EXCEPTION_TLBSTORE, TRUE, "exception_tlbstore"); - static_generate_exception(mips3, EXCEPTION_TLBLOAD_FILL, TRUE, "exception_tlbload_fill"); - static_generate_exception(mips3, EXCEPTION_TLBSTORE_FILL, TRUE, "exception_tlbstore_fill"); - static_generate_exception(mips3, EXCEPTION_ADDRLOAD, TRUE, "exception_addrload"); - static_generate_exception(mips3, EXCEPTION_ADDRSTORE, TRUE, "exception_addrstore"); - static_generate_exception(mips3, EXCEPTION_SYSCALL, TRUE, "exception_syscall"); - static_generate_exception(mips3, EXCEPTION_BREAK, TRUE, "exception_break"); - static_generate_exception(mips3, EXCEPTION_INVALIDOP, TRUE, "exception_invalidop"); - static_generate_exception(mips3, EXCEPTION_BADCOP, TRUE, "exception_badcop"); - static_generate_exception(mips3, EXCEPTION_OVERFLOW, TRUE, "exception_overflow"); - static_generate_exception(mips3, EXCEPTION_TRAP, TRUE, "exception_trap"); - - /* add subroutines for memory accesses */ - for (mode = 0; mode < 3; mode++) + mips3->impstate->drcuml->reset(); + + try { - static_generate_memory_accessor(mips3, mode, 1, FALSE, FALSE, "read8", &mips3->impstate->read8[mode]); - static_generate_memory_accessor(mips3, mode, 1, TRUE, FALSE, "write8", &mips3->impstate->write8[mode]); - static_generate_memory_accessor(mips3, mode, 2, FALSE, FALSE, "read16", &mips3->impstate->read16[mode]); - static_generate_memory_accessor(mips3, mode, 2, TRUE, FALSE, "write16", &mips3->impstate->write16[mode]); - static_generate_memory_accessor(mips3, mode, 4, FALSE, FALSE, "read32", &mips3->impstate->read32[mode]); - static_generate_memory_accessor(mips3, mode, 4, FALSE, TRUE, "read32mask", &mips3->impstate->read32mask[mode]); - static_generate_memory_accessor(mips3, mode, 4, TRUE, FALSE, "write32", &mips3->impstate->write32[mode]); - static_generate_memory_accessor(mips3, mode, 4, TRUE, TRUE, "write32mask", &mips3->impstate->write32mask[mode]); - static_generate_memory_accessor(mips3, mode, 8, FALSE, FALSE, "read64", &mips3->impstate->read64[mode]); - static_generate_memory_accessor(mips3, mode, 8, FALSE, TRUE, "read64mask", &mips3->impstate->read64mask[mode]); - static_generate_memory_accessor(mips3, mode, 8, TRUE, FALSE, "write64", &mips3->impstate->write64[mode]); - static_generate_memory_accessor(mips3, mode, 8, TRUE, TRUE, "write64mask", &mips3->impstate->write64mask[mode]); + /* generate the entry point and out-of-cycles handlers */ + static_generate_entry_point(mips3); + static_generate_nocode_handler(mips3); + static_generate_out_of_cycles(mips3); + static_generate_tlb_mismatch(mips3); + + /* append exception handlers for various types */ + static_generate_exception(mips3, EXCEPTION_INTERRUPT, TRUE, "exception_interrupt"); + static_generate_exception(mips3, EXCEPTION_INTERRUPT, FALSE, "exception_interrupt_norecover"); + static_generate_exception(mips3, EXCEPTION_TLBMOD, TRUE, "exception_tlbmod"); + static_generate_exception(mips3, EXCEPTION_TLBLOAD, TRUE, "exception_tlbload"); + static_generate_exception(mips3, EXCEPTION_TLBSTORE, TRUE, "exception_tlbstore"); + static_generate_exception(mips3, EXCEPTION_TLBLOAD_FILL, TRUE, "exception_tlbload_fill"); + static_generate_exception(mips3, EXCEPTION_TLBSTORE_FILL, TRUE, "exception_tlbstore_fill"); + static_generate_exception(mips3, EXCEPTION_ADDRLOAD, TRUE, "exception_addrload"); + static_generate_exception(mips3, EXCEPTION_ADDRSTORE, TRUE, "exception_addrstore"); + static_generate_exception(mips3, EXCEPTION_SYSCALL, TRUE, "exception_syscall"); + static_generate_exception(mips3, EXCEPTION_BREAK, TRUE, "exception_break"); + static_generate_exception(mips3, EXCEPTION_INVALIDOP, TRUE, "exception_invalidop"); + static_generate_exception(mips3, EXCEPTION_BADCOP, TRUE, "exception_badcop"); + static_generate_exception(mips3, EXCEPTION_OVERFLOW, TRUE, "exception_overflow"); + static_generate_exception(mips3, EXCEPTION_TRAP, TRUE, "exception_trap"); + + /* add subroutines for memory accesses */ + for (mode = 0; mode < 3; mode++) + { + static_generate_memory_accessor(mips3, mode, 1, FALSE, FALSE, "read8", &mips3->impstate->read8[mode]); + static_generate_memory_accessor(mips3, mode, 1, TRUE, FALSE, "write8", &mips3->impstate->write8[mode]); + static_generate_memory_accessor(mips3, mode, 2, FALSE, FALSE, "read16", &mips3->impstate->read16[mode]); + static_generate_memory_accessor(mips3, mode, 2, TRUE, FALSE, "write16", &mips3->impstate->write16[mode]); + static_generate_memory_accessor(mips3, mode, 4, FALSE, FALSE, "read32", &mips3->impstate->read32[mode]); + static_generate_memory_accessor(mips3, mode, 4, FALSE, TRUE, "read32mask", &mips3->impstate->read32mask[mode]); + static_generate_memory_accessor(mips3, mode, 4, TRUE, FALSE, "write32", &mips3->impstate->write32[mode]); + static_generate_memory_accessor(mips3, mode, 4, TRUE, TRUE, "write32mask", &mips3->impstate->write32mask[mode]); + static_generate_memory_accessor(mips3, mode, 8, FALSE, FALSE, "read64", &mips3->impstate->read64[mode]); + static_generate_memory_accessor(mips3, mode, 8, FALSE, TRUE, "read64mask", &mips3->impstate->read64mask[mode]); + static_generate_memory_accessor(mips3, mode, 8, TRUE, FALSE, "write64", &mips3->impstate->write64[mode]); + static_generate_memory_accessor(mips3, mode, 8, TRUE, TRUE, "write64mask", &mips3->impstate->write64mask[mode]); + } + } + catch (drcuml_block::abort_compilation &) + { + fatalerror("Unrecoverable error generating static code"); } } @@ -758,7 +763,6 @@ static void code_compile_block(mips3_state *mips3, UINT8 mode, offs_t pc) const opcode_desc *desclist; int override = FALSE; drcuml_block *block; - jmp_buf errorbuf; g_profiler.start(PROFILER_DRC_COMPILE); @@ -768,84 +772,93 @@ static void code_compile_block(mips3_state *mips3, UINT8 mode, offs_t pc) log_opcode_desc(drcuml, desclist, 0); /* if we get an error back, flush the cache and try again */ - if (setjmp(errorbuf) != 0) - code_flush_cache(mips3); - - /* start the block */ - block = drcuml_block_begin(drcuml, 4096, &errorbuf); - - /* loop until we get through all instruction sequences */ - for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + bool succeeded = false; + while (!succeeded) { - const opcode_desc *curdesc; - UINT32 nextpc; - - /* add a code log entry */ - if (LOG_UML) - UML_COMMENT(block, "-------------------------"); // comment - - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != NULL); - - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml_hash_exists(drcuml, mode, seqhead->pc)) - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) + try { - override = TRUE; - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - } + /* start the block */ + block = drcuml->begin_block(4096); - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(seqhead->pc), mips3->impstate->nocode); - // hashjmp <mode>,seqhead->pc,nocode - continue; - } + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + UINT32 nextpc; + + /* add a code log entry */ + if (LOG_UML) + block->append_comment("-------------------------"); // comment + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != NULL); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(mode, seqhead->pc)) + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = TRUE; + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + } + + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(seqhead->pc), *mips3->impstate->nocode); + // hashjmp <mode>,seqhead->pc,nocode + continue; + } - /* validate this code block if we're not pointing into ROM */ - if (mips3->program->get_write_ptr(seqhead->physpc) != NULL) - generate_checksum_block(mips3, block, &compiler, seqhead, seqlast); + /* validate this code block if we're not pointing into ROM */ + if (mips3->program->get_write_ptr(seqhead->physpc) != NULL) + generate_checksum_block(mips3, block, &compiler, seqhead, seqlast); - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - generate_sequence_instruction(mips3, block, &compiler, curdesc); + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + generate_sequence_instruction(mips3, block, &compiler, curdesc); - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - nextpc = pc; + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + nextpc = pc; - /* otherwise we just go to the next instruction */ - else - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; - - /* count off cycles and go there */ - generate_update_cycles(mips3, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> - - /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ - if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) - UML_HASHJMP(block, MEM(&mips3->impstate->mode), IMM(nextpc), mips3->impstate->nocode); - // hashjmp <mode>,nextpc,nocode - else if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) - UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(nextpc), mips3->impstate->nocode); - // hashjmp <mode>,nextpc,nocode - } + /* otherwise we just go to the next instruction */ + else + nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; + + /* count off cycles and go there */ + generate_update_cycles(mips3, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> + + /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ + if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) + UML_HASHJMP(block, MEM(&mips3->impstate->mode), IMM(nextpc), *mips3->impstate->nocode); + // hashjmp <mode>,nextpc,nocode + else if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) + UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(nextpc), *mips3->impstate->nocode); + // hashjmp <mode>,nextpc,nocode + } - /* end the sequence */ - drcuml_block_end(block); - g_profiler.stop(); + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; + } + catch (drcuml_block::abort_compilation &) + { + code_flush_cache(mips3); + } + } } @@ -972,27 +985,21 @@ static void cfunc_unimplemented(void *param) static void static_generate_entry_point(mips3_state *mips3) { drcuml_state *drcuml = mips3->impstate->drcuml; - drcuml_codelabel skip = 1; + code_label skip = 1; drcuml_block *block; - jmp_buf errorbuf; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_entry_point"); - - /* begin generating */ - block = drcuml_block_begin(drcuml, 20, &errorbuf); + block = drcuml->begin_block(20); /* forward references */ alloc_handle(drcuml, &mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT], "interrupt_norecover"); alloc_handle(drcuml, &mips3->impstate->nocode, "nocode"); alloc_handle(drcuml, &mips3->impstate->entry, "entry"); - UML_HANDLE(block, mips3->impstate->entry); // handle entry + UML_HANDLE(block, *mips3->impstate->entry); // handle entry /* reset the FPU mode */ UML_AND(block, IREG(0), CCR132(31), IMM(3)); // and i0,ccr1[31],3 - UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), BYTE); // load i0,fpmode,i0,byte + UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), SIZE_BYTE, SCALE_x1);// load i0,fpmode,i0,byte UML_SETFMOD(block, IREG(0)); // setfmod i0 /* load fast integer registers */ @@ -1008,13 +1015,13 @@ static void static_generate_entry_point(mips3_state *mips3) UML_JMPc(block, IF_NZ, skip); // jmp skip,NZ UML_MOV(block, IREG(0), MEM(&mips3->pc)); // mov i0,pc UML_MOV(block, IREG(1), IMM(0)); // mov i1,0 - UML_CALLH(block, mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]); // callh exception_norecover + UML_CALLH(block, *mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]); // callh exception_norecover UML_LABEL(block, skip); // skip: /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, MEM(&mips3->impstate->mode), MEM(&mips3->pc), mips3->impstate->nocode); + UML_HASHJMP(block, MEM(&mips3->impstate->mode), MEM(&mips3->pc), *mips3->impstate->nocode); // hashjmp <mode>,<pc>,nocode - drcuml_block_end(block); + block->end(); } @@ -1027,24 +1034,19 @@ static void static_generate_nocode_handler(mips3_state *mips3) { drcuml_state *drcuml = mips3->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_nocode_handler"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &mips3->impstate->nocode, "nocode"); - UML_HANDLE(block, mips3->impstate->nocode); // handle nocode + UML_HANDLE(block, *mips3->impstate->nocode); // handle nocode UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&mips3->pc), IREG(0)); // mov [pc],i0 save_fast_iregs(mips3, block); UML_EXIT(block, IMM(EXECUTE_MISSING_CODE)); // exit EXECUTE_MISSING_CODE - drcuml_block_end(block); + block->end(); } @@ -1057,24 +1059,19 @@ static void static_generate_out_of_cycles(mips3_state *mips3) { drcuml_state *drcuml = mips3->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_out_of_cycles"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &mips3->impstate->out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, mips3->impstate->out_of_cycles); // handle out_of_cycles + UML_HANDLE(block, *mips3->impstate->out_of_cycles); // handle out_of_cycles UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&mips3->pc), IREG(0)); // mov <pc>,i0 save_fast_iregs(mips3, block); UML_EXIT(block, IMM(EXECUTE_OUT_OF_CYCLES)); // exit EXECUTE_OUT_OF_CYCLES - drcuml_block_end(block); + block->end(); } @@ -1087,26 +1084,21 @@ static void static_generate_tlb_mismatch(mips3_state *mips3) { drcuml_state *drcuml = mips3->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_tlb_mismatch"); /* forward references */ alloc_handle(drcuml, &mips3->impstate->exception[EXCEPTION_TLBLOAD], "exception_tlbload"); alloc_handle(drcuml, &mips3->impstate->exception[EXCEPTION_TLBLOAD_FILL], "exception_tlbload_fill"); /* begin generating */ - block = drcuml_block_begin(drcuml, 20, &errorbuf); + block = drcuml->begin_block(20); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &mips3->impstate->tlb_mismatch, "tlb_mismatch"); - UML_HANDLE(block, mips3->impstate->tlb_mismatch); // handle tlb_mismatch + UML_HANDLE(block, *mips3->impstate->tlb_mismatch); // handle tlb_mismatch UML_RECOVER(block, IREG(0), MAPVAR_PC); // recover i0,PC UML_MOV(block, MEM(&mips3->pc), IREG(0)); // mov <pc>,i0 UML_SHR(block, IREG(1), IREG(0), IMM(12)); // shr i1,i0,12 - UML_LOAD(block, IREG(1), (void *)vtlb_table(mips3->vtlb), IREG(1), DWORD); // load i1,[vtlb_table],i1,dword + UML_LOAD(block, IREG(1), (void *)vtlb_table(mips3->vtlb), IREG(1), SIZE_DWORD, SCALE_x4);// load i1,[vtlb_table],i1,dword if (PRINTF_MMU) { static const char text[] = "TLB mismatch @ %08X (ent=%08X)\n"; @@ -1118,8 +1110,8 @@ static void static_generate_tlb_mismatch(mips3_state *mips3) UML_TEST(block, IREG(1), IMM(VTLB_FETCH_ALLOWED)); // test i1,VTLB_FETCH_ALLOWED UML_JMPc(block, IF_NZ, 1); // jmp 1,nz UML_TEST(block, IREG(1), IMM(VTLB_FLAG_FIXED)); // test i1,VTLB_FLAG_FIXED - UML_EXHc(block, IF_NZ, mips3->impstate->exception[EXCEPTION_TLBLOAD], IREG(0)); // exh exception[TLBLOAD],i0,nz - UML_EXH(block, mips3->impstate->exception[EXCEPTION_TLBLOAD_FILL], IREG(0)); // exh exception[TLBLOAD_FILL],i0 + UML_EXHc(block, IF_NZ, *mips3->impstate->exception[EXCEPTION_TLBLOAD], IREG(0)); // exh exception[TLBLOAD],i0,nz + UML_EXH(block, *mips3->impstate->exception[EXCEPTION_TLBLOAD_FILL], IREG(0)); // exh exception[TLBLOAD_FILL],i0 UML_LABEL(block, 1); // 1: save_fast_iregs(mips3, block); @@ -1129,7 +1121,7 @@ static void static_generate_tlb_mismatch(mips3_state *mips3) UML_AND(block, MEM(&mips3->pc), IREG(0), IMM(~3)); // and <pc>,i0,~3 UML_EXIT(block, IMM(EXECUTE_MISSING_CODE)); // exit EXECUTE_MISSING_CODE - drcuml_block_end(block); + block->end(); } @@ -1140,17 +1132,12 @@ static void static_generate_tlb_mismatch(mips3_state *mips3) static void static_generate_exception(mips3_state *mips3, UINT8 exception, int recover, const char *name) { - drcuml_codehandle **exception_handle = recover ? &mips3->impstate->exception[exception] : &mips3->impstate->exception_norecover[exception]; + code_handle *&exception_handle = recover ? mips3->impstate->exception[exception] : mips3->impstate->exception_norecover[exception]; drcuml_state *drcuml = mips3->impstate->drcuml; UINT32 offset = 0x180; - drcuml_codelabel next = 1; - drcuml_codelabel skip = 2; + code_label next = 1; + code_label skip = 2; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_exception"); /* translate our fake fill exceptions into real exceptions */ if (exception == EXCEPTION_TLBLOAD_FILL || exception == EXCEPTION_TLBSTORE_FILL) @@ -1160,10 +1147,10 @@ static void static_generate_exception(mips3_state *mips3, UINT8 exception, int r } /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ - alloc_handle(drcuml, exception_handle, name); + alloc_handle(drcuml, &exception_handle, name); UML_HANDLE(block, *exception_handle); // handle name /* exception parameter is expected to be the fault address in this case */ @@ -1229,11 +1216,11 @@ static void static_generate_exception(mips3_state *mips3, UINT8 exception, int r /* adjust cycles */ UML_SUB(block, MEM(&mips3->icount), MEM(&mips3->icount), IREG(1)); // sub icount,icount,cycles,S - UML_EXHc(block, IF_S, mips3->impstate->out_of_cycles, IREG(0)); // exh out_of_cycles,i0 + UML_EXHc(block, IF_S, *mips3->impstate->out_of_cycles, IREG(0)); // exh out_of_cycles,i0 - UML_HASHJMP(block, MEM(&mips3->impstate->mode), IREG(0), mips3->impstate->nocode);// hashjmp <mode>,i0,nocode + UML_HASHJMP(block, MEM(&mips3->impstate->mode), IREG(0), *mips3->impstate->nocode);// hashjmp <mode>,i0,nocode - drcuml_block_end(block); + block->end(); } @@ -1241,31 +1228,26 @@ static void static_generate_exception(mips3_state *mips3, UINT8 exception, int r static_generate_memory_accessor ------------------------------------------------------------------*/ -static void static_generate_memory_accessor(mips3_state *mips3, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr) +static void static_generate_memory_accessor(mips3_state *mips3, int mode, int size, int iswrite, int ismasked, const char *name, code_handle **handleptr) { /* on entry, address is in I0; data for writes is in I1; mask for accesses is in I2 */ /* on exit, read result is in I0 */ /* routine trashes I0-I3 */ - drcuml_codehandle *exception_tlb = mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD]; - drcuml_codehandle *exception_tlbfill = mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE_FILL : EXCEPTION_TLBLOAD_FILL]; - drcuml_codehandle *exception_addrerr = mips3->impstate->exception[iswrite ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD]; + code_handle &exception_tlb = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD]; + code_handle &exception_tlbfill = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE_FILL : EXCEPTION_TLBLOAD_FILL]; + code_handle &exception_addrerr = *mips3->impstate->exception[iswrite ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD]; drcuml_state *drcuml = mips3->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; int tlbmiss = 0; int label = 1; int ramnum; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_exception"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ alloc_handle(drcuml, handleptr, name); - UML_HANDLE(block, *handleptr); // handle *handleptr + UML_HANDLE(block, **handleptr); // handle *handleptr /* user mode? generate address exception if top bit is set */ if (mode == MODE_USER) @@ -1288,7 +1270,7 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si /* general case: assume paging and perform a translation */ UML_SHR(block, IREG(3), IREG(0), IMM(12)); // shr i3,i0,12 - UML_LOAD(block, IREG(3), (void *)vtlb_table(mips3->vtlb), IREG(3), DWORD); // load i3,[vtlb_table],i3,dword + UML_LOAD(block, IREG(3), (void *)vtlb_table(mips3->vtlb), IREG(3), SIZE_DWORD, SCALE_x4);// load i3,[vtlb_table],i3,dword UML_TEST(block, IREG(3), IMM(iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED));// test i3,iswrite ? VTLB_WRITE_ALLOWED : VTLB_READ_ALLOWED UML_JMPc(block, IF_Z, tlbmiss = label++); // jmp tlbmiss,z UML_ROLINS(block, IREG(0), IREG(3), IMM(0), IMM(0xfffff000)); // rolins i0,i3,0,0xfffff000 @@ -1316,21 +1298,21 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si { UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0))); // xor i0,i0,bytexor - UML_LOAD(block, IREG(0), fastbase, IREG(0), BYTE); // load i0,fastbase,i0,byte + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte } else if (size == 2) { UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0))); // xor i0,i0,wordxor - UML_LOAD(block, IREG(0), fastbase, IREG(0), WORD_x1); // load i0,fastbase,i0,word_x1 + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1 } else if (size == 4) { - UML_LOAD(block, IREG(0), fastbase, IREG(0), DWORD_x1); // load i0,fastbase,i0,dword_x1 + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1 } else if (size == 8) { - UML_DLOAD(block, IREG(0), fastbase, IREG(0), QWORD_x1); // dload i0,fastbase,i0,qword_x1 + UML_DLOAD(block, IREG(0), fastbase, IREG(0), SIZE_QWORD, SCALE_x1); // dload i0,fastbase,i0,qword_x1 UML_DROR(block, IREG(0), IREG(0), IMM(32 * (mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0)))); // dror i0,i0,32*bytexor } @@ -1342,24 +1324,24 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si { UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? BYTE4_XOR_BE(0) : BYTE4_XOR_LE(0))); // xor i0,i0,bytexor - UML_STORE(block, fastbase, IREG(0), IREG(1), BYTE); // store fastbase,i0,i1,byte + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_BYTE, SCALE_x1);// store fastbase,i0,i1,byte } else if (size == 2) { UML_XOR(block, IREG(0), IREG(0), IMM(mips3->bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0))); // xor i0,i0,wordxor - UML_STORE(block, fastbase, IREG(0), IREG(1), WORD_x1); // store fastbase,i0,i1,word_x1 + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_WORD, SCALE_x1);// store fastbase,i0,i1,word_x1 } else if (size == 4) { if (ismasked) { - UML_LOAD(block, IREG(3), fastbase, IREG(0), DWORD_x1); // load i3,fastbase,i0,dword_x1 + UML_LOAD(block, IREG(3), fastbase, IREG(0), SIZE_DWORD, SCALE_x1); // load i3,fastbase,i0,dword_x1 UML_ROLINS(block, IREG(3), IREG(1), IMM(0), IREG(2)); // rolins i3,i1,0,i2 - UML_STORE(block, fastbase, IREG(0), IREG(3), DWORD_x1); // store fastbase,i0,i3,dword_x1 + UML_STORE(block, fastbase, IREG(0), IREG(3), SIZE_DWORD, SCALE_x1); // store fastbase,i0,i3,dword_x1 } else - UML_STORE(block, fastbase, IREG(0), IREG(1), DWORD_x1); // store fastbase,i0,i1,dword_x1 + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1 } else if (size == 8) { @@ -1369,12 +1351,12 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si { UML_DROR(block, IREG(2), IREG(2), IMM(32 * (mips3->bigendian ? BYTE_XOR_BE(0) : BYTE_XOR_LE(0)))); // dror i2,i2,32*bytexor - UML_DLOAD(block, IREG(3), fastbase, IREG(0), QWORD_x1); // dload i3,fastbase,i0,qword_x1 + UML_DLOAD(block, IREG(3), fastbase, IREG(0), SIZE_QWORD, SCALE_x1); // dload i3,fastbase,i0,qword_x1 UML_DROLINS(block, IREG(3), IREG(1), IMM(0), IREG(2)); // drolins i3,i1,0,i2 - UML_DSTORE(block, fastbase, IREG(0), IREG(3), QWORD_x1); // dstore fastbase,i0,i3,qword_x1 + UML_DSTORE(block, fastbase, IREG(0), IREG(3), SIZE_QWORD, SCALE_x1); // dstore fastbase,i0,i3,qword_x1 } else - UML_DSTORE(block, fastbase, IREG(0), IREG(1), QWORD_x1); // dstore fastbase,i0,i1,qword_x1 + UML_DSTORE(block, fastbase, IREG(0), IREG(1), SIZE_QWORD, SCALE_x1); // dstore fastbase,i0,i1,qword_x1 } UML_RET(block); // ret } @@ -1386,32 +1368,32 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si { case 1: if (iswrite) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_BYTE); // write i0,i1,program_byte + UML_WRITE(block, IREG(0), IREG(1), SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte else - UML_READ(block, IREG(0), IREG(0), PROGRAM_BYTE); // read i0,i0,program_byte + UML_READ(block, IREG(0), IREG(0), SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte break; case 2: if (iswrite) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_WORD); // write i0,i1,program_word + UML_WRITE(block, IREG(0), IREG(1), SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word else - UML_READ(block, IREG(0), IREG(0), PROGRAM_WORD); // read i0,i0,program_word + UML_READ(block, IREG(0), IREG(0), SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word break; case 4: if (iswrite) { if (!ismasked) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_DWORD); // write i0,i1,program_dword + UML_WRITE(block, IREG(0), IREG(1), SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword else - UML_WRITEM(block, IREG(0), IREG(1), IREG(2), PROGRAM_DWORD); // writem i0,i1,i2,program_dword + UML_WRITEM(block, IREG(0), IREG(1), IREG(2), SIZE_DWORD, SPACE_PROGRAM); // writem i0,i1,i2,program_dword } else { if (!ismasked) - UML_READ(block, IREG(0), IREG(0), PROGRAM_DWORD); // read i0,i0,program_dword + UML_READ(block, IREG(0), IREG(0), SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword else - UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_DWORD); // readm i0,i0,i2,program_dword + UML_READM(block, IREG(0), IREG(0), IREG(2), SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword } break; @@ -1419,16 +1401,16 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si if (iswrite) { if (!ismasked) - UML_DWRITE(block, IREG(0), IREG(1), PROGRAM_QWORD); // dwrite i0,i1,program_qword + UML_DWRITE(block, IREG(0), IREG(1), SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword else - UML_DWRITEM(block, IREG(0), IREG(1), IREG(2), PROGRAM_QWORD); // dwritem i0,i1,i2,program_qword + UML_DWRITEM(block, IREG(0), IREG(1), IREG(2), SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i1,i2,program_qword } else { if (!ismasked) - UML_DREAD(block, IREG(0), IREG(0), PROGRAM_QWORD); // dread i0,i0,program_qword + UML_DREAD(block, IREG(0), IREG(0), SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword else - UML_DREADM(block, IREG(0), IREG(0), IREG(2), PROGRAM_QWORD); // dreadm i0,i0,i2,program_qword + UML_DREADM(block, IREG(0), IREG(0), IREG(2), SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword } break; } @@ -1440,7 +1422,7 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si if (iswrite) { UML_TEST(block, IREG(3), IMM(VTLB_READ_ALLOWED)); // test i3,VTLB_READ_ALLOWED - UML_EXHc(block, IF_NZ, mips3->impstate->exception[EXCEPTION_TLBMOD], IREG(0)); + UML_EXHc(block, IF_NZ, *mips3->impstate->exception[EXCEPTION_TLBMOD], IREG(0)); // exh tlbmod,i0,nz } UML_TEST(block, IREG(3), IMM(VTLB_FLAG_FIXED)); // test i3,VTLB_FLAG_FIXED @@ -1448,7 +1430,7 @@ static void static_generate_memory_accessor(mips3_state *mips3, int mode, int si UML_EXH(block, exception_tlbfill, IREG(0)); // exh tlbfill,i0 } - drcuml_block_end(block); + block->end(); } @@ -1478,27 +1460,27 @@ static void generate_update_mode(mips3_state *mips3, drcuml_block *block) an exception if out -------------------------------------------------*/ -static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception) +static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception) { /* check software interrupts if pending */ if (compiler->checksoftints) { - drcuml_codelabel skip; + code_label skip; compiler->checksoftints = FALSE; UML_AND(block, IREG(0), CPR032(COP0_Cause), CPR032(COP0_Status)); // and i0,[Cause],[Status] UML_AND(block, IREG(0), IREG(0), IMM(0x0300)); // and i0,i0,0x0300 UML_JMPc(block, IF_Z, skip = compiler->labelnum++); // jmp skip,Z - UML_MOV(block, IREG(0), PARAM(ptype, pvalue)); // mov i0,nextpc + UML_MOV(block, IREG(0), param); // mov i0,nextpc UML_MOV(block, IREG(1), IMM(compiler->cycles)); // mov i1,cycles - UML_CALLH(block, mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]);// callh interrupt_norecover + UML_CALLH(block, *mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]);// callh interrupt_norecover UML_LABEL(block, skip); // skip: } /* check full interrupts if pending */ if (compiler->checkints) { - drcuml_codelabel skip; + code_label skip; compiler->checkints = FALSE; UML_AND(block, IREG(0), CPR032(COP0_Cause), CPR032(COP0_Status)); // and i0,[Cause],[Status] @@ -1508,9 +1490,9 @@ static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, comp UML_JMPc(block, IF_Z, skip); // jmp skip,Z UML_TEST(block, CPR032(COP0_Status), IMM(SR_EXL | SR_ERL)); // test [Status],SR_EXL | SR_ERL UML_JMPc(block, IF_NZ, skip); // jmp skip,NZ - UML_MOV(block, IREG(0), PARAM(ptype, pvalue)); // mov i0,nextpc + UML_MOV(block, IREG(0), param); // mov i0,nextpc UML_MOV(block, IREG(1), IMM(compiler->cycles)); // mov i1,cycles - UML_CALLH(block, mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]);// callh interrupt_norecover + UML_CALLH(block, *mips3->impstate->exception_norecover[EXCEPTION_INTERRUPT]);// callh interrupt_norecover UML_LABEL(block, skip); // skip: } @@ -1520,7 +1502,7 @@ static void generate_update_cycles(mips3_state *mips3, drcuml_block *block, comp UML_SUB(block, MEM(&mips3->icount), MEM(&mips3->icount), MAPVAR_CYCLES); // sub icount,icount,cycles UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 if (allow_exception) - UML_EXHc(block, IF_S, mips3->impstate->out_of_cycles, PARAM(ptype, pvalue)); + UML_EXHc(block, IF_S, *mips3->impstate->out_of_cycles, param); // exh out_of_cycles,nextpc } compiler->cycles = 0; @@ -1536,7 +1518,7 @@ static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, com { const opcode_desc *curdesc; if (LOG_UML) - UML_COMMENT(block, "[Validation for %08X]", seqhead->pc); // comment + block->append_comment("[Validation for %08X]", seqhead->pc); // comment /* loose verify or single instruction: just compare and fail */ if (!(mips3->impstate->drcoptions & MIPS3DRC_STRICT_VERIFY) || seqhead->next() == NULL) @@ -1544,9 +1526,9 @@ static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, com if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = mips3->direct->read_decrypted_ptr(seqhead->physpc); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,0,dword UML_CMP(block, IREG(0), IMM(seqhead->opptr.l[0])); // cmp i0,opptr[0] - UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } } @@ -1558,33 +1540,33 @@ static void generate_checksum_block(mips3_state *mips3, drcuml_block *block, com if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = mips3->direct->read_decrypted_ptr(seqhead->physpc); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,0,dword UML_CMP(block, IREG(0), IMM(curdesc->opptr.l[0])); // cmp i0,opptr[0] - UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } #else UINT32 sum = 0; void *base = mips3->direct->read_decrypted_ptr(seqhead->physpc); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,0,dword sum += seqhead->opptr.l[0]; for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { base = mips3->direct->read_decrypted_ptr(curdesc->physpc); - UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword + UML_LOAD(block, IREG(1), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i1,base,dword UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1 sum += curdesc->opptr.l[0]; if (curdesc->delay.first() != NULL && (curdesc == seqlast || (curdesc->next() != NULL && curdesc->next()->physpc != curdesc->delay.first()->physpc))) { base = mips3->direct->read_decrypted_ptr(curdesc->delay.first()->physpc); - UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword + UML_LOAD(block, IREG(1), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i1,base,dword UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1 sum += curdesc->delay.first()->opptr.l[0]; } } UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum - UML_EXHc(block, IF_NE, mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *mips3->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc #endif } } @@ -1655,7 +1637,7 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, mips3); // callc printf_debug } - UML_EXH(block, mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 + UML_EXH(block, *mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 } /* validate our TLB entry at this PC; if we fail, we need to handle it */ @@ -1673,9 +1655,9 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, mips3); // callc printf_debug } - UML_LOAD(block, IREG(0), &tlbtable[desc->pc >> 12], IMM(0), DWORD); // load i0,tlbtable[desc->pc >> 12],0,dword + UML_LOAD(block, IREG(0), &tlbtable[desc->pc >> 12], IMM(0), SIZE_DWORD, SCALE_x4); // load i0,tlbtable[desc->pc >> 12],0,dword UML_CMP(block, IREG(0), IMM(tlbtable[desc->pc >> 12])); // cmp i0,*tlbentry - UML_EXHc(block, IF_NE, mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0,NE + UML_EXHc(block, IF_NE, *mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0,NE } /* otherwise, we generate an unconditional exception */ @@ -1688,13 +1670,13 @@ static void generate_sequence_instruction(mips3_state *mips3, drcuml_block *bloc UML_MOV(block, MEM(&mips3->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, mips3); // callc printf_debug } - UML_EXH(block, mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 + UML_EXH(block, *mips3->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 } } /* if this is an invalid opcode, generate the exception now */ if (desc->flags & OPFLAG_INVALID_OPCODE) - UML_EXH(block, mips3->impstate->exception[EXCEPTION_INVALIDOP], IMM(0)); // exh invalidop,0 + UML_EXH(block, *mips3->impstate->exception[EXCEPTION_INVALIDOP], IMM(0)); // exh invalidop,0 /* otherwise, unless this is a virtual no-op, it's a regular instruction */ else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) @@ -1738,14 +1720,14 @@ static void generate_delay_slot_and_branch(mips3_state *mips3, drcuml_block *blo if (desc->flags & OPFLAG_INTRABLOCK_BRANCH) UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000 else - UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(desc->targetpc), mips3->impstate->nocode); + UML_HASHJMP(block, IMM(mips3->impstate->mode), IMM(desc->targetpc), *mips3->impstate->nocode); // hashjmp <mode>,desc->targetpc,nocode } else { generate_update_cycles(mips3, block, &compiler_temp, MEM(&mips3->impstate->jmpdest), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(mips3->impstate->mode), MEM(&mips3->impstate->jmpdest), mips3->impstate->nocode); + UML_HASHJMP(block, IMM(mips3->impstate->mode), MEM(&mips3->impstate->jmpdest), *mips3->impstate->nocode); // hashjmp <mode>,<rsreg>,nocode } @@ -1768,7 +1750,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); UINT32 op = desc->opptr.l[0]; UINT8 opswitch = op >> 26; - drcuml_codelabel skip; + code_label skip; switch (opswitch) { @@ -1842,24 +1824,24 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x08: /* ADDI - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0 if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0,dword + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_DWORD); // dsext <rtreg>,i0,dword return TRUE; case 0x09: /* ADDIU - MIPS I */ if (RTREG != 0) { UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL,V - UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0,dword + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_DWORD); // dsext <rtreg>,i0,dword } return TRUE; case 0x18: /* DADDI - MIPS III */ UML_DADD(block, IREG(0), R64(RSREG), IMM(SIMMVAL)); // dadd i0,<rsreg>,SIMMVAL if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0 if (RTREG != 0) UML_DMOV(block, R64(RTREG), IREG(0)); // dmov <rtreg>,i0 @@ -1906,36 +1888,36 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x20: /* LB - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read8[mips3->impstate->mode >> 1]); // callh read8 + UML_CALLH(block, *mips3->impstate->read8[mips3->impstate->mode >> 1]); // callh read8 if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), IREG(0), BYTE); // dsext <rtreg>,i0,byte + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_BYTE); // dsext <rtreg>,i0,byte if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; case 0x21: /* LH - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read16[mips3->impstate->mode >> 1]); // callh read16 + UML_CALLH(block, *mips3->impstate->read16[mips3->impstate->mode >> 1]); // callh read16 if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), IREG(0), WORD); // dsext <rtreg>,i0,word + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_WORD); // dsext <rtreg>,i0,word if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; case 0x23: /* LW - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0 + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_DWORD); // dsext <rtreg>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; case 0x30: /* LL - MIPS II */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0 + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_DWORD); // dsext <rtreg>,i0 UML_MOV(block, MEM(&mips3->llbit), IMM(1)); // mov [llbit],1 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -1943,7 +1925,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x24: /* LBU - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read8[mips3->impstate->mode >> 1]); // callh read8 + UML_CALLH(block, *mips3->impstate->read8[mips3->impstate->mode >> 1]); // callh read8 if (RTREG != 0) UML_DAND(block, R64(RTREG), IREG(0), IMM(0xff)); // dand <rtreg>,i0,0xff if (!in_delay_slot) @@ -1952,7 +1934,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x25: /* LHU - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read16[mips3->impstate->mode >> 1]); // callh read16 + UML_CALLH(block, *mips3->impstate->read16[mips3->impstate->mode >> 1]); // callh read16 if (RTREG != 0) UML_DAND(block, R64(RTREG), IREG(0), IMM(0xffff)); // dand <rtreg>,i0,0xffff if (!in_delay_slot) @@ -1961,7 +1943,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x27: /* LWU - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 if (RTREG != 0) UML_DAND(block, R64(RTREG), IREG(0), IMM(0xffffffff)); // dand <rtreg>,i0,0xffffffff if (!in_delay_slot) @@ -1970,7 +1952,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x37: /* LD - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 + UML_CALLH(block, *mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 if (RTREG != 0) UML_DMOV(block, R64(RTREG), IREG(0)); // dmov <rtreg>,i0 if (!in_delay_slot) @@ -1979,7 +1961,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x34: /* LLD - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 + UML_CALLH(block, *mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 if (RTREG != 0) UML_DMOV(block, R64(RTREG), IREG(0)); // dmov <rtreg>,i0 UML_MOV(block, MEM(&mips3->llbit), IMM(1)); // mov [llbit],1 @@ -1994,14 +1976,14 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta if (!mips3->bigendian) UML_XOR(block, IREG(1), IREG(1), IMM(0x18)); // xor i1,i1,0x18 UML_SHR(block, IREG(2), IMM(~0), IREG(1)); // shr i2,~0,i1 - UML_CALLH(block, mips3->impstate->read32mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->read32mask[mips3->impstate->mode >> 1]); // callh read32mask if (RTREG != 0) { UML_SHL(block, IREG(2), IMM(~0), IREG(1)); // shl i2,~0,i1 UML_MOV(block, IREG(3), R32(RTREG)); // mov i3,<rtreg> UML_ROLINS(block, IREG(3), IREG(0), IREG(1), IREG(2)); // rolins i3,i0,i1,i2 - UML_DSEXT(block, R64(RTREG), IREG(3), DWORD); // dsext <rtreg>,i3,dword + UML_DSEXT(block, R64(RTREG), IREG(3), SIZE_DWORD); // dsext <rtreg>,i3,dword } if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2014,7 +1996,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta if (mips3->bigendian) UML_XOR(block, IREG(1), IREG(1), IMM(0x18)); // xor i1,i1,0x18 UML_SHL(block, IREG(2), IMM(~0), IREG(1)); // shl i2,~0,i1 - UML_CALLH(block, mips3->impstate->read32mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->read32mask[mips3->impstate->mode >> 1]); // callh read32mask if (RTREG != 0) { @@ -2022,7 +2004,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_SUB(block, IREG(1), IMM(32), IREG(1)); // sub i1,32,i1 UML_MOV(block, IREG(3), R32(RTREG)); // mov i3,<rtreg> UML_ROLINS(block, IREG(3), IREG(0), IREG(1), IREG(2)); // rolins i3,i0,i1,i2 - UML_DSEXT(block, R64(RTREG), IREG(3), DWORD); // dsext <rtreg>,i3,dword + UML_DSEXT(block, R64(RTREG), IREG(3), SIZE_DWORD); // dsext <rtreg>,i3,dword } if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2035,7 +2017,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta if (!mips3->bigendian) UML_XOR(block, IREG(1), IREG(1), IMM(0x38)); // xor i1,i1,0x38 UML_DSHR(block, IREG(2), IMM((UINT64)~0), IREG(1)); // dshr i2,~0,i1 - UML_CALLH(block, mips3->impstate->read64mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->read64mask[mips3->impstate->mode >> 1]); // callh read64mask if (RTREG != 0) { @@ -2053,7 +2035,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta if (mips3->bigendian) UML_XOR(block, IREG(1), IREG(1), IMM(0x38)); // xor i1,i1,0x38 UML_DSHL(block, IREG(2), IMM((UINT64)~0), IREG(1)); // dshl i2,~0,i1 - UML_CALLH(block, mips3->impstate->read64mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->read64mask[mips3->impstate->mode >> 1]); // callh read64mask if (RTREG != 0) { @@ -2067,7 +2049,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x31: /* LWC1 - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 UML_MOV(block, FPR32(RTREG), IREG(0)); // mov <cpr1_rt>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2075,7 +2057,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x35: /* LDC1 - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 + UML_CALLH(block, *mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 UML_DMOV(block, FPR64(RTREG), IREG(0)); // dmov <cpr1_rt>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2083,7 +2065,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x32: /* LWC2 - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 UML_DAND(block, CPR264(RTREG), IREG(0), IMM(0xffffffff)); // dand <cpr2_rt>,i0,0xffffffff if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2091,7 +2073,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x36: /* LDC2 - MIPS II */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 + UML_CALLH(block, *mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 UML_DMOV(block, CPR264(RTREG), IREG(0)); // dmov <cpr2_rt>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2103,7 +2085,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x28: /* SB - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write8[mips3->impstate->mode >> 1]); // callh write8 + UML_CALLH(block, *mips3->impstate->write8[mips3->impstate->mode >> 1]); // callh write8 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2111,7 +2093,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x29: /* SH - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write16[mips3->impstate->mode >> 1]); // callh write16 + UML_CALLH(block, *mips3->impstate->write16[mips3->impstate->mode >> 1]); // callh write16 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2119,7 +2101,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x2b: /* SW - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 + UML_CALLH(block, *mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2129,9 +2111,9 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_JMPc(block, IF_E, skip = compiler->labelnum++); // je skip UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 + UML_CALLH(block, *mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 UML_LABEL(block, skip); // skip: - UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), DWORD); // dsext <rtreg>,[llbit],dword + UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), SIZE_DWORD); // dsext <rtreg>,[llbit],dword if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2139,7 +2121,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x3f: /* SD - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_DMOV(block, IREG(1), R64(RTREG)); // dmov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 + UML_CALLH(block, *mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2149,9 +2131,9 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_JMPc(block, IF_E, skip = compiler->labelnum++); // je skip UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_DMOV(block, IREG(1), R64(RTREG)); // dmov i1,<rtreg> - UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 + UML_CALLH(block, *mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 UML_LABEL(block, skip); // skip: - UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), DWORD); // dsext <rtreg>,[llbit],dword + UML_DSEXT(block, R64(RTREG), MEM(&mips3->llbit), SIZE_DWORD); // dsext <rtreg>,[llbit],dword if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2165,7 +2147,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_XOR(block, IREG(3), IREG(3), IMM(0x18)); // xor i3,i3,0x18 UML_SHR(block, IREG(2), IMM(~0), IREG(3)); // shr i2,~0,i3 UML_SHR(block, IREG(1), IREG(1), IREG(3)); // shr i1,i1,i3 - UML_CALLH(block, mips3->impstate->write32mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->write32mask[mips3->impstate->mode >> 1]); // callh write32mask if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2180,7 +2162,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_XOR(block, IREG(3), IREG(3), IMM(0x18)); // xor i3,i3,0x18 UML_SHL(block, IREG(2), IMM(~0), IREG(3)); // shl i2,~0,i3 UML_SHL(block, IREG(1), IREG(1), IREG(3)); // shl i1,i1,i3 - UML_CALLH(block, mips3->impstate->write32mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->write32mask[mips3->impstate->mode >> 1]); // callh write32mask if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2195,7 +2177,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_XOR(block, IREG(3), IREG(3), IMM(0x38)); // xor i3,i3,0x38 UML_DSHR(block, IREG(2), IMM((UINT64)~0), IREG(3)); // dshr i2,~0,i3 UML_DSHR(block, IREG(1), IREG(1), IREG(3)); // dshr i1,i1,i3 - UML_CALLH(block, mips3->impstate->write64mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->write64mask[mips3->impstate->mode >> 1]); // callh write64mask if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2210,7 +2192,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta UML_XOR(block, IREG(3), IREG(3), IMM(0x38)); // xor i3,i3,0x38 UML_DSHL(block, IREG(2), IMM((UINT64)~0), IREG(3)); // dshl i2,~0,i3 UML_DSHL(block, IREG(1), IREG(1), IREG(3)); // dshl i1,i1,i3 - UML_CALLH(block, mips3->impstate->write64mask[mips3->impstate->mode >> 1]); + UML_CALLH(block, *mips3->impstate->write64mask[mips3->impstate->mode >> 1]); // callh write64mask if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2219,7 +2201,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x39: /* SWC1 - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), FPR32(RTREG)); // mov i1,<cpr1_rt> - UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 + UML_CALLH(block, *mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2227,7 +2209,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x3d: /* SDC1 - MIPS III */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_DMOV(block, IREG(1), FPR64(RTREG)); // dmov i1,<cpr1_rt> - UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 + UML_CALLH(block, *mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2235,7 +2217,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x3a: /* SWC2 - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), CPR232(RTREG)); // mov i1,<cpr2_rt> - UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 + UML_CALLH(block, *mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2243,7 +2225,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x3e: /* SDC2 - MIPS II */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_DMOV(block, IREG(1), CPR264(RTREG)); // dmov i1,<cpr2_rt> - UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 + UML_CALLH(block, *mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -2268,7 +2250,7 @@ static int generate_opcode(mips3_state *mips3, drcuml_block *block, compiler_sta return generate_cop1x(mips3, block, compiler, desc); case 0x12: /* COP2 - MIPS I */ - UML_EXH(block, mips3->impstate->exception[EXCEPTION_INVALIDOP], IMM(0));// exh invalidop,0 + UML_EXH(block, *mips3->impstate->exception[EXCEPTION_INVALIDOP], IMM(0));// exh invalidop,0 return TRUE; @@ -2299,7 +2281,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SHL(block, IREG(0), R32(RTREG), IMM(SHIFT)); // shl i0,<rtreg>,<shift> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2307,7 +2289,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SHR(block, IREG(0), R32(RTREG), IMM(SHIFT)); // shr i0,<rtreg>,<shift> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2315,7 +2297,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SAR(block, IREG(0), R32(RTREG), IMM(SHIFT)); // sar i0,<rtreg>,<shift> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2323,7 +2305,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SHL(block, IREG(0), R32(RTREG), R32(RSREG)); // shl i0,<rtreg>,<rsreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2331,7 +2313,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SHR(block, IREG(0), R32(RTREG), R32(RSREG)); // shr i0,<rtreg>,<rsreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2339,7 +2321,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SAR(block, IREG(0), R32(RTREG), R32(RSREG)); // sar i0,<rtreg>,<rsreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2395,15 +2377,15 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) { UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0,V if (RDREG != 0) - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } else if (RDREG != 0) { UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2411,7 +2393,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2419,7 +2401,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) { UML_DADD(block, IREG(0), R64(RSREG), R64(RTREG)); // dadd i0,<rsreg>,<rtreg> - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0,V if (RDREG != 0) UML_DMOV(block, R64(RDREG), IREG(0)); // dmov <rdreg>,i0 @@ -2437,15 +2419,15 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) { UML_SUB(block, IREG(0), R32(RSREG), R32(RTREG)); // sub i0,<rsreg>,<rtreg> - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0,V if (RDREG != 0) - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } else if (RDREG != 0) { UML_SUB(block, IREG(0), R32(RSREG), R32(RTREG)); // sub i0,<rsreg>,<rtreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2453,7 +2435,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (RDREG != 0) { UML_SUB(block, IREG(0), R32(RSREG), R32(RTREG)); // sub i0,<rsreg>,<rtreg> - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext <rdreg>,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext <rdreg>,i0,dword } return TRUE; @@ -2461,7 +2443,7 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS) { UML_DSUB(block, IREG(0), R64(RSREG), R64(RTREG)); // dsub i0,<rsreg>,<rtreg> - UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); + UML_EXHc(block, IF_V, *mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0)); // exh overflow,0,V if (RDREG != 0) UML_DMOV(block, R64(RDREG), IREG(0)); // dmov <rdreg>,i0 @@ -2477,14 +2459,14 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st case 0x18: /* MULT - MIPS I */ UML_MULS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // muls i0,i1,<rsreg>,<rtreg> - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword return TRUE; case 0x19: /* MULTU - MIPS I */ UML_MULU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // mulu i0,i1,<rsreg>,<rtreg> - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword return TRUE; case 0x1c: /* DMULT - MIPS III */ @@ -2497,14 +2479,14 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st case 0x1a: /* DIV - MIPS I */ UML_DIVS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // divs i0,i1,<rsreg>,<rtreg> - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword return TRUE; case 0x1b: /* DIVU - MIPS I */ UML_DIVU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // divu i0,i1,<rsreg>,<rtreg> - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword return TRUE; case 0x1e: /* DDIV - MIPS III */ @@ -2565,32 +2547,32 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st case 0x30: /* TGE - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_GE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,GE + UML_EXHc(block, IF_GE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,GE return TRUE; case 0x31: /* TGEU - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_AE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,AE + UML_EXHc(block, IF_AE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,AE return TRUE; case 0x32: /* TLT - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_L, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,LT + UML_EXHc(block, IF_L, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,LT return TRUE; case 0x33: /* TLTU - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_B, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,B + UML_EXHc(block, IF_B, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,B return TRUE; case 0x34: /* TEQ - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_E, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,E + UML_EXHc(block, IF_E, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,E return TRUE; case 0x36: /* TNE - MIPS II */ UML_DCMP(block, R64(RSREG), R64(RTREG)); // dcmp <rsreg>,<rtreg> - UML_EXHc(block, IF_NE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,NE + UML_EXHc(block, IF_NE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,NE return TRUE; @@ -2636,11 +2618,11 @@ static int generate_special(mips3_state *mips3, drcuml_block *block, compiler_st /* ----- system calls ----- */ case 0x0c: /* SYSCALL - MIPS I */ - UML_EXH(block, mips3->impstate->exception[EXCEPTION_SYSCALL], IMM(0)); // exh syscall,0 + UML_EXH(block, *mips3->impstate->exception[EXCEPTION_SYSCALL], IMM(0)); // exh syscall,0 return TRUE; case 0x0d: /* BREAK - MIPS I */ - UML_EXH(block, mips3->impstate->exception[EXCEPTION_BREAK], IMM(0)); // exh break,0 + UML_EXH(block, *mips3->impstate->exception[EXCEPTION_BREAK], IMM(0)); // exh break,0 return TRUE; @@ -2683,7 +2665,7 @@ static int generate_regimm(mips3_state *mips3, drcuml_block *block, compiler_sta { UINT32 op = desc->opptr.l[0]; UINT8 opswitch = RTREG; - drcuml_codelabel skip; + code_label skip; switch (opswitch) { @@ -2720,32 +2702,32 @@ static int generate_regimm(mips3_state *mips3, drcuml_block *block, compiler_sta case 0x08: /* TGEI */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_GE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,GE + UML_EXHc(block, IF_GE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,GE return TRUE; case 0x09: /* TGEIU */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_AE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,AE + UML_EXHc(block, IF_AE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,AE return TRUE; case 0x0a: /* TLTI */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_L, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,L + UML_EXHc(block, IF_L, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,L return TRUE; case 0x0b: /* TLTIU */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_B, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,B + UML_EXHc(block, IF_B, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,B return TRUE; case 0x0c: /* TEQI */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_E, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,E + UML_EXHc(block, IF_E, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,E return TRUE; case 0x0e: /* TNEI */ UML_DCMP(block, R64(RSREG), IMM(SIMMVAL)); // dcmp <rsreg>,SIMMVAL - UML_EXHc(block, IF_NE, mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,NE + UML_EXHc(block, IF_NE, *mips3->impstate->exception[EXCEPTION_TRAP], IMM(0));// exh trap,0,NE return TRUE; } return FALSE; @@ -2774,8 +2756,8 @@ static int generate_idt(mips3_state *mips3, drcuml_block *block, compiler_state UML_MULS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // muls i0,i1,rsreg,rtreg UML_ADD(block, IREG(0), IREG(0), LO32); // add i0,i0,lo UML_ADDC(block, IREG(1), IREG(1), HI32); // addc i1,i1,hi - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword } return TRUE; @@ -2785,8 +2767,8 @@ static int generate_idt(mips3_state *mips3, drcuml_block *block, compiler_state UML_MULU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // mulu i0,i1,rsreg,rtreg UML_ADD(block, IREG(0), IREG(0), LO32); // add i0,i0,lo UML_ADDC(block, IREG(1), IREG(1), HI32); // addc i1,i1,hi - UML_DSEXT(block, LO64, IREG(0), DWORD); // dsext lo,i0,dword - UML_DSEXT(block, HI64, IREG(1), DWORD); // dsext hi,i1,dword + UML_DSEXT(block, LO64, IREG(0), SIZE_DWORD); // dsext lo,i0,dword + UML_DSEXT(block, HI64, IREG(1), SIZE_DWORD); // dsext hi,i1,dword } return TRUE; @@ -2794,7 +2776,7 @@ static int generate_idt(mips3_state *mips3, drcuml_block *block, compiler_state if (RDREG != 0) { UML_MULS(block, IREG(0), IREG(0), R32(RSREG), R32(RTREG)); // muls i0,i0,rsreg,rtreg - UML_DSEXT(block, R64(RDREG), IREG(0), DWORD); // dsext rdreg,i0,dword + UML_DSEXT(block, R64(RDREG), IREG(0), SIZE_DWORD); // dsext rdreg,i0,dword } return TRUE; } @@ -2810,7 +2792,7 @@ static int generate_idt(mips3_state *mips3, drcuml_block *block, compiler_state static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg) { int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); - drcuml_codelabel link; + code_label link; switch (reg) { @@ -2828,7 +2810,7 @@ static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compil generate_update_mode(mips3, block); // <update mode> UML_XOR(block, IREG(0), IREG(0), IREG(1)); // xor i0,i0,i1 UML_TEST(block, IREG(0), IMM(0x8000)); // test i0,0x8000 - UML_CALLCc(block, IF_NZ, mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core,NZ + UML_CALLCc(block, IF_NZ, (c_function)mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core,NZ compiler->checkints = TRUE; if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -2842,7 +2824,7 @@ static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compil UML_DADD(block, IREG(0), IREG(0), IREG(0)); // dadd i0,i0,i0 UML_DSUB(block, MEM(&mips3->count_zero_time), MEM(&mips3->impstate->numcycles), IREG(0)); // dsub [count_zero_time],[mips3->impstate->numcycles],i0 - UML_CALLC(block, mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core + UML_CALLC(block, (c_function)mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core return TRUE; case COP0_Compare: @@ -2850,7 +2832,7 @@ static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compil generate_update_cycles(mips3, block, compiler, IMM(desc->pc), !in_delay_slot); // <subtract cycles> UML_MOV(block, CPR032(COP0_Compare), IREG(0)); // mov [Compare],i0 UML_AND(block, CPR032(COP0_Cause), CPR032(COP0_Cause), IMM(~0x8000)); // and [Cause],[Cause],~0x8000 - UML_CALLC(block, mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core + UML_CALLC(block, (c_function)mips3com_update_cycle_counting, mips3); // callc mips3com_update_cycle_counting,mips.core return TRUE; case COP0_PRId: @@ -2865,7 +2847,7 @@ static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compil UML_MOV(block, CPR032(reg), IREG(0)); // mov cpr0[reg],i0 UML_TEST(block, IREG(1), IMM(0xff)); // test i1,0xff UML_JMPc(block, IF_Z, link = compiler->labelnum++); // jmp link,z - UML_CALLC(block, mips3com_asid_changed, mips3); // callc mips3com_asid_changed + UML_CALLC(block, (c_function)mips3com_asid_changed, mips3); // callc mips3com_asid_changed UML_LABEL(block, link); // link: return TRUE; @@ -2883,7 +2865,7 @@ static int generate_set_cop0_reg(mips3_state *mips3, drcuml_block *block, compil static int generate_get_cop0_reg(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 reg) { - drcuml_codelabel link1, link2; + code_label link1, link2; switch (reg) { @@ -2893,7 +2875,7 @@ static int generate_get_cop0_reg(mips3_state *mips3, drcuml_block *block, compil UML_DSUB(block, IREG(0), MEM(&mips3->impstate->numcycles), MEM(&mips3->count_zero_time)); // dsub i0,[numcycles],[count_zero_time] UML_DSHR(block, IREG(0), IREG(0), IMM(1)); // dshr i0,i0,1 - UML_DSEXT(block, IREG(0), IREG(0), DWORD); // dsext i0,i0,dword + UML_DSEXT(block, IREG(0), IREG(0), SIZE_DWORD); // dsext i0,i0,dword return TRUE; case COP0_Random: @@ -2915,7 +2897,7 @@ static int generate_get_cop0_reg(mips3_state *mips3, drcuml_block *block, compil return TRUE; default: - UML_DSEXT(block, IREG(0), CPR032(reg), DWORD); // dsext i0,cpr0[reg],dword + UML_DSEXT(block, IREG(0), CPR032(reg), SIZE_DWORD); // dsext i0,cpr0[reg],dword return TRUE; } } @@ -2935,7 +2917,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state if ((mips3->impstate->mode >> 1) != MODE_KERNEL) { UML_TEST(block, CPR032(COP0_Status), IMM(SR_COP0)); // test [Status],SR_COP0 - UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(0));// exh cop,0,Z + UML_EXHc(block, IF_Z, *mips3->impstate->exception[EXCEPTION_BADCOP], IMM(0));// exh cop,0,Z } switch (opswitch) @@ -2944,7 +2926,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state if (RTREG != 0) { generate_get_cop0_reg(mips3, block, compiler, desc, RDREG); // <get cop0 reg> - UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0,dword + UML_DSEXT(block, R64(RTREG), IREG(0), SIZE_DWORD); // dsext <rtreg>,i0,dword } return TRUE; @@ -2958,11 +2940,11 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state case 0x02: /* CFCz */ if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), CCR032(RDREG), DWORD); // dsext <rtreg>,ccr0[rdreg],dword + UML_DSEXT(block, R64(RTREG), CCR032(RDREG), SIZE_DWORD); // dsext <rtreg>,ccr0[rdreg],dword return TRUE; case 0x04: /* MTCz */ - UML_DSEXT(block, IREG(0), R32(RTREG), DWORD); // dsext i0,<rtreg>,dword + UML_DSEXT(block, IREG(0), R32(RTREG), SIZE_DWORD); // dsext i0,<rtreg>,dword generate_set_cop0_reg(mips3, block, compiler, desc, RDREG); // <set cop0 reg> return TRUE; @@ -2972,7 +2954,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state return TRUE; case 0x06: /* CTCz */ - UML_DSEXT(block, CCR064(RDREG), R32(RTREG), DWORD); // dsext ccr0[rdreg],<rtreg>,dword + UML_DSEXT(block, CCR064(RDREG), R32(RTREG), SIZE_DWORD); // dsext ccr0[rdreg],<rtreg>,dword return TRUE; case 0x10: @@ -2994,19 +2976,19 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state switch (op & 0x01ffffff) { case 0x01: /* TLBR */ - UML_CALLC(block, mips3com_tlbr, mips3); // callc mips3com_tlbr,mips3 + UML_CALLC(block, (c_function)mips3com_tlbr, mips3); // callc mips3com_tlbr,mips3 return TRUE; case 0x02: /* TLBWI */ - UML_CALLC(block, mips3com_tlbwi, mips3); // callc mips3com_tlbwi,mips3 + UML_CALLC(block, (c_function)mips3com_tlbwi, mips3); // callc mips3com_tlbwi,mips3 return TRUE; case 0x06: /* TLBWR */ - UML_CALLC(block, mips3com_tlbwr, mips3); // callc mips3com_tlbwr,mips3 + UML_CALLC(block, (c_function)mips3com_tlbwr, mips3); // callc mips3com_tlbwr,mips3 return TRUE; case 0x08: /* TLBP */ - UML_CALLC(block, mips3com_tlbp, mips3); // callc mips3com_tlbp,mips3 + UML_CALLC(block, (c_function)mips3com_tlbp, mips3); // callc mips3com_tlbp,mips3 return TRUE; case 0x18: /* ERET */ @@ -3019,7 +3001,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state generate_update_mode(mips3, block); compiler->checkints = TRUE; generate_update_cycles(mips3, block, compiler, CPR032(COP0_EPC), TRUE);// <subtract cycles> - UML_HASHJMP(block, MEM(&mips3->impstate->mode), CPR032(COP0_EPC), mips3->impstate->nocode); + UML_HASHJMP(block, MEM(&mips3->impstate->mode), CPR032(COP0_EPC), *mips3->impstate->nocode); // hashjmp <mode>,[EPC],nocode UML_LABEL(block, skip); // skip: UML_AND(block, IREG(0), IREG(0), IMM(~SR_ERL)); // and i0,i0,~SR_ERL @@ -3028,7 +3010,7 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state compiler->checkints = TRUE; generate_update_cycles(mips3, block, compiler, CPR032(COP0_ErrorPC), TRUE); // <subtract cycles> - UML_HASHJMP(block, MEM(&mips3->impstate->mode), CPR032(COP0_ErrorPC), mips3->impstate->nocode); + UML_HASHJMP(block, MEM(&mips3->impstate->mode), CPR032(COP0_ErrorPC), *mips3->impstate->nocode); // hashjmp <mode>,[EPC],nocode return TRUE; @@ -3054,21 +3036,21 @@ static int generate_cop0(mips3_state *mips3, drcuml_block *block, compiler_state static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) { UINT32 op = desc->opptr.l[0]; - drcuml_codelabel skip; - int condition; + code_label skip; + condition_t condition; /* generate an exception if COP1 is disabled */ if (mips3->impstate->drcoptions & MIPS3DRC_STRICT_COP1) { UML_TEST(block, CPR032(COP0_Status), IMM(SR_COP1)); // test [Status],SR_COP1 - UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh cop,1,Z + UML_EXHc(block, IF_Z, *mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh cop,1,Z } switch (RSREG) { case 0x00: /* MFCz - MIPS I */ if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), FPR32(RDREG), DWORD); // dsext <rtreg>,fpr[rdreg],dword + UML_DSEXT(block, R64(RTREG), FPR32(RDREG), SIZE_DWORD); // dsext <rtreg>,fpr[rdreg],dword return TRUE; case 0x01: /* DMFCz - MIPS III */ @@ -3078,7 +3060,7 @@ static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state case 0x02: /* CFCz - MIPS I */ if (RTREG != 0) - UML_DSEXT(block, R64(RTREG), CCR132(RDREG), DWORD); // dsext <rtreg>,ccr132[rdreg],dword + UML_DSEXT(block, R64(RTREG), CCR132(RDREG), SIZE_DWORD); // dsext <rtreg>,ccr132[rdreg],dword return TRUE; case 0x04: /* MTCz - MIPS I */ @@ -3091,15 +3073,15 @@ static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state case 0x06: /* CTCz - MIPS I */ if (RDREG != 31) - UML_DSEXT(block, CCR164(RDREG), R32(RTREG), DWORD); // dsext ccr1[rdreg],<rtreg>,dword + UML_DSEXT(block, CCR164(RDREG), R32(RTREG), SIZE_DWORD); // dsext ccr1[rdreg],<rtreg>,dword else { UML_XOR(block, IREG(0), CCR132(31), R32(RTREG)); // xor i0,ccr1[31],<rtreg> - UML_DSEXT(block, CCR164(31), R32(RTREG), DWORD); // dsext ccr1[31],<rtreg>,dword + UML_DSEXT(block, CCR164(31), R32(RTREG), SIZE_DWORD); // dsext ccr1[31],<rtreg>,dword UML_TEST(block, IREG(0), IMM(3)); // test i0,3 UML_JMPc(block, IF_Z, skip = compiler->labelnum++); // jmp skip,Z UML_AND(block, IREG(0), CCR132(31), IMM(3)); // and i0,ccr1[31],3 - UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), BYTE);// load i0,fpmode,i0,byte + UML_LOAD(block, IREG(0), &mips3->impstate->fpmode[0], IREG(0), SIZE_BYTE, SCALE_x1);// load i0,fpmode,i0,byte UML_SETFMOD(block, IREG(0)); // setfmod i0 UML_LABEL(block, skip); // skip: } @@ -3187,58 +3169,58 @@ static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state case 0x08: if (IS_SINGLE(op)) /* ROUND.L.S - MIPS III */ - UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, ROUND);// fstoint <fdreg>,<fsreg>,qword,round + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_ROUND);// fstoint <fdreg>,<fsreg>,qword,round else /* ROUND.L.D - MIPS III */ - UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, ROUND);// fdtoint <fdreg>,<fsreg>,qword,round + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_ROUND);// fdtoint <fdreg>,<fsreg>,qword,round return TRUE; case 0x09: if (IS_SINGLE(op)) /* TRUNC.L.S - MIPS III */ - UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, TRUNC);// fstoint <fdreg>,<fsreg>,qword,trunc + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_TRUNC);// fstoint <fdreg>,<fsreg>,qword,trunc else /* TRUNC.L.D - MIPS III */ - UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, TRUNC);// fdtoint <fdreg>,<fsreg>,qword,trunc + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_TRUNC);// fdtoint <fdreg>,<fsreg>,qword,trunc return TRUE; case 0x0a: if (IS_SINGLE(op)) /* CEIL.L.S - MIPS III */ - UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, CEIL);// fstoint <fdreg>,<fsreg>,qword,ceil + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_CEIL);// fstoint <fdreg>,<fsreg>,qword,ceil else /* CEIL.L.D - MIPS III */ - UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, CEIL);// fdtoint <fdreg>,<fsreg>,qword,ceil + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_CEIL);// fdtoint <fdreg>,<fsreg>,qword,ceil return TRUE; case 0x0b: if (IS_SINGLE(op)) /* FLOOR.L.S - MIPS III */ - UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, FLOOR);// fstoint <fdreg>,<fsreg>,qword,floor + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_FLOOR);// fstoint <fdreg>,<fsreg>,qword,floor else /* FLOOR.L.D - MIPS III */ - UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, FLOOR);// fdtoint <fdreg>,<fsreg>,qword,floor + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_FLOOR);// fdtoint <fdreg>,<fsreg>,qword,floor return TRUE; case 0x0c: if (IS_SINGLE(op)) /* ROUND.W.S - MIPS II */ - UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, ROUND);// fstoint <fdreg>,<fsreg>,dword,round + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_ROUND);// fstoint <fdreg>,<fsreg>,dword,round else /* ROUND.W.D - MIPS II */ - UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, ROUND);// fdtoint <fdreg>,<fsreg>,dword,round + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_ROUND);// fdtoint <fdreg>,<fsreg>,dword,round return TRUE; case 0x0d: if (IS_SINGLE(op)) /* TRUNC.W.S - MIPS II */ - UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, TRUNC);// fstoint <fdreg>,<fsreg>,dword,trunc + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_TRUNC);// fstoint <fdreg>,<fsreg>,dword,trunc else /* TRUNC.W.D - MIPS II */ - UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, TRUNC);// fdtoint <fdreg>,<fsreg>,dword,trunc + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_TRUNC);// fdtoint <fdreg>,<fsreg>,dword,trunc return TRUE; case 0x0e: if (IS_SINGLE(op)) /* CEIL.W.S - MIPS II */ - UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, CEIL);// fstoint <fdreg>,<fsreg>,dword,ceil + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_CEIL);// fstoint <fdreg>,<fsreg>,dword,ceil else /* CEIL.W.D - MIPS II */ - UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, CEIL);// fdtoint <fdreg>,<fsreg>,dword,ceil + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_CEIL);// fdtoint <fdreg>,<fsreg>,dword,ceil return TRUE; case 0x0f: if (IS_SINGLE(op)) /* FLOOR.W.S - MIPS II */ - UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, FLOOR);// fstoint <fdreg>,<fsreg>,dword,floor + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_FLOOR);// fstoint <fdreg>,<fsreg>,dword,floor else /* FLOOR.W.D - MIPS II */ - UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, FLOOR);// fdtoint <fdreg>,<fsreg>,dword,floor + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_FLOOR);// fdtoint <fdreg>,<fsreg>,dword,floor return TRUE; case 0x11: @@ -3284,38 +3266,38 @@ static int generate_cop1(mips3_state *mips3, drcuml_block *block, compiler_state if (IS_INTEGRAL(op)) { if (IS_SINGLE(op)) /* CVT.S.W - MIPS I */ - UML_FSFRINT(block, FPR32(FDREG), FPR32(FSREG), DWORD); // fsfrint <fdreg>,<fsreg>,dword + UML_FSFRINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD); // fsfrint <fdreg>,<fsreg>,dword else /* CVT.S.L - MIPS I */ - UML_FSFRINT(block, FPR32(FDREG), FPR64(FSREG), QWORD); // fsfrint <fdreg>,<fsreg>,qword + UML_FSFRINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_QWORD); // fsfrint <fdreg>,<fsreg>,qword } else /* CVT.S.D - MIPS I */ - UML_FSFRFLT(block, FPR32(FDREG), FPR64(FSREG), QWORD); // fsfrflt <fdreg>,<fsreg>,qword + UML_FSFRFLT(block, FPR32(FDREG), FPR64(FSREG), SIZE_QWORD); // fsfrflt <fdreg>,<fsreg>,qword return TRUE; case 0x21: if (IS_INTEGRAL(op)) { if (IS_SINGLE(op)) /* CVT.D.W - MIPS I */ - UML_FDFRINT(block, FPR64(FDREG), FPR32(FSREG), DWORD); // fdfrint <fdreg>,<fsreg>,dword + UML_FDFRINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_DWORD); // fdfrint <fdreg>,<fsreg>,dword else /* CVT.D.L - MIPS I */ - UML_FDFRINT(block, FPR64(FDREG), FPR64(FSREG), QWORD); // fdfrint <fdreg>,<fsreg>,qword + UML_FDFRINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD); // fdfrint <fdreg>,<fsreg>,qword } else /* CVT.D.S - MIPS I */ - UML_FDFRFLT(block, FPR64(FDREG), FPR32(FSREG), DWORD); // fdfrflt <fdreg>,<fsreg>,dword + UML_FDFRFLT(block, FPR64(FDREG), FPR32(FSREG), SIZE_DWORD); // fdfrflt <fdreg>,<fsreg>,dword return TRUE; case 0x24: if (IS_SINGLE(op)) /* CVT.W.S - MIPS I */ - UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), DWORD, DEFAULT);// fstoint <fdreg>,<fsreg>,dword,default + UML_FSTOINT(block, FPR32(FDREG), FPR32(FSREG), SIZE_DWORD, ROUND_DEFAULT);// fstoint <fdreg>,<fsreg>,dword,default else /* CVT.W.D - MIPS I */ - UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), DWORD, DEFAULT);// fdtoint <fdreg>,<fsreg>,dword,default + UML_FDTOINT(block, FPR32(FDREG), FPR64(FSREG), SIZE_DWORD, ROUND_DEFAULT);// fdtoint <fdreg>,<fsreg>,dword,default return TRUE; case 0x25: if (IS_SINGLE(op)) /* CVT.L.S - MIPS I */ - UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), QWORD, DEFAULT);// fstoint <fdreg>,<fsreg>,qword,default + UML_FSTOINT(block, FPR64(FDREG), FPR32(FSREG), SIZE_QWORD, ROUND_DEFAULT);// fstoint <fdreg>,<fsreg>,qword,default else /* CVT.L.D - MIPS I */ - UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), QWORD, DEFAULT);// fdtoint <fdreg>,<fsreg>,qword,default + UML_FDTOINT(block, FPR64(FDREG), FPR64(FSREG), SIZE_QWORD, ROUND_DEFAULT);// fdtoint <fdreg>,<fsreg>,qword,default return TRUE; case 0x30: @@ -3435,14 +3417,14 @@ static int generate_cop1x(mips3_state *mips3, drcuml_block *block, compiler_stat if (mips3->impstate->drcoptions & MIPS3DRC_STRICT_COP1) { UML_TEST(block, CPR032(COP0_Status), IMM(SR_COP1)); // test [Status],SR_COP1 - UML_EXHc(block, IF_Z, mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh cop,1,Z + UML_EXHc(block, IF_Z, *mips3->impstate->exception[EXCEPTION_BADCOP], IMM(1));// exh cop,1,Z } switch (op & 0x3f) { case 0x00: /* LWXC1 - MIPS IV */ UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> - UML_CALLH(block, mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 + UML_CALLH(block, *mips3->impstate->read32[mips3->impstate->mode >> 1]); // callh read32 UML_MOV(block, FPR32(FDREG), IREG(0)); // mov <cpr1_fd>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -3450,7 +3432,7 @@ static int generate_cop1x(mips3_state *mips3, drcuml_block *block, compiler_stat case 0x01: /* LDXC1 - MIPS IV */ UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> - UML_CALLH(block, mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 + UML_CALLH(block, *mips3->impstate->read64[mips3->impstate->mode >> 1]); // callh read64 UML_DMOV(block, FPR64(FDREG), IREG(0)); // dmov <cpr1_fd>,i0 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); @@ -3459,7 +3441,7 @@ static int generate_cop1x(mips3_state *mips3, drcuml_block *block, compiler_stat case 0x08: /* SWXC1 - MIPS IV */ UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> UML_MOV(block, IREG(1), FPR32(FSREG)); // mov i1,<cpr1_fs> - UML_CALLH(block, mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 + UML_CALLH(block, *mips3->impstate->write32[mips3->impstate->mode >> 1]); // callh write32 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -3467,7 +3449,7 @@ static int generate_cop1x(mips3_state *mips3, drcuml_block *block, compiler_stat case 0x09: /* SDXC1 - MIPS IV */ UML_ADD(block, IREG(0), R32(RSREG), R32(RTREG)); // add i0,<rsreg>,<rtreg> UML_DMOV(block, IREG(1), FPR64(FSREG)); // dmov i1,<cpr1_fs> - UML_CALLH(block, mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 + UML_CALLH(block, *mips3->impstate->write64[mips3->impstate->mode >> 1]); // callh write64 if (!in_delay_slot) generate_update_cycles(mips3, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -3540,7 +3522,7 @@ static void log_add_disasm_comment(mips3_state *mips3, drcuml_block *block, UINT #if (LOG_UML) char buffer[100]; dasmmips3(buffer, pc, op); - UML_COMMENT(block, "%08X: %s", pc, buffer); // comment + block->append_comment("%08X: %s", pc, buffer); // comment #endif } @@ -3614,44 +3596,44 @@ static void log_register_list(drcuml_state *drcuml, const char *string, const UI if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0) return; - drcuml_log_printf(drcuml, "[%s:", string); + drcuml->log_printf("[%s:", string); for (regnum = 1; regnum < 32; regnum++) if (reglist[0] & REGFLAG_R(regnum)) { - drcuml_log_printf(drcuml, "%sr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[0] & REGFLAG_R(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } for (regnum = 0; regnum < 32; regnum++) if (reglist[1] & REGFLAG_CPR1(regnum)) { - drcuml_log_printf(drcuml, "%sfr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_CPR1(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[2] & REGFLAG_LO) { - drcuml_log_printf(drcuml, "%slo", (count++ == 0) ? "" : ","); + drcuml->log_printf("%slo", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[2] & REGFLAG_LO)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[2] & REGFLAG_HI) { - drcuml_log_printf(drcuml, "%shi", (count++ == 0) ? "" : ","); + drcuml->log_printf("%shi", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[2] & REGFLAG_HI)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[2] & REGFLAG_FCC) { - drcuml_log_printf(drcuml, "%sfcc", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sfcc", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[2] & REGFLAG_FCC)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } - drcuml_log_printf(drcuml, "] "); + drcuml->log_printf("] "); } @@ -3663,7 +3645,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i { /* open the file, creating it if necessary */ if (indent == 0) - drcuml_log_printf(drcuml, "\nDescriptor list @ %08X\n", desclist->pc); + drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); /* output each descriptor */ for ( ; desclist != NULL; desclist = desclist->next()) @@ -3679,12 +3661,12 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i #else strcpy(buffer, "???"); #endif - drcuml_log_printf(drcuml, "%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); + drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); /* output register states */ log_register_list(drcuml, "use", desclist->regin, NULL); log_register_list(drcuml, "mod", desclist->regout, desclist->regreq); - drcuml_log_printf(drcuml, "\n"); + drcuml->log_printf("\n"); /* if we have a delay slot, output it recursively */ if (desclist->delay.first() != NULL) @@ -3692,7 +3674,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i /* at the end of a sequence add a dividing line */ if (desclist->flags & OPFLAG_END_SEQUENCE) - drcuml_log_printf(drcuml, "-----\n"); + drcuml->log_printf("-----\n"); } } diff --git a/src/emu/cpu/powerpc/ppcdrc.c b/src/emu/cpu/powerpc/ppcdrc.c index 3c0d830f1d9..63876956420 100644 --- a/src/emu/cpu/powerpc/ppcdrc.c +++ b/src/emu/cpu/powerpc/ppcdrc.c @@ -25,6 +25,8 @@ #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" +using namespace uml; + extern offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op); @@ -84,9 +86,9 @@ extern offs_t ppc_dasm_one(char *buffer, UINT32 pc, UINT32 op); MACROS ***************************************************************************/ -#define R32(reg) ppc->impstate->regmap[reg].type, ppc->impstate->regmap[reg].value -#define R32Z(reg) (((reg) == 0) ? DRCUML_PTYPE_IMMEDIATE : ppc->impstate->regmap[reg].type), (((reg) == 0) ? 0 : ppc->impstate->regmap[reg].value) -#define F64(reg) ppc->impstate->fdregmap[reg].type, ppc->impstate->fdregmap[reg].value +#define R32(reg) ppc->impstate->regmap[reg] +#define R32Z(reg) (((reg) == 0) ? parameter(0) : ppc->impstate->regmap[reg]) +#define F64(reg) ppc->impstate->fdregmap[reg] #define CR32(reg) MEM(&ppc->cr[reg]) #define FPSCR32 MEM(&ppc->fpscr) #define MSR32 MEM(&ppc->msr) @@ -155,7 +157,7 @@ struct _compiler_state UINT32 cycles; /* accumulated cycles */ UINT8 checkints; /* need to check interrupts before next instruction */ UINT8 checksoftints; /* need to check software interrupts before next instruction */ - drcuml_codelabel labelnum; /* index for local labels */ + code_label labelnum; /* index for local labels */ }; @@ -190,35 +192,35 @@ struct _ppcimp_state UINT8 cache_dirty; /* true if we need to flush the cache */ /* register mappings */ - drcuml_parameter regmap[32]; /* parameter to register mappings for all 32 integer registers */ - drcuml_parameter fdregmap[32]; /* parameter to register mappings for all 32 floating point registers */ + parameter regmap[32]; /* parameter to register mappings for all 32 integer registers */ + parameter fdregmap[32]; /* parameter to register mappings for all 32 floating point registers */ /* subroutines */ - drcuml_codehandle * entry; /* entry point */ - drcuml_codehandle * nocode; /* nocode exception handler */ - drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */ - drcuml_codehandle * tlb_mismatch; /* tlb mismatch handler */ - drcuml_codehandle * swap_tgpr; /* swap TGPR handler */ - drcuml_codehandle * lsw[8][32]; /* lsw entries */ - drcuml_codehandle * stsw[8][32]; /* stsw entries */ - drcuml_codehandle * read8[8]; /* read byte */ - drcuml_codehandle * write8[8]; /* write byte */ - drcuml_codehandle * read16[8]; /* read half */ - drcuml_codehandle * read16mask[8]; /* read half */ - drcuml_codehandle * write16[8]; /* write half */ - drcuml_codehandle * write16mask[8]; /* write half */ - drcuml_codehandle * read32[8]; /* read word */ - drcuml_codehandle * read32align[8]; /* read word aligned */ - drcuml_codehandle * read32mask[8]; /* read word */ - drcuml_codehandle * write32[8]; /* write word */ - drcuml_codehandle * write32align[8]; /* write word aligned */ - drcuml_codehandle * write32mask[8]; /* write word */ - drcuml_codehandle * read64[8]; /* read double */ - drcuml_codehandle * read64mask[8]; /* read double */ - drcuml_codehandle * write64[8]; /* write double */ - drcuml_codehandle * write64mask[8]; /* write double */ - drcuml_codehandle * exception[EXCEPTION_COUNT]; /* array of exception handlers */ - drcuml_codehandle * exception_norecover[EXCEPTION_COUNT]; /* array of exception handlers */ + code_handle * entry; /* entry point */ + code_handle * nocode; /* nocode exception handler */ + code_handle * out_of_cycles; /* out of cycles exception handler */ + code_handle * tlb_mismatch; /* tlb mismatch handler */ + code_handle * swap_tgpr; /* swap TGPR handler */ + code_handle * lsw[8][32]; /* lsw entries */ + code_handle * stsw[8][32]; /* stsw entries */ + code_handle * read8[8]; /* read byte */ + code_handle * write8[8]; /* write byte */ + code_handle * read16[8]; /* read half */ + code_handle * read16mask[8]; /* read half */ + code_handle * write16[8]; /* write half */ + code_handle * write16mask[8]; /* write half */ + code_handle * read32[8]; /* read word */ + code_handle * read32align[8]; /* read word aligned */ + code_handle * read32mask[8]; /* read word */ + code_handle * write32[8]; /* write word */ + code_handle * write32align[8]; /* write word aligned */ + code_handle * write32mask[8]; /* write word */ + code_handle * read64[8]; /* read double */ + code_handle * read64mask[8]; /* read double */ + code_handle * write64[8]; /* write double */ + code_handle * write64mask[8]; /* write double */ + code_handle * exception[EXCEPTION_COUNT]; /* array of exception handlers */ + code_handle * exception_norecover[EXCEPTION_COUNT]; /* array of exception handlers */ /* fast RAM */ UINT32 fastram_select; @@ -246,13 +248,13 @@ static void static_generate_nocode_handler(powerpc_state *ppc); static void static_generate_out_of_cycles(powerpc_state *ppc); static void static_generate_tlb_mismatch(powerpc_state *ppc); static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int recover, const char *name); -static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr, drcuml_codehandle *masked); +static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int size, int iswrite, int ismasked, const char *name, code_handle *&handleptr, code_handle *masked); static void static_generate_swap_tgpr(powerpc_state *ppc); static void static_generate_lsw_entries(powerpc_state *ppc, int mode); static void static_generate_stsw_entries(powerpc_state *ppc, int mode); static void generate_update_mode(powerpc_state *ppc, drcuml_block *block); -static void generate_update_cycles(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception); +static void generate_update_cycles(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, parameter, int allow_exception); static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); @@ -275,10 +277,10 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i /* lookup table for FP modes */ static const UINT8 fpmode_source[4] = { - DRCUML_FMOD_ROUND, - DRCUML_FMOD_TRUNC, - DRCUML_FMOD_CEIL, - DRCUML_FMOD_FLOOR + ROUND_ROUND, + ROUND_TRUNC, + ROUND_CEIL, + ROUND_FLOOR }; /* flag lookup table for SZ */ @@ -455,10 +457,10 @@ INLINE powerpc_state *get_safe_token(device_t *device) already allocated -------------------------------------------------*/ -INLINE void alloc_handle(drcuml_state *drcuml, drcuml_codehandle **handleptr, const char *name) +INLINE void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) { if (*handleptr == NULL) - *handleptr = drcuml_handle_alloc(drcuml, name); + *handleptr = drcuml->handle_alloc(name); } @@ -472,8 +474,8 @@ INLINE void load_fast_iregs(powerpc_state *ppc, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(ppc->impstate->regmap); regnum++) - if (ppc->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_MOV(block, IREG(ppc->impstate->regmap[regnum].value - DRCUML_REG_I0), MEM(&ppc->r[regnum])); + if (ppc->impstate->regmap[regnum].is_int_register()) + UML_MOV(block, IREG(ppc->impstate->regmap[regnum].ireg() - REG_I0), MEM(&ppc->r[regnum])); } @@ -487,8 +489,8 @@ INLINE void save_fast_iregs(powerpc_state *ppc, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(ppc->impstate->regmap); regnum++) - if (ppc->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_MOV(block, MEM(&ppc->r[regnum]), IREG(ppc->impstate->regmap[regnum].value - DRCUML_REG_I0)); + if (ppc->impstate->regmap[regnum].is_int_register()) + UML_MOV(block, MEM(&ppc->r[regnum]), IREG(ppc->impstate->regmap[regnum].ireg() - REG_I0)); } @@ -576,52 +578,50 @@ static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, legacy flags |= DRCUML_OPTION_LOG_UML; if (LOG_NATIVE) flags |= DRCUML_OPTION_LOG_NATIVE; - ppc->impstate->drcuml = drcuml_alloc(device, cache, flags, 8, 32, 2); - if (ppc->impstate->drcuml == NULL) - fatalerror("Error initializing the UML"); + ppc->impstate->drcuml = auto_alloc(device->machine, drcuml_state(*device, *cache, flags, 8, 32, 2)); /* add symbols for our stuff */ - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->pc, sizeof(ppc->pc), "pc"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->icount, sizeof(ppc->icount), "icount"); + ppc->impstate->drcuml->symbol_add(&ppc->pc, sizeof(ppc->pc), "pc"); + ppc->impstate->drcuml->symbol_add(&ppc->icount, sizeof(ppc->icount), "icount"); for (regnum = 0; regnum < 32; regnum++) { char buf[10]; sprintf(buf, "r%d", regnum); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->r[regnum], sizeof(ppc->r[regnum]), buf); + ppc->impstate->drcuml->symbol_add(&ppc->r[regnum], sizeof(ppc->r[regnum]), buf); sprintf(buf, "fpr%d", regnum); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->f[regnum], sizeof(ppc->r[regnum]), buf); + ppc->impstate->drcuml->symbol_add(&ppc->f[regnum], sizeof(ppc->r[regnum]), buf); } for (regnum = 0; regnum < 8; regnum++) { char buf[10]; sprintf(buf, "cr%d", regnum); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->cr[regnum], sizeof(ppc->cr[regnum]), buf); + ppc->impstate->drcuml->symbol_add(&ppc->cr[regnum], sizeof(ppc->cr[regnum]), buf); } - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->xerso, sizeof(ppc->xerso), "xerso"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->fpscr, sizeof(ppc->fpscr), "fpscr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->msr, sizeof(ppc->msr), "msr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->sr, sizeof(ppc->sr), "sr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_XER], sizeof(ppc->spr[SPR_XER]), "xer"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_LR], sizeof(ppc->spr[SPR_LR]), "lr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr[SPR_CTR], sizeof(ppc->spr[SPR_CTR]), "ctr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->spr, sizeof(ppc->spr), "spr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->dcr, sizeof(ppc->dcr), "dcr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->param0, sizeof(ppc->param0), "param0"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->param1, sizeof(ppc->param1), "param1"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->irq_pending, sizeof(ppc->irq_pending), "irq_pending"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->mode, sizeof(ppc->impstate->mode), "mode"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->arg0, sizeof(ppc->impstate->arg0), "arg0"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->arg1, sizeof(ppc->impstate->arg1), "arg1"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->updateaddr, sizeof(ppc->impstate->updateaddr), "updateaddr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->swcount, sizeof(ppc->impstate->swcount), "swcount"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->tempaddr, sizeof(ppc->impstate->tempaddr), "tempaddr"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->tempdata, sizeof(ppc->impstate->tempdata), "tempdata"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->fp0, sizeof(ppc->impstate->fp0), "fp0"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->fpmode, sizeof(ppc->impstate->fpmode), "fpmode"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->sz_cr_table, sizeof(ppc->impstate->sz_cr_table), "sz_cr_table"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->cmp_cr_table, sizeof(ppc->impstate->cmp_cr_table), "cmp_cr_table"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->cmpl_cr_table, sizeof(ppc->impstate->cmpl_cr_table), "cmpl_cr_table"); - drcuml_symbol_add(ppc->impstate->drcuml, &ppc->impstate->fcmp_cr_table, sizeof(ppc->impstate->fcmp_cr_table), "fcmp_cr_table"); + ppc->impstate->drcuml->symbol_add(&ppc->xerso, sizeof(ppc->xerso), "xerso"); + ppc->impstate->drcuml->symbol_add(&ppc->fpscr, sizeof(ppc->fpscr), "fpscr"); + ppc->impstate->drcuml->symbol_add(&ppc->msr, sizeof(ppc->msr), "msr"); + ppc->impstate->drcuml->symbol_add(&ppc->sr, sizeof(ppc->sr), "sr"); + ppc->impstate->drcuml->symbol_add(&ppc->spr[SPR_XER], sizeof(ppc->spr[SPR_XER]), "xer"); + ppc->impstate->drcuml->symbol_add(&ppc->spr[SPR_LR], sizeof(ppc->spr[SPR_LR]), "lr"); + ppc->impstate->drcuml->symbol_add(&ppc->spr[SPR_CTR], sizeof(ppc->spr[SPR_CTR]), "ctr"); + ppc->impstate->drcuml->symbol_add(&ppc->spr, sizeof(ppc->spr), "spr"); + ppc->impstate->drcuml->symbol_add(&ppc->dcr, sizeof(ppc->dcr), "dcr"); + ppc->impstate->drcuml->symbol_add(&ppc->param0, sizeof(ppc->param0), "param0"); + ppc->impstate->drcuml->symbol_add(&ppc->param1, sizeof(ppc->param1), "param1"); + ppc->impstate->drcuml->symbol_add(&ppc->irq_pending, sizeof(ppc->irq_pending), "irq_pending"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->mode, sizeof(ppc->impstate->mode), "mode"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->arg0, sizeof(ppc->impstate->arg0), "arg0"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->arg1, sizeof(ppc->impstate->arg1), "arg1"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->updateaddr, sizeof(ppc->impstate->updateaddr), "updateaddr"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->swcount, sizeof(ppc->impstate->swcount), "swcount"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->tempaddr, sizeof(ppc->impstate->tempaddr), "tempaddr"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->tempdata, sizeof(ppc->impstate->tempdata), "tempdata"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->fp0, sizeof(ppc->impstate->fp0), "fp0"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->fpmode, sizeof(ppc->impstate->fpmode), "fpmode"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->sz_cr_table, sizeof(ppc->impstate->sz_cr_table), "sz_cr_table"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->cmp_cr_table, sizeof(ppc->impstate->cmp_cr_table), "cmp_cr_table"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->cmpl_cr_table, sizeof(ppc->impstate->cmpl_cr_table), "cmpl_cr_table"); + ppc->impstate->drcuml->symbol_add(&ppc->impstate->fcmp_cr_table, sizeof(ppc->impstate->fcmp_cr_table), "fcmp_cr_table"); /* initialize the front-end helper */ ppc->impstate->drcfe = auto_alloc(device->machine, ppc_frontend(*ppc, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE)); @@ -636,31 +636,20 @@ static void ppcdrc_init(powerpc_flavor flavor, UINT8 cap, int tb_divisor, legacy /* compute the register parameters */ for (regnum = 0; regnum < 32; regnum++) { - ppc->impstate->regmap[regnum].type = DRCUML_PTYPE_MEMORY; - ppc->impstate->regmap[regnum].value = (FPTR)&ppc->r[regnum]; - ppc->impstate->fdregmap[regnum].type = DRCUML_PTYPE_MEMORY; - ppc->impstate->fdregmap[regnum].value = (FPTR)&ppc->f[regnum]; + ppc->impstate->regmap[regnum] = MEM(&ppc->r[regnum]); + ppc->impstate->fdregmap[regnum] = MEM(&ppc->f[regnum]); } /* if we have registers to spare, assign r0, r1, r2 to leftovers */ if (!DISABLE_FAST_REGISTERS) { - drcuml_get_backend_info(ppc->impstate->drcuml, &beinfo); + ppc->impstate->drcuml->get_backend_info(beinfo); if (beinfo.direct_iregs > 5) - { - ppc->impstate->regmap[0].type = DRCUML_PTYPE_INT_REGISTER; - ppc->impstate->regmap[0].value = DRCUML_REG_I5; - } + ppc->impstate->regmap[0] = IREG(5); if (beinfo.direct_iregs > 6) - { - ppc->impstate->regmap[1].type = DRCUML_PTYPE_INT_REGISTER; - ppc->impstate->regmap[1].value = DRCUML_REG_I6; - } + ppc->impstate->regmap[1] = IREG(6); if (beinfo.direct_iregs > 7) - { - ppc->impstate->regmap[2].type = DRCUML_PTYPE_INT_REGISTER; - ppc->impstate->regmap[2].value = DRCUML_REG_I7; - } + ppc->impstate->regmap[2] = IREG(7); } /* mark the cache dirty so it is updated on next execute */ @@ -703,7 +692,7 @@ static CPU_EXECUTE( ppcdrc ) do { /* run as much as we can */ - execute_result = drcuml_execute(drcuml, ppc->impstate->entry); + execute_result = drcuml->execute(*ppc->impstate->entry); /* if we need to recompile, do it */ if (execute_result == EXECUTE_MISSING_CODE) @@ -728,7 +717,7 @@ static CPU_EXIT( ppcdrc ) /* clean up the DRC */ auto_free(device->machine, ppc->impstate->drcfe); - drcuml_free(ppc->impstate->drcuml); + auto_free(device->machine, ppc->impstate->drcuml); auto_free(device->machine, ppc->impstate->cache); } @@ -865,58 +854,65 @@ static void code_flush_cache(powerpc_state *ppc) int mode; /* empty the transient cache contents */ - drcuml_reset(drcuml); + drcuml->reset(); - /* generate the entry point and out-of-cycles handlers */ - static_generate_entry_point(ppc); - static_generate_nocode_handler(ppc); - static_generate_out_of_cycles(ppc); - static_generate_tlb_mismatch(ppc); - if (ppc->cap & PPCCAP_603_MMU) - static_generate_swap_tgpr(ppc); - - /* append exception handlers for various types */ - static_generate_exception(ppc, EXCEPTION_RESET, TRUE, "exception_reset"); - static_generate_exception(ppc, EXCEPTION_MACHCHECK, TRUE, "exception_machine_check"); - static_generate_exception(ppc, EXCEPTION_DSI, TRUE, "exception_dsi"); - static_generate_exception(ppc, EXCEPTION_ISI, TRUE, "exception_isi"); - static_generate_exception(ppc, EXCEPTION_EI, TRUE, "exception_ei"); - static_generate_exception(ppc, EXCEPTION_EI, FALSE, "exception_ei_norecover"); - static_generate_exception(ppc, EXCEPTION_ALIGN, TRUE, "exception_align"); - static_generate_exception(ppc, EXCEPTION_PROGRAM, TRUE, "exception_program"); - static_generate_exception(ppc, EXCEPTION_NOFPU, TRUE, "exception_fpu_unavailable"); - static_generate_exception(ppc, EXCEPTION_DECREMENT, TRUE, "exception_decrementer"); - static_generate_exception(ppc, EXCEPTION_SYSCALL, TRUE, "exception_syscall"); - static_generate_exception(ppc, EXCEPTION_TRACE, TRUE, "exception_trace"); - static_generate_exception(ppc, EXCEPTION_FPASSIST, TRUE, "exception_floating_point_assist"); - if (ppc->cap & PPCCAP_603_MMU) + try { - static_generate_exception(ppc, EXCEPTION_ITLBMISS, TRUE, "exception_itlb_miss"); - static_generate_exception(ppc, EXCEPTION_DTLBMISSL, TRUE, "exception_dtlb_miss_load"); - static_generate_exception(ppc, EXCEPTION_DTLBMISSS, TRUE, "exception_dtlb_miss_store"); - } + /* generate the entry point and out-of-cycles handlers */ + static_generate_entry_point(ppc); + static_generate_nocode_handler(ppc); + static_generate_out_of_cycles(ppc); + static_generate_tlb_mismatch(ppc); + if (ppc->cap & PPCCAP_603_MMU) + static_generate_swap_tgpr(ppc); + + /* append exception handlers for various types */ + static_generate_exception(ppc, EXCEPTION_RESET, TRUE, "exception_reset"); + static_generate_exception(ppc, EXCEPTION_MACHCHECK, TRUE, "exception_machine_check"); + static_generate_exception(ppc, EXCEPTION_DSI, TRUE, "exception_dsi"); + static_generate_exception(ppc, EXCEPTION_ISI, TRUE, "exception_isi"); + static_generate_exception(ppc, EXCEPTION_EI, TRUE, "exception_ei"); + static_generate_exception(ppc, EXCEPTION_EI, FALSE, "exception_ei_norecover"); + static_generate_exception(ppc, EXCEPTION_ALIGN, TRUE, "exception_align"); + static_generate_exception(ppc, EXCEPTION_PROGRAM, TRUE, "exception_program"); + static_generate_exception(ppc, EXCEPTION_NOFPU, TRUE, "exception_fpu_unavailable"); + static_generate_exception(ppc, EXCEPTION_DECREMENT, TRUE, "exception_decrementer"); + static_generate_exception(ppc, EXCEPTION_SYSCALL, TRUE, "exception_syscall"); + static_generate_exception(ppc, EXCEPTION_TRACE, TRUE, "exception_trace"); + static_generate_exception(ppc, EXCEPTION_FPASSIST, TRUE, "exception_floating_point_assist"); + if (ppc->cap & PPCCAP_603_MMU) + { + static_generate_exception(ppc, EXCEPTION_ITLBMISS, TRUE, "exception_itlb_miss"); + static_generate_exception(ppc, EXCEPTION_DTLBMISSL, TRUE, "exception_dtlb_miss_load"); + static_generate_exception(ppc, EXCEPTION_DTLBMISSS, TRUE, "exception_dtlb_miss_store"); + } - /* add subroutines for memory accesses */ - for (mode = 0; mode < 8; mode++) + /* add subroutines for memory accesses */ + for (mode = 0; mode < 8; mode++) + { + static_generate_memory_accessor(ppc, mode, 1, FALSE, FALSE, "read8", ppc->impstate->read8[mode], NULL); + static_generate_memory_accessor(ppc, mode, 1, TRUE, FALSE, "write8", ppc->impstate->write8[mode], NULL); + static_generate_memory_accessor(ppc, mode, 2, FALSE, TRUE, "read16mask", ppc->impstate->read16mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 2, FALSE, FALSE, "read16", ppc->impstate->read16[mode], ppc->impstate->read16mask[mode]); + static_generate_memory_accessor(ppc, mode, 2, TRUE, TRUE, "write16mask", ppc->impstate->write16mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 2, TRUE, FALSE, "write16", ppc->impstate->write16[mode], ppc->impstate->write16mask[mode]); + static_generate_memory_accessor(ppc, mode, 4, FALSE, TRUE, "read32mask", ppc->impstate->read32mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 4, FALSE, FALSE, "read32align", ppc->impstate->read32align[mode], NULL); + static_generate_memory_accessor(ppc, mode, 4, FALSE, FALSE, "read32", ppc->impstate->read32[mode], ppc->impstate->read32mask[mode]); + static_generate_memory_accessor(ppc, mode, 4, TRUE, TRUE, "write32mask", ppc->impstate->write32mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 4, TRUE, FALSE, "write32align",ppc->impstate->write32align[mode],NULL); + static_generate_memory_accessor(ppc, mode, 4, TRUE, FALSE, "write32", ppc->impstate->write32[mode], ppc->impstate->write32mask[mode]); + static_generate_memory_accessor(ppc, mode, 8, FALSE, TRUE, "read64mask", ppc->impstate->read64mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 8, FALSE, FALSE, "read64", ppc->impstate->read64[mode], ppc->impstate->read64mask[mode]); + static_generate_memory_accessor(ppc, mode, 8, TRUE, TRUE, "write64mask", ppc->impstate->write64mask[mode], NULL); + static_generate_memory_accessor(ppc, mode, 8, TRUE, FALSE, "write64", ppc->impstate->write64[mode], ppc->impstate->write64mask[mode]); + static_generate_lsw_entries(ppc, mode); + static_generate_stsw_entries(ppc, mode); + } + } + catch (drcuml_block::abort_compilation &) { - static_generate_memory_accessor(ppc, mode, 1, FALSE, FALSE, "read8", &ppc->impstate->read8[mode], NULL); - static_generate_memory_accessor(ppc, mode, 1, TRUE, FALSE, "write8", &ppc->impstate->write8[mode], NULL); - static_generate_memory_accessor(ppc, mode, 2, FALSE, TRUE, "read16mask", &ppc->impstate->read16mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 2, FALSE, FALSE, "read16", &ppc->impstate->read16[mode], ppc->impstate->read16mask[mode]); - static_generate_memory_accessor(ppc, mode, 2, TRUE, TRUE, "write16mask", &ppc->impstate->write16mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 2, TRUE, FALSE, "write16", &ppc->impstate->write16[mode], ppc->impstate->write16mask[mode]); - static_generate_memory_accessor(ppc, mode, 4, FALSE, TRUE, "read32mask", &ppc->impstate->read32mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 4, FALSE, FALSE, "read32align", &ppc->impstate->read32align[mode], NULL); - static_generate_memory_accessor(ppc, mode, 4, FALSE, FALSE, "read32", &ppc->impstate->read32[mode], ppc->impstate->read32mask[mode]); - static_generate_memory_accessor(ppc, mode, 4, TRUE, TRUE, "write32mask", &ppc->impstate->write32mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 4, TRUE, FALSE, "write32align",&ppc->impstate->write32align[mode],NULL); - static_generate_memory_accessor(ppc, mode, 4, TRUE, FALSE, "write32", &ppc->impstate->write32[mode], ppc->impstate->write32mask[mode]); - static_generate_memory_accessor(ppc, mode, 8, FALSE, TRUE, "read64mask", &ppc->impstate->read64mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 8, FALSE, FALSE, "read64", &ppc->impstate->read64[mode], ppc->impstate->read64mask[mode]); - static_generate_memory_accessor(ppc, mode, 8, TRUE, TRUE, "write64mask", &ppc->impstate->write64mask[mode], NULL); - static_generate_memory_accessor(ppc, mode, 8, TRUE, FALSE, "write64", &ppc->impstate->write64[mode], ppc->impstate->write64mask[mode]); - static_generate_lsw_entries(ppc, mode); - static_generate_stsw_entries(ppc, mode); + fatalerror("Error generating PPC static handlers"); } } @@ -934,7 +930,6 @@ static void code_compile_block(powerpc_state *ppc, UINT8 mode, offs_t pc) const opcode_desc *desclist; int override = FALSE; drcuml_block *block; - jmp_buf errorbuf; logerror("Compile %08X\n", pc); g_profiler.start(PROFILER_DRC_COMPILE); @@ -943,83 +938,92 @@ logerror("Compile %08X\n", pc); if (LOG_UML || LOG_NATIVE) log_opcode_desc(drcuml, desclist, 0); - /* if we get an error back, flush the cache and try again */ - if (setjmp(errorbuf) != 0) - code_flush_cache(ppc); - - /* start the block */ - block = drcuml_block_begin(drcuml, 4096, &errorbuf); - - /* loop until we get through all instruction sequences */ - for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + bool succeeded = false; + while (!succeeded) { - const opcode_desc *curdesc; - UINT32 nextpc; - - /* add a code log entry */ - if (LOG_UML) - UML_COMMENT(block, "-------------------------"); // comment - - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != NULL); - - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml_hash_exists(drcuml, mode, seqhead->pc)) - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) + try { - override = TRUE; - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - } + /* start the block */ + block = drcuml->begin_block(4096); - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(seqhead->pc), ppc->impstate->nocode); - // hashjmp <mode>,seqhead->pc,nocode - continue; - } + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + UINT32 nextpc; + + /* add a code log entry */ + if (LOG_UML) + block->append_comment("-------------------------"); // comment + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != NULL); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(mode, seqhead->pc)) + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = TRUE; + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + } - /* validate this code block if we're not pointing into ROM */ - if (ppc->program->get_write_ptr(seqhead->physpc) != NULL) - generate_checksum_block(ppc, block, &compiler, seqhead, seqlast); // <checksum> + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(seqhead->pc), *ppc->impstate->nocode); + // hashjmp <mode>,seqhead->pc,nocode + continue; + } - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + /* validate this code block if we're not pointing into ROM */ + if (ppc->program->get_write_ptr(seqhead->physpc) != NULL) + generate_checksum_block(ppc, block, &compiler, seqhead, seqlast); // <checksum> - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - generate_sequence_instruction(ppc, block, &compiler, curdesc); // <instruction> + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - nextpc = pc; + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + generate_sequence_instruction(ppc, block, &compiler, curdesc); // <instruction> - /* otherwise we just go to the next instruction */ - else - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + nextpc = pc; - /* count off cycles and go there */ - generate_update_cycles(ppc, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> + /* otherwise we just go to the next instruction */ + else + nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; - /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ - if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) - UML_HASHJMP(block, MEM(&ppc->impstate->mode), IMM(nextpc), ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode - else if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) - UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(nextpc), ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode - } + /* count off cycles and go there */ + generate_update_cycles(ppc, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> + + /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ + if (seqlast->flags & OPFLAG_CAN_CHANGE_MODES) + UML_HASHJMP(block, MEM(&ppc->impstate->mode), IMM(nextpc), *ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode + else if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) + UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(nextpc), *ppc->impstate->nocode);// hashjmp <mode>,nextpc,nocode + } - /* end the sequence */ - drcuml_block_end(block); - g_profiler.stop(); + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; + } + catch (drcuml_block::abort_compilation &) + { + // flush the cache and try again + code_flush_cache(ppc); + } + } } @@ -1109,27 +1113,22 @@ static void cfunc_unimplemented(void *param) static void static_generate_entry_point(powerpc_state *ppc) { drcuml_state *drcuml = ppc->impstate->drcuml; - drcuml_codelabel skip = 1; + code_label skip = 1; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_entry_point"); /* begin generating */ - block = drcuml_block_begin(drcuml, 20, &errorbuf); + block = drcuml->begin_block(20); /* forward references */ alloc_handle(drcuml, &ppc->impstate->nocode, "nocode"); alloc_handle(drcuml, &ppc->impstate->exception_norecover[EXCEPTION_EI], "exception_ei_norecover"); alloc_handle(drcuml, &ppc->impstate->entry, "entry"); - UML_HANDLE(block, ppc->impstate->entry); // handle entry + UML_HANDLE(block, *ppc->impstate->entry); // handle entry /* reset the FPU mode */ UML_AND(block, IREG(0), FPSCR32, IMM(3)); // and i0,fpscr,3 - UML_LOAD(block, IREG(0), &ppc->impstate->fpmode[0], IREG(0), BYTE); // load i0,fpmode,i0,byte + UML_LOAD(block, IREG(0), &ppc->impstate->fpmode[0], IREG(0), SIZE_BYTE, SCALE_x1); // load i0,fpmode,i0,byte UML_SETFMOD(block, IREG(0)); // setfmod i0 /* load fast integer registers */ @@ -1142,13 +1141,13 @@ static void static_generate_entry_point(powerpc_state *ppc) UML_JMPc(block, IF_Z, skip); // jmp skip,Z UML_MOV(block, IREG(0), MEM(&ppc->pc)); // mov i0,pc UML_MOV(block, IREG(1), IMM(0)); // mov i1,0 - UML_CALLH(block, ppc->impstate->exception_norecover[EXCEPTION_EI]); // callh exception_norecover + UML_CALLH(block, *ppc->impstate->exception_norecover[EXCEPTION_EI]); // callh exception_norecover UML_LABEL(block, skip); // skip: /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, MEM(&ppc->impstate->mode), MEM(&ppc->pc), ppc->impstate->nocode); // hashjmp <mode>,<pc>,nocode + UML_HASHJMP(block, MEM(&ppc->impstate->mode), MEM(&ppc->pc), *ppc->impstate->nocode); // hashjmp <mode>,<pc>,nocode - drcuml_block_end(block); + block->end(); } @@ -1161,24 +1160,19 @@ static void static_generate_nocode_handler(powerpc_state *ppc) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_nocode_handler"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &ppc->impstate->nocode, "nocode"); - UML_HANDLE(block, ppc->impstate->nocode); // handle nocode + UML_HANDLE(block, *ppc->impstate->nocode); // handle nocode UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&ppc->pc), IREG(0)); // mov [pc],i0 save_fast_iregs(ppc, block); // <save fastregs> UML_EXIT(block, IMM(EXECUTE_MISSING_CODE)); // exit EXECUTE_MISSING_CODE - drcuml_block_end(block); + block->end(); } @@ -1191,24 +1185,19 @@ static void static_generate_out_of_cycles(powerpc_state *ppc) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_out_of_cycles"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &ppc->impstate->out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, ppc->impstate->out_of_cycles); // handle out_of_cycles + UML_HANDLE(block, *ppc->impstate->out_of_cycles); // handle out_of_cycles UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&ppc->pc), IREG(0)); // mov <pc>,i0 save_fast_iregs(ppc, block); // <save fastregs> UML_EXIT(block, IMM(EXECUTE_OUT_OF_CYCLES)); // exit EXECUTE_OUT_OF_CYCLES - drcuml_block_end(block); + block->end(); } @@ -1221,36 +1210,31 @@ static void static_generate_tlb_mismatch(powerpc_state *ppc) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; int isi, exit, label = 1; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_tlb_mismatch"); - /* forward references */ alloc_handle(drcuml, &ppc->impstate->exception[EXCEPTION_ISI], "exception_isi"); if (ppc->cap & PPCCAP_603_MMU) alloc_handle(drcuml, &ppc->impstate->exception[EXCEPTION_ITLBMISS], "exception_itlb_miss"); /* begin generating */ - block = drcuml_block_begin(drcuml, 20, &errorbuf); + block = drcuml->begin_block(20); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &ppc->impstate->tlb_mismatch, "tlb_mismatch"); - UML_HANDLE(block, ppc->impstate->tlb_mismatch); // handle tlb_mismatch + UML_HANDLE(block, *ppc->impstate->tlb_mismatch); // handle tlb_mismatch UML_RECOVER(block, IREG(0), MAPVAR_PC); // recover i0,PC UML_SHR(block, IREG(1), IREG(0), IMM(12)); // shr i1,i0,12 - UML_LOAD(block, IREG(2), (void *)vtlb_table(ppc->vtlb), IREG(1), DWORD); // load i2,[vtlb],i1,dword + UML_LOAD(block, IREG(2), (void *)vtlb_table(ppc->vtlb), IREG(1), SIZE_DWORD, SCALE_x4); // load i2,[vtlb],i1,dword UML_MOV(block, MEM(&ppc->param0), IREG(0)); // mov [param0],i0 UML_MOV(block, MEM(&ppc->param1), IMM(TRANSLATE_FETCH)); // mov [param1],TRANSLATE_FETCH - UML_CALLC(block, ppccom_tlb_fill, ppc); // callc tlbfill,ppc - UML_LOAD(block, IREG(1), (void *)vtlb_table(ppc->vtlb), IREG(1), DWORD); // load i1,[vtlb],i1,dword + UML_CALLC(block, (c_function)ppccom_tlb_fill, ppc); // callc tlbfill,ppc + UML_LOAD(block, IREG(1), (void *)vtlb_table(ppc->vtlb), IREG(1), SIZE_DWORD, SCALE_x4); // load i1,[vtlb],i1,dword UML_TEST(block, IREG(1), IMM(VTLB_FETCH_ALLOWED)); // test i1,VTLB_FETCH_ALLOWED UML_JMPc(block, IF_Z, isi = label++); // jmp isi,z UML_CMP(block, IREG(2), IMM(0)); // cmp i2,0 UML_JMPc(block, IF_NZ, exit = label++); // jmp exit,nz - UML_HASHJMP(block, MEM(&ppc->impstate->mode), IREG(0), ppc->impstate->nocode); // hashjmp <mode>,i0,nocode + UML_HASHJMP(block, MEM(&ppc->impstate->mode), IREG(0), *ppc->impstate->nocode); // hashjmp <mode>,i0,nocode UML_LABEL(block, exit); // exit: UML_MOV(block, MEM(&ppc->pc), IREG(0)); // mov <pc>,i0 save_fast_iregs(ppc, block); // <save fastregs> @@ -1259,7 +1243,7 @@ static void static_generate_tlb_mismatch(powerpc_state *ppc) if (!(ppc->cap & PPCCAP_603_MMU)) { UML_MOV(block, SPR32(SPROEA_DSISR), MEM(&ppc->param0)); // mov [dsisr],[param0] - UML_EXH(block, ppc->impstate->exception[EXCEPTION_ISI], IREG(0)); // exh isi,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_ISI], IREG(0)); // exh isi,i0 } else { @@ -1267,10 +1251,10 @@ static void static_generate_tlb_mismatch(powerpc_state *ppc) UML_MOV(block, SPR32(SPR603_ICMP), MEM(&ppc->mmu603_cmp)); // mov [icmp],[mmu603_cmp] UML_MOV(block, SPR32(SPR603_HASH1), MEM(&ppc->mmu603_hash[0])); // mov [hash1],[mmu603_hash][0] UML_MOV(block, SPR32(SPR603_HASH2), MEM(&ppc->mmu603_hash[1])); // mov [hash2],[mmu603_hash][1] - UML_EXH(block, ppc->impstate->exception[EXCEPTION_ITLBMISS], IREG(0)); // exh itlbmiss,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_ITLBMISS], IREG(0)); // exh itlbmiss,i0 } - drcuml_block_end(block); + block->end(); } @@ -1282,21 +1266,16 @@ static void static_generate_tlb_mismatch(powerpc_state *ppc) static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int recover, const char *name) { drcuml_state *drcuml = ppc->impstate->drcuml; - drcuml_codehandle **exception_handle = recover ? &ppc->impstate->exception[exception] : &ppc->impstate->exception_norecover[exception]; + code_handle *&exception_handle = recover ? ppc->impstate->exception[exception] : ppc->impstate->exception_norecover[exception]; UINT32 vector = exception << 8; - drcuml_codelabel label = 1; + code_label label = 1; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_exception"); /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ - alloc_handle(drcuml, exception_handle, name); + alloc_handle(drcuml, &exception_handle, name); UML_HANDLE(block, *exception_handle); // handle name /* exception parameter is expected to be the fault address in this case */ @@ -1323,7 +1302,7 @@ static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int r UML_MOV(block, IREG(3), IMM(vector)); // mov i3,vector if (exception == EXCEPTION_EI) { - drcuml_codelabel not_decrementer; + code_label not_decrementer; UML_TEST(block, MEM(&ppc->irq_pending), IMM(0x01)); // test [irq_pending],0x01 UML_JMPc(block, IF_NZ, not_decrementer = label++); // jmp not_decrementer,nz @@ -1369,7 +1348,7 @@ static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int r { UML_XOR(block, IREG(0), IREG(0), IREG(2)); // xor i0,i0,i2 UML_TEST(block, IREG(0), IMM(MSR603_TGPR)); // test i0,tgpr - UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr); // callh swap_tgpr,nz + UML_CALLHc(block, IF_NZ, *ppc->impstate->swap_tgpr); // callh swap_tgpr,nz } generate_update_mode(ppc, block); // <update mode> @@ -1390,7 +1369,7 @@ static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int r UML_MOV(block, IREG(3), IMM(vector)); // mov i3,vector if (exception == EXCEPTION_EI) { - drcuml_codelabel notwdog, common; + code_label notwdog, common; UML_TEST(block, SPR32(SPR4XX_TSR), IMM(PPC4XX_TSR_PIS)); // test [tsr],PIS UML_MOVc(block, IF_NZ, IREG(3), IMM(0x1000)); // mov i3,0x1000,NZ @@ -1450,10 +1429,10 @@ static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int r /* adjust cycles */ UML_SUB(block, MEM(&ppc->icount), MEM(&ppc->icount), IREG(1)); // sub icount,icount,cycles - UML_EXHc(block, IF_S, ppc->impstate->out_of_cycles, IREG(0)); // exh out_of_cycles,i0 - UML_HASHJMP(block, MEM(&ppc->impstate->mode), IREG(0), ppc->impstate->nocode); // hashjmp <mode>,i0,nocode + UML_EXHc(block, IF_S, *ppc->impstate->out_of_cycles, IREG(0)); // exh out_of_cycles,i0 + UML_HASHJMP(block, MEM(&ppc->impstate->mode), IREG(0), *ppc->impstate->nocode); // hashjmp <mode>,i0,nocode - drcuml_block_end(block); + block->end(); } @@ -1461,7 +1440,7 @@ static void static_generate_exception(powerpc_state *ppc, UINT8 exception, int r static_generate_memory_accessor ------------------------------------------------------------------*/ -static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int size, int iswrite, int ismasked, const char *name, drcuml_codehandle **handleptr, drcuml_codehandle *masked) +static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int size, int iswrite, int ismasked, const char *name, code_handle *&handleptr, code_handle *masked) { /* on entry, address is in I0; data for writes is in I1; masks are in I2 */ /* on exit, read result is in I0 */ @@ -1469,7 +1448,6 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si drcuml_state *drcuml = ppc->impstate->drcuml; int fastxor = BYTE8_XOR_BE(0) >> (int)(ppc->device->space_config(AS_PROGRAM)->m_databus_width < 64); drcuml_block *block; - jmp_buf errorbuf; int translate_type; int tlbreturn = 0; int unaligned = 0; @@ -1483,15 +1461,11 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si else translate_type = iswrite ? TRANSLATE_WRITE : TRANSLATE_READ; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_exception"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ - alloc_handle(drcuml, handleptr, name); + alloc_handle(drcuml, &handleptr, name); UML_HANDLE(block, *handleptr); // handle *handleptr /* check for unaligned accesses and break into two */ @@ -1527,7 +1501,7 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (((ppc->cap & PPCCAP_OEA) && (mode & MODE_DATA_TRANSLATION)) || (iswrite && (ppc->cap & PPCCAP_4XX) && (mode & MODE_PROTECTION))) { UML_SHR(block, IREG(3), IREG(0), IMM(12)); // shr i3,i0,12 - UML_LOAD(block, IREG(3), (void *)vtlb_table(ppc->vtlb), IREG(3), DWORD); // load i3,[vtlb],i3,dword + UML_LOAD(block, IREG(3), (void *)vtlb_table(ppc->vtlb), IREG(3), SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword UML_TEST(block, IREG(3), IMM((UINT64)1 << translate_type)); // test i3,1 << translate_type UML_JMPc(block, IF_Z, tlbmiss = label++); // jmp tlbmiss,z UML_LABEL(block, tlbreturn = label++); // tlbreturn: @@ -1560,21 +1534,21 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (size == 1) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 7)); // xor i0,i0,fastxor & 7 - UML_LOAD(block, IREG(0), fastbase, IREG(0), BYTE); // load i0,fastbase,i0,byte + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_BYTE, SCALE_x1); // load i0,fastbase,i0,byte } else if (size == 2) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 6)); // xor i0,i0,fastxor & 6 - UML_LOAD(block, IREG(0), fastbase, IREG(0), WORD_x1); // load i0,fastbase,i0,word_x1 + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_WORD, SCALE_x1); // load i0,fastbase,i0,word_x1 } else if (size == 4) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 4)); // xor i0,i0,fastxor & 4 - UML_LOAD(block, IREG(0), fastbase, IREG(0), DWORD_x1); // load i0,fastbase,i0,dword_x1 + UML_LOAD(block, IREG(0), fastbase, IREG(0), SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1 } else if (size == 8) { - UML_DLOAD(block, IREG(0), fastbase, IREG(0), QWORD_x1); // dload i0,fastbase,i0,qword + UML_DLOAD(block, IREG(0), fastbase, IREG(0), SIZE_QWORD, SCALE_x1); // dload i0,fastbase,i0,qword } UML_RET(block); // ret } @@ -1583,37 +1557,37 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (size == 1) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 7)); // xor i0,i0,fastxor & 7 - UML_STORE(block, fastbase, IREG(0), IREG(1), BYTE); // store fastbase,i0,i1,byte + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_BYTE, SCALE_x1); // store fastbase,i0,i1,byte } else if (size == 2) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 6)); // xor i0,i0,fastxor & 6 - UML_STORE(block, fastbase, IREG(0), IREG(1), WORD_x1); // store fastbase,i0,i1,word_x1 + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_WORD, SCALE_x1); // store fastbase,i0,i1,word_x1 } else if (size == 4) { UML_XOR(block, IREG(0), IREG(0), IMM(fastxor & 4)); // xor i0,i0,fastxor & 4 if (ismasked) { - UML_LOAD(block, IREG(3), fastbase, IREG(0), DWORD_x1); // load i3,fastbase,i0,dword_x1 + UML_LOAD(block, IREG(3), fastbase, IREG(0), SIZE_DWORD, SCALE_x1); // load i3,fastbase,i0,dword_x1 UML_AND(block, IREG(1), IREG(1), IREG(2)); // and i1,i1,i2 UML_XOR(block, IREG(2), IREG(2), IMM(0xffffffff)); // xor i2,i2,0xfffffffff UML_AND(block, IREG(3), IREG(3), IREG(2)); // and i3,i3,i2 UML_OR(block, IREG(1), IREG(1), IREG(3)); // or i1,i1,i3 } - UML_STORE(block, fastbase, IREG(0), IREG(1), DWORD_x1); // store fastbase,i0,i1,dword_x1 + UML_STORE(block, fastbase, IREG(0), IREG(1), SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1 } else if (size == 8) { if (ismasked) { - UML_DLOAD(block, IREG(3), fastbase, IREG(0), QWORD_x1); // dload i3,fastbase,i0,qword_x1 + UML_DLOAD(block, IREG(3), fastbase, IREG(0), SIZE_QWORD, SCALE_x1); // dload i3,fastbase,i0,qword_x1 UML_DAND(block, IREG(1), IREG(1), IREG(2)); // dand i1,i1,i2 UML_DXOR(block, IREG(2), IREG(2), IMM(U64(0xffffffffffffffff))); // dxor i2,i2,0xfffffffffffffffff UML_DAND(block, IREG(3), IREG(3), IREG(2)); // dand i3,i3,i2 UML_DOR(block, IREG(1), IREG(1), IREG(3)); // dor i1,i1,i3 } - UML_DSTORE(block, fastbase, IREG(0), IREG(1), QWORD_x1); // dstore fastbase,i0,i1,qword_x1 + UML_DSTORE(block, fastbase, IREG(0), IREG(1), SIZE_QWORD, SCALE_x1); // dstore fastbase,i0,i1,qword_x1 } UML_RET(block); // ret } @@ -1625,25 +1599,25 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si { case 1: if (iswrite) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_BYTE); // write i0,i1,program_byte + UML_WRITE(block, IREG(0), IREG(1), SIZE_BYTE, SPACE_PROGRAM); // write i0,i1,program_byte else - UML_READ(block, IREG(0), IREG(0), PROGRAM_BYTE); // read i0,i0,program_byte + UML_READ(block, IREG(0), IREG(0), SIZE_BYTE, SPACE_PROGRAM); // read i0,i0,program_byte break; case 2: if (iswrite) { if (!ismasked) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_WORD); // write i0,i1,program_word + UML_WRITE(block, IREG(0), IREG(1), SIZE_WORD, SPACE_PROGRAM); // write i0,i1,program_word else - UML_WRITEM(block, IREG(0), IREG(1), IREG(2), PROGRAM_WORD); // writem i0,i2,i1,program_word + UML_WRITEM(block, IREG(0), IREG(1), IREG(2), SIZE_WORD, SPACE_PROGRAM); // writem i0,i2,i1,program_word } else { if (!ismasked) - UML_READ(block, IREG(0), IREG(0), PROGRAM_WORD); // read i0,i0,program_word + UML_READ(block, IREG(0), IREG(0), SIZE_WORD, SPACE_PROGRAM); // read i0,i0,program_word else - UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_WORD); // readm i0,i0,i2,program_word + UML_READM(block, IREG(0), IREG(0), IREG(2), SIZE_WORD, SPACE_PROGRAM); // readm i0,i0,i2,program_word } break; @@ -1651,16 +1625,16 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (iswrite) { if (!ismasked) - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_DWORD); // write i0,i1,program_dword + UML_WRITE(block, IREG(0), IREG(1), SIZE_DWORD, SPACE_PROGRAM); // write i0,i1,program_dword else - UML_WRITEM(block, IREG(0), IREG(1), IREG(2), PROGRAM_DWORD); // writem i0,i2,i1,program_dword + UML_WRITEM(block, IREG(0), IREG(1), IREG(2), SIZE_DWORD, SPACE_PROGRAM); // writem i0,i2,i1,program_dword } else { if (!ismasked) - UML_READ(block, IREG(0), IREG(0), PROGRAM_DWORD); // read i0,i0,program_dword + UML_READ(block, IREG(0), IREG(0), SIZE_DWORD, SPACE_PROGRAM); // read i0,i0,program_dword else - UML_READM(block, IREG(0), IREG(0), IREG(2), PROGRAM_DWORD); // readm i0,i0,i2,program_dword + UML_READM(block, IREG(0), IREG(0), IREG(2), SIZE_DWORD, SPACE_PROGRAM); // readm i0,i0,i2,program_dword } break; @@ -1668,16 +1642,16 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (iswrite) { if (!ismasked) - UML_DWRITE(block, IREG(0), IREG(1), PROGRAM_QWORD); // dwrite i0,i1,program_qword + UML_DWRITE(block, IREG(0), IREG(1), SIZE_QWORD, SPACE_PROGRAM); // dwrite i0,i1,program_qword else - UML_DWRITEM(block, IREG(0), IREG(1), IREG(2), PROGRAM_QWORD); // dwritem i0,i2,i1,program_qword + UML_DWRITEM(block, IREG(0), IREG(1), IREG(2), SIZE_QWORD, SPACE_PROGRAM); // dwritem i0,i2,i1,program_qword } else { if (!ismasked) - UML_DREAD(block, IREG(0), IREG(0), PROGRAM_QWORD); // dread i0,i0,program_qword + UML_DREAD(block, IREG(0), IREG(0), SIZE_QWORD, SPACE_PROGRAM); // dread i0,i0,program_qword else - UML_DREADM(block, IREG(0), IREG(0), IREG(2), PROGRAM_QWORD); // dreadm i0,i0,i2,program_qword + UML_DREADM(block, IREG(0), IREG(0), IREG(2), SIZE_QWORD, SPACE_PROGRAM); // dreadm i0,i0,i2,program_qword } break; } @@ -1696,22 +1670,22 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_SUB(block, IREG(0), IREG(0), IMM(1)); // sub i0,i0,1 UML_SHR(block, IREG(1), IREG(1), IMM(8)); // shr i1,i1,8 UML_MOV(block, IREG(2), IMM(0x00ff)); // mov i2,0x00ff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1)); // add i0,[tempaddr],1 UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l), IMM(8)); // shl i1,[tempdata],8 UML_MOV(block, IREG(2), IMM(0xff00)); // mov i2,0xff00 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked } else { UML_MOV(block, MEM(&ppc->impstate->tempaddr), IREG(0)); // mov [tempaddr],i0 UML_SUB(block, IREG(0), IREG(0), IMM(1)); // sub i0,i0,1 UML_MOV(block, IREG(2), IMM(0x00ff)); // mov i2,0x00ff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHL(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(8)); // shl [tempdata],i0,8 UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1)); // add i0,[tempaddr],1 UML_MOV(block, IREG(2), IMM(0xff00)); // mov i2,0xff00 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHR(block, IREG(0), IREG(0), IMM(8)); // shr i0,i0,8 UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata.w.l)); // or i0,i0,[tempdata] } @@ -1728,11 +1702,11 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_SUB(block, IREG(0), IREG(0), IMM(1)); // sub i0,i0,1 UML_SHR(block, IREG(1), IREG(1), IMM(8)); // shr i1,i1,8 UML_MOV(block, IREG(2), IMM(0x00ffffff)); // mov i2,0x00ffffff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(3)); // add i0,[tempaddr],3 UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l), IMM(24)); // shl i1,[tempdata],24 UML_MOV(block, IREG(2), IMM(0xff000000)); // mov i2,0xff000000 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_RET(block); // ret UML_LABEL(block, offs2); // offs2: UML_TEST(block, IREG(0), IMM(1)); // test i0,i0,1 @@ -1740,21 +1714,21 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_SUB(block, IREG(0), IREG(0), IMM(2)); // sub i0,i0,2 UML_SHR(block, IREG(1), IREG(1), IMM(16)); // shr i1,i1,16 UML_MOV(block, IREG(2), IMM(0x0000ffff)); // mov i2,0x0000ffff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(2)); // add i0,[tempaddr],2 UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l), IMM(16)); // shl i1,[tempdata],16 UML_MOV(block, IREG(2), IMM(0xffff0000)); // mov i2,0xffff0000 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_RET(block); // ret UML_LABEL(block, offs3); // offs3: UML_SUB(block, IREG(0), IREG(0), IMM(3)); // sub i0,i0,3 UML_SHR(block, IREG(1), IREG(1), IMM(24)); // shr i1,i1,24 UML_MOV(block, IREG(2), IMM(0x000000ff)); // mov i2,0x000000ff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1)); // add i0,[tempaddr],1 UML_SHL(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l), IMM(8)); // shl i1,[tempdata],8 UML_MOV(block, IREG(2), IMM(0xffffff00)); // mov i2,0xffffff00 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked } else { @@ -1763,11 +1737,11 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_JMPc(block, IF_NZ, offs2 = label++); // jnz offs2 UML_SUB(block, IREG(0), IREG(0), IMM(1)); // sub i0,i0,1 UML_MOV(block, IREG(2), IMM(0x00ffffff)); // mov i2,0x00ffffff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHL(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(8)); // shl [tempdata],i0,8 UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(3)); // add i0,[tempaddr],3 UML_MOV(block, IREG(2), IMM(0xff000000)); // mov i2,0xff000000 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHR(block, IREG(0), IREG(0), IMM(24)); // shr i0,i0,24 UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata.w.l)); // or i0,i0,[tempdata] UML_RET(block); // ret @@ -1776,22 +1750,22 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_JMPc(block, IF_NZ, offs3 = label++); // jnz offs3 UML_SUB(block, IREG(0), IREG(0), IMM(2)); // sub i0,i0,2 UML_MOV(block, IREG(2), IMM(0x0000ffff)); // mov i2,0x0000ffff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHL(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(16)); // shl [tempdata],i0,16 UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(2)); // add i0,[tempaddr],2 UML_MOV(block, IREG(2), IMM(0xffff0000)); // mov i2,0xffff0000 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHR(block, IREG(0), IREG(0), IMM(16)); // shr i0,i0,16 UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata.w.l)); // or i0,i0,[tempdata] UML_RET(block); // ret UML_LABEL(block, offs3); // offs3: UML_SUB(block, IREG(0), IREG(0), IMM(3)); // sub i0,i0,3 UML_MOV(block, IREG(2), IMM(0x000000ff)); // mov i2,0x000000ff - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHL(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(24)); // shl [tempdata],i0,24 UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(1)); // add i0,[tempaddr],1 UML_MOV(block, IREG(2), IMM(0xffffff00)); // mov i2,0xffffff00 - UML_CALLH(block, masked); // callh masked + UML_CALLH(block, *masked); // callh masked UML_SHR(block, IREG(0), IREG(0), IMM(8)); // shr i0,i0,8 UML_OR(block, IREG(0), IREG(0), MEM(&ppc->impstate->tempdata.w.l)); // or i0,i0,[tempdata] } @@ -1804,7 +1778,7 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si { UML_LABEL(block, alignex); // alignex: UML_RECOVER(block, SPR32(SPROEA_DSISR), MAPVAR_DSISR); // recover [dsisr],DSISR - UML_EXH(block, ppc->impstate->exception[EXCEPTION_ALIGN], IREG(0)); // exh align,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_ALIGN], IREG(0)); // exh align,i0 } /* handle a TLB miss */ @@ -1813,9 +1787,9 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_LABEL(block, tlbmiss); // tlbmiss: UML_MOV(block, MEM(&ppc->param0), IREG(0)); // mov [param0],i0 UML_MOV(block, MEM(&ppc->param1), IMM(translate_type)); // mov [param1],translate_type - UML_CALLC(block, ppccom_tlb_fill, ppc); // callc tlbfill,ppc + UML_CALLC(block, (c_function)ppccom_tlb_fill, ppc); // callc tlbfill,ppc UML_SHR(block, IREG(3), IREG(0), IMM(12)); // shr i3,i0,12 - UML_LOAD(block, IREG(3), (void *)vtlb_table(ppc->vtlb), IREG(3), DWORD); // load i3,[vtlb],i3,dword + UML_LOAD(block, IREG(3), (void *)vtlb_table(ppc->vtlb), IREG(3), SIZE_DWORD, SCALE_x4);// load i3,[vtlb],i3,dword UML_TEST(block, IREG(3), IMM((UINT64)1 << translate_type)); // test i3,1 << translate_type UML_JMPc(block, IF_NZ, tlbreturn); // jmp tlbreturn,nz @@ -1823,7 +1797,7 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si if (ppc->cap & PPCCAP_4XX) { UML_MOV(block, SPR32(SPR4XX_DEAR), IREG(0)); // mov [dear],i0 - UML_EXH(block, ppc->impstate->exception[EXCEPTION_DSI], IREG(0)); // exh dsi,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_DSI], IREG(0)); // exh dsi,i0 } /* 603 case: TLBMISS exception */ @@ -1834,20 +1808,20 @@ static void static_generate_memory_accessor(powerpc_state *ppc, int mode, int si UML_MOV(block, SPR32(SPR603_HASH1), MEM(&ppc->mmu603_hash[0])); // mov [hash1],[mmu603_hash][0] UML_MOV(block, SPR32(SPR603_HASH2), MEM(&ppc->mmu603_hash[1])); // mov [hash2],[mmu603_hash][1] if (iswrite) - UML_EXH(block, ppc->impstate->exception[EXCEPTION_DTLBMISSS], IREG(0)); // exh dtlbmisss,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_DTLBMISSS], IREG(0)); // exh dtlbmisss,i0 else - UML_EXH(block, ppc->impstate->exception[EXCEPTION_DTLBMISSL], IREG(0)); // exh dtlbmissl,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_DTLBMISSL], IREG(0)); // exh dtlbmissl,i0 } /* general case: DSI exception */ else { UML_MOV(block, SPR32(SPROEA_DSISR), MEM(&ppc->param0)); // mov [dsisr],[param0] - UML_EXH(block, ppc->impstate->exception[EXCEPTION_DSI], IREG(0)); // exh dsi,i0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_DSI], IREG(0)); // exh dsi,i0 } } - drcuml_block_end(block); + block->end(); } @@ -1860,19 +1834,14 @@ static void static_generate_swap_tgpr(powerpc_state *ppc) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; int regnum; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_swap_tgpr"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 30, &errorbuf); + block = drcuml->begin_block(30); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &ppc->impstate->swap_tgpr, "swap_tgpr"); - UML_HANDLE(block, ppc->impstate->swap_tgpr); // handle swap_tgpr + UML_HANDLE(block, *ppc->impstate->swap_tgpr); // handle swap_tgpr for (regnum = 0; regnum < 4; regnum++) { UML_MOV(block, IREG(1), R32(regnum)); // mov i1,r[regnum] @@ -1881,7 +1850,7 @@ static void static_generate_swap_tgpr(powerpc_state *ppc) } UML_RET(block); // ret - drcuml_block_end(block); + block->end(); } @@ -1895,15 +1864,10 @@ static void static_generate_lsw_entries(powerpc_state *ppc, int mode) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; int regnum; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_lsw_entries"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 32 * 30, &errorbuf); + block = drcuml->begin_block(32 * 30); /* iterate over all possible registers */ for (regnum = 0; regnum < 32; regnum++) @@ -1913,28 +1877,28 @@ static void static_generate_lsw_entries(powerpc_state *ppc, int mode) /* allocate a handle */ sprintf(temp, "lsw%d", regnum); alloc_handle(drcuml, &ppc->impstate->lsw[mode][regnum], temp); - UML_HANDLE(block, ppc->impstate->lsw[mode][regnum]); // handle lsw<regnum> + UML_HANDLE(block, *ppc->impstate->lsw[mode][regnum]); // handle lsw<regnum> UML_LABEL(block, regnum); // regnum: UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(0)); // add i0,[updateaddr],0 - UML_CALLH(block, ppc->impstate->read8[mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[mode]); // callh read8 UML_ROLAND(block, R32(regnum), IREG(0), IMM(24), IMM(0xff000000)); // roland reg,i0,24,0xff000000 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(1)); // add i0,[updateaddr],1 - UML_CALLH(block, ppc->impstate->read8[mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[mode]); // callh read8 UML_ROLAND(block, IREG(0), IREG(0), IMM(16), IMM(0x00ff0000)); // roland i0,i0,16,0x00ff0000 UML_OR(block, R32(regnum), R32(regnum), IREG(0)); // or reg,i0 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(2)); // add i0,[updateaddr],2 - UML_CALLH(block, ppc->impstate->read8[mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[mode]); // callh read8 UML_ROLAND(block, IREG(0), IREG(0), IMM(8), IMM(0x0000ff00)); // roland i0,i0,8,0x0000ff00 UML_OR(block, R32(regnum), R32(regnum), IREG(0)); // or reg,i0 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(3)); // add i0,[updateaddr],3 UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1)); // add [updateaddr],i0,1 - UML_CALLH(block, ppc->impstate->read8[mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[mode]); // callh read8 UML_ROLAND(block, IREG(0), IREG(0), IMM(0), IMM(0x000000ff)); // roland i0,i0,0,0x000000ff UML_OR(block, R32(regnum), R32(regnum), IREG(0)); // or reg,i0 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 @@ -1942,7 +1906,7 @@ static void static_generate_lsw_entries(powerpc_state *ppc, int mode) UML_JMP(block, (regnum + 1) % 32); // jmp nextreg } - drcuml_block_end(block); + block->end(); } @@ -1956,15 +1920,10 @@ static void static_generate_stsw_entries(powerpc_state *ppc, int mode) { drcuml_state *drcuml = ppc->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; int regnum; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_stsw_entries"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 32 * 30, &errorbuf); + block = drcuml->begin_block(32 * 30); /* iterate over all possible registers */ for (regnum = 0; regnum < 32; regnum++) @@ -1974,33 +1933,33 @@ static void static_generate_stsw_entries(powerpc_state *ppc, int mode) /* allocate a handle */ sprintf(temp, "stsw%d", regnum); alloc_handle(drcuml, &ppc->impstate->stsw[mode][regnum], temp); - UML_HANDLE(block, ppc->impstate->stsw[mode][regnum]); // handle stsw<regnum> + UML_HANDLE(block, *ppc->impstate->stsw[mode][regnum]); // handle stsw<regnum> UML_LABEL(block, regnum); // regnum: UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(0)); // add i0,[updateaddr],0 UML_ROLAND(block, IREG(1), R32(regnum), IMM(8), IMM(0xff)); // roland i1,regnum,8,0xff - UML_CALLH(block, ppc->impstate->write8[mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[mode]); // callh write8 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(1)); // add i0,[updateaddr],1 UML_ROLAND(block, IREG(1), R32(regnum), IMM(16), IMM(0xff)); // roland i1,regnum,16,0xff - UML_CALLH(block, ppc->impstate->write8[mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[mode]); // callh write8 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(2)); // add i0,[updateaddr],2 UML_ROLAND(block, IREG(1), R32(regnum), IMM(24), IMM(0xff)); // roland i1,regnum,24,0xff - UML_CALLH(block, ppc->impstate->write8[mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[mode]); // callh write8 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_ADD(block, IREG(0), MEM(&ppc->impstate->updateaddr), IMM(3)); // add i0,[updateaddr],3 UML_ADD(block, MEM(&ppc->impstate->updateaddr), IREG(0), IMM(1)); // add [updateaddr],i0,1 UML_ROLAND(block, IREG(1), R32(regnum), IMM(0), IMM(0xff)); // roland i1,regnum,0,0xff - UML_CALLH(block, ppc->impstate->write8[mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[mode]); // callh write8 UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1)); // sub [swcount],[swcount],1 UML_RETc(block, IF_Z); // ret z UML_JMP(block, (regnum + 1) % 32); // jmp nextreg } - drcuml_block_end(block); + block->end(); } @@ -2045,21 +2004,21 @@ static void generate_update_mode(powerpc_state *ppc, drcuml_block *block) an exception if out -------------------------------------------------*/ -static void generate_update_cycles(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception) +static void generate_update_cycles(powerpc_state *ppc, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception) { /* check full interrupts if pending */ if (compiler->checkints) { - drcuml_codelabel skip; + code_label skip; compiler->checkints = FALSE; UML_TEST(block, MEM(&ppc->irq_pending), IMM(~0)); // test [irq_pending],0 UML_JMPc(block, IF_Z, skip = compiler->labelnum++); // jmp skip,Z UML_TEST(block, MSR32, IMM(MSR_EE)); // test [msr],MSR_EE UML_JMPc(block, IF_Z, skip); // jmp skip,Z - UML_MOV(block, IREG(0), PARAM(ptype, pvalue)); // mov i0,nextpc + UML_MOV(block, IREG(0), param); // mov i0,nextpc UML_MOV(block, IREG(1), IMM(compiler->cycles)); // mov i1,cycles - UML_CALLH(block, ppc->impstate->exception_norecover[EXCEPTION_EI]); // callh interrupt_norecover + UML_CALLH(block, *ppc->impstate->exception_norecover[EXCEPTION_EI]); // callh interrupt_norecover UML_LABEL(block, skip); // skip: } @@ -2069,7 +2028,7 @@ static void generate_update_cycles(powerpc_state *ppc, drcuml_block *block, comp UML_SUB(block, MEM(&ppc->icount), MEM(&ppc->icount), MAPVAR_CYCLES); // sub icount,icount,cycles UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 if (allow_exception) - UML_EXHc(block, IF_S, ppc->impstate->out_of_cycles, PARAM(ptype, pvalue)); // exh out_of_cycles,nextpc + UML_EXHc(block, IF_S, *ppc->impstate->out_of_cycles, param); // exh out_of_cycles,nextpc } compiler->cycles = 0; } @@ -2084,7 +2043,7 @@ static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, com { const opcode_desc *curdesc; if (LOG_UML) - UML_COMMENT(block, "[Validation for %08X]", seqhead->pc); // comment + block->append_comment("[Validation for %08X]", seqhead->pc); // comment /* loose verify or single instruction: just compare and fail */ if (!(ppc->impstate->drcoptions & PPCDRC_STRICT_VERIFY) || seqhead->next() == NULL) @@ -2092,9 +2051,9 @@ static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, com if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = ppc->direct->read_decrypted_ptr(seqhead->physpc, ppc->codexor); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,dword UML_CMP(block, IREG(0), IMM(seqhead->opptr.l[0])); // cmp i0,*opptr - UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc } } @@ -2106,25 +2065,25 @@ static void generate_checksum_block(powerpc_state *ppc, drcuml_block *block, com if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = ppc->direct->read_decrypted_ptr(seqhead->physpc, ppc->codexor); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,dword UML_CMP(block, IREG(0), IMM(curdesc->opptr.l[0])); // cmp i0,*opptr - UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc } #else UINT32 sum = 0; void *base = ppc->direct->read_decrypted_ptr(seqhead->physpc, ppc->codexor); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,dword sum += seqhead->opptr.l[0]; for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { base = ppc->direct->read_decrypted_ptr(curdesc->physpc, ppc->codexor); - UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword + UML_LOAD(block, IREG(1), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i1,base,dword UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1 sum += curdesc->opptr.l[0]; } UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum - UML_EXHc(block, IF_NE, ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *ppc->impstate->nocode, IMM(seqhead->pc)); // exne nocode,seqhead->pc #endif } } @@ -2164,7 +2123,7 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc if (desc->pc == PROBE_ADDRESS) { UML_MOV(block, MEM(&ppc->pc), IMM(desc->pc)); // mov [pc],desc->pc - UML_CALLC(block, cfunc_printf_probe, desc->pc); // callc cfunc_printf_probe,desc->pc + UML_CALLC(block, cfunc_printf_probe, (void *)desc->pc); // callc cfunc_printf_probe,desc->pc } /* if we are debugging, call the debugger */ @@ -2193,7 +2152,7 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, ppc); // callc printf_debug } - UML_EXH(block, ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 + UML_EXH(block, *ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 } /* validate our TLB entry at this PC; if we fail, we need to handle it */ @@ -2211,9 +2170,9 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, ppc); // callc printf_debug } - UML_LOAD(block, IREG(0), &tlbtable[desc->pc >> 12], IMM(0), DWORD); // load i0,tlbtable[desc->pc >> 12],dword + UML_LOAD(block, IREG(0), &tlbtable[desc->pc >> 12], IMM(0), SIZE_DWORD, SCALE_x4);// load i0,tlbtable[desc->pc >> 12],dword UML_CMP(block, IREG(0), IMM(tlbtable[desc->pc >> 12])); // cmp i0,*tlbentry - UML_EXHc(block, IF_NE, ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0,NE + UML_EXHc(block, IF_NE, *ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0,NE } /* otherwise, we generate an unconditional exception */ @@ -2226,17 +2185,17 @@ static void generate_sequence_instruction(powerpc_state *ppc, drcuml_block *bloc UML_MOV(block, MEM(&ppc->impstate->arg0), IMM(desc->pc)); // mov [arg0],desc->pc UML_CALLC(block, cfunc_printf_debug, ppc); // callc printf_debug } - UML_EXH(block, ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 + UML_EXH(block, *ppc->impstate->tlb_mismatch, IMM(0)); // exh tlb_mismatch,0 } } /* if this is an invalid opcode, generate the exception now */ if (desc->flags & OPFLAG_INVALID_OPCODE) - UML_EXH(block, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x80000)); // exh exception_program,0x80000 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x80000)); // exh exception_program,0x80000 /* if this is a privileged opcode in user mode, generate the exception */ else if ((desc->flags & OPFLAG_PRIVILEGED) && (ppc->impstate->mode & MODE_USER)) - UML_EXH(block, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x40000)); // exh exception_program,0x40000 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x40000)); // exh exception_program,0x40000 /* otherwise, unless this is a virtual no-op, it's a regular instruction */ else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP)) @@ -2268,7 +2227,7 @@ static void generate_compute_flags(powerpc_state *ppc, drcuml_block *block, cons if (!(desc->regreq[2] & REGFLAG_CR(0))) updatecr = 0; } - xerflags = ((xermask & XER_OV) ? DRCUML_FLAG_V : 0) | ((xermask & XER_CA) ? DRCUML_FLAG_C : 0); + xerflags = ((xermask & XER_OV) ? FLAG_V : 0) | ((xermask & XER_CA) ? FLAG_C : 0); /* easy case: nothing to do */ if (!updatecr && xermask == 0) @@ -2277,8 +2236,8 @@ static void generate_compute_flags(powerpc_state *ppc, drcuml_block *block, cons /* semi-easy case: crfield only */ if (xermask == 0) { - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z); // getflgs i0,sz - UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), BYTE); // load i0,sz_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_S | FLAG_Z); // getflgs i0,sz + UML_LOAD(block, IREG(0), ppc->impstate->sz_cr_table, IREG(0), SIZE_BYTE, SCALE_x1); // load i0,sz_cr_table,i0,byte UML_OR(block, CR32(0), IREG(0), XERSO32); // or [cr0],i0,[xerso] return; } @@ -2290,7 +2249,7 @@ static void generate_compute_flags(powerpc_state *ppc, drcuml_block *block, cons { UML_GETFLGS(block, IREG(0), xerflags); // getflgs i0,xerflags if (invertcarry && (xermask & XER_CA)) - UML_XOR(block, IREG(0), IREG(0), IMM(DRCUML_FLAG_C)); // xor i0,i0,FLAG_C + UML_XOR(block, IREG(0), IREG(0), IMM(FLAG_C)); // xor i0,i0,FLAG_C UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(xermask)); // rolins [xer],i0,29,xermask UML_SHR(block, IREG(0), IREG(0), IMM(1)); // shr i0,i0,1 UML_OR(block, XERSO32, XERSO32, IREG(0)); // or [xerso],i0 @@ -2304,10 +2263,10 @@ static void generate_compute_flags(powerpc_state *ppc, drcuml_block *block, cons } /* tricky case: both */ - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_S | DRCUML_FLAG_Z | xerflags); // getflgs i0,SZ | xerflags - UML_LOAD(block, IREG(1), ppc->impstate->sz_cr_table, IREG(0), BYTE); // load i1,sz_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_S | FLAG_Z | xerflags); // getflgs i0,SZ | xerflags + UML_LOAD(block, IREG(1), ppc->impstate->sz_cr_table, IREG(0), SIZE_BYTE, SCALE_x1); // load i1,sz_cr_table,i0,byte if (invertcarry && (xermask & XER_CA)) - UML_XOR(block, IREG(0), IREG(0), IMM(DRCUML_FLAG_C)); // xor i0,i0,FLAG_C + UML_XOR(block, IREG(0), IREG(0), IMM(FLAG_C)); // xor i0,i0,FLAG_C UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(xermask)); // rolins [xer],i0,29,xermask if (xermask & XER_OV) { @@ -2330,7 +2289,7 @@ static void generate_fp_flags(powerpc_state *ppc, drcuml_block *block, const opc if (updatefprf) { UML_MOV(block, MEM(&ppc->param0), IMM(G_RD(desc->opptr.l[0]))); - UML_CALLC(block, ppccom_update_fprf, ppc); + UML_CALLC(block, (c_function)ppccom_update_fprf, ppc); } } @@ -2362,13 +2321,13 @@ static void generate_branch(powerpc_state *ppc, drcuml_block *block, compiler_st if (desc->flags & OPFLAG_INTRABLOCK_BRANCH) UML_JMP(block, desc->targetpc | 0x80000000); // jmp desc->targetpc | 0x80000000 else - UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(desc->targetpc), ppc->impstate->nocode); + UML_HASHJMP(block, IMM(ppc->impstate->mode), IMM(desc->targetpc), *ppc->impstate->nocode); // hashjmp <mode>,desc->targetpc,nocode } else { generate_update_cycles(ppc, block, &compiler_temp, MEM(srcptr), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(ppc->impstate->mode), MEM(srcptr), ppc->impstate->nocode); // hashjmp <mode>,<rsreg>,nocode + UML_HASHJMP(block, IMM(ppc->impstate->mode), MEM(srcptr), *ppc->impstate->nocode); // hashjmp <mode>,<rsreg>,nocode } /* update the label */ @@ -2425,15 +2384,15 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x03: /* TWI */ UML_CMP(block, R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // cmp ra,simm if (G_TO(op) & 0x10) - UML_EXHc(block, IF_L, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l + UML_EXHc(block, IF_L, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l if (G_TO(op) & 0x08) - UML_EXHc(block, IF_G, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g + UML_EXHc(block, IF_G, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g if (G_TO(op) & 0x04) - UML_EXHc(block, IF_E, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e + UML_EXHc(block, IF_E, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e if (G_TO(op) & 0x02) - UML_EXHc(block, IF_B, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b + UML_EXHc(block, IF_B, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b if (G_TO(op) & 0x01) - UML_EXHc(block, IF_A, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a + UML_EXHc(block, IF_A, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a return TRUE; case 0x07: /* MULLI */ @@ -2451,15 +2410,15 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x0a: /* CMPLI */ UML_CMP(block, R32(G_RA(op)), IMM(G_UIMM(op))); // cmp ra,uimm - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C); // getflgs i0,zc - UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), BYTE); // load i0,cmpl_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_Z | FLAG_C); // getflgs i0,zc + UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,cmpl_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] return TRUE; case 0x0b: /* CMPI */ UML_CMP(block, R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // cmp ra,uimm - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S); // getflgs i0,zcs - UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), BYTE); // load i0,cmp_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_Z | FLAG_C | FLAG_S); // getflgs i0,zcs + UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,cmp_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] return TRUE; @@ -2484,7 +2443,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x11: /* SC */ UML_MAPVAR(block, MAPVAR_PC, desc->pc + 4); // mapvar PC,desc->pc+4 - UML_EXH(block, ppc->impstate->exception[EXCEPTION_SYSCALL], IMM(0)); // exh syscall,0 + UML_EXH(block, *ppc->impstate->exception[EXCEPTION_SYSCALL], IMM(0)); // exh syscall,0 return TRUE; case 0x12: /* Bx */ @@ -2547,7 +2506,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x22: /* LBZ */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[ppc->impstate->mode]); // callh read8 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff)); // and rd,i0,0xff generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2555,7 +2514,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x28: /* LHZ */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff)); // and rd,i0,0xffff generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2563,15 +2522,15 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x2a: /* LHA */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 - UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD); // sext rd,i0,word + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_SEXT(block, R32(G_RD(op)), IREG(0), SIZE_WORD); // sext rd,i0,word generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x20: /* LWZ */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2580,7 +2539,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[ppc->impstate->mode]); // callh read8 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff)); // and rd,i0,0xff UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -2590,7 +2549,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff)); // and rd,i0,0xffff UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -2600,8 +2559,8 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 - UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD); // sext rd,i0,word + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_SEXT(block, R32(G_RD(op)), IREG(0), SIZE_WORD); // sext rd,i0,word UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2610,7 +2569,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -2620,7 +2579,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff)); // and i1,rs,0xff UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[ppc->impstate->mode]); // callh write8 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2628,7 +2587,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff)); // and i1,rs,0xffff UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode]); // callh write16 + UML_CALLH(block, *ppc->impstate->write16[ppc->impstate->mode]); // callh write16 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2636,7 +2595,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2645,7 +2604,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff)); // and i1,rs,0xff UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[ppc->impstate->mode]); // callh write8 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2655,7 +2614,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff)); // and i1,rs,0xffff UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode]); // callh write16 + UML_CALLH(block, *ppc->impstate->write16[ppc->impstate->mode]); // callh write16 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2665,7 +2624,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2677,7 +2636,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta { UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM((INT16)G_SIMM(op) + 4 * (regnum - G_RD(op)))); // add i0,[tempaddr],simm + 4*(regnum-rd) - UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align + UML_CALLH(block, *ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align UML_MOV(block, R32(regnum), IREG(0)); // mov regnum,i0 } generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -2691,7 +2650,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM((INT16)G_SIMM(op) + 4 * (regnum - G_RS(op)))); // add i0,[tempaddr],simm + 4*(regnum-rs) UML_MOV(block, IREG(1), R32(regnum)); // mov i1,regnum - UML_CALLH(block, ppc->impstate->write32align[ppc->impstate->mode]); // callh write32align + UML_CALLH(block, *ppc->impstate->write32align[ppc->impstate->mode]); // callh write32align } generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2699,16 +2658,16 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x30: /* LFS */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0)); // mov [tempdata],i0 - UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), DWORD); // fdfrflt fd,[tempdata],dword + UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), SIZE_DWORD); // fdfrflt fd,[tempdata],dword generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x32: /* LFD */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode]); // callh read64 + UML_CALLH(block, *ppc->impstate->read64[ppc->impstate->mode]); // callh read64 UML_DMOV(block, MEM(&ppc->impstate->tempdata.d), IREG(0)); // dmov [tempdata],i0 UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.d)); // fdmov fd,[tempdata] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -2718,9 +2677,9 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0)); // mov [tempdata],i0 - UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), DWORD); // fdfrflt fd,[tempdata],dword + UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), SIZE_DWORD); // fdfrflt fd,[tempdata],dword UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2729,7 +2688,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode]); // callh read64 + UML_CALLH(block, *ppc->impstate->read64[ppc->impstate->mode]); // callh read64 UML_DMOV(block, MEM(&ppc->impstate->tempdata.d), IREG(0)); // dmov [tempdata],i0 UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.d)); // fdmov fd,[tempdata] UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] @@ -2738,10 +2697,10 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta case 0x34: /* STFS */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm - UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), QWORD); // fsfrflt [tempdata],rs,qword + UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), SIZE_QWORD); // fsfrflt [tempdata],rs,qword UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l)); // mov i1,[tempdata] UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2750,17 +2709,17 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_FDMOV(block, MEM(&ppc->impstate->tempdata.d), F64(G_RS(op))); // fdmov [tempdata],rs UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata.d)); // dmov i1,[tempdata] UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMM(op)); // mapvar dsisr,DSISR_IMM(op) - UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode]); // callh write64 + UML_CALLH(block, *ppc->impstate->write64[ppc->impstate->mode]); // callh write64 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x35: /* STFSU */ UML_ADD(block, IREG(0), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add i0,ra,simm - UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), QWORD); // fsfrflt [tempdata],rs,qword + UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), SIZE_QWORD); // fsfrflt [tempdata],rs,qword UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l)); // mov i1,[tempdata] UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2771,7 +2730,7 @@ static int generate_opcode(powerpc_state *ppc, drcuml_block *block, compiler_sta UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata.d)); // dmov i1,[tempdata] UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IMMU(op)); // mapvar dsisr,DSISR_IMMU(op) - UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode]); // callh write64 + UML_CALLH(block, *ppc->impstate->write64[ppc->impstate->mode]); // callh write64 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -2893,7 +2852,7 @@ static int generate_instruction_13(powerpc_state *ppc, drcuml_block *block, comp // rolins [msr],[srr1],0,0x87c0ffff | MSR603_TGPR UML_XOR(block, IREG(0), IREG(0), MSR32); // xor i0,i0,[msr] UML_TEST(block, IREG(0), IMM(MSR603_TGPR)); // test i0,tgpr - UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr); // callh swap_tgpr,nz + UML_CALLHc(block, IF_NZ, *ppc->impstate->swap_tgpr); // callh swap_tgpr,nz } } else if (ppc->cap & PPCCAP_4XX) @@ -2901,7 +2860,7 @@ static int generate_instruction_13(powerpc_state *ppc, drcuml_block *block, comp generate_update_mode(ppc, block); // <update mode> compiler->checkints = TRUE; generate_update_cycles(ppc, block, compiler, SPR32(SPROEA_SRR0), TRUE); // <subtract cycles> - UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPROEA_SRR0), ppc->impstate->nocode); + UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPROEA_SRR0), *ppc->impstate->nocode); // hashjmp mode,[srr0],nocode return TRUE; @@ -2911,7 +2870,7 @@ static int generate_instruction_13(powerpc_state *ppc, drcuml_block *block, comp generate_update_mode(ppc, block); // <update mode> compiler->checkints = TRUE; generate_update_cycles(ppc, block, compiler, SPR32(SPR4XX_SRR2), TRUE); // <subtract cycles> - UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPR4XX_SRR2), ppc->impstate->nocode); + UML_HASHJMP(block, MEM(&ppc->impstate->mode), SPR32(SPR4XX_SRR2), *ppc->impstate->nocode); // hashjmp mode,[srr2],nocode return TRUE; @@ -2968,15 +2927,15 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x004: /* TW */ UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra,rb if (G_TO(op) & 0x10) - UML_EXHc(block, IF_L, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l + UML_EXHc(block, IF_L, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,l if (G_TO(op) & 0x08) - UML_EXHc(block, IF_G, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g + UML_EXHc(block, IF_G, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,g if (G_TO(op) & 0x04) - UML_EXHc(block, IF_E, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e + UML_EXHc(block, IF_E, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,e if (G_TO(op) & 0x02) - UML_EXHc(block, IF_B, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b + UML_EXHc(block, IF_B, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,b if (G_TO(op) & 0x01) - UML_EXHc(block, IF_A, ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a + UML_EXHc(block, IF_A, *ppc->impstate->exception[EXCEPTION_PROGRAM], IMM(0x20000));// exh program,0x20000,a return TRUE; case 0x10a: /* ADDx */ @@ -3067,15 +3026,15 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x000: /* CMP */ UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra,rb - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S); // getflgs i0,zcs - UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), BYTE); // load i0,cmp_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_Z | FLAG_C | FLAG_S); // getflgs i0,zcs + UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,cmp_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] return TRUE; case 0x020: /* CMPL */ UML_CMP(block, R32(G_RA(op)), R32(G_RB(op))); // cmp ra,rb - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C); // getflgs i0,zc - UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), BYTE); // load i0,cmpl_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_Z | FLAG_C); // getflgs i0,zc + UML_LOAD(block, IREG(0), ppc->impstate->cmpl_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,cmpl_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] return TRUE; @@ -3211,13 +3170,13 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp return TRUE; case 0x3ba: /* EXTSBx */ - UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), BYTE); // sext ra,rs,byte + UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), SIZE_BYTE); // sext ra,rs,byte if (op & M_RC) generate_compute_flags(ppc, block, desc, op & M_RC, 0, FALSE); // <update flags> return TRUE; case 0x39a: /* EXTSHx */ - UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), WORD); // sext ra,rs,word + UML_SEXT(block, R32(G_RA(op)), R32(G_RS(op)), SIZE_WORD); // sext ra,rs,word if (op & M_RC) generate_compute_flags(ppc, block, desc, op & M_RC, 0, FALSE); // <update flags> return TRUE; @@ -3225,7 +3184,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x057: /* LBZX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[ppc->impstate->mode]); // callh read8 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff)); // and rd,i0,0xff generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3233,7 +3192,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x117: /* LHZX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff)); // and rd,i0,0xffff generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3241,15 +3200,15 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x157: /* LHAX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 - UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD); // sext rd,i0,word + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_SEXT(block, R32(G_RD(op)), IREG(0), SIZE_WORD); // sext rd,i0,word generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x017: /* LWZX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3257,16 +3216,16 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x217: /* LFSX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0)); // mov [tempdata],i0 - UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), DWORD); // fdfrflt fd,[tempdata],dword + UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), SIZE_DWORD); // fdfrflt fd,[tempdata],dword generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x257: /* LFDX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode]); // callh read64 + UML_CALLH(block, *ppc->impstate->read64[ppc->impstate->mode]); // callh read64 UML_DMOV(block, MEM(&ppc->impstate->tempdata.d), IREG(0)); // dmov [tempdata],i0 UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.d)); // fdmov fd,[tempdata] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -3275,7 +3234,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x316: /* LHBRX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 UML_BSWAP(block, IREG(0), IREG(0)); // bswap i0,i0 UML_SHR(block, R32(G_RD(op)), IREG(0), IMM(16)); // shr rd,i0,16 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -3284,7 +3243,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x216: /* LWBRX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align + UML_CALLH(block, *ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align UML_BSWAP(block, R32(G_RD(op)), IREG(0)); // bswap rd,i0 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3293,7 +3252,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op)); // mapvar dsisr,DSISR_IDXU(op) - UML_CALLH(block, ppc->impstate->read8[ppc->impstate->mode]); // callh read8 + UML_CALLH(block, *ppc->impstate->read8[ppc->impstate->mode]); // callh read8 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xff)); // and rd,i0,0xff UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -3303,7 +3262,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op)); // mapvar dsisr,DSISR_IDXU(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 UML_AND(block, R32(G_RD(op)), IREG(0), IMM(0xffff)); // and rd,i0,0xffff UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -3313,8 +3272,8 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op)); // mapvar dsisr,DSISR_IDXU(op) - UML_CALLH(block, ppc->impstate->read16[ppc->impstate->mode]); // callh read16 - UML_SEXT(block, R32(G_RD(op)), IREG(0), WORD); // sext rd,i0,word + UML_CALLH(block, *ppc->impstate->read16[ppc->impstate->mode]); // callh read16 + UML_SEXT(block, R32(G_RD(op)), IREG(0), SIZE_WORD); // sext rd,i0,word UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3323,7 +3282,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op)); // mapvar dsisr,DSISR_IDXU(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> @@ -3333,9 +3292,9 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read32[ppc->impstate->mode]); // callh read32 + UML_CALLH(block, *ppc->impstate->read32[ppc->impstate->mode]); // callh read32 UML_MOV(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0)); // mov [tempdata],i0 - UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), DWORD); // fdfrflt fd,[tempdata],dword + UML_FDFRFLT(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l), SIZE_DWORD); // fdfrflt fd,[tempdata],dword UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3344,7 +3303,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read64[ppc->impstate->mode]); // callh read64 + UML_CALLH(block, *ppc->impstate->read64[ppc->impstate->mode]); // callh read64 UML_DMOV(block, MEM(&ppc->impstate->tempdata.d), IREG(0)); // dmov [tempdata],i0 UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.d)); // fdmov fd,[tempdata] UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] @@ -3354,7 +3313,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x014: /* LWARX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align + UML_CALLH(block, *ppc->impstate->read32align[ppc->impstate->mode]); // callh read32align UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3362,7 +3321,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x255: /* LSWI */ UML_MOV(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op))); // mov [updateaddr],ra UML_MOV(block, MEM(&ppc->impstate->swcount), IMM(((G_NB(op) - 1) & 0x1f) + 1)); // mov [swcount],G_NB - UML_CALLH(block, ppc->impstate->lsw[ppc->impstate->mode][G_RD(op)]); // call lsw[rd] + UML_CALLH(block, *ppc->impstate->lsw[ppc->impstate->mode][G_RD(op)]); // call lsw[rd] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3370,7 +3329,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb UML_AND(block, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f)); // and [swcount],[xer],0x7f UML_SUB(block, MEM(&ppc->icount), MEM(&ppc->icount), MEM(&ppc->impstate->swcount));// sub icount,icount,[swcount] - UML_CALLHc(block, IF_NZ, ppc->impstate->lsw[ppc->impstate->mode][G_RD(op)]); // call lsw[rd],nz + UML_CALLHc(block, IF_NZ, *ppc->impstate->lsw[ppc->impstate->mode][G_RD(op)]); // call lsw[rd],nz generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3382,7 +3341,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff)); // and i1,rs,0xff UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[ppc->impstate->mode]); // callh write8 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3390,7 +3349,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff)); // and i1,rs UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode]); // callh write16 + UML_CALLH(block, *ppc->impstate->write16[ppc->impstate->mode]); // callh write16 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3398,16 +3357,16 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x297: /* STFSX */ UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb - UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), QWORD); // fsfrflt [tempdata],rs,qword + UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), SIZE_QWORD); // fsfrflt [tempdata],rs,qword UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l)); // mov i1,[tempdata] UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3416,7 +3375,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_FDMOV(block, MEM(&ppc->impstate->tempdata.d), F64(G_RS(op))); // fdmov [tempdata],rs UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l)); // mov i1,[tempdata.lo] UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3425,7 +3384,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_FDMOV(block, MEM(&ppc->impstate->tempdata.d), F64(G_RS(op))); // fdmov [tempdata],rs UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata.d)); // dmov i1,[tempdata] UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode]); // callh write64 + UML_CALLH(block, *ppc->impstate->write64[ppc->impstate->mode]); // callh write64 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3434,7 +3393,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_BSWAP(block, IREG(1), R32(G_RS(op))); // bswap i1,rs UML_SHR(block, IREG(1), IREG(1), IMM(16)); // shr i1,i1,16 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode]); // callh write16 + UML_CALLH(block, *ppc->impstate->write16[ppc->impstate->mode]); // callh write16 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3442,7 +3401,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_BSWAP(block, IREG(1), R32(G_RS(op))); // bswap i1,rs UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3451,7 +3410,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xff)); // and i1,rs,0xff UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode]); // callh write8 + UML_CALLH(block, *ppc->impstate->write8[ppc->impstate->mode]); // callh write8 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3461,7 +3420,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_AND(block, IREG(1), R32(G_RS(op)), IMM(0xffff)); // and i1,rs,0xffff UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write16[ppc->impstate->mode]); // callh write16 + UML_CALLH(block, *ppc->impstate->write16[ppc->impstate->mode]); // callh write16 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3471,18 +3430,18 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDXU(op)); // mapvar dsisr,DSISR_IDXU(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; case 0x2b7: /* STFSUX */ UML_ADD(block, IREG(0), R32(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb - UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), QWORD); // fsfrflt [tempdata],rs,qword + UML_FSFRFLT(block, MEM(&ppc->impstate->tempdata.w.l), F64(G_RS(op)), SIZE_QWORD); // fsfrflt [tempdata],rs,qword UML_MOV(block, IREG(1), MEM(&ppc->impstate->tempdata.w.l)); // mov i1,[tempdata] UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32[ppc->impstate->mode]); // callh write32 + UML_CALLH(block, *ppc->impstate->write32[ppc->impstate->mode]); // callh write32 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3493,7 +3452,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_DMOV(block, IREG(1), MEM(&ppc->impstate->tempdata.d)); // dmov i1,[tempdata] UML_MOV(block, MEM(&ppc->impstate->updateaddr), IREG(0)); // mov [updateaddr],i0 UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode]); // callh write64 + UML_CALLH(block, *ppc->impstate->write64[ppc->impstate->mode]); // callh write64 UML_MOV(block, R32(G_RA(op)), MEM(&ppc->impstate->updateaddr)); // mov ra,[updateaddr] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3502,12 +3461,12 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, IREG(0), R32Z(G_RA(op)), R32(G_RB(op))); // add i0,ra,rb UML_MOV(block, IREG(1), R32(G_RS(op))); // mov i1,rs UML_MAPVAR(block, MAPVAR_DSISR, DSISR_IDX(op)); // mapvar dsisr,DSISR_IDX(op) - UML_CALLH(block, ppc->impstate->write32align[ppc->impstate->mode]); // callh write32align + UML_CALLH(block, *ppc->impstate->write32align[ppc->impstate->mode]); // callh write32align generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> UML_CMP(block, IREG(0), IREG(0)); // cmp i0,i0 - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_Z | DRCUML_FLAG_C | DRCUML_FLAG_S); // getflgs i0,zcs - UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), BYTE); // load i0,cmp_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_Z | FLAG_C | FLAG_S); // getflgs i0,zcs + UML_LOAD(block, IREG(0), ppc->impstate->cmp_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,cmp_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] generate_compute_flags(ppc, block, desc, TRUE, 0, FALSE); // <update flags> @@ -3516,7 +3475,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x2d5: /* STSWI */ UML_MOV(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op))); // mov [updateaddr],ra UML_MOV(block, MEM(&ppc->impstate->swcount), IMM(((G_NB(op) - 1) & 0x1f) + 1)); // mov [swcount],G_NB - UML_CALLH(block, ppc->impstate->stsw[ppc->impstate->mode][G_RD(op)]); // call stsw[rd] + UML_CALLH(block, *ppc->impstate->stsw[ppc->impstate->mode][G_RD(op)]); // call stsw[rd] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3524,7 +3483,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb UML_AND(block, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f)); // and [swcount],[xer],0x7f UML_SUB(block, MEM(&ppc->icount), MEM(&ppc->icount), MEM(&ppc->impstate->swcount));// sub icount,icount,[swcount] - UML_CALLHc(block, IF_NZ, ppc->impstate->stsw[ppc->impstate->mode][G_RD(op)]); // call stsw[rd] + UML_CALLHc(block, IF_NZ, *ppc->impstate->stsw[ppc->impstate->mode][G_RD(op)]); // call stsw[rd] generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3552,31 +3511,31 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp { UML_ADD(block, IREG(0), MEM(&ppc->impstate->tempaddr), IMM(8 * item)); // add i0,[tempaddr],8*item UML_DMOV(block, IREG(1), IMM(0)); // dmov i1,0 - UML_CALLH(block, ppc->impstate->write64[ppc->impstate->mode]); // callh write64 + UML_CALLH(block, *ppc->impstate->write64[ppc->impstate->mode]); // callh write64 } return TRUE; case 0x132: /* TLBIE */ UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op))); // mov [param0],rb - UML_CALLC(block, ppccom_execute_tlbie, ppc); // callc ppccom_execute_tlbie,ppc + UML_CALLC(block, (c_function)ppccom_execute_tlbie, ppc); // callc ppccom_execute_tlbie,ppc return TRUE; case 0x172: /* TLBIA */ - UML_CALLC(block, ppccom_execute_tlbia, ppc); // callc ppccom_execute_tlbia,ppc + UML_CALLC(block, (c_function)ppccom_execute_tlbia, ppc); // callc ppccom_execute_tlbia,ppc return TRUE; case 0x3d2: /* TLBLD */ assert(ppc->cap & PPCCAP_603_MMU); UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op))); // mov [param0],rb UML_MOV(block, MEM(&ppc->param1), IMM(0)); // mov [param1],0 - UML_CALLC(block, ppccom_execute_tlbl, ppc); // callc ppccom_execute_tlbl,ppc + UML_CALLC(block, (c_function)ppccom_execute_tlbl, ppc); // callc ppccom_execute_tlbl,ppc return TRUE; case 0x3f2: /* TLBLI */ assert(ppc->cap & PPCCAP_603_MMU); UML_MOV(block, MEM(&ppc->param0), R32(G_RB(op))); // mov [param0],rb UML_MOV(block, MEM(&ppc->param1), IMM(1)); // mov [param1],1 - UML_CALLC(block, ppccom_execute_tlbl, ppc); // callc ppccom_execute_tlbl,ppc + UML_CALLC(block, (c_function)ppccom_execute_tlbl, ppc); // callc ppccom_execute_tlbl,ppc return TRUE; case 0x013: /* MFCR */ @@ -3617,7 +3576,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp { generate_update_cycles(ppc, block, compiler, IMM(desc->pc), TRUE); // <update cycles> UML_MOV(block, MEM(&ppc->param0), IMM(spr)); // mov [param0],spr - UML_CALLC(block, ppccom_execute_mfspr, ppc); // callc ppccom_execute_mfspr,ppc + UML_CALLC(block, (c_function)ppccom_execute_mfspr, ppc); // callc ppccom_execute_mfspr,ppc UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1)); // mov rd,[param1] } return TRUE; @@ -3629,7 +3588,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x293: /* MFSRIN */ UML_SHR(block, IREG(0), R32(G_RB(op)), IMM(28)); // shr i0,G_RB,28 - UML_LOAD(block, R32(G_RD(op)), &ppc->sr[0], IREG(0), DWORD); // load rd,sr,i0,dword + UML_LOAD(block, R32(G_RD(op)), &ppc->sr[0], IREG(0), SIZE_DWORD, SCALE_x4); // load rd,sr,i0,dword return TRUE; case 0x173: /* MFTB */ @@ -3639,7 +3598,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp return FALSE; generate_update_cycles(ppc, block, compiler, IMM(desc->pc), TRUE); // <update cycles> UML_MOV(block, MEM(&ppc->param0), IMM(tbr)); // mov [param0],tbr - UML_CALLC(block, ppccom_execute_mftb, ppc); // callc ppccom_execute_mftb,ppc + UML_CALLC(block, (c_function)ppccom_execute_mftb, ppc); // callc ppccom_execute_mftb,ppc UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1)); // mov rd,[param1] return TRUE; } @@ -3663,7 +3622,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp if (ppc->cap & PPCCAP_603_MMU) { UML_TEST(block, IREG(0), IMM(MSR603_TGPR)); // test i0,tgpr - UML_CALLHc(block, IF_NZ, ppc->impstate->swap_tgpr); // callh swap_tgpr,nz + UML_CALLHc(block, IF_NZ, *ppc->impstate->swap_tgpr); // callh swap_tgpr,nz } generate_update_mode(ppc, block); // <update mode> return TRUE; @@ -3685,7 +3644,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp generate_update_cycles(ppc, block, compiler, IMM(desc->pc), TRUE); // <update cycles> UML_MOV(block, MEM(&ppc->param0), IMM(spr)); // mov [param0],spr UML_MOV(block, MEM(&ppc->param1), R32(G_RS(op))); // mov [param1],rs - UML_CALLC(block, ppccom_execute_mtspr, ppc); // callc ppccom_execute_mtspr,ppc + UML_CALLC(block, (c_function)ppccom_execute_mtspr, ppc); // callc ppccom_execute_mtspr,ppc compiler->checkints = TRUE; generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> } @@ -3694,13 +3653,13 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp case 0x0d2: /* MTSR */ UML_MOV(block, SR32(G_SR(op)), R32(G_RS(op))); // mov sr[G_SR],rs - UML_CALLC(block, ppccom_tlb_flush, ppc); // callc ppccom_tlb_flush,ppc + UML_CALLC(block, (c_function)ppccom_tlb_flush, ppc); // callc ppccom_tlb_flush,ppc return TRUE; case 0x0f2: /* MTSRIN */ UML_SHR(block, IREG(0), R32(G_RB(op)), IMM(28)); // shr i0,G_RB,28 - UML_STORE(block, &ppc->sr[0], IREG(0), R32(G_RS(op)), DWORD); // store sr,i0,rs,dword - UML_CALLC(block, ppccom_tlb_flush, ppc); // callc ppccom_tlb_flush,ppc + UML_STORE(block, &ppc->sr[0], IREG(0), R32(G_RS(op)), SIZE_DWORD, SCALE_x4); // store sr,i0,rs,dword + UML_CALLC(block, (c_function)ppccom_tlb_flush, ppc); // callc ppccom_tlb_flush,ppc return TRUE; case 0x200: /* MCRXR */ @@ -3730,7 +3689,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp assert(ppc->cap & PPCCAP_4XX); generate_update_cycles(ppc, block, compiler, IMM(desc->pc), TRUE); // <update cycles> UML_MOV(block, MEM(&ppc->param0), IMM(spr)); // mov [param0],spr - UML_CALLC(block, ppccom_execute_mfdcr, ppc); // callc ppccom_execute_mfdcr,ppc + UML_CALLC(block, (c_function)ppccom_execute_mfdcr, ppc); // callc ppccom_execute_mfdcr,ppc UML_MOV(block, R32(G_RD(op)), MEM(&ppc->param1)); // mov rd,[param1] return TRUE; } @@ -3742,7 +3701,7 @@ static int generate_instruction_1f(powerpc_state *ppc, drcuml_block *block, comp generate_update_cycles(ppc, block, compiler, IMM(desc->pc), TRUE); // <update cycles> UML_MOV(block, MEM(&ppc->param0), IMM(spr)); // mov [param0],spr UML_MOV(block, MEM(&ppc->param1), R32(G_RS(op))); // mov [param1],rs - UML_CALLC(block, ppccom_execute_mtdcr, ppc); // callc ppccom_execute_mtdcr,ppc + UML_CALLC(block, (c_function)ppccom_execute_mtdcr, ppc); // callc ppccom_execute_mtdcr,ppc compiler->checkints = TRUE; generate_update_cycles(ppc, block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles> return TRUE; @@ -3830,9 +3789,9 @@ static int generate_instruction_3b(powerpc_state *ppc, drcuml_block *block, comp return TRUE; case 0x18: /* FRESx */ - UML_FSFRFLT(block, FREG(0), F64(G_RB(op)), QWORD); // fsfrlt f0,rb,qword + UML_FSFRFLT(block, FREG(0), F64(G_RB(op)), SIZE_QWORD); // fsfrlt f0,rb,qword UML_FSRECIP(block, FREG(0), FREG(0)); // fsrecip f0,f0 - UML_FDFRFLT(block, F64(G_RD(op)), FREG(0), DWORD); // fdfrflt rd,f0,dword + UML_FDFRFLT(block, F64(G_RD(op)), FREG(0), SIZE_DWORD); // fdfrflt rd,f0,dword generate_fp_flags(ppc, block, desc, TRUE); return TRUE; @@ -3968,8 +3927,8 @@ static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, comp case 0x000: /* FCMPU */ case 0x020: /* FCMPO */ UML_FDCMP(block, F64(G_RA(op)), F64(G_RB(op))); // fdcmp ra,rb - UML_GETFLGS(block, IREG(0), DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U); // getflgs i0,czu - UML_LOAD(block, IREG(0), ppc->impstate->fcmp_cr_table, IREG(0), BYTE); // load i0,fcmp_cr_table,i0,byte + UML_GETFLGS(block, IREG(0), FLAG_C | FLAG_Z | FLAG_U); // getflgs i0,czu + UML_LOAD(block, IREG(0), ppc->impstate->fcmp_cr_table, IREG(0), SIZE_BYTE, SCALE_x1);// load i0,fcmp_cr_table,i0,byte UML_OR(block, CR32(G_CRFD(op)), IREG(0), XERSO32); // or [crn],i0,[xerso] return TRUE; @@ -3979,13 +3938,13 @@ static int generate_instruction_3f(powerpc_state *ppc, drcuml_block *block, comp return TRUE; case 0x00e: /* FCTIWx */ - UML_FDTOINT(block, IREG(0), F64(G_RB(op)), DWORD, DEFAULT); // fdtoint i0,rb,dword,default + UML_FDTOINT(block, IREG(0), F64(G_RB(op)), SIZE_DWORD, ROUND_DEFAULT); // fdtoint i0,rb,dword,default UML_DAND(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(0xffffffff));// dand i0,i0,0xffffffff UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l)); // fdmovr rd,i0 return TRUE; case 0x00f: /* FCTIWZx */ - UML_FDTOINT(block, IREG(0), F64(G_RB(op)), DWORD, TRUNC); // fdtoint i0,rb,dword,default + UML_FDTOINT(block, IREG(0), F64(G_RB(op)), SIZE_DWORD, ROUND_TRUNC); // fdtoint i0,rb,dword,default UML_DAND(block, MEM(&ppc->impstate->tempdata.w.l), IREG(0), IMM(0xffffffff));// dand i0,i0,0xffffffff UML_FDMOV(block, F64(G_RD(op)), MEM(&ppc->impstate->tempdata.w.l)); // fdmovr rd,i0 return TRUE; @@ -4059,7 +4018,7 @@ static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op) if (LOG_UML) { ppc_dasm_one(buffer, pc, op); - UML_COMMENT(block, "%08X: %s", pc, buffer); // comment + block->append_comment("%08X: %s", pc, buffer); // comment } } @@ -4135,22 +4094,22 @@ static void log_register_list(drcuml_state *drcuml, const char *string, const UI if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0 && reglist[3] == 0) return; - drcuml_log_printf(drcuml, "[%s:", string); + drcuml->log_printf("[%s:", string); for (regnum = 0; regnum < 32; regnum++) if (reglist[0] & REGFLAG_R(regnum)) { - drcuml_log_printf(drcuml, "%sr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[0] & REGFLAG_R(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } for (regnum = 0; regnum < 32; regnum++) if (reglist[1] & REGFLAG_FR(regnum)) { - drcuml_log_printf(drcuml, "%sfr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sfr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_FR(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } for (regnum = 0; regnum < 8; regnum++) @@ -4158,68 +4117,68 @@ static void log_register_list(drcuml_state *drcuml, const char *string, const UI { if ((reglist[2] & REGFLAG_CR(regnum)) == REGFLAG_CR(regnum) && (regnostarlist == NULL || (regnostarlist[2] & REGFLAG_CR(regnum)) == REGFLAG_CR(regnum))) { - drcuml_log_printf(drcuml, "%scr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%scr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[2] & REGFLAG_CR(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } else { for (crnum = 0; crnum < 4; crnum++) if (reglist[2] & REGFLAG_CR_BIT(regnum * 4 + crnum)) { - drcuml_log_printf(drcuml, "%scr%d[%s]", (count++ == 0) ? "" : ",", regnum, crtext[crnum]); + drcuml->log_printf("%scr%d[%s]", (count++ == 0) ? "" : ",", regnum, crtext[crnum]); if (regnostarlist != NULL && !(regnostarlist[2] & REGFLAG_CR_BIT(regnum * 4 + crnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } } } if (reglist[3] & REGFLAG_XER_CA) { - drcuml_log_printf(drcuml, "%sxer_ca", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sxer_ca", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_XER_CA)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[3] & REGFLAG_XER_OV) { - drcuml_log_printf(drcuml, "%sxer_ov", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sxer_ov", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_XER_OV)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[3] & REGFLAG_XER_SO) { - drcuml_log_printf(drcuml, "%sxer_so", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sxer_so", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_XER_SO)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[3] & REGFLAG_XER_COUNT) { - drcuml_log_printf(drcuml, "%sxer_count", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sxer_count", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_XER_COUNT)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[3] & REGFLAG_CTR) { - drcuml_log_printf(drcuml, "%sctr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sctr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_CTR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[3] & REGFLAG_LR) { - drcuml_log_printf(drcuml, "%slr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%slr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_LR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } for (regnum = 0; regnum < 8; regnum++) if (reglist[3] & REGFLAG_FPSCR(regnum)) { - drcuml_log_printf(drcuml, "%sfpscr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sfpscr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[3] & REGFLAG_FPSCR(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } - drcuml_log_printf(drcuml, "] "); + drcuml->log_printf("] "); } @@ -4231,7 +4190,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i { /* open the file, creating it if necessary */ if (indent == 0) - drcuml_log_printf(drcuml, "\nDescriptor list @ %08X\n", desclist->pc); + drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); /* output each descriptor */ for ( ; desclist != NULL; desclist = desclist->next()) @@ -4249,12 +4208,12 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i else strcpy(buffer, "???"); - drcuml_log_printf(drcuml, "%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); + drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); /* output register states */ log_register_list(drcuml, "use", desclist->regin, NULL); log_register_list(drcuml, "mod", desclist->regout, desclist->regreq); - drcuml_log_printf(drcuml, "\n"); + drcuml->log_printf("\n"); /* if we have a delay slot, output it recursively */ if (desclist->delay.first() != NULL) @@ -4262,7 +4221,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i /* at the end of a sequence add a dividing line */ if (desclist->flags & OPFLAG_END_SEQUENCE) - drcuml_log_printf(drcuml, "-----\n"); + drcuml->log_printf("-----\n"); } } diff --git a/src/emu/cpu/rsp/rspdrc.c b/src/emu/cpu/rsp/rspdrc.c index 821d0ca541e..0d0931441e1 100644 --- a/src/emu/cpu/rsp/rspdrc.c +++ b/src/emu/cpu/rsp/rspdrc.c @@ -28,6 +28,8 @@ #include "cpu/drcuml.h" #include "cpu/drcumlsh.h" +using namespace uml; + CPU_DISASSEMBLE( rsp ); extern offs_t rsp_dasm_one(char *buffer, offs_t pc, UINT32 op); @@ -74,7 +76,7 @@ extern offs_t rsp_dasm_one(char *buffer, offs_t pc, UINT32 op); MACROS ***************************************************************************/ -#define R32(reg) rsp->impstate->regmap[reg].type, rsp->impstate->regmap[reg].value +#define R32(reg) rsp->impstate->regmap[reg] /*************************************************************************** STRUCTURES & TYPEDEFS @@ -98,7 +100,7 @@ struct _compiler_state UINT32 cycles; /* accumulated cycles */ UINT8 checkints; /* need to check interrupts before next instruction */ UINT8 checksoftints; /* need to check software interrupts before next instruction */ - drcuml_codelabel labelnum; /* index for local labels */ + code_label labelnum; /* index for local labels */ }; struct _rspimp_state @@ -123,18 +125,18 @@ struct _rspimp_state UINT32 vres[8]; /* used for temporary vector results */ /* register mappings */ - drcuml_parameter regmap[32]; /* parameter to register mappings for all 32 integer registers */ + parameter regmap[32]; /* parameter to register mappings for all 32 integer registers */ /* subroutines */ - drcuml_codehandle * entry; /* entry point */ - drcuml_codehandle * nocode; /* nocode exception handler */ - drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */ - drcuml_codehandle * read8; /* read byte */ - drcuml_codehandle * write8; /* write byte */ - drcuml_codehandle * read16; /* read half */ - drcuml_codehandle * write16; /* write half */ - drcuml_codehandle * read32; /* read word */ - drcuml_codehandle * write32; /* write word */ + code_handle * entry; /* entry point */ + code_handle * nocode; /* nocode exception handler */ + code_handle * out_of_cycles; /* out of cycles exception handler */ + code_handle * read8; /* read byte */ + code_handle * write8; /* write byte */ + code_handle * read16; /* read half */ + code_handle * write16; /* write half */ + code_handle * read32; /* read word */ + code_handle * write32; /* write word */ }; /*************************************************************************** @@ -184,11 +186,11 @@ static void cfunc_rsp_stv(void *param); static void static_generate_entry_point(rsp_state *rsp); static void static_generate_nocode_handler(rsp_state *rsp); static void static_generate_out_of_cycles(rsp_state *rsp); -static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, drcuml_codehandle **handleptr); +static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, code_handle *&handleptr); static int generate_lwc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); static int generate_swc2(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); -static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception); +static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception); static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); static void generate_sequence_instruction(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); static void generate_delay_slot_and_branch(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg); @@ -261,10 +263,10 @@ INLINE UINT32 epc(const opcode_desc *desc) already allocated -------------------------------------------------*/ -INLINE void alloc_handle(drcuml_state *drcuml, drcuml_codehandle **handleptr, const char *name) +INLINE void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) { if (*handleptr == NULL) - *handleptr = drcuml_handle_alloc(drcuml, name); + *handleptr = drcuml->handle_alloc(name); } @@ -278,8 +280,8 @@ INLINE void load_fast_iregs(rsp_state *rsp, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(rsp->impstate->regmap); regnum++) - if (rsp->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_MOV(block, IREG(rsp->impstate->regmap[regnum].value - DRCUML_REG_I0), MEM(&rsp->r[regnum])); + if (rsp->impstate->regmap[regnum].is_int_register()) + UML_MOV(block, IREG(rsp->impstate->regmap[regnum].ireg() - REG_I0), MEM(&rsp->r[regnum])); } @@ -293,8 +295,8 @@ INLINE void save_fast_iregs(rsp_state *rsp, drcuml_block *block) int regnum; for (regnum = 0; regnum < ARRAY_LENGTH(rsp->impstate->regmap); regnum++) - if (rsp->impstate->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) - UML_MOV(block, MEM(&rsp->r[regnum]), IREG(rsp->impstate->regmap[regnum].value - DRCUML_REG_I0)); + if (rsp->impstate->regmap[regnum].is_int_register()) + UML_MOV(block, MEM(&rsp->r[regnum]), IREG(rsp->impstate->regmap[regnum].ireg() - REG_I0)); } /*************************************************************************** @@ -636,64 +638,52 @@ static CPU_INIT( rsp ) { flags |= DRCUML_OPTION_LOG_NATIVE; } - rsp->impstate->drcuml = drcuml_alloc(device, cache, flags, 8, 32, 2); - if (rsp->impstate->drcuml == NULL) - { - fatalerror("Error initializing the UML"); - } + rsp->impstate->drcuml = auto_alloc(device->machine, drcuml_state(*device, *cache, flags, 8, 32, 2)); /* add symbols for our stuff */ - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->pc, sizeof(rsp->pc), "pc"); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->icount, sizeof(rsp->icount), "icount"); + rsp->impstate->drcuml->symbol_add(&rsp->pc, sizeof(rsp->pc), "pc"); + rsp->impstate->drcuml->symbol_add(&rsp->icount, sizeof(rsp->icount), "icount"); for (regnum = 0; regnum < 32; regnum++) { char buf[10]; sprintf(buf, "r%d", regnum); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->r[regnum], sizeof(rsp->r[regnum]), buf); + rsp->impstate->drcuml->symbol_add(&rsp->r[regnum], sizeof(rsp->r[regnum]), buf); } - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg0, sizeof(rsp->impstate->arg0), "arg0"); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg1, sizeof(rsp->impstate->arg1), "arg1"); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg2, sizeof(rsp->impstate->arg2), "arg2"); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->arg3, sizeof(rsp->impstate->arg3), "arg3"); - drcuml_symbol_add(rsp->impstate->drcuml, &rsp->impstate->numcycles, sizeof(rsp->impstate->numcycles), "numcycles"); + rsp->impstate->drcuml->symbol_add(&rsp->impstate->arg0, sizeof(rsp->impstate->arg0), "arg0"); + rsp->impstate->drcuml->symbol_add(&rsp->impstate->arg1, sizeof(rsp->impstate->arg1), "arg1"); + rsp->impstate->drcuml->symbol_add(&rsp->impstate->arg2, sizeof(rsp->impstate->arg2), "arg2"); + rsp->impstate->drcuml->symbol_add(&rsp->impstate->arg3, sizeof(rsp->impstate->arg3), "arg3"); + rsp->impstate->drcuml->symbol_add(&rsp->impstate->numcycles, sizeof(rsp->impstate->numcycles), "numcycles"); /* initialize the front-end helper */ rsp->impstate->drcfe = auto_alloc(device->machine, rsp_frontend(*rsp, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE)); /* compute the register parameters */ for (regnum = 0; regnum < 32; regnum++) - { - rsp->impstate->regmap[regnum].type = (regnum == 0) ? DRCUML_PTYPE_IMMEDIATE : DRCUML_PTYPE_MEMORY; - rsp->impstate->regmap[regnum].value = (regnum == 0) ? 0 : (FPTR)&rsp->r[regnum]; - } + rsp->impstate->regmap[regnum] = (regnum == 0) ? parameter(0) : parameter::make_memory(&rsp->r[regnum]); /* drcbe_info beinfo; - drcuml_get_backend_info(rsp->impstate->drcuml, &beinfo); + rsp->impstate->drcuml->get_backend_info(beinfo); if (beinfo.direct_iregs > 2) { - rsp->impstate->regmap[30].type = DRCUML_PTYPE_INT_REGISTER; - rsp->impstate->regmap[30].value = DRCUML_REG_I2; + rsp->impstate->regmap[30] = IREG(2); } if (beinfo.direct_iregs > 3) { - rsp->impstate->regmap[31].type = DRCUML_PTYPE_INT_REGISTER; - rsp->impstate->regmap[31].value = DRCUML_REG_I3; + rsp->impstate->regmap[31] = IREG(3); } if (beinfo.direct_iregs > 4) { - rsp->impstate->regmap[2].type = DRCUML_PTYPE_INT_REGISTER; - rsp->impstate->regmap[2].value = DRCUML_REG_I4; + rsp->impstate->regmap[2] = IREG(4); } if (beinfo.direct_iregs > 5) { - rsp->impstate->regmap[3].type = DRCUML_PTYPE_INT_REGISTER; - rsp->impstate->regmap[3].value = DRCUML_REG_I5; + rsp->impstate->regmap[3] = IREG(5); } if (beinfo.direct_iregs > 6) { - rsp->impstate->regmap[4].type = DRCUML_PTYPE_INT_REGISTER; - rsp->impstate->regmap[4].value = DRCUML_REG_I6; + rsp->impstate->regmap[4] = IREG(6); } */ @@ -707,7 +697,7 @@ static CPU_EXIT( rsp ) /* clean up the DRC */ auto_free(device->machine, rsp->impstate->drcfe); - drcuml_free(rsp->impstate->drcuml); + auto_free(device->machine, rsp->impstate->drcuml); auto_free(device->machine, rsp->impstate->cache); } @@ -3388,7 +3378,7 @@ static CPU_EXECUTE( rsp ) } /* run as much as we can */ - execute_result = drcuml_execute(drcuml, rsp->impstate->entry); + execute_result = drcuml->execute(*rsp->impstate->entry); /* if we need to recompile, do it */ if (execute_result == EXECUTE_MISSING_CODE) @@ -3429,20 +3419,27 @@ void rspdrc_flush_drc_cache(device_t *device) static void code_flush_cache(rsp_state *rsp) { /* empty the transient cache contents */ - drcuml_reset(rsp->impstate->drcuml); - - /* generate the entry point and out-of-cycles handlers */ - static_generate_entry_point(rsp); - static_generate_nocode_handler(rsp); - static_generate_out_of_cycles(rsp); - - /* add subroutines for memory accesses */ - static_generate_memory_accessor(rsp, 1, FALSE, "read8", &rsp->impstate->read8); - static_generate_memory_accessor(rsp, 1, TRUE, "write8", &rsp->impstate->write8); - static_generate_memory_accessor(rsp, 2, FALSE, "read16", &rsp->impstate->read16); - static_generate_memory_accessor(rsp, 2, TRUE, "write16", &rsp->impstate->write16); - static_generate_memory_accessor(rsp, 4, FALSE, "read32", &rsp->impstate->read32); - static_generate_memory_accessor(rsp, 4, TRUE, "write32", &rsp->impstate->write32); + rsp->impstate->drcuml->reset(); + + try + { + /* generate the entry point and out-of-cycles handlers */ + static_generate_entry_point(rsp); + static_generate_nocode_handler(rsp); + static_generate_out_of_cycles(rsp); + + /* add subroutines for memory accesses */ + static_generate_memory_accessor(rsp, 1, FALSE, "read8", rsp->impstate->read8); + static_generate_memory_accessor(rsp, 1, TRUE, "write8", rsp->impstate->write8); + static_generate_memory_accessor(rsp, 2, FALSE, "read16", rsp->impstate->read16); + static_generate_memory_accessor(rsp, 2, TRUE, "write16", rsp->impstate->write16); + static_generate_memory_accessor(rsp, 4, FALSE, "read32", rsp->impstate->read32); + static_generate_memory_accessor(rsp, 4, TRUE, "write32", rsp->impstate->write32); + } + catch (drcuml_block::abort_compilation &) + { + fatalerror("Unable to generate static RSP code"); + } } @@ -3459,90 +3456,95 @@ static void code_compile_block(rsp_state *rsp, offs_t pc) const opcode_desc *desclist; int override = FALSE; drcuml_block *block; - jmp_buf errorbuf; g_profiler.start(PROFILER_DRC_COMPILE); /* get a description of this sequence */ desclist = rsp->impstate->drcfe->describe_code(pc); - /* if we get an error back, flush the cache and try again */ - if (setjmp(errorbuf) != 0) + bool succeeded = false; + while (!succeeded) { - code_flush_cache(rsp); - } - - /* start the block */ - block = drcuml_block_begin(drcuml, 8192, &errorbuf); - - /* loop until we get through all instruction sequences */ - for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) - { - const opcode_desc *curdesc; - UINT32 nextpc; - - /* add a code log entry */ - if (LOG_UML) - UML_COMMENT(block, "-------------------------"); // comment - - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != NULL); + try + { + /* start the block */ + block = drcuml->begin_block(8192); - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml_hash_exists(drcuml, 0, seqhead->pc)) - UML_HASH(block, 0, seqhead->pc); // hash mode,pc + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + UINT32 nextpc; + + /* add a code log entry */ + if (LOG_UML) + block->append_comment("-------------------------"); // comment + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != NULL); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(0, seqhead->pc)) + UML_HASH(block, 0, seqhead->pc); // hash mode,pc + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = TRUE; + UML_HASH(block, 0, seqhead->pc); // hash mode,pc + } - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) - { - override = TRUE; - UML_HASH(block, 0, seqhead->pc); // hash mode,pc - } + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc + UML_HASHJMP(block, IMM(0), IMM(seqhead->pc), *rsp->impstate->nocode); + // hashjmp <0>,seqhead->pc,nocode + continue; + } - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc - UML_HASHJMP(block, IMM(0), IMM(seqhead->pc), rsp->impstate->nocode); - // hashjmp <0>,seqhead->pc,nocode - continue; - } + /* validate this code block if we're not pointing into ROM */ + if (rsp->program->get_write_ptr(seqhead->physpc) != NULL) + generate_checksum_block(rsp, block, &compiler, seqhead, seqlast); - /* validate this code block if we're not pointing into ROM */ - if (rsp->program->get_write_ptr(seqhead->physpc) != NULL) - generate_checksum_block(rsp, block, &compiler, seqhead, seqlast); + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + generate_sequence_instruction(rsp, block, &compiler, curdesc); - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - generate_sequence_instruction(rsp, block, &compiler, curdesc); + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + nextpc = pc; - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - nextpc = pc; + /* otherwise we just go to the next instruction */ + else + nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; - /* otherwise we just go to the next instruction */ - else - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 4; + /* count off cycles and go there */ + generate_update_cycles(rsp, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> - /* count off cycles and go there */ - generate_update_cycles(rsp, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> + /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ + if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) + UML_HASHJMP(block, IMM(0), IMM(nextpc), *rsp->impstate->nocode); // hashjmp <mode>,nextpc,nocode + } - /* if the last instruction can change modes, use a variable mode; otherwise, assume the same mode */ - if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) - UML_HASHJMP(block, IMM(0), IMM(nextpc), rsp->impstate->nocode); // hashjmp <mode>,nextpc,nocode + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; + } + catch (drcuml_block::abort_compilation &) + { + code_flush_cache(rsp); + } } - - /* end the sequence */ - drcuml_block_end(block); - g_profiler.stop(); } /*************************************************************************** @@ -3587,28 +3589,23 @@ static void static_generate_entry_point(rsp_state *rsp) { drcuml_state *drcuml = rsp->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_entry_point"); /* begin generating */ - block = drcuml_block_begin(drcuml, 20, &errorbuf); + block = drcuml->begin_block(20); /* forward references */ alloc_handle(drcuml, &rsp->impstate->nocode, "nocode"); alloc_handle(drcuml, &rsp->impstate->entry, "entry"); - UML_HANDLE(block, rsp->impstate->entry); // handle entry + UML_HANDLE(block, *rsp->impstate->entry); // handle entry /* load fast integer registers */ load_fast_iregs(rsp, block); /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, IMM(0), MEM(&rsp->pc), rsp->impstate->nocode); + UML_HASHJMP(block, IMM(0), MEM(&rsp->pc), *rsp->impstate->nocode); // hashjmp <mode>,<pc>,nocode - drcuml_block_end(block); + block->end(); } @@ -3621,26 +3618,19 @@ static void static_generate_nocode_handler(rsp_state *rsp) { drcuml_state *drcuml = rsp->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - { - fatalerror("Unrecoverable error in static_generate_nocode_handler"); - } /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &rsp->impstate->nocode, "nocode"); - UML_HANDLE(block, rsp->impstate->nocode); // handle nocode + UML_HANDLE(block, *rsp->impstate->nocode); // handle nocode UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&rsp->pc), IREG(0)); // mov [pc],i0 save_fast_iregs(rsp, block); UML_EXIT(block, IMM(EXECUTE_MISSING_CODE)); // exit EXECUTE_MISSING_CODE - drcuml_block_end(block); + block->end(); } @@ -3653,52 +3643,38 @@ static void static_generate_out_of_cycles(rsp_state *rsp) { drcuml_state *drcuml = rsp->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - { - fatalerror("Unrecoverable error in static_generate_out_of_cycles"); - } /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &rsp->impstate->out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, rsp->impstate->out_of_cycles); // handle out_of_cycles + UML_HANDLE(block, *rsp->impstate->out_of_cycles); // handle out_of_cycles UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&rsp->pc), IREG(0)); // mov <pc>,i0 save_fast_iregs(rsp, block); UML_EXIT(block, IMM(EXECUTE_OUT_OF_CYCLES)); // exit EXECUTE_OUT_OF_CYCLES - drcuml_block_end(block); + block->end(); } /*------------------------------------------------------------------ static_generate_memory_accessor ------------------------------------------------------------------*/ -static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, drcuml_codehandle **handleptr) +static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrite, const char *name, code_handle *&handleptr) { /* on entry, address is in I0; data for writes is in I1 */ /* on exit, read result is in I0 */ /* routine trashes I0-I1 */ drcuml_state *drcuml = rsp->impstate->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - { - fatalerror("Unrecoverable error in static_generate_exception"); - } /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ - alloc_handle(drcuml, handleptr, name); + alloc_handle(drcuml, &handleptr, name); UML_HANDLE(block, *handleptr); // handle *handleptr // write: @@ -3746,7 +3722,7 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit } UML_RET(block); - drcuml_block_end(block); + block->end(); } @@ -3760,14 +3736,14 @@ static void static_generate_memory_accessor(rsp_state *rsp, int size, int iswrit subtract cycles from the icount and generate an exception if out -------------------------------------------------*/ -static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception) +static void generate_update_cycles(rsp_state *rsp, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception) { /* account for cycles */ if (compiler->cycles > 0) { UML_SUB(block, MEM(&rsp->icount), MEM(&rsp->icount), MAPVAR_CYCLES); // sub icount,icount,cycles UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 - UML_EXHc(block, IF_S, rsp->impstate->out_of_cycles, PARAM(ptype, pvalue)); + UML_EXHc(block, IF_S, *rsp->impstate->out_of_cycles, param); } compiler->cycles = 0; } @@ -3782,7 +3758,7 @@ static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compile const opcode_desc *curdesc; if (LOG_UML) { - UML_COMMENT(block, "[Validation for %08X]", seqhead->pc | 0x1000); // comment + block->append_comment("[Validation for %08X]", seqhead->pc | 0x1000); // comment } /* loose verify or single instruction: just compare and fail */ if (!(rsp->impstate->drcoptions & RSPDRC_STRICT_VERIFY) || seqhead->next() == NULL) @@ -3790,9 +3766,9 @@ static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compile if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = rsp->direct->read_decrypted_ptr(seqhead->physpc | 0x1000); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,0,dword UML_CMP(block, IREG(0), IMM(seqhead->opptr.l[0])); // cmp i0,opptr[0] - UML_EXHc(block, IF_NE, rsp->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *rsp->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } } @@ -3801,18 +3777,18 @@ static void generate_checksum_block(rsp_state *rsp, drcuml_block *block, compile { UINT32 sum = 0; void *base = rsp->direct->read_decrypted_ptr(seqhead->physpc | 0x1000); - UML_LOAD(block, IREG(0), base, IMM(0), DWORD); // load i0,base,0,dword + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i0,base,0,dword sum += seqhead->opptr.l[0]; for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { base = rsp->direct->read_decrypted_ptr(curdesc->physpc | 0x1000); - UML_LOAD(block, IREG(1), base, IMM(0), DWORD); // load i1,base,dword + UML_LOAD(block, IREG(1), base, IMM(0), SIZE_DWORD, SCALE_x4); // load i1,base,dword UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1 sum += curdesc->opptr.l[0]; } UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum - UML_EXHc(block, IF_NE, rsp->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *rsp->impstate->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } } @@ -3907,7 +3883,7 @@ static void generate_delay_slot_and_branch(rsp_state *rsp, drcuml_block *block, } else { - UML_HASHJMP(block, IMM(0), IMM(desc->targetpc), rsp->impstate->nocode); + UML_HASHJMP(block, IMM(0), IMM(desc->targetpc), *rsp->impstate->nocode); // hashjmp <mode>,desc->targetpc,nocode } } @@ -3915,7 +3891,7 @@ static void generate_delay_slot_and_branch(rsp_state *rsp, drcuml_block *block, { generate_update_cycles(rsp, block, &compiler_temp, MEM(&rsp->impstate->jmpdest), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&rsp->impstate->jmpdest), rsp->impstate->nocode); + UML_HASHJMP(block, IMM(0), MEM(&rsp->impstate->jmpdest), *rsp->impstate->nocode); // hashjmp <mode>,<rsreg>,nocode } @@ -4146,7 +4122,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); UINT32 op = desc->opptr.l[0]; UINT8 opswitch = op >> 26; - drcuml_codelabel skip; + code_label skip; switch (opswitch) { @@ -4253,25 +4229,25 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x20: /* LB - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, rsp->impstate->read8); // callh read8 + UML_CALLH(block, *rsp->impstate->read8); // callh read8 if (RTREG != 0) - UML_SEXT(block, R32(RTREG), IREG(0), BYTE); // dsext <rtreg>,i0,byte + UML_SEXT(block, R32(RTREG), IREG(0), SIZE_BYTE); // dsext <rtreg>,i0,byte if (!in_delay_slot) generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; case 0x21: /* LH - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, rsp->impstate->read16); // callh read16 + UML_CALLH(block, *rsp->impstate->read16); // callh read16 if (RTREG != 0) - UML_SEXT(block, R32(RTREG), IREG(0), WORD); // dsext <rtreg>,i0,word + UML_SEXT(block, R32(RTREG), IREG(0), SIZE_WORD); // dsext <rtreg>,i0,word if (!in_delay_slot) generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; case 0x23: /* LW - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, rsp->impstate->read32); // callh read32 + UML_CALLH(block, *rsp->impstate->read32); // callh read32 if (RTREG != 0) UML_MOV(block, R32(RTREG), IREG(0)); if (!in_delay_slot) @@ -4280,7 +4256,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x24: /* LBU - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, rsp->impstate->read8); // callh read8 + UML_CALLH(block, *rsp->impstate->read8); // callh read8 if (RTREG != 0) UML_AND(block, R32(RTREG), IREG(0), IMM(0xff)); // dand <rtreg>,i0,0xff if (!in_delay_slot) @@ -4289,7 +4265,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x25: /* LHU - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL - UML_CALLH(block, rsp->impstate->read16); // callh read16 + UML_CALLH(block, *rsp->impstate->read16); // callh read16 if (RTREG != 0) UML_AND(block, R32(RTREG), IREG(0), IMM(0xffff)); // dand <rtreg>,i0,0xffff if (!in_delay_slot) @@ -4305,7 +4281,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x28: /* SB - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, rsp->impstate->write8); // callh write8 + UML_CALLH(block, *rsp->impstate->write8); // callh write8 if (!in_delay_slot) generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -4313,7 +4289,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x29: /* SH - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, rsp->impstate->write16); // callh write16 + UML_CALLH(block, *rsp->impstate->write16); // callh write16 if (!in_delay_slot) generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -4321,7 +4297,7 @@ static int generate_opcode(rsp_state *rsp, drcuml_block *block, compiler_state * case 0x2b: /* SW - MIPS I */ UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL UML_MOV(block, IREG(1), R32(RTREG)); // mov i1,<rtreg> - UML_CALLH(block, rsp->impstate->write32); // callh write32 + UML_CALLH(block, *rsp->impstate->write32); // callh write32 if (!in_delay_slot) generate_update_cycles(rsp, block, compiler, IMM(desc->pc + 4), TRUE); return TRUE; @@ -4361,7 +4337,7 @@ static int generate_special(rsp_state *rsp, drcuml_block *block, compiler_state { UINT32 op = desc->opptr.l[0]; UINT8 opswitch = op & 63; - //drcuml_codelabel skip; + //code_label skip; switch (opswitch) { @@ -4513,7 +4489,7 @@ static int generate_regimm(rsp_state *rsp, drcuml_block *block, compiler_state * { UINT32 op = desc->opptr.l[0]; UINT8 opswitch = RTREG; - drcuml_codelabel skip; + code_label skip; switch (opswitch) { @@ -4683,7 +4659,7 @@ static void log_add_disasm_comment(rsp_state *rsp, drcuml_block *block, UINT32 p #if (LOG_UML) char buffer[100]; rsp_dasm_one(buffer, pc, op); - UML_COMMENT(block, "%08X: %s", pc, buffer); // comment + block->append_comment("%08X: %s", pc, buffer); // comment #endif } diff --git a/src/emu/cpu/sh2/sh2comn.h b/src/emu/cpu/sh2/sh2comn.h index 3bd1915f7f5..3ea30d359f2 100644 --- a/src/emu/cpu/sh2/sh2comn.h +++ b/src/emu/cpu/sh2/sh2comn.h @@ -169,19 +169,19 @@ typedef struct UINT32 irq; /* irq we're taking */ /* register mappings */ - drcuml_parameter regmap[16]; /* parameter to register mappings for all 16 integer registers */ - - drcuml_codehandle * entry; /* entry point */ - drcuml_codehandle * read8; /* read byte */ - drcuml_codehandle * write8; /* write byte */ - drcuml_codehandle * read16; /* read half */ - drcuml_codehandle * write16; /* write half */ - drcuml_codehandle * read32; /* read word */ - drcuml_codehandle * write32; /* write word */ - - drcuml_codehandle * interrupt; /* interrupt */ - drcuml_codehandle * nocode; /* nocode */ - drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */ + uml::parameter regmap[16]; /* parameter to register mappings for all 16 integer registers */ + + uml::code_handle * entry; /* entry point */ + uml::code_handle * read8; /* read byte */ + uml::code_handle * write8; /* write byte */ + uml::code_handle * read16; /* read half */ + uml::code_handle * write16; /* write half */ + uml::code_handle * read32; /* read word */ + uml::code_handle * write32; /* write word */ + + uml::code_handle * interrupt; /* interrupt */ + uml::code_handle * nocode; /* nocode */ + uml::code_handle * out_of_cycles; /* out of cycles exception handler */ #endif } sh2_state; diff --git a/src/emu/cpu/sh2/sh2drc.c b/src/emu/cpu/sh2/sh2drc.c index bc7abd87851..2c057ca83be 100644 --- a/src/emu/cpu/sh2/sh2drc.c +++ b/src/emu/cpu/sh2/sh2drc.c @@ -26,6 +26,8 @@ extern unsigned DasmSH2(char *buffer, unsigned pc, UINT16 opcode); #ifdef USE_SH2DRC +using namespace uml; + /*************************************************************************** DEBUGGING ***************************************************************************/ @@ -81,7 +83,7 @@ extern int sh2_describe(void *param, opcode_desc *desc, const opcode_desc *prev) MACROS ***************************************************************************/ -#define R32(reg) sh2->regmap[reg].type, sh2->regmap[reg].value +#define R32(reg) sh2->regmap[reg] /*************************************************************************** STRUCTURES & TYPEDEFS @@ -93,7 +95,7 @@ struct _compiler_state { UINT32 cycles; /* accumulated cycles */ UINT8 checkints; /* need to check interrupts before next instruction */ - drcuml_codelabel labelnum; /* index for local labels */ + code_label labelnum; /* index for local labels */ }; /*************************************************************************** @@ -103,9 +105,9 @@ struct _compiler_state static void static_generate_entry_point(sh2_state *sh2); static void static_generate_nocode_handler(sh2_state *sh2); static void static_generate_out_of_cycles(sh2_state *sh2); -static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrite, const char *name, drcuml_codehandle **handleptr); +static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrite, const char *name, code_handle **handleptr); -static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception); +static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception); static void generate_checksum_block(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast); static void generate_sequence_instruction(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 ovrpc); static void generate_delay_slot(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 ovrpc); @@ -183,10 +185,10 @@ INLINE UINT32 epc(const opcode_desc *desc) already allocated -------------------------------------------------*/ -INLINE void alloc_handle(drcuml_state *drcuml, drcuml_codehandle **handleptr, const char *name) +INLINE void alloc_handle(drcuml_state *drcuml, code_handle **handleptr, const char *name) { if (*handleptr == NULL) - *handleptr = drcuml_handle_alloc(drcuml, name); + *handleptr = drcuml->handle_alloc(name); } /*------------------------------------------------- @@ -200,9 +202,9 @@ INLINE void load_fast_iregs(sh2_state *sh2, drcuml_block *block) for (regnum = 0; regnum < ARRAY_LENGTH(sh2->regmap); regnum++) { - if (sh2->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) + if (sh2->regmap[regnum].is_int_register()) { - UML_MOV(block, IREG(sh2->regmap[regnum].value - DRCUML_REG_I0), MEM(&sh2->r[regnum])); + UML_MOV(block, parameter::make_ireg(sh2->regmap[regnum].ireg()), MEM(&sh2->r[regnum])); } } } @@ -219,9 +221,9 @@ INLINE void save_fast_iregs(sh2_state *sh2, drcuml_block *block) for (regnum = 0; regnum < ARRAY_LENGTH(sh2->regmap); regnum++) { - if (sh2->regmap[regnum].type == DRCUML_PTYPE_INT_REGISTER) + if (sh2->regmap[regnum].is_int_register()) { - UML_MOV(block, MEM(&sh2->r[regnum]), IREG(sh2->regmap[regnum].value - DRCUML_REG_I0)); + UML_MOV(block, MEM(&sh2->r[regnum]), parameter::make_ireg(sh2->regmap[regnum].ireg())); } } } @@ -703,25 +705,23 @@ static CPU_INIT( sh2 ) flags |= DRCUML_OPTION_LOG_UML; if (LOG_NATIVE) flags |= DRCUML_OPTION_LOG_NATIVE; - sh2->drcuml = drcuml_alloc(device, cache, flags, 1, 32, 1); - if (sh2->drcuml == NULL) - fatalerror("Error initializing the UML"); + sh2->drcuml = auto_alloc(device->machine, drcuml_state(*device, *cache, flags, 1, 32, 1)); /* add symbols for our stuff */ - drcuml_symbol_add(sh2->drcuml, &sh2->pc, sizeof(sh2->pc), "pc"); - drcuml_symbol_add(sh2->drcuml, &sh2->icount, sizeof(sh2->icount), "icount"); + sh2->drcuml->symbol_add(&sh2->pc, sizeof(sh2->pc), "pc"); + sh2->drcuml->symbol_add(&sh2->icount, sizeof(sh2->icount), "icount"); for (regnum = 0; regnum < 16; regnum++) { char buf[10]; sprintf(buf, "r%d", regnum); - drcuml_symbol_add(sh2->drcuml, &sh2->r[regnum], sizeof(sh2->r[regnum]), buf); + sh2->drcuml->symbol_add(&sh2->r[regnum], sizeof(sh2->r[regnum]), buf); } - drcuml_symbol_add(sh2->drcuml, &sh2->pr, sizeof(sh2->pr), "pr"); - drcuml_symbol_add(sh2->drcuml, &sh2->sr, sizeof(sh2->sr), "sr"); - drcuml_symbol_add(sh2->drcuml, &sh2->gbr, sizeof(sh2->gbr), "gbr"); - drcuml_symbol_add(sh2->drcuml, &sh2->vbr, sizeof(sh2->vbr), "vbr"); - drcuml_symbol_add(sh2->drcuml, &sh2->macl, sizeof(sh2->macl), "macl"); - drcuml_symbol_add(sh2->drcuml, &sh2->mach, sizeof(sh2->macl), "mach"); + sh2->drcuml->symbol_add(&sh2->pr, sizeof(sh2->pr), "pr"); + sh2->drcuml->symbol_add(&sh2->sr, sizeof(sh2->sr), "sr"); + sh2->drcuml->symbol_add(&sh2->gbr, sizeof(sh2->gbr), "gbr"); + sh2->drcuml->symbol_add(&sh2->vbr, sizeof(sh2->vbr), "vbr"); + sh2->drcuml->symbol_add(&sh2->macl, sizeof(sh2->macl), "macl"); + sh2->drcuml->symbol_add(&sh2->mach, sizeof(sh2->macl), "mach"); /* initialize the front-end helper */ sh2->drcfe = auto_alloc(device->machine, sh2_frontend(*sh2, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE)); @@ -729,29 +729,25 @@ static CPU_INIT( sh2 ) /* compute the register parameters */ for (regnum = 0; regnum < 16; regnum++) { - sh2->regmap[regnum].type = DRCUML_PTYPE_MEMORY; - sh2->regmap[regnum].value = (FPTR)&sh2->r[regnum]; + sh2->regmap[regnum] = MEM(&sh2->r[regnum]); } /* if we have registers to spare, assign r0, r1, r2 to leftovers */ /* WARNING: do not use synthetic registers that are mapped here! */ if (!DISABLE_FAST_REGISTERS) { - drcuml_get_backend_info(sh2->drcuml, &beinfo); + sh2->drcuml->get_backend_info(beinfo); if (beinfo.direct_iregs > 4) { - sh2->regmap[0].type = DRCUML_PTYPE_INT_REGISTER; - sh2->regmap[0].value = DRCUML_REG_I4; + sh2->regmap[0] = IREG(4); } if (beinfo.direct_iregs > 5) { - sh2->regmap[1].type = DRCUML_PTYPE_INT_REGISTER; - sh2->regmap[1].value = DRCUML_REG_I5; + sh2->regmap[1] = IREG(5); } if (beinfo.direct_iregs > 6) { - sh2->regmap[2].type = DRCUML_PTYPE_INT_REGISTER; - sh2->regmap[2].value = DRCUML_REG_I6; + sh2->regmap[2] = IREG(6); } } @@ -769,7 +765,7 @@ static CPU_EXIT( sh2 ) /* clean up the DRC */ auto_free(device->machine, sh2->drcfe); - drcuml_free(sh2->drcuml); + auto_free(device->machine, sh2->drcuml); auto_free(device->machine, sh2->cache); } @@ -849,20 +845,27 @@ static void code_flush_cache(sh2_state *sh2) drcuml_state *drcuml = sh2->drcuml; /* empty the transient cache contents */ - drcuml_reset(drcuml); - - /* generate the entry point and out-of-cycles handlers */ - static_generate_nocode_handler(sh2); - static_generate_out_of_cycles(sh2); - static_generate_entry_point(sh2); + drcuml->reset(); - /* add subroutines for memory accesses */ - static_generate_memory_accessor(sh2, 1, FALSE, "read8", &sh2->read8); - static_generate_memory_accessor(sh2, 1, TRUE, "write8", &sh2->write8); - static_generate_memory_accessor(sh2, 2, FALSE, "read16", &sh2->read16); - static_generate_memory_accessor(sh2, 2, TRUE, "write16", &sh2->write16); - static_generate_memory_accessor(sh2, 4, FALSE, "read32", &sh2->read32); - static_generate_memory_accessor(sh2, 4, TRUE, "write32", &sh2->write32); + try + { + /* generate the entry point and out-of-cycles handlers */ + static_generate_nocode_handler(sh2); + static_generate_out_of_cycles(sh2); + static_generate_entry_point(sh2); + + /* add subroutines for memory accesses */ + static_generate_memory_accessor(sh2, 1, FALSE, "read8", &sh2->read8); + static_generate_memory_accessor(sh2, 1, TRUE, "write8", &sh2->write8); + static_generate_memory_accessor(sh2, 2, FALSE, "read16", &sh2->read16); + static_generate_memory_accessor(sh2, 2, TRUE, "write16", &sh2->write16); + static_generate_memory_accessor(sh2, 4, FALSE, "read32", &sh2->read32); + static_generate_memory_accessor(sh2, 4, TRUE, "write32", &sh2->write32); + } + catch (drcuml_block::abort_compilation &) + { + fatalerror("Unable to generate SH2 static code"); + } sh2->cache_dirty = FALSE; } @@ -894,7 +897,7 @@ static CPU_EXECUTE( sh2 ) do { /* run as much as we can */ - execute_result = drcuml_execute(drcuml, sh2->entry); + execute_result = drcuml->execute(*sh2->entry); /* if we need to recompile, do it */ if (execute_result == EXECUTE_MISSING_CODE) @@ -925,7 +928,6 @@ static void code_compile_block(sh2_state *sh2, UINT8 mode, offs_t pc) const opcode_desc *desclist; int override = FALSE; drcuml_block *block; - jmp_buf errorbuf; g_profiler.start(PROFILER_DRC_COMPILE); @@ -934,91 +936,99 @@ static void code_compile_block(sh2_state *sh2, UINT8 mode, offs_t pc) if (LOG_UML || LOG_NATIVE) log_opcode_desc(drcuml, desclist, 0); - /* if we get an error back, flush the cache and try again */ - if (setjmp(errorbuf) != 0) - code_flush_cache(sh2); - - /* start the block */ - block = drcuml_block_begin(drcuml, 4096, &errorbuf); - - /* loop until we get through all instruction sequences */ - for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + bool succeeded = false; + while (!succeeded) { - const opcode_desc *curdesc; - UINT32 nextpc; + try + { + /* start the block */ + block = drcuml->begin_block(4096); - /* add a code log entry */ - if (LOG_UML) - UML_COMMENT(block, "-------------------------"); // comment + /* loop until we get through all instruction sequences */ + for (seqhead = desclist; seqhead != NULL; seqhead = seqlast->next()) + { + const opcode_desc *curdesc; + UINT32 nextpc; + + /* add a code log entry */ + if (LOG_UML) + block->append_comment("-------------------------"); // comment + + /* determine the last instruction in this sequence */ + for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) + if (seqlast->flags & OPFLAG_END_SEQUENCE) + break; + assert(seqlast != NULL); + + /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ + if (override || !drcuml->hash_exists(mode, seqhead->pc)) + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + + /* if we already have a hash, and this is the first sequence, assume that we */ + /* are recompiling due to being out of sync and allow future overrides */ + else if (seqhead == desclist) + { + override = TRUE; + UML_HASH(block, mode, seqhead->pc); // hash mode,pc + } - /* determine the last instruction in this sequence */ - for (seqlast = seqhead; seqlast != NULL; seqlast = seqlast->next()) - if (seqlast->flags & OPFLAG_END_SEQUENCE) - break; - assert(seqlast != NULL); + /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ + else + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + UML_HASHJMP(block, IMM(0), IMM(seqhead->pc), *sh2->nocode); + // hashjmp <mode>,seqhead->pc,nocode + continue; + } - /* if we don't have a hash for this mode/pc, or if we are overriding all, add one */ - if (override || !drcuml_hash_exists(drcuml, mode, seqhead->pc)) - UML_HASH(block, mode, seqhead->pc); // hash mode,pc + /* validate this code block if we're not pointing into ROM */ + if (sh2->program->get_write_ptr(seqhead->physpc) != NULL) + generate_checksum_block(sh2, block, &compiler, seqhead, seqlast); - /* if we already have a hash, and this is the first sequence, assume that we */ - /* are recompiling due to being out of sync and allow future overrides */ - else if (seqhead == desclist) - { - override = TRUE; - UML_HASH(block, mode, seqhead->pc); // hash mode,pc - } + /* label this instruction, if it may be jumped to locally */ + if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) + { + UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 + } - /* otherwise, redispatch to that fixed PC and skip the rest of the processing */ - else - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - UML_HASHJMP(block, IMM(0), IMM(seqhead->pc), sh2->nocode); - // hashjmp <mode>,seqhead->pc,nocode - continue; - } + /* iterate over instructions in the sequence and compile them */ + for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) + { + generate_sequence_instruction(sh2, block, &compiler, curdesc, 0xffffffff); + } - /* validate this code block if we're not pointing into ROM */ - if (sh2->program->get_write_ptr(seqhead->physpc) != NULL) - generate_checksum_block(sh2, block, &compiler, seqhead, seqlast); + /* if we need to return to the start, do it */ + if (seqlast->flags & OPFLAG_RETURN_TO_START) + { + nextpc = pc; + } + /* otherwise we just go to the next instruction */ + else + { + nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2; + } - /* label this instruction, if it may be jumped to locally */ - if (seqhead->flags & OPFLAG_IS_BRANCH_TARGET) - { - UML_LABEL(block, seqhead->pc | 0x80000000); // label seqhead->pc | 0x80000000 - } + /* count off cycles and go there */ + generate_update_cycles(sh2, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> - /* iterate over instructions in the sequence and compile them */ - for (curdesc = seqhead; curdesc != seqlast->next(); curdesc = curdesc->next()) - { - generate_sequence_instruction(sh2, block, &compiler, curdesc, 0xffffffff); - } + /* SH2 has no modes */ + if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) + { + UML_HASHJMP(block, IMM(0), IMM(nextpc), *sh2->nocode); + } + // hashjmp <mode>,nextpc,nocode + } - /* if we need to return to the start, do it */ - if (seqlast->flags & OPFLAG_RETURN_TO_START) - { - nextpc = pc; - } - /* otherwise we just go to the next instruction */ - else - { - nextpc = seqlast->pc + (seqlast->skipslots + 1) * 2; + /* end the sequence */ + block->end(); + g_profiler.stop(); + succeeded = true; } - - /* count off cycles and go there */ - generate_update_cycles(sh2, block, &compiler, IMM(nextpc), TRUE); // <subtract cycles> - - /* SH2 has no modes */ - if (seqlast->next() == NULL || seqlast->next()->pc != nextpc) + catch (drcuml_block::abort_compilation &) { - UML_HASHJMP(block, IMM(0), IMM(nextpc), sh2->nocode); + code_flush_cache(sh2); } - // hashjmp <mode>,nextpc,nocode } - - /* end the sequence */ - drcuml_block_end(block); - g_profiler.stop(); } /*------------------------------------------------- @@ -1029,22 +1039,17 @@ static void code_compile_block(sh2_state *sh2, UINT8 mode, offs_t pc) static void static_generate_entry_point(sh2_state *sh2) { drcuml_state *drcuml = sh2->drcuml; - drcuml_codelabel skip = 1; + code_label skip = 1; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_entry_point"); /* begin generating */ - block = drcuml_block_begin(drcuml, 200, &errorbuf); + block = drcuml->begin_block(200); /* forward references */ alloc_handle(drcuml, &sh2->nocode, "nocode"); alloc_handle(drcuml, &sh2->write32, "write32"); // necessary? alloc_handle(drcuml, &sh2->entry, "entry"); - UML_HANDLE(block, sh2->entry); // handle entry + UML_HANDLE(block, *sh2->entry); // handle entry /* load fast integer registers */ load_fast_iregs(sh2, block); @@ -1089,21 +1094,21 @@ static void static_generate_entry_point(sh2_state *sh2) UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), MEM(&sh2->irqsr)); // mov r1, irqsr - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), MEM(&sh2->pc)); // mov r1, pc - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 UML_MOV(block, MEM(&sh2->pc), MEM(&sh2->evec)); // mov pc, evec UML_LABEL(block, skip); // skip: /* generate a hash jump via the current mode and PC */ - UML_HASHJMP(block, IMM(0), MEM(&sh2->pc), sh2->nocode); // hashjmp <mode>,<pc>,nocode + UML_HASHJMP(block, IMM(0), MEM(&sh2->pc), *sh2->nocode); // hashjmp <mode>,<pc>,nocode - drcuml_block_end(block); + block->end(); } /*------------------------------------------------- @@ -1115,24 +1120,19 @@ static void static_generate_nocode_handler(sh2_state *sh2) { drcuml_state *drcuml = sh2->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_nocode_handler"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &sh2->nocode, "nocode"); - UML_HANDLE(block, sh2->nocode); // handle nocode + UML_HANDLE(block, *sh2->nocode); // handle nocode UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&sh2->pc), IREG(0)); // mov [pc],i0 save_fast_iregs(sh2, block); UML_EXIT(block, IMM(EXECUTE_MISSING_CODE)); // exit EXECUTE_MISSING_CODE - drcuml_block_end(block); + block->end(); } @@ -1145,50 +1145,40 @@ static void static_generate_out_of_cycles(sh2_state *sh2) { drcuml_state *drcuml = sh2->drcuml; drcuml_block *block; - jmp_buf errorbuf; - - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_out_of_cycles"); /* begin generating */ - block = drcuml_block_begin(drcuml, 10, &errorbuf); + block = drcuml->begin_block(10); /* generate a hash jump via the current mode and PC */ alloc_handle(drcuml, &sh2->out_of_cycles, "out_of_cycles"); - UML_HANDLE(block, sh2->out_of_cycles); // handle out_of_cycles + UML_HANDLE(block, *sh2->out_of_cycles); // handle out_of_cycles UML_GETEXP(block, IREG(0)); // getexp i0 UML_MOV(block, MEM(&sh2->pc), IREG(0)); // mov <pc>,i0 save_fast_iregs(sh2,block); UML_EXIT(block, IMM(EXECUTE_OUT_OF_CYCLES)); // exit EXECUTE_OUT_OF_CYCLES - drcuml_block_end(block); + block->end(); } /*------------------------------------------------------------------ static_generate_memory_accessor ------------------------------------------------------------------*/ -static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrite, const char *name, drcuml_codehandle **handleptr) +static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrite, const char *name, code_handle **handleptr) { /* on entry, address is in I0; data for writes is in I1 */ /* on exit, read result is in I0 */ /* routine trashes I0 */ drcuml_state *drcuml = sh2->drcuml; drcuml_block *block; - jmp_buf errorbuf; int label = 1; - /* if we get an error back, we're screwed */ - if (setjmp(errorbuf) != 0) - fatalerror("Unrecoverable error in static_generate_memory_accessor"); - /* begin generating */ - block = drcuml_block_begin(drcuml, 1024, &errorbuf); + block = drcuml->begin_block(1024); /* add a global entry for this */ alloc_handle(drcuml, handleptr, name); - UML_HANDLE(block, *handleptr); // handle *handleptr + UML_HANDLE(block, **handleptr); // handle *handleptr // with internal handlers this becomes easier. // if addr < 0x40000000 AND it with AM and do the read/write, else just do the read/write @@ -1207,15 +1197,15 @@ static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrit switch (size) { case 1: - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_BYTE); // write r0, r1, program_byte + UML_WRITE(block, IREG(0), IREG(1), SIZE_BYTE, SPACE_PROGRAM); // write r0, r1, program_byte break; case 2: - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_WORD); // write r0, r1, program_word + UML_WRITE(block, IREG(0), IREG(1), SIZE_WORD, SPACE_PROGRAM); // write r0, r1, program_word break; case 4: - UML_WRITE(block, IREG(0), IREG(1), PROGRAM_DWORD); // write r0, r1, program_dword + UML_WRITE(block, IREG(0), IREG(1), SIZE_DWORD, SPACE_PROGRAM); // write r0, r1, program_dword break; } } @@ -1224,22 +1214,22 @@ static void static_generate_memory_accessor(sh2_state *sh2, int size, int iswrit switch (size) { case 1: - UML_READ(block, IREG(0), IREG(0), PROGRAM_BYTE); // read r0, program_byte + UML_READ(block, IREG(0), IREG(0), SIZE_BYTE, SPACE_PROGRAM); // read r0, program_byte break; case 2: - UML_READ(block, IREG(0), IREG(0), PROGRAM_WORD); // read r0, program_word + UML_READ(block, IREG(0), IREG(0), SIZE_WORD, SPACE_PROGRAM); // read r0, program_word break; case 4: - UML_READ(block, IREG(0), IREG(0), PROGRAM_DWORD); // read r0, program_dword + UML_READ(block, IREG(0), IREG(0), SIZE_DWORD, SPACE_PROGRAM); // read r0, program_dword break; } } UML_RET(block); // ret - drcuml_block_end(block); + block->end(); } /*------------------------------------------------- @@ -1311,61 +1301,61 @@ static void log_register_list(drcuml_state *drcuml, const char *string, const UI if (reglist[0] == 0 && reglist[1] == 0 && reglist[2] == 0) return; - drcuml_log_printf(drcuml, "[%s:", string); + drcuml->log_printf("[%s:", string); for (regnum = 0; regnum < 16; regnum++) { if (reglist[0] & REGFLAG_R(regnum)) { - drcuml_log_printf(drcuml, "%sr%d", (count++ == 0) ? "" : ",", regnum); + drcuml->log_printf("%sr%d", (count++ == 0) ? "" : ",", regnum); if (regnostarlist != NULL && !(regnostarlist[0] & REGFLAG_R(regnum))) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } } if (reglist[1] & REGFLAG_PR) { - drcuml_log_printf(drcuml, "%spr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%spr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_PR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[1] & REGFLAG_SR) { - drcuml_log_printf(drcuml, "%ssr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%ssr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_SR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[1] & REGFLAG_MACL) { - drcuml_log_printf(drcuml, "%smacl", (count++ == 0) ? "" : ","); + drcuml->log_printf("%smacl", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_MACL)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[1] & REGFLAG_MACH) { - drcuml_log_printf(drcuml, "%smach", (count++ == 0) ? "" : ","); + drcuml->log_printf("%smach", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_MACH)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[1] & REGFLAG_GBR) { - drcuml_log_printf(drcuml, "%sgbr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%sgbr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_GBR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } if (reglist[1] & REGFLAG_VBR) { - drcuml_log_printf(drcuml, "%svbr", (count++ == 0) ? "" : ","); + drcuml->log_printf("%svbr", (count++ == 0) ? "" : ","); if (regnostarlist != NULL && !(regnostarlist[1] & REGFLAG_VBR)) - drcuml_log_printf(drcuml, "*"); + drcuml->log_printf("*"); } - drcuml_log_printf(drcuml, "] "); + drcuml->log_printf("] "); } /*------------------------------------------------- @@ -1376,7 +1366,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i { /* open the file, creating it if necessary */ if (indent == 0) - drcuml_log_printf(drcuml, "\nDescriptor list @ %08X\n", desclist->pc); + drcuml->log_printf("\nDescriptor list @ %08X\n", desclist->pc); /* output each descriptor */ for ( ; desclist != NULL; desclist = desclist->next()) @@ -1392,12 +1382,12 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i #else strcpy(buffer, "???"); #endif - drcuml_log_printf(drcuml, "%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); + drcuml->log_printf("%08X [%08X] t:%08X f:%s: %-30s", desclist->pc, desclist->physpc, desclist->targetpc, log_desc_flags_to_string(desclist->flags), buffer); /* output register states */ log_register_list(drcuml, "use", desclist->regin, NULL); log_register_list(drcuml, "mod", desclist->regout, desclist->regreq); - drcuml_log_printf(drcuml, "\n"); + drcuml->log_printf("\n"); /* if we have a delay slot, output it recursively */ if (desclist->delay.first() != NULL) @@ -1405,7 +1395,7 @@ static void log_opcode_desc(drcuml_state *drcuml, const opcode_desc *desclist, i /* at the end of a sequence add a dividing line */ if (desclist->flags & OPFLAG_END_SEQUENCE) - drcuml_log_printf(drcuml, "-----\n"); + drcuml->log_printf("-----\n"); } } @@ -1419,7 +1409,7 @@ static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op) #if (LOG_UML) char buffer[100]; DasmSH2(buffer, pc, op); - UML_COMMENT(block, "%08X: %s", pc, buffer); // comment + block->append_comment("%08X: %s", pc, buffer); // comment #endif } @@ -1428,12 +1418,12 @@ static void log_add_disasm_comment(drcuml_block *block, UINT32 pc, UINT32 op) subtract cycles from the icount and generate an exception if out -------------------------------------------------*/ -static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, drcuml_ptype ptype, UINT64 pvalue, int allow_exception) +static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception) { /* check full interrupts if pending */ if (compiler->checkints) { - drcuml_codelabel skip = compiler->labelnum++; + code_label skip = compiler->labelnum++; compiler->checkints = FALSE; compiler->labelnum += 4; @@ -1477,14 +1467,14 @@ static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), MEM(&sh2->irqsr)); // mov r1, irqsr - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 - UML_MOV(block, IREG(1), PARAM(ptype, pvalue)); // mov r1, nextpc - UML_CALLH(block, sh2->write32); // call write32 + UML_MOV(block, IREG(1), param); // mov r1, nextpc + UML_CALLH(block, *sh2->write32); // call write32 - UML_HASHJMP(block, IMM(0), MEM(&sh2->evec), sh2->nocode); // hashjmp sh2->evec + UML_HASHJMP(block, IMM(0), MEM(&sh2->evec), *sh2->nocode); // hashjmp sh2->evec UML_LABEL(block, skip); // skip: } @@ -1495,7 +1485,7 @@ static void generate_update_cycles(sh2_state *sh2, drcuml_block *block, compiler UML_SUB(block, MEM(&sh2->icount), MEM(&sh2->icount), MAPVAR_CYCLES); // sub icount,icount,cycles UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 if (allow_exception) - UML_EXHc(block, IF_S, sh2->out_of_cycles, PARAM(ptype, pvalue)); + UML_EXHc(block, IF_S, *sh2->out_of_cycles, param); // exh out_of_cycles,nextpc } compiler->cycles = 0; @@ -1510,7 +1500,7 @@ static void generate_checksum_block(sh2_state *sh2, drcuml_block *block, compile { const opcode_desc *curdesc; if (LOG_UML) - UML_COMMENT(block, "[Validation for %08X]", seqhead->pc); // comment + block->append_comment("[Validation for %08X]", seqhead->pc); // comment /* loose verify or single instruction: just compare and fail */ if (!(sh2->drcoptions & SH2DRC_STRICT_VERIFY) || seqhead->next() == NULL) @@ -1518,9 +1508,9 @@ static void generate_checksum_block(sh2_state *sh2, drcuml_block *block, compile if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP)) { void *base = sh2->direct->read_decrypted_ptr(seqhead->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, IREG(0), base, IMM(0), WORD); // load i0,base,word + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_WORD, SCALE_x2); // load i0,base,word UML_CMP(block, IREG(0), IMM(seqhead->opptr.w[0])); // cmp i0,*opptr - UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } } @@ -1532,25 +1522,25 @@ static void generate_checksum_block(sh2_state *sh2, drcuml_block *block, compile if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { base = sh2->direct->read_decrypted_ptr(curdesc->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, IREG(0), curdesc->opptr.w, IMM(0), WORD); // load i0,*opptr,0,word + UML_LOAD(block, IREG(0), curdesc->opptr.w, IMM(0), SIZE_WORD, SCALE_x2); // load i0,*opptr,0,word UML_CMP(block, IREG(0), IMM(curdesc->opptr.w[0])); // cmp i0,*opptr - UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc } #else UINT32 sum = 0; void *base = sh2->direct->read_decrypted_ptr(seqhead->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, IREG(0), base, IMM(0), WORD); // load i0,base,word + UML_LOAD(block, IREG(0), base, IMM(0), SIZE_WORD, SCALE_x4); // load i0,base,word sum += seqhead->opptr.w[0]; for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next()) if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP)) { base = sh2->direct->read_decrypted_ptr(curdesc->physpc, SH2_CODE_XOR(0)); - UML_LOAD(block, IREG(1), base, IMM(0), WORD); // load i1,*opptr,word + UML_LOAD(block, IREG(1), base, IMM(0), SIZE_WORD, SCALE_x2); // load i1,*opptr,word UML_ADD(block, IREG(0), IREG(0), IREG(1)); // add i0,i0,i1 sum += curdesc->opptr.w[0]; } UML_CMP(block, IREG(0), IMM(sum)); // cmp i0,sum - UML_EXHc(block, IF_NE, sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc + UML_EXHc(block, IF_NE, *sh2->nocode, IMM(epc(seqhead))); // exne nocode,seqhead->pc #endif } } @@ -1680,7 +1670,7 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * UML_ADD(block, IREG(0), R32(Rn), IMM(scratch)); // add r0, Rn, scratch UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm SETEA(0); // set ea for debug - UML_CALLH(block, sh2->write32); + UML_CALLH(block, *sh2->write32); if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1697,7 +1687,7 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * scratch = (opcode & 0x0f) * 4; UML_ADD(block, IREG(0), R32(Rm), IMM(scratch)); // add r0, Rm, scratch SETEA(0); // set ea for debug - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0 if (!in_delay_slot) @@ -1730,8 +1720,8 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * { UML_MOV(block, IREG(0), IMM(scratch)); // mov r0, scratch SETEA(0); // set ea for debug - UML_CALLH(block, sh2->read16); // read16(r0, r1) - UML_SEXT(block, R32(Rn), IREG(0), WORD); // sext Rn, r0, WORD + UML_CALLH(block, *sh2->read16); // read16(r0, r1) + UML_SEXT(block, R32(Rn), IREG(0), SIZE_WORD); // sext Rn, r0, WORD } else { @@ -1750,7 +1740,7 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * generate_delay_slot(sh2, block, compiler, desc, sh2->ea-2); generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // hashjmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // hashjmp sh2->ea return TRUE; case 11: // BSR @@ -1764,7 +1754,7 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * generate_delay_slot(sh2, block, compiler, desc, sh2->ea-2); generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // hashjmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // hashjmp sh2->ea return TRUE; case 12: @@ -1783,7 +1773,7 @@ static int generate_opcode(sh2_state *sh2, drcuml_block *block, compiler_state * if (sh2->drcoptions & SH2DRC_STRICT_PCREL) { UML_MOV(block, IREG(0), IMM(scratch)); // mov r0, scratch - UML_CALLH(block, sh2->read32); // read32(r0, r1) + UML_CALLH(block, *sh2->read32); // read32(r0, r1) UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0 } else @@ -1848,7 +1838,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->target); generate_update_cycles(sh2, block, compiler, MEM(&sh2->target), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->target), sh2->nocode); // jmp target + UML_HASHJMP(block, IMM(0), MEM(&sh2->target), *sh2->nocode); // jmp target return TRUE; } break; @@ -1859,7 +1849,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x34: // MOVBS0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rn)); // add r0, R0, Rn UML_AND(block, IREG(1), R32(Rm), IMM(0x000000ff)); // and r1, Rm, 0xff - UML_CALLH(block, sh2->write8); // call write8 + UML_CALLH(block, *sh2->write8); // call write8 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1871,7 +1861,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x35: // MOVWS0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rn)); // add r0, R0, Rn UML_AND(block, IREG(1), R32(Rm), IMM(0x0000ffff)); // and r1, Rm, 0xffff - UML_CALLH(block, sh2->write16); // call write16 + UML_CALLH(block, *sh2->write16); // call write16 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1883,7 +1873,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x36: // MOVLS0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rn)); // add r0, R0, Rn UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1914,7 +1904,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->target); generate_update_cycles(sh2, block, compiler, MEM(&sh2->target), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->target), sh2->nocode); + UML_HASHJMP(block, IMM(0), MEM(&sh2->target), *sh2->nocode); return TRUE; case 0x0c: // MOVBL0(Rm, Rn); @@ -1922,8 +1912,8 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x2c: // MOVBL0(Rm, Rn); case 0x3c: // MOVBL0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, sh2->read8); // call read8 - UML_SEXT(block, R32(Rn), IREG(0), BYTE); // sext Rn, r0, BYTE + UML_CALLH(block, *sh2->read8); // call read8 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_BYTE); // sext Rn, r0, BYTE if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1934,8 +1924,8 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x2d: // MOVWL0(Rm, Rn); case 0x3d: // MOVWL0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, sh2->read16); // call read16 - UML_SEXT(block, R32(Rn), IREG(0), WORD); // sext Rn, r0, WORD + UML_CALLH(block, *sh2->read16); // call read16 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_WORD); // sext Rn, r0, WORD if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -1946,7 +1936,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state case 0x2e: // MOVLL0(Rm, Rn); case 0x3e: // MOVLL0(Rm, Rn); UML_ADD(block, IREG(0), R32(0), R32(Rm)); // add r0, R0, Rm - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0 if (!in_delay_slot) @@ -1995,14 +1985,14 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), MEM(&sh2->irqsr)); // mov r1, irqsr - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), IMM(desc->pc+2)); // mov r1, nextpc - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 - UML_HASHJMP(block, IMM(0), MEM(&sh2->evec), sh2->nocode); // hashjmp sh2->evec + UML_HASHJMP(block, IMM(0), MEM(&sh2->evec), *sh2->nocode); // hashjmp sh2->evec UML_LABEL(block, compiler->labelnum++); // skip: @@ -2011,11 +2001,11 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state { UML_MOV(block, MEM(&sh2->icount), IMM(0)); // mov icount, #0 UML_MAPVAR(block, MAPVAR_CYCLES, 0); // mapvar cycles,0 - UML_EXH(block, sh2->out_of_cycles, IMM(desc->pc)); // go out of cycles + UML_EXH(block, *sh2->out_of_cycles, IMM(desc->pc)); // go out of cycles } else { - UML_HASHJMP(block, IMM(0), IMM(desc->pc), sh2->nocode); + UML_HASHJMP(block, IMM(0), IMM(desc->pc), *sh2->nocode); } return TRUE; @@ -2032,7 +2022,7 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->target); generate_update_cycles(sh2, block, compiler, MEM(&sh2->target), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->target), sh2->nocode); // jmp target + UML_HASHJMP(block, IMM(0), MEM(&sh2->target), *sh2->nocode); // jmp target return TRUE; } break; @@ -2054,19 +2044,19 @@ static int generate_group_0(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, 0xffffffff); UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, MEM(&sh2->pc), IREG(0)); // mov pc, r0 UML_ADD(block, R32(15), R32(15), IMM(4)); // add R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, MEM(&sh2->sr), IREG(0)); // mov sr, r0 UML_ADD(block, R32(15), R32(15), IMM(4)); // add R15, R15, #4 compiler->checkints = TRUE; UML_MOV(block, MEM(&sh2->ea), MEM(&sh2->pc)); // mov ea, pc generate_update_cycles(sh2, block, compiler, MEM(&sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->pc), sh2->nocode); // and jump to the "resume PC" + UML_HASHJMP(block, IMM(0), MEM(&sh2->pc), *sh2->nocode); // and jump to the "resume PC" return TRUE; } @@ -2081,7 +2071,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state case 0: // MOVBS(Rm, Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_AND(block, IREG(1), R32(Rm), IMM(0xff)); // and r1, Rm, 0xff - UML_CALLH(block, sh2->write8); + UML_CALLH(block, *sh2->write8); if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2090,7 +2080,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state case 1: // MOVWS(Rm, Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_AND(block, IREG(1), R32(Rm), IMM(0xffff)); // and r1, Rm, 0xffff - UML_CALLH(block, sh2->write16); + UML_CALLH(block, *sh2->write16); if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2099,7 +2089,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state case 2: // MOVLS(Rm, Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm - UML_CALLH(block, sh2->write32); + UML_CALLH(block, *sh2->write32); if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2112,7 +2102,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm UML_SUB(block, R32(Rn), R32(Rn), IMM(1)); // sub Rn, Rn, 1 UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn - UML_CALLH(block, sh2->write8); // call write8 + UML_CALLH(block, *sh2->write8); // call write8 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2122,7 +2112,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm UML_SUB(block, R32(Rn), R32(Rn), IMM(2)); // sub Rn, Rn, 2 UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn - UML_CALLH(block, sh2->write16); // call write16 + UML_CALLH(block, *sh2->write16); // call write16 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2132,7 +2122,7 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(1), R32(Rm)); // mov r1, Rm UML_SUB(block, R32(Rn), R32(Rn), IMM(4)); // sub Rn, Rn, 4 UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2234,8 +2224,8 @@ static int generate_group_2(sh2_state *sh2, drcuml_block *block, compiler_state return TRUE; case 15: // MULS(Rm, Rn); - UML_SEXT(block, IREG(0), R32(Rm), WORD); // sext r0, Rm - UML_SEXT(block, IREG(1), R32(Rn), WORD); // sext r1, Rn + UML_SEXT(block, IREG(0), R32(Rm), SIZE_WORD); // sext r0, Rm + UML_SEXT(block, IREG(1), R32(Rn), SIZE_WORD); // sext r1, Rn UML_MULS(block, MEM(&sh2->macl), MEM(&sh2->ea), IREG(0), IREG(1)); // muls macl, ea, r0, r1 return TRUE; } @@ -2388,7 +2378,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_MOV(block, IREG(1), MEM(&sh2->mach)); // mov r1, mach SETEA(0); // set ea for debug - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2399,7 +2389,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_MOV(block, IREG(1), MEM(&sh2->sr)); // mov r1, sr SETEA(0); // set ea for debug - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2408,7 +2398,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x06: // LDSMMACH(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, #4 UML_MOV(block, MEM(&sh2->mach), IREG(0)); // mov mach, r0 @@ -2419,7 +2409,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x07: // LDCMSR(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, #4 UML_MOV(block, MEM(&sh2->sr), IREG(0)); // mov sr, r0 @@ -2465,7 +2455,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->target-4); generate_update_cycles(sh2, block, compiler, MEM(&sh2->target), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->target), sh2->nocode); // and do the jump + UML_HASHJMP(block, IMM(0), MEM(&sh2->target), *sh2->nocode); // and do the jump return TRUE; case 0x0e: // LDCSR(Rn); @@ -2532,7 +2522,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_MOV(block, IREG(1), MEM(&sh2->macl)); // mov r1, macl SETEA(0); // set ea for debug - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2543,7 +2533,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn UML_MOV(block, IREG(1), MEM(&sh2->gbr)); // mov r1, gbr SETEA(0); // set ea for debug - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2552,7 +2542,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x16: // LDSMMACL(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, #4 UML_MOV(block, MEM(&sh2->macl), IREG(0)); // mov macl, r0 @@ -2563,7 +2553,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x17: // LDCMGBR(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, #4 UML_MOV(block, MEM(&sh2->gbr), IREG(0)); // mov gbr, r0 @@ -2578,7 +2568,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x1b: // TAS(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read8); // call read8 + UML_CALLH(block, *sh2->read8); // call read8 UML_AND(block, MEM(&sh2->sr), MEM(&sh2->sr), IMM(~T)); // and sr, sr, ~T @@ -2592,7 +2582,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_OR(block, IREG(1), IREG(0), IMM(0x80)); // or r1, r0, #0x80 UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn - UML_CALLH(block, sh2->write8); // write the value back + UML_CALLH(block, *sh2->write8); // write the value back if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2622,7 +2612,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); UML_MOV(block, IREG(1), MEM(&sh2->pr)); // mov r1, pr - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2633,7 +2623,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); UML_MOV(block, IREG(1), MEM(&sh2->vbr)); // mov r1, vbr - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2656,7 +2646,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x26: // LDSMPR(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, MEM(&sh2->pr), IREG(0)); // mov sh2->pr, r0 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, Rn, #4 @@ -2667,7 +2657,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state case 0x27: // LDCMVBR(Rn); UML_MOV(block, IREG(0), R32(Rn)); // mov r0, Rn SETEA(0); - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, MEM(&sh2->vbr), IREG(0)); // mov sh2->vbr, r0 UML_ADD(block, R32(Rn), R32(Rn), IMM(4)); // add Rn, Rn, #4 @@ -2685,7 +2675,7 @@ static int generate_group_4(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->target); generate_update_cycles(sh2, block, compiler, MEM(&sh2->target), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), MEM(&sh2->target), sh2->nocode); // jmp (target) + UML_HASHJMP(block, IMM(0), MEM(&sh2->target), *sh2->nocode); // jmp (target) return TRUE; case 0x2e: // LDCVBR(Rn); @@ -2727,8 +2717,8 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state case 0: // MOVBL(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm SETEA(0); // debug: ea = r0 - UML_CALLH(block, sh2->read8); // call read8 - UML_SEXT(block, R32(Rn), IREG(0), BYTE); // sext Rn, r0, BYTE + UML_CALLH(block, *sh2->read8); // call read8 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_BYTE); // sext Rn, r0, BYTE if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2737,8 +2727,8 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state case 1: // MOVWL(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm SETEA(0); // debug: ea = r0 - UML_CALLH(block, sh2->read16); // call read16 - UML_SEXT(block, R32(Rn), IREG(0), WORD); // sext Rn, r0, WORD + UML_CALLH(block, *sh2->read16); // call read16 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_WORD); // sext Rn, r0, WORD if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2747,7 +2737,7 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state case 2: // MOVLL(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm SETEA(0); // debug: ea = r0 - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0 if (!in_delay_slot) @@ -2779,17 +2769,17 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state return TRUE; case 14: // EXTSB(Rm, Rn); - UML_SEXT(block, R32(Rn), R32(Rm), BYTE); // sext Rn, Rm, BYTE + UML_SEXT(block, R32(Rn), R32(Rm), SIZE_BYTE); // sext Rn, Rm, BYTE return TRUE; case 15: // EXTSW(Rm, Rn); - UML_SEXT(block, R32(Rn), R32(Rm), WORD); // sext Rn, Rm, WORD + UML_SEXT(block, R32(Rn), R32(Rm), SIZE_WORD); // sext Rn, Rm, WORD return TRUE; case 4: // MOVBP(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm - UML_CALLH(block, sh2->read8); // call read8 - UML_SEXT(block, R32(Rn), IREG(0), BYTE); // sext Rn, r0, BYTE + UML_CALLH(block, *sh2->read8); // call read8 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_BYTE); // sext Rn, r0, BYTE if (Rm != Rn) UML_ADD(block, R32(Rm), R32(Rm), IMM(1)); // add Rm, Rm, #1 @@ -2800,8 +2790,8 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state case 5: // MOVWP(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm - UML_CALLH(block, sh2->read16); // call read16 - UML_SEXT(block, R32(Rn), IREG(0), WORD); // sext Rn, r0, WORD + UML_CALLH(block, *sh2->read16); // call read16 + UML_SEXT(block, R32(Rn), IREG(0), SIZE_WORD); // sext Rn, r0, WORD if (Rm != Rn) UML_ADD(block, R32(Rm), R32(Rm), IMM(2)); // add Rm, Rm, #2 @@ -2812,7 +2802,7 @@ static int generate_group_6(sh2_state *sh2, drcuml_block *block, compiler_state case 6: // MOVLP(Rm, Rn); UML_MOV(block, IREG(0), R32(Rm)); // mov r0, Rm - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, R32(Rn), IREG(0)); // mov Rn, r0 if (Rm != Rn) @@ -2854,7 +2844,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state { INT32 disp; UINT32 udisp; - drcuml_codelabel templabel; + code_label templabel; switch ( opcode & (15<<8) ) { @@ -2862,7 +2852,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state udisp = (opcode & 0x0f); UML_ADD(block, IREG(0), R32(Rm), IMM(udisp)); // add r0, Rm, udisp UML_MOV(block, IREG(1), R32(0)); // mov r1, R0 - UML_CALLH(block, sh2->write8); // call write8 + UML_CALLH(block, *sh2->write8); // call write8 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2872,7 +2862,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state udisp = (opcode & 0x0f) * 2; UML_ADD(block, IREG(0), R32(Rm), IMM(udisp)); // add r0, Rm, udisp UML_MOV(block, IREG(1), R32(0)); // mov r1, R0 - UML_CALLH(block, sh2->write16); // call write16 + UML_CALLH(block, *sh2->write16); // call write16 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2891,8 +2881,8 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state udisp = opcode & 0x0f; UML_ADD(block, IREG(0), R32(Rm), IMM(udisp)); // add r0, Rm, udisp SETEA(0); - UML_CALLH(block, sh2->read8); // call read8 - UML_SEXT(block, R32(0), IREG(0), BYTE); // sext R0, r0, BYTE + UML_CALLH(block, *sh2->read8); // call read8 + UML_SEXT(block, R32(0), IREG(0), SIZE_BYTE); // sext R0, r0, BYTE if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2902,8 +2892,8 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state udisp = (opcode & 0x0f)*2; UML_ADD(block, IREG(0), R32(Rm), IMM(udisp)); // add r0, Rm, udisp SETEA(0); - UML_CALLH(block, sh2->read16); // call read16 - UML_SEXT(block, R32(0), IREG(0), WORD); // sext R0, r0, WORD + UML_CALLH(block, *sh2->read16); // call read16 + UML_SEXT(block, R32(0), IREG(0), SIZE_WORD); // sext R0, r0, WORD if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -2912,7 +2902,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state case 8<< 8: // CMPIM(opcode & 0xff); UML_AND(block, IREG(0), MEM(&sh2->sr), IMM(~T)); // and r0, sr, ~T (clear the T bit) - UML_SEXT(block, IREG(1), IMM(opcode&0xff), BYTE); // sext r1, opcode&0xff, BYTE + UML_SEXT(block, IREG(1), IMM(opcode&0xff), SIZE_BYTE); // sext r1, opcode&0xff, BYTE UML_CMP(block, IREG(1), R32(0)); // cmp r1, R0 UML_JMPc(block, IF_NZ, compiler->labelnum); // jnz compiler->labelnum (if negative) @@ -2930,7 +2920,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state sh2->ea = (desc->pc + 2) + disp * 2 + 2; // sh2->ea = destination generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // jmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // jmp sh2->ea UML_LABEL(block, compiler->labelnum++); // labelnum: return TRUE; @@ -2943,7 +2933,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state sh2->ea = (desc->pc + 2) + disp * 2 + 2; // sh2->ea = destination generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // jmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // jmp sh2->ea UML_LABEL(block, compiler->labelnum++); // labelnum: return TRUE; @@ -2962,7 +2952,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->ea-2); generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // jmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // jmp sh2->ea UML_LABEL(block, templabel); // labelnum: return TRUE; @@ -2983,7 +2973,7 @@ static int generate_group_8(sh2_state *sh2, drcuml_block *block, compiler_state generate_delay_slot(sh2, block, compiler, desc, sh2->ea-2); // delay slot only if the branch is taken generate_update_cycles(sh2, block, compiler, IMM(sh2->ea), TRUE); // <subtract cycles> - UML_HASHJMP(block, IMM(0), IMM(sh2->ea), sh2->nocode); // jmp sh2->ea + UML_HASHJMP(block, IMM(0), IMM(sh2->ea), *sh2->nocode); // jmp sh2->ea UML_LABEL(block, templabel); // labelnum: return TRUE; @@ -3004,7 +2994,7 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state scratch = (opcode & 0xff); UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch UML_AND(block, IREG(1), R32(0), IMM(0xff)); // and r1, R0, 0xff - UML_CALLH(block, sh2->write8); // call write8 + UML_CALLH(block, *sh2->write8); // call write8 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -3014,7 +3004,7 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state scratch = (opcode & 0xff) * 2; UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch UML_AND(block, IREG(1), R32(0), IMM(0xffff)); // and r1, R0, 0xffff - UML_CALLH(block, sh2->write16); // call write16 + UML_CALLH(block, *sh2->write16); // call write16 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -3024,7 +3014,7 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state scratch = (opcode & 0xff) * 4; UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch UML_MOV(block, IREG(1), R32(0)); // mov r1, R0 - UML_CALLH(block, sh2->write32); // call write32 + UML_CALLH(block, *sh2->write32); // call write32 if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -3037,24 +3027,24 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), MEM(&sh2->sr)); // mov r1, sr - UML_CALLH(block, sh2->write32); // write32 + UML_CALLH(block, *sh2->write32); // write32 UML_SUB(block, R32(15), R32(15), IMM(4)); // sub R15, R15, #4 UML_MOV(block, IREG(0), R32(15)); // mov r0, R15 UML_MOV(block, IREG(1), IMM(desc->pc+2)); // mov r1, pc+2 - UML_CALLH(block, sh2->write32); // write32 + UML_CALLH(block, *sh2->write32); // write32 UML_MOV(block, IREG(0), MEM(&sh2->ea)); // mov r0, ea - UML_CALLH(block, sh2->read32); // read32 - UML_HASHJMP(block, IMM(0), IREG(0), sh2->nocode); // jmp (r0) + UML_CALLH(block, *sh2->read32); // read32 + UML_HASHJMP(block, IMM(0), IREG(0), *sh2->nocode); // jmp (r0) return TRUE; case 4<<8: // MOVBLG(opcode & 0xff); scratch = (opcode & 0xff); UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch - UML_CALLH(block, sh2->read8); // call read16 - UML_SEXT(block, R32(0), IREG(0), BYTE); // sext R0, r0, BYTE + UML_CALLH(block, *sh2->read8); // call read16 + UML_SEXT(block, R32(0), IREG(0), SIZE_BYTE); // sext R0, r0, BYTE if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -3063,8 +3053,8 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state case 5<<8: // MOVWLG(opcode & 0xff); scratch = (opcode & 0xff) * 2; UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch - UML_CALLH(block, sh2->read16); // call read16 - UML_SEXT(block, R32(0), IREG(0), WORD); // sext R0, r0, WORD + UML_CALLH(block, *sh2->read16); // call read16 + UML_SEXT(block, R32(0), IREG(0), SIZE_WORD); // sext R0, r0, WORD if (!in_delay_slot) generate_update_cycles(sh2, block, compiler, IMM(desc->pc + 2), TRUE); @@ -3073,7 +3063,7 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state case 6<<8: // MOVLLG(opcode & 0xff); scratch = (opcode & 0xff) * 4; UML_ADD(block, IREG(0), MEM(&sh2->gbr), IMM(scratch)); // add r0, gbr, scratch - UML_CALLH(block, sh2->read32); // call read32 + UML_CALLH(block, *sh2->read32); // call read32 UML_MOV(block, R32(0), IREG(0)); // mov R0, r0 if (!in_delay_slot) @@ -3115,7 +3105,7 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state case 12<<8: // TSTM(opcode & 0xff); UML_AND(block, MEM(&sh2->sr), MEM(&sh2->sr), IMM(~T)); // and sr, sr, ~T (clear the T bit) UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr - UML_CALLH(block, sh2->read8); // read8 + UML_CALLH(block, *sh2->read8); // read8 UML_AND(block, IREG(0), IREG(0), IMM(opcode & 0xff)); UML_CMP(block, IREG(0), IMM(0)); // cmp r0, #0 @@ -3128,32 +3118,32 @@ static int generate_group_12(sh2_state *sh2, drcuml_block *block, compiler_state case 13<<8: // ANDM(opcode & 0xff); UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr - UML_CALLH(block, sh2->read8); // read8 + UML_CALLH(block, *sh2->read8); // read8 UML_AND(block, IREG(1), IREG(0), IMM(opcode&0xff)); // and r1, r0, #opcode&0xff UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr SETEA(0); - UML_CALLH(block, sh2->write8); // write8 + UML_CALLH(block, *sh2->write8); // write8 return TRUE; case 14<<8: // XORM(opcode & 0xff); UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr - UML_CALLH(block, sh2->read8); // read8 + UML_CALLH(block, *sh2->read8); // read8 UML_XOR(block, IREG(1), IREG(0), IMM(opcode&0xff)); // xor r1, r0, #opcode&0xff UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr SETEA(0); - UML_CALLH(block, sh2->write8); // write8 + UML_CALLH(block, *sh2->write8); // write8 return TRUE; case 15<<8: // ORM(opcode & 0xff); UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr - UML_CALLH(block, sh2->read8); // read8 + UML_CALLH(block, *sh2->read8); // read8 UML_OR(block, IREG(1), IREG(0), IMM(opcode&0xff)); // or r1, r0, #opcode&0xff UML_ADD(block, IREG(0), R32(0), MEM(&sh2->gbr)); // add r0, R0, gbr SETEA(0); - UML_CALLH(block, sh2->write8); // write8 + UML_CALLH(block, *sh2->write8); // write8 return TRUE; } diff --git a/src/emu/cpu/uml.c b/src/emu/cpu/uml.c new file mode 100644 index 00000000000..0dc9ff63829 --- /dev/null +++ b/src/emu/cpu/uml.c @@ -0,0 +1,1059 @@ +/*************************************************************************** + + uml.c + + Universal machine language definitions and classes. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +**************************************************************************** + + Future improvements/changes: + + * UML optimizer: + - constant folding + + * Write a back-end validator: + - checks all combinations of memory/register/immediate on all params + - checks behavior of all opcodes + + * Extend registers to 16? Depends on if PPC can use them + + * Support for FPU exceptions + + * New instructions? + - FCOPYI, ICOPYF + copy raw between float and integer registers + + - VALID opcode_desc,handle,param + checksum/compare code referenced by opcode_desc; if not + matching, generate exception with handle,param + + - RECALL handle + change code at caller to call handle in the future + +***************************************************************************/ + +#include "emu.h" +#include "drcuml.h" +#include "drcumlsh.h" +#include <setjmp.h> + +using namespace uml; + + + +//************************************************************************** +// DEBUGGING +//************************************************************************** + +#define VALIDATE_BACKEND (0) +#define LOG_SIMPLIFICATIONS (0) + + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// opcode validation condition/flag valid bitmasks +#define OPFLAGS_NONE 0x00 +#define OPFLAGS_C FLAG_C +#define OPFLAGS_SZ (FLAG_S | FLAG_Z) +#define OPFLAGS_SZC (FLAG_S | FLAG_Z | FLAG_C) +#define OPFLAGS_SZV (FLAG_S | FLAG_Z | FLAG_V) +#define OPFLAGS_SZVC (FLAG_S | FLAG_Z | FLAG_V | FLAG_C) +#define OPFLAGS_UZC (FLAG_U | FLAG_Z | FLAG_C) +#define OPFLAGS_ALL 0x1f +#define OPFLAGS_P1 0x81 +#define OPFLAGS_P2 0x82 +#define OPFLAGS_P3 0x83 +#define OPFLAGS_P4 0x84 + +// parameter input/output states +#define PIO_IN 0x01 +#define PIO_OUT 0x02 +#define PIO_INOUT (PIO_IN | PIO_OUT) + +// parameter sizes +#define PSIZE_4 SIZE_DWORD +#define PSIZE_8 SIZE_QWORD +#define PSIZE_OP 0x80 +#define PSIZE_P1 0x81 +#define PSIZE_P2 0x82 +#define PSIZE_P3 0x83 +#define PSIZE_P4 0x84 + +// basic parameter types +#define PTYPES_NONE 0 +#define PTYPES_IMM (1 << parameter::PTYPE_IMMEDIATE) +#define PTYPES_IREG (1 << parameter::PTYPE_INT_REGISTER) +#define PTYPES_FREG (1 << parameter::PTYPE_FLOAT_REGISTER) +#define PTYPES_VREG (1 << parameter::PTYPE_VECTOR_REGISTER) +#define PTYPES_MVAR (1 << parameter::PTYPE_MAPVAR) +#define PTYPES_MEM (1 << parameter::PTYPE_MEMORY) +#define PTYPES_SIZE (1 << parameter::PTYPE_SIZE) +#define PTYPES_SCSIZE (1 << parameter::PTYPE_SIZE_SCALE) +#define PTYPES_SPSIZE (1 << parameter::PTYPE_SIZE_SPACE) +#define PTYPES_HANDLE (1 << parameter::PTYPE_CODE_HANDLE) +#define PTYPES_LABEL (1 << parameter::PTYPE_CODE_LABEL) +#define PTYPES_CFUNC (1 << parameter::PTYPE_C_FUNCTION) +#define PTYPES_ROUND (1 << parameter::PTYPE_ROUNDING) +#define PTYPES_STR (1 << parameter::PTYPE_STRING) + +// special parameter types +#define PTYPES_PTR (PTYPES_MEM | 0x1000) +#define PTYPES_STATE (PTYPES_MEM | 0x2000) + +// combinations of types +#define PTYPES_IRM (PTYPES_IREG | PTYPES_MEM) +#define PTYPES_FRM (PTYPES_FREG | PTYPES_MEM) +#define PTYPES_IMV (PTYPES_IMM | PTYPES_MVAR) +#define PTYPES_IANY (PTYPES_IRM | PTYPES_IMV) +#define PTYPES_FANY (PTYPES_FRM) + + + +//************************************************************************** +// TABLES +//************************************************************************** + +// macro to simplify the table +#define PINFO(inout, size, types) { PIO_##inout, PSIZE_##size, PTYPES_##types } +#define OPINFO0(op,str,sizes,cond,iflag,oflag,mflag) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { { 0 } } }, +#define OPINFO1(op,str,sizes,cond,iflag,oflag,mflag,p0) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0 } }, +#define OPINFO2(op,str,sizes,cond,iflag,oflag,mflag,p0,p1) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1 } }, +#define OPINFO3(op,str,sizes,cond,iflag,oflag,mflag,p0,p1,p2) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1, p2 } }, +#define OPINFO4(op,str,sizes,cond,iflag,oflag,mflag,p0,p1,p2,p3) { OP_##op, str, sizes, cond, OPFLAGS_##iflag, OPFLAGS_##oflag, OPFLAGS_##mflag, { p0, p1, p2, p3 } }, + +// opcode validation table +const opcode_info instruction::s_opcode_info_table[OP_MAX] = +{ + OPINFO0(INVALID, "invalid", 4, false, NONE, NONE, NONE) + + // Compile-time opcodes + OPINFO1(HANDLE, "handle", 4, false, NONE, NONE, NONE, PINFO(IN, OP, HANDLE)) + OPINFO2(HASH, "hash", 4, false, NONE, NONE, NONE, PINFO(IN, OP, IMV), PINFO(IN, OP, IMV)) + OPINFO1(LABEL, "label", 4, false, NONE, NONE, NONE, PINFO(IN, OP, LABEL)) + OPINFO1(COMMENT, "comment", 4, false, NONE, NONE, NONE, PINFO(IN, OP, STR)) + OPINFO2(MAPVAR, "mapvar", 4, false, NONE, NONE, NONE, PINFO(OUT, OP, MVAR), PINFO(IN, OP, IMV)) + + // Control Flow Operations + OPINFO0(NOP, "nop", 4, false, NONE, NONE, NONE) + OPINFO1(DEBUG, "debug", 4, false, NONE, NONE, ALL, PINFO(IN, OP, IANY)) + OPINFO1(EXIT, "exit", 4, true, NONE, NONE, ALL, PINFO(IN, OP, IANY)) + OPINFO3(HASHJMP, "hashjmp", 4, false, NONE, NONE, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, HANDLE)) + OPINFO1(JMP, "jmp", 4, true, NONE, NONE, NONE, PINFO(IN, OP, LABEL)) + OPINFO2(EXH, "exh", 4, true, NONE, NONE, ALL, PINFO(IN, OP, HANDLE), PINFO(IN, OP, IANY)) + OPINFO1(CALLH, "callh", 4, true, NONE, NONE, ALL, PINFO(IN, OP, HANDLE)) + OPINFO0(RET, "ret", 4, true, NONE, NONE, ALL) + OPINFO2(CALLC, "callc", 4, true, NONE, NONE, ALL, PINFO(IN, OP, CFUNC), PINFO(IN, OP, PTR)) + OPINFO2(RECOVER, "recover", 4, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, MVAR)) + + // Internal Register Operations + OPINFO1(SETFMOD, "setfmod", 4, false, NONE, NONE, ALL, PINFO(IN, OP, IANY)) + OPINFO1(GETFMOD, "getfmod", 4, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) + OPINFO1(GETEXP, "getexp", 4, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) + OPINFO2(GETFLGS, "getflgs", 4, false, P2, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IMV)) + OPINFO1(SAVE, "save", 4, false, ALL, NONE, ALL, PINFO(OUT, OP, STATE)) + OPINFO1(RESTORE, "restore", 4, false, NONE, ALL, ALL, PINFO(IN, OP, STATE)) + + // Integer Operations + OPINFO4(LOAD, "!load", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, SCSIZE)) + OPINFO4(LOADS, "!loads", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, SCSIZE)) + OPINFO4(STORE, "!store", 4|8, false, NONE, NONE, ALL, PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SCSIZE)) + OPINFO3(READ, "!read", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, 4, IANY), PINFO(IN, OP, SPSIZE)) + OPINFO4(READM, "!readm", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, IRM), PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSIZE)) + OPINFO3(WRITE, "!write", 4|8, false, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSIZE)) + OPINFO4(WRITEM, "!writem", 4|8, false, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, SPSIZE)) + OPINFO2(CARRY, "!carry", 4|8, false, NONE, C, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO1(SET, "!set", 4|8, true, NONE, NONE, ALL, PINFO(OUT, OP, IRM)) + OPINFO2(MOV, "!mov", 4|8, true, NONE, NONE, NONE, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) + OPINFO3(SEXT, "!sext", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, P3, IANY), PINFO(IN, OP, SIZE)) + OPINFO4(ROLAND, "!roland", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO4(ROLINS, "!rolins", 4|8, false, NONE, SZ, ALL, PINFO(INOUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(ADD, "!add", 4|8, false, NONE, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(ADDC, "!addc", 4|8, false, C, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(SUB, "!sub", 4|8, false, NONE, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(SUBB, "!subb", 4|8, false, C, SZVC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO2(CMP, "!cmp", 4|8, false, NONE, SZVC, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO4(MULU, "!mulu", 4|8, false, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO4(MULS, "!muls", 4|8, false, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO4(DIVU, "!divu", 4|8, false, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO4(DIVS, "!divs", 4|8, false, NONE, SZV, ALL, PINFO(OUT, OP, IRM), PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(AND, "!and", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO2(TEST, "!test", 4|8, false, NONE, SZ, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(OR, "!or", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(XOR, "!xor", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO2(LZCNT, "!lzcnt", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) + OPINFO2(BSWAP, "!bswap", 4|8, false, NONE, SZ, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY)) + OPINFO3(SHL, "!shl", 4|8, false, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(SHR, "!shr", 4|8, false, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(SAR, "!sar", 4|8, false, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(ROL, "!rol", 4|8, false, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(ROLC, "!rolc", 4|8, false, C, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(ROR, "!ror", 4|8, false, NONE, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + OPINFO3(RORC, "!rorc", 4|8, false, C, SZC, ALL, PINFO(OUT, OP, IRM), PINFO(IN, OP, IANY), PINFO(IN, OP, IANY)) + + // Floating Point Operations + OPINFO3(FLOAD, "f#load", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, PTR), PINFO(IN, 4, IANY)) + OPINFO3(FSTORE, "f#store", 4|8, false, NONE, NONE, ALL, PINFO(IN, OP, PTR), PINFO(IN, 4, IANY), PINFO(IN, OP, FRM)) + OPINFO3(FREAD, "f#read", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, 4, IANY), PINFO(IN, OP, SPSIZE)) + OPINFO3(FWRITE, "f#write", 4|8, false, NONE, NONE, ALL, PINFO(IN, 4, IANY), PINFO(IN, OP, FANY), PINFO(IN, OP, SPSIZE)) + OPINFO2(FMOV, "f#mov", 4|8, true, NONE, NONE, NONE, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) + OPINFO4(FTOINT, "f#toint", 4|8, false, NONE, NONE, ALL, PINFO(OUT, P3, IRM), PINFO(IN, OP, FANY), PINFO(IN, OP, SIZE), PINFO(IN, OP, ROUND)) + OPINFO3(FFRINT, "f#frint", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, IANY), PINFO(IN, OP, SIZE)) + OPINFO3(FFRFLT, "f#frflt", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, FANY), PINFO(IN, OP, SIZE)) + OPINFO2(FRNDS, "f#rnds", 8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, P3, FANY)) + OPINFO3(FADD, "f#add", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) + OPINFO3(FSUB, "f#sub", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) + OPINFO2(FCMP, "f#cmp", 4|8, false, NONE, UZC, ALL, PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) + OPINFO3(FMUL, "f#mul", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) + OPINFO3(FDIV, "f#div", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY), PINFO(IN, OP, FANY)) + OPINFO2(FNEG, "f#neg", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) + OPINFO2(FABS, "f#abs", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) + OPINFO2(FSQRT, "f#sqrt", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) + OPINFO2(FRECIP, "f#recip", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) + OPINFO2(FRSQRT, "f#rsqrt", 4|8, false, NONE, NONE, ALL, PINFO(OUT, OP, FRM), PINFO(IN, OP, FANY)) +}; + + + +//************************************************************************** +// INLINE FUNCTIONS +//************************************************************************** + +//------------------------------------------------- +// rol32 - perform a 32-bit left rotate +//------------------------------------------------- + +inline UINT32 rol32(UINT32 source, UINT8 count) +{ + count &= 31; + return (source << count) | (source >> (32 - count)); +} + + +//------------------------------------------------- +// rol64 - perform a 64-bit left rotate +//------------------------------------------------- + +inline UINT64 rol64(UINT64 source, UINT8 count) +{ + count &= 63; + return (source << count) | (source >> (64 - count)); +} + + + +//************************************************************************** +// UML CODE HANDLE +//************************************************************************** + +//------------------------------------------------- +// code_handle - constructor +//------------------------------------------------- + +uml::code_handle::code_handle(drcuml_state &drcuml, const char *name) + : m_code(reinterpret_cast<drccodeptr *>(drcuml.cache().alloc_near(sizeof(drccodeptr)))), + m_string(name), + m_next(NULL), + m_drcuml(drcuml) +{ + if (m_code == NULL) + throw std::bad_alloc(); + *m_code = NULL; +} + + +//------------------------------------------------- +// set_codeptr - set a new code pointer +//------------------------------------------------- + +void uml::code_handle::set_codeptr(drccodeptr code) +{ + assert(*m_code == NULL); + assert_in_cache(m_drcuml.cache(), code); + *m_code = code; +} + + + +//************************************************************************** +// UML INSTRUCTION +//************************************************************************** + +//------------------------------------------------- +// instruction - constructor +//------------------------------------------------- + +uml::instruction::instruction() + : m_opcode(OP_INVALID), + m_condition(COND_ALWAYS), + m_flags(0), + m_size(4), + m_numparams(0) +{ +} + + +//------------------------------------------------- +// configure - configure an opcode with no +// parameters +//------------------------------------------------- + +void uml::instruction::configure(opcode_t op, UINT8 size, condition_t condition) +{ + // fill in the instruction + m_opcode = (opcode_t)(UINT8)op; + m_size = size; + m_condition = condition; + m_flags = 0; + m_numparams = 0; + + // validate + validate(); +} + + +//------------------------------------------------- +// configure - configure an opcode with 1 +// parameter +//------------------------------------------------- + +void uml::instruction::configure(opcode_t op, UINT8 size, parameter p0, condition_t condition) +{ + // fill in the instruction + m_opcode = (opcode_t)(UINT8)op; + m_size = size; + m_condition = condition; + m_flags = 0; + m_numparams = 1; + m_param[0] = p0; + + // validate + validate(); +} + + +//------------------------------------------------- +// configure - configure an opcode with 2 +// parameters +//------------------------------------------------- + +void uml::instruction::configure(opcode_t op, UINT8 size, parameter p0, parameter p1, condition_t condition) +{ + // fill in the instruction + m_opcode = (opcode_t)(UINT8)op; + m_size = size; + m_condition = condition; + m_flags = 0; + m_numparams = 2; + m_param[0] = p0; + m_param[1] = p1; + + // validate + validate(); +} + + +//------------------------------------------------- +// configure - configure an opcode with 3 +// parameters +//------------------------------------------------- + +void uml::instruction::configure(opcode_t op, UINT8 size, parameter p0, parameter p1, parameter p2, condition_t condition) +{ + // fill in the instruction + m_opcode = (opcode_t)(UINT8)op; + m_size = size; + m_condition = condition; + m_flags = 0; + m_numparams = 3; + m_param[0] = p0; + m_param[1] = p1; + m_param[2] = p2; + + // validate + validate(); +} + + +//------------------------------------------------- +// configure - configure an opcode with 4 +// parameters +//------------------------------------------------- + +void uml::instruction::configure(opcode_t op, UINT8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t condition) +{ + // fill in the instruction + m_opcode = (opcode_t)(UINT8)op; + m_size = size; + m_condition = condition; + m_flags = 0; + m_numparams = 4; + m_param[0] = p0; + m_param[1] = p1; + m_param[2] = p2; + m_param[3] = p3; + + // validate + validate(); +} + + +//------------------------------------------------- +// simplify - simplify instructions that have +// immediate values we can evaluate at compile +// time +//------------------------------------------------- + +void uml::instruction::simplify() +{ + // can't simplify if flags are in play + if (m_flags != 0) + return; + + static const UINT64 instsizemask[] = { 0, 0, 0, 0, 0xffffffff, 0, 0, 0, U64(0xffffffffffffffff) }; + static const UINT64 paramsizemask[] = { 0xff, 0xffff, 0xffffffff, U64(0xffffffffffffffff) }; + + // loop until we've simplified all we can + opcode_t origop; + do + { + // switch off the opcode + origop = m_opcode; + switch (m_opcode) + { + // READM: convert to READ if the mask is wide open + case OP_READM: + if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) + { + m_opcode = OP_READ; + m_numparams = 2; + m_param[2] = m_param[3]; + } + break; + + // WRITEM: convert to WRITE if the mask is wide open + case OP_WRITEM: + if (m_param[2].is_immediate_value(paramsizemask[m_param[3].size()])) + { + m_opcode = OP_WRITE; + m_numparams = 2; + m_param[2] = m_param[3]; + } + break; + + // SET: convert to MOV if constant condition + case OP_SET: + if (m_condition == COND_ALWAYS) + convert_to_mov_immediate(1); + break; + + // MOV: convert to NOP if move-to-self + case OP_MOV: + if (m_param[0] == m_param[1]) + nop(); + break; + + // SEXT: convert immediates to MOV + case OP_SEXT: + if (m_param[1].is_immediate()) + switch (m_param[2].size()) + { + case SIZE_BYTE: convert_to_mov_immediate((INT8)m_param[1].immediate()); break; + case SIZE_WORD: convert_to_mov_immediate((INT16)m_param[1].immediate()); break; + case SIZE_DWORD: convert_to_mov_immediate((INT32)m_param[1].immediate()); break; + case SIZE_QWORD: convert_to_mov_immediate((INT64)m_param[1].immediate()); break; + case SIZE_DQWORD: fatalerror("Invalid SEXT target size"); break; + } + break; + + // ROLAND: convert to MOV if all immediate, or to ROL or AND if one is not needed, or to SHL/SHR if the mask is right + case OP_ROLAND: + if (m_param[1].is_immediate() && m_param[2].is_immediate() && m_param[3].is_immediate()) + { + assert(m_size == 4 || m_size == 8); + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); + else + convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate()) & m_param[3].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + { + m_opcode = OP_AND; + m_numparams = 3; + m_param[2] = m_param[3]; + } + else if (m_param[3].is_immediate_value(instsizemask[m_size])) + { + m_opcode = OP_ROL; + m_numparams = 3; + } + else if (m_param[2].is_immediate() && m_param[3].is_immediate_value((U64(0xffffffffffffffff) << m_param[2].immediate()) & instsizemask[m_size])) + { + m_opcode = OP_SHL; + m_numparams = 3; + } + else if (m_param[2].is_immediate() && m_param[3].is_immediate_value(instsizemask[m_size] >> (8 * m_size - m_param[2].immediate()))) + { + m_opcode = OP_SHR; + m_numparams = 3; + m_param[2] = 8 * m_size - m_param[2].immediate(); + } + break; + + // ROLINS: convert to ROLAND if the mask is full + case OP_ROLINS: + if (m_param[3].is_immediate_value(instsizemask[m_size])) + m_opcode = OP_ROLAND; + break; + + // ADD: convert to MOV if immediate, or if adding 0 + case OP_ADD: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() + m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SUB: convert to MOV if immediate, or if subtracting 0 + case OP_SUB: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() - m_param[2].immediate()); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // CMP: no-op if no flags needed, compare i0 to i0 if the parameters are equal + case OP_CMP: + if (m_flags == 0) + nop(); + else if (m_param[0] == m_param[1]) + cmp(I0, I0); + break; + + // MULU: convert simple form to MOV if immediate, or if multiplying by 0 + case OP_MULU: + if (m_param[0] == m_param[1]) + { + if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((UINT32)((UINT32)m_param[1].immediate() * (UINT32)m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate((UINT64)((UINT64)m_param[1].immediate() * (UINT64)m_param[2].immediate())); + } + } + break; + + // MULS: convert simple form to MOV if immediate, or if multiplying by 0 + case OP_MULS: + if (m_param[0] == m_param[1]) + { + if (m_param[2].is_immediate_value(0) || m_param[3].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((INT32)((INT32)m_param[1].immediate() * (INT32)m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate((INT64)((INT64)m_param[1].immediate() * (INT64)m_param[2].immediate())); + } + } + break; + + // DIVU: convert simple form to MOV if immediate, or if dividing with 0 + case OP_DIVU: + if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) + { + if (m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((UINT32)((UINT32)m_param[1].immediate() / (UINT32)m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate((UINT64)((UINT64)m_param[1].immediate() / (UINT64)m_param[2].immediate())); + } + } + break; + + // DIVS: convert simple form to MOV if immediate, or if dividing with 0 + case OP_DIVS: + if (m_param[0] == m_param[1] && !m_param[3].is_immediate_value(0)) + { + if (m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[2].is_immediate() && m_param[3].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((INT32)((INT32)m_param[1].immediate() / (INT32)m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate((INT64)((INT64)m_param[1].immediate() / (INT64)m_param[2].immediate())); + } + } + break; + + // AND: convert to MOV if immediate, or if anding against 0 or 0xffffffff + case OP_AND: + if (m_param[1].is_immediate_value(0) || m_param[2].is_immediate_value(0)) + convert_to_mov_immediate(0); + else if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() & m_param[2].immediate()); + else if (m_param[1].is_immediate_value(instsizemask[m_size])) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(instsizemask[m_size])) + convert_to_mov_param(1); + break; + + // TEST: no-op if no flags needed + case OP_TEST: + if (m_flags == 0) + nop(); + break; + + // OR: convert to MOV if immediate, or if oring against 0 or 0xffffffff + case OP_OR: + if (m_param[1].is_immediate_value(instsizemask[m_size]) || m_param[2].is_immediate_value(instsizemask[m_size])) + convert_to_mov_immediate(instsizemask[m_size]); + else if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() | m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // XOR: convert to MOV if immediate, or if xoring against 0 + case OP_XOR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() ^ m_param[2].immediate()); + else if (m_param[1].is_immediate_value(0)) + convert_to_mov_param(2); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // LZCNT: convert to MOV if immediate + case OP_LZCNT: + if (m_param[1].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate())); + else if (m_size == 8) + { + if ((m_param[1].immediate() >> 32) == 0) + convert_to_mov_immediate(32 + count_leading_zeros(m_param[1].immediate())); + else + convert_to_mov_immediate(count_leading_zeros(m_param[1].immediate() >> 32)); + } + } + break; + + // BSWAP: convert to MOV if immediate + case OP_BSWAP: + if (m_param[1].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(FLIPENDIAN_INT32(m_param[1].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(FLIPENDIAN_INT64(m_param[1].immediate())); + } + break; + + // SHL: convert to MOV if immediate or shifting by 0 + case OP_SHL: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + convert_to_mov_immediate(m_param[1].immediate() << m_param[2].immediate()); + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SHR: convert to MOV if immediate or shifting by 0 + case OP_SHR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((UINT32)m_param[1].immediate() >> m_param[2].immediate()); + else if (m_size == 8) + convert_to_mov_immediate((UINT64)m_param[1].immediate() >> m_param[2].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // SAR: convert to MOV if immediate or shifting by 0 + case OP_SAR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate((INT32)m_param[1].immediate() >> m_param[2].immediate()); + else if (m_size == 8) + convert_to_mov_immediate((INT64)m_param[1].immediate() >> m_param[2].immediate()); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // ROL: convert to NOP if immediate or rotating by 0 + case OP_ROL: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(rol64(m_param[1].immediate(), m_param[2].immediate())); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // ROR: convert to NOP if immediate or rotating by 0 + case OP_ROR: + if (m_param[1].is_immediate() && m_param[2].is_immediate()) + { + if (m_size == 4) + convert_to_mov_immediate(rol32(m_param[1].immediate(), 32 - m_param[2].immediate())); + else if (m_size == 8) + convert_to_mov_immediate(rol64(m_param[1].immediate(), 64 - m_param[2].immediate())); + } + else if (m_param[2].is_immediate_value(0)) + convert_to_mov_param(1); + break; + + // FMOV: convert to NOP if move-to-self + case OP_FMOV: + if (m_param[0] == m_param[1]) + nop(); + break; + + default: + break; + } + + /* + if (LOG_SIMPLIFICATIONS && memcmp(&orig, inst, sizeof(orig)) != 0) + { + astring disasm1, disasm2; + orig.disasm(disasm1, block->drcuml); + inst->disasm(disasm2, block->drcuml); + mame_printf_debug("Simplified: %-50.50s -> %s\n", disasm1.cstr(), disasm2.cstr()); + } + */ + + // loop until we stop changing opcodes + } while (m_opcode != origop); +} + + +//------------------------------------------------- +// validate - verify that the instruction created +// meets all requirements +//------------------------------------------------- + +void uml::instruction::validate() +{ +#ifdef MAME_DEBUG + const opcode_info &opinfo = s_opcode_info_table[m_opcode]; + assert(opinfo.opcode == m_opcode); + + // validate raw information + assert(m_opcode != OP_INVALID && m_opcode < OP_MAX); + assert(m_size == 1 || m_size == 2 || m_size == 4 || m_size == 8); + + // validate against opcode limits + assert((opinfo.sizes & m_size) != 0); + assert(m_condition == COND_ALWAYS || opinfo.condition); + + // validate each parameter + for (int pnum = 0; pnum < m_numparams; pnum++) + { + // ensure the type is valid + const parameter ¶m = m_param[pnum]; + assert((opinfo.param[pnum].typemask >> param.type()) & 1); + } + + // make sure we aren't missing any parameters + if (m_numparams < ARRAY_LENGTH(opinfo.param)) + assert(opinfo.param[m_numparams].typemask == 0); +#endif +} + + +//------------------------------------------------- +// input_flags - return the effective input flags +// based on any conditions encoded in an +// instruction +//------------------------------------------------- + +UINT8 uml::instruction::input_flags() const +{ + static const UINT8 flags_for_condition[] = + { + FLAG_Z, // COND_Z + FLAG_Z, // COND_NZ + FLAG_S, // COND_S + FLAG_S, // COND_NS + FLAG_C, // COND_C + FLAG_C, // COND_NC + FLAG_V, // COND_V + FLAG_V, // COND_NV + FLAG_U, // COND_U + FLAG_U, // COND_NU + FLAG_C | FLAG_Z, // COND_A + FLAG_C | FLAG_Z, // COND_BE + FLAG_S | FLAG_V | FLAG_Z, // COND_G + FLAG_S | FLAG_V | FLAG_Z, // COND_LE + FLAG_S | FLAG_V, // COND_L + FLAG_S | FLAG_V // COND_GE + }; + + UINT8 flags = s_opcode_info_table[m_opcode].inflags; + if (flags & 0x80) + flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; + if (m_condition != COND_ALWAYS) + flags |= flags_for_condition[m_condition & 0x0f]; + return flags; +} + + +//------------------------------------------------- +// output_flags - return the effective output +// flags based on any conditions encoded in an +// instruction +//------------------------------------------------- + +UINT8 uml::instruction::output_flags() const +{ + UINT8 flags = s_opcode_info_table[m_opcode].outflags; + if (flags & 0x80) + flags = m_param[flags - OPFLAGS_P1].immediate() & OPFLAGS_ALL; + return flags; +} + + +//------------------------------------------------- +// modified_flags - return the effective output +// flags based on any conditions encoded in an +// instruction +//------------------------------------------------- + +UINT8 uml::instruction::modified_flags() const +{ + return s_opcode_info_table[m_opcode].modflags; +} + + +//------------------------------------------------- +// disasm - disassemble an instruction to the +// given buffer +//------------------------------------------------- + +const char *uml::instruction::disasm(astring &buffer, drcuml_state *drcuml) const +{ + static const char *const conditions[] = { "z", "nz", "s", "ns", "c", "nc", "v", "nv", "u", "nu", "a", "be", "g", "le", "l", "ge" }; + static const char *const pound_size[] = { "?", "?", "?", "?", "s", "?", "?", "?", "d" }; + static const char *const bang_size[] = { "?", "b", "h", "?", "", "?", "?", "?", "d" }; + static const char *const fmods[] = { "trunc", "round", "ceil", "floor", "default" }; + static const char *const spaces[] = { "program", "data", "io", "3", "4", "5", "6", "7" }; + static const char *const sizes[] = { "byte", "word", "dword", "qword" }; + + const opcode_info &opinfo = s_opcode_info_table[m_opcode]; + + assert(m_opcode != OP_INVALID && m_opcode < OP_MAX); + + // start with the raw mnemonic and substitute sizes + buffer.reset(); + for (const char *opsrc = opinfo.mnemonic; *opsrc != 0; opsrc++) + if (*opsrc == '!') + buffer.catprintf("%s", bang_size[m_size]); + else if (*opsrc == '#') + buffer.catprintf("%s", pound_size[m_size]); + else + buffer.cat(*opsrc); + + // pad to 8 spaces + int pad = 8 - buffer.len(); + for (int ch = 0; ch < pad; ch++) + buffer.cat(' '); + + // iterate through parameters + for (int pnum = 0; pnum < m_numparams; pnum++) + { + const parameter ¶m = m_param[pnum]; + + // start with a comma for all except the first parameter + if (pnum != 0) + buffer.cat(','); + + // ouput based on type + switch (param.type()) + { + // immediates have several special cases + case parameter::PTYPE_IMMEDIATE: + { + // determine the size of the immediate + int size; + switch (opinfo.param[pnum].size) + { + case PSIZE_4: size = 4; break; + case PSIZE_8: size = 8; break; + case PSIZE_P1: size = 1 << m_param[0].size(); break; + case PSIZE_P2: size = 1 << m_param[1].size(); break; + case PSIZE_P3: size = 1 << m_param[2].size(); break; + case PSIZE_P4: size = 1 << m_param[3].size(); break; + default: + case PSIZE_OP: size = m_size; break; + } + + // truncate to size + UINT64 value = param.immediate(); + if (size == 1) value = (UINT8)value; + if (size == 2) value = (UINT16)value; + if (size == 4) value = (UINT32)value; + if ((UINT32)value == value) + buffer.catprintf("$%X", (UINT32)value); + else + buffer.catprintf("$%X%08X", (UINT32)(value >> 32), (UINT32)value); + } + break; + + // immediates have several special cases + case parameter::PTYPE_SIZE: + buffer.catprintf("%s", sizes[param.size()]); + break; + + // size + address space immediate + case parameter::PTYPE_SIZE_SPACE: + buffer.catprintf("%s_%s", spaces[param.space()], sizes[param.size()]); + break; + + // size + scale immediate + case parameter::PTYPE_SIZE_SCALE: + { + int scale = param.scale(); + int size = param.size(); + if (scale == size) + buffer.catprintf("%s", sizes[size]); + else + buffer.catprintf("%s_x%d", sizes[size], 1 << scale); + } + break; + + // fmod immediate + case parameter::PTYPE_ROUNDING: + buffer.catprintf("%s", fmods[param.rounding()]); + break; + + // integer registers + case parameter::PTYPE_INT_REGISTER: + buffer.catprintf("i%d", param.ireg() - REG_I0); + break; + + // floating point registers + case parameter::PTYPE_FLOAT_REGISTER: + buffer.catprintf("f%d", param.freg() - REG_F0); + break; + + // map variables + case parameter::PTYPE_MAPVAR: + buffer.catprintf("m%d", param.mapvar() - MAPVAR_M0); + break; + + // memory + case parameter::PTYPE_MEMORY: + { + const char *symbol; + UINT32 symoffset; + + // symbol + if (drcuml != NULL && (symbol = drcuml->symbol_find(param.memory(), &symoffset)) != NULL) + { + if (symoffset == 0) + buffer.catprintf("[%s]", symbol); + else + buffer.catprintf("[%s+$%X]", symbol, symoffset); + } + + // cache memory + else if (drcuml != NULL && drcuml->cache().contains_pointer(param.memory())) + buffer.catprintf("[+$%X]", (UINT32)(FPTR)((drccodeptr)param.memory() - drcuml->cache().near())); + + // general memory + else + buffer.catprintf("[[$%p]]", param.memory()); + break; + } + + // string pointer + case parameter::PTYPE_STRING: + buffer.catprintf("%s", (const char *)(FPTR)param.string()); + break; + + // handle pointer + case parameter::PTYPE_CODE_HANDLE: + buffer.catprintf("%s", param.handle().string()); + break; + + default: + buffer.catprintf("???"); + break; + } + } + + // if there's a condition, append it + if (m_condition != COND_ALWAYS) + buffer.catprintf(",%s", conditions[m_condition & 0x0f]); + + // if there are flags, append them + if (m_flags != 0) + { + buffer.cat(','); + if (m_flags & FLAG_U) + buffer.cat('U'); + if (m_flags & FLAG_S) + buffer.cat('S'); + if (m_flags & FLAG_Z) + buffer.cat('Z'); + if (m_flags & FLAG_V) + buffer.cat('V'); + if (m_flags & FLAG_C) + buffer.cat('C'); + } + return buffer; +} diff --git a/src/emu/cpu/uml.h b/src/emu/cpu/uml.h new file mode 100644 index 00000000000..cda2b85ab1d --- /dev/null +++ b/src/emu/cpu/uml.h @@ -0,0 +1,687 @@ +/*************************************************************************** + + uml.h + + Universal machine language definitions and classes. + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#pragma once + +#ifndef __UML_H__ +#define __UML_H__ + +#include "drccache.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// opaque structure describing UML generation state +class drcuml_state; + +struct drcuml_machine_state; + + +// use a namespace to wrap all the UML instruction concepts so that +// we can keep names short +namespace uml +{ + // integer registers + const int REG_I0 = 0x400; + const int REG_I_COUNT = 10; + const int REG_I_END = REG_I0 + REG_I_COUNT; + + // floating point registers + const int REG_F0 = 0x800; + const int REG_F_COUNT = 10; + const int REG_F_END = REG_F0 + REG_F_COUNT; + + // vector registers + const int REG_V0 = 0xc00; + const int REG_V_COUNT = 10; + const int REG_V_END = REG_V0 + REG_V_COUNT; + + // map variables + const int MAPVAR_M0 = 0x1000; + const int MAPVAR_COUNT = 10; + const int MAPVAR_END = MAPVAR_M0 + MAPVAR_COUNT; + + // flag definitions + const UINT8 FLAG_C = 0x01; // carry flag + const UINT8 FLAG_V = 0x02; // overflow flag (defined for integer only) + const UINT8 FLAG_Z = 0x04; // zero flag + const UINT8 FLAG_S = 0x08; // sign flag (defined for integer only) + const UINT8 FLAG_U = 0x10; // unordered flag (defined for FP only) + + // testable conditions; note that these are defined such that (condition ^ 1) is + // always the opposite + enum condition_t + { + COND_ALWAYS = 0, + + COND_Z = 0x80, // requires Z + COND_NZ, // requires Z + COND_S, // requires S + COND_NS, // requires S + COND_C, // requires C + COND_NC, // requires C + COND_V, // requires V + COND_NV, // requires V + COND_U, // requires U + COND_NU, // requires U + COND_A, // requires CZ + COND_BE, // requires CZ + COND_G, // requires SVZ + COND_LE, // requires SVZ + COND_L, // requires SV + COND_GE, // requires SV + + COND_MAX, + + // basic condition code aliases + COND_E = COND_Z, + COND_NE = COND_NZ, + COND_B = COND_C, + COND_AE = COND_NC + }; + + // floating point rounding modes + enum float_rounding_mode + { + ROUND_TRUNC = 0, // truncate + ROUND_ROUND, // round + ROUND_CEIL, // round up + ROUND_FLOOR, // round down + ROUND_DEFAULT + }; + + // operand sizes + enum operand_size + { + SIZE_BYTE = 0, // 1-byte + SIZE_WORD, // 2-byte + SIZE_DWORD, // 4-byte + SIZE_QWORD, // 8-byte + SIZE_DQWORD, // 16-byte (vector) + SIZE_SHORT = SIZE_DWORD, // 4-byte (float) + SIZE_DOUBLE = SIZE_QWORD // 8-byte (float) + }; + + // memory scale factors + enum memory_scale + { + SCALE_x1 = 0, // index * 1 + SCALE_x2, // index * 2 + SCALE_x4, // index * 4 + SCALE_x8, // index * 8 + SCALE_DEFAULT + }; + + // spaces + enum memory_space + { + SPACE_PROGRAM = AS_PROGRAM, + SPACE_DATA = AS_DATA, + SPACE_IO = AS_IO + }; + + // opcodes + enum opcode_t + { + OP_INVALID, + + // compile-time opcodes + OP_HANDLE, // HANDLE handle + OP_HASH, // HASH mode,pc + OP_LABEL, // LABEL imm + OP_COMMENT, // COMMENT string + OP_MAPVAR, // MAPVAR mapvar,value + + // control flow operations + OP_NOP, // NOP + OP_DEBUG, // DEBUG pc + OP_EXIT, // EXIT src1[,c] + OP_HASHJMP, // HASHJMP mode,pc,handle + OP_JMP, // JMP imm[,c] + OP_EXH, // EXH handle,param[,c] + OP_CALLH, // CALLH handle[,c] + OP_RET, // RET [c] + OP_CALLC, // CALLC func,ptr[,c] + OP_RECOVER, // RECOVER dst,mapvar + + // internal register operations + OP_SETFMOD, // SETFMOD src + OP_GETFMOD, // GETFMOD dst + OP_GETEXP, // GETEXP dst + OP_GETFLGS, // GETFLGS dst[,f] + OP_SAVE, // SAVE mem + OP_RESTORE, // RESTORE mem + + // integer operations + OP_LOAD, // LOAD dst,base,index,size + OP_LOADS, // LOADS dst,base,index,size + OP_STORE, // STORE base,index,src,size + OP_READ, // READ dst,src1,space/size + OP_READM, // READM dst,src1,mask,space/size + OP_WRITE, // WRITE dst,src1,space/size + OP_WRITEM, // WRITEM dst,mask,src1,space/size + OP_CARRY, // CARRY src,bitnum + OP_SET, // SET dst,c + OP_MOV, // MOV dst,src[,c] + OP_SEXT, // SEXT dst,src,size + OP_ROLAND, // ROLAND dst,src,shift,mask + OP_ROLINS, // ROLINS dst,src,shift,mask + OP_ADD, // ADD dst,src1,src2[,f] + OP_ADDC, // ADDC dst,src1,src2[,f] + OP_SUB, // SUB dst,src1,src2[,f] + OP_SUBB, // SUBB dst,src1,src2[,f] + OP_CMP, // CMP src1,src2[,f] + OP_MULU, // MULU dst,edst,src1,src2[,f] + OP_MULS, // MULS dst,edst,src1,src2[,f] + OP_DIVU, // DIVU dst,edst,src1,src2[,f] + OP_DIVS, // DIVS dst,edst,src1,src2[,f] + OP_AND, // AND dst,src1,src2[,f] + OP_TEST, // TEST src1,src2[,f] + OP_OR, // OR dst,src1,src2[,f] + OP_XOR, // XOR dst,src1,src2[,f] + OP_LZCNT, // LZCNT dst,src + OP_BSWAP, // BSWAP dst,src + OP_SHL, // SHL dst,src,count[,f] + OP_SHR, // SHR dst,src,count[,f] + OP_SAR, // SAR dst,src,count[,f] + OP_ROL, // ROL dst,src,count[,f] + OP_ROLC, // ROLC dst,src,count[,f] + OP_ROR, // ROL dst,src,count[,f] + OP_RORC, // ROLC dst,src,count[,f] + + // floating point operations + OP_FLOAD, // FLOAD dst,base,index + OP_FSTORE, // FSTORE base,index,src + OP_FREAD, // FREAD dst,space,src1 + OP_FWRITE, // FWRITE space,dst,src1 + OP_FMOV, // FMOV dst,src1[,c] + OP_FTOINT, // FTOINT dst,src1,size,round + OP_FFRINT, // FFRINT dst,src1,size + OP_FFRFLT, // FFRFLT dst,src1,size + OP_FRNDS, // FRNDS dst,src1 + OP_FADD, // FADD dst,src1,src2 + OP_FSUB, // FSUB dst,src1,src2 + OP_FCMP, // FCMP src1,src2 + OP_FMUL, // FMUL dst,src1,src2 + OP_FDIV, // FDIV dst,src1,src2 + OP_FNEG, // FNEG dst,src1 + OP_FABS, // FABS dst,src1 + OP_FSQRT, // FSQRT dst,src1 + OP_FRECIP, // FRECIP dst,src1 + OP_FRSQRT, // FRSQRT dst,src1 + + OP_MAX + }; + + // C function callback deinition + typedef void (*c_function)(void *ptr); + + // class describing a global code handle + class code_handle + { + friend class ::drcuml_state; + template<class T> friend class ::simple_list; + + // construction/destruction + code_handle(drcuml_state &drcuml, const char *name); + + public: + // getters + code_handle *next() const { return m_next; } + drccodeptr codeptr() const { return *m_code; } + drccodeptr *codeptr_addr() { return m_code; } + const char *string() const { return m_string; } + + // setters + void set_codeptr(drccodeptr code); + + private: + // internal state + drccodeptr * m_code; // pointer in the cache to the associated code + astring m_string; // pointer to string attached to handle + code_handle * m_next; // link to next handle in the list + drcuml_state & m_drcuml; // pointer to owning object + }; + + // class describing a local code label + class code_label + { + public: + // construction + code_label(UINT32 label = 0) : m_label(label) { } + + // operators + operator UINT32 &() { return m_label; } + bool operator==(const code_label &rhs) const { return (m_label == rhs.m_label); } + bool operator!=(const code_label &rhs) const { return (m_label != rhs.m_label); } + + // getters + UINT32 label() const { return m_label; } + + private: + UINT32 m_label; + }; + + // a parameter for a UML instructon is encoded like this + class parameter + { + public: + // opcode parameter types + enum parameter_type + { + PTYPE_NONE = 0, // invalid + PTYPE_IMMEDIATE, // immediate; value = sign-extended to 64 bits + PTYPE_INT_REGISTER, // integer register; value = REG_I0 - REG_I_END + PTYPE_FLOAT_REGISTER, // floating point register; value = REG_F0 - REG_F_END + PTYPE_VECTOR_REGISTER, // vector register; value = REG_V0 - REG_V_END + PTYPE_MAPVAR, // map variable; value = MAPVAR_M0 - MAPVAR_END + PTYPE_MEMORY, // memory; value = pointer to memory + PTYPE_SIZE, // size; value = operand_size + PTYPE_SIZE_SCALE, // scale + size; value = memory_scale * 16 + operand_size + PTYPE_SIZE_SPACE, // space + size; value = memory_space * 16 + operand_size + PTYPE_CODE_HANDLE, // code handle; value = pointer to handle + PTYPE_CODE_LABEL, // code label; value = label index + PTYPE_C_FUNCTION, // C function; value = pointer to C code + PTYPE_ROUNDING, // floating point rounding mode; value = float_rounding_mode + PTYPE_STRING, // string parameter; value = pointer to string + PTYPE_MAX + }; + + // represents the value of an opcode parameter + typedef UINT64 parameter_value; + + // construction + parameter() : m_type(PTYPE_NONE), m_value(0) { } + parameter(const parameter ¶m) : m_type(param.m_type), m_value(param.m_value) { } + parameter(UINT64 val) : m_type(PTYPE_IMMEDIATE), m_value(val) { } + parameter(operand_size size, memory_scale scale) : m_type(PTYPE_SIZE_SCALE), m_value((scale << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(scale >= SCALE_x1 && scale <= SCALE_x8); } + parameter(operand_size size, memory_space space) : m_type(PTYPE_SIZE_SPACE), m_value((space << 4) | size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); assert(space >= SPACE_PROGRAM && space <= SPACE_IO); } + parameter(code_handle &handle) : m_type(PTYPE_CODE_HANDLE), m_value(reinterpret_cast<parameter_value>(&handle)) { } + parameter(code_label &label) : m_type(PTYPE_CODE_LABEL), m_value(label) { } + + // creators for types that don't safely default + static inline parameter make_ireg(int regnum) { assert(regnum >= REG_I0 && regnum < REG_I_END); return parameter(PTYPE_INT_REGISTER, regnum); } + static inline parameter make_freg(int regnum) { assert(regnum >= REG_F0 && regnum < REG_F_END); return parameter(PTYPE_FLOAT_REGISTER, regnum); } + static inline parameter make_vreg(int regnum) { assert(regnum >= REG_V0 && regnum < REG_V_END); return parameter(PTYPE_VECTOR_REGISTER, regnum); } + static inline parameter make_mapvar(int mvnum) { assert(mvnum >= MAPVAR_M0 && mvnum < MAPVAR_END); return parameter(PTYPE_MAPVAR, mvnum); } + static inline parameter make_memory(void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(base)); } + static inline parameter make_memory(const void *base) { return parameter(PTYPE_MEMORY, reinterpret_cast<parameter_value>(const_cast<void *>(base))); } + static inline parameter make_size(operand_size size) { assert(size >= SIZE_BYTE && size <= SIZE_DQWORD); return parameter(PTYPE_SIZE, size); } + static inline parameter make_string(const char *string) { return parameter(PTYPE_STRING, reinterpret_cast<parameter_value>(const_cast<char *>(string))); } + static inline parameter make_cfunc(c_function func) { return parameter(PTYPE_C_FUNCTION, reinterpret_cast<parameter_value>(func)); } + static inline parameter make_rounding(float_rounding_mode mode) { assert(mode >= ROUND_TRUNC && mode <= ROUND_DEFAULT); return parameter(PTYPE_ROUNDING, mode); } + + // operators + bool operator==(const parameter &rhs) const { return (m_type == rhs.m_type && m_value == rhs.m_value); } + bool operator!=(const parameter &rhs) const { return (m_type != rhs.m_type || m_value != rhs.m_value); } + + // getters + parameter_type type() const { return m_type; } + UINT64 immediate() const { assert(m_type == PTYPE_IMMEDIATE); return m_value; } + int ireg() const { assert(m_type == PTYPE_INT_REGISTER); assert(m_value >= REG_I0 && m_value < REG_I_END); return m_value; } + int freg() const { assert(m_type == PTYPE_FLOAT_REGISTER); assert(m_value >= REG_F0 && m_value < REG_F_END); return m_value; } + int vreg() const { assert(m_type == PTYPE_VECTOR_REGISTER); assert(m_value >= REG_V0 && m_value < REG_V_END); return m_value; } + int mapvar() const { assert(m_type == PTYPE_MAPVAR); assert(m_value >= MAPVAR_M0 && m_value < MAPVAR_END); return m_value; } + void *memory() const { assert(m_type == PTYPE_MEMORY); return reinterpret_cast<void *>(m_value); } + operand_size size() const { assert(m_type == PTYPE_SIZE || m_type == PTYPE_SIZE_SCALE || m_type == PTYPE_SIZE_SPACE); return operand_size(m_value & 15); } + memory_scale scale() const { assert(m_type == PTYPE_SIZE_SCALE); return memory_scale(m_value >> 4); } + memory_space space() const { assert(m_type == PTYPE_SIZE_SPACE); return memory_space(m_value >> 4); } + code_handle &handle() const { assert(m_type == PTYPE_CODE_HANDLE); return *reinterpret_cast<code_handle *>(m_value); } + code_label label() const { assert(m_type == PTYPE_CODE_LABEL); return code_label(m_value); } + c_function cfunc() const { assert(m_type == PTYPE_C_FUNCTION); return reinterpret_cast<c_function>(m_value); } + float_rounding_mode rounding() const { assert(m_type == PTYPE_ROUNDING); return float_rounding_mode(m_value); } + const char *string() const { assert(m_type == PTYPE_STRING); return reinterpret_cast<const char *>(m_value); } + + // type queries + bool is_immediate() const { return (m_type == PTYPE_IMMEDIATE); } + bool is_int_register() const { return (m_type == PTYPE_INT_REGISTER); } + bool is_float_register() const { return (m_type == PTYPE_FLOAT_REGISTER); } + bool is_vector_register() const { return (m_type == PTYPE_VECTOR_REGISTER); } + bool is_mapvar() const { return (m_type == PTYPE_MAPVAR); } + bool is_memory() const { return (m_type == PTYPE_MEMORY); } + bool is_size() const { return (m_type == PTYPE_SIZE); } + bool is_size_scale() const { return (m_type == PTYPE_SIZE_SCALE); } + bool is_size_space() const { return (m_type == PTYPE_SIZE_SPACE); } + bool is_code_handle() const { return (m_type == PTYPE_CODE_HANDLE); } + bool is_code_label() const { return (m_type == PTYPE_CODE_LABEL); } + bool is_c_function() const { return (m_type == PTYPE_C_FUNCTION); } + bool is_rounding() const { return (m_type == PTYPE_ROUNDING); } + bool is_string() const { return (m_type == PTYPE_STRING); } + + // other queries + bool is_immediate_value(UINT64 value) const { return (m_type == PTYPE_IMMEDIATE && m_value == value); } + + private: + // private constructor + parameter(parameter_type type, parameter_value value) : m_type(type), m_value(value) { } + + // internals + parameter_type m_type; // parameter type + parameter_value m_value; // parameter value + }; + + // structure describing rules for opcode encoding + struct opcode_info + { + struct parameter_info + { + UINT8 output; // input or output? + UINT8 size; // size of the parameter + UINT16 typemask; // types allowed + }; + + opcode_t opcode; // the opcode itself + const char * mnemonic; // mnemonic string + UINT8 sizes; // allowed sizes + bool condition; // conditions allowed? + UINT8 inflags; // input flags + UINT8 outflags; // output flags + UINT8 modflags; // modified flags + parameter_info param[4]; // information about parameters + }; + + // a single UML instructon is encoded like this + class instruction + { + public: + // construction/destruction + instruction(); + + // getters + opcode_t opcode() const { return m_opcode; } + condition_t condition() const { return m_condition; } + UINT8 flags() const { return m_flags; } + UINT8 size() const { return m_size; } + UINT8 numparams() const { return m_numparams; } + const parameter ¶m(int index) const { assert(index < m_numparams); return m_param[index]; } + + // setters + void set_flags(UINT8 flags) { m_flags = flags; } + void set_mapvar(int paramnum, UINT32 value) { assert(paramnum < m_numparams); assert(m_param[paramnum].is_mapvar()); m_param[paramnum] = value; } + + // misc + const char *disasm(astring &string, drcuml_state *drcuml = NULL) const; + UINT8 input_flags() const; + UINT8 output_flags() const; + UINT8 modified_flags() const; + void simplify(); + + // compile-time opcodes + void handle(code_handle &hand) { configure(OP_HANDLE, 4, hand); } + void hash(UINT32 mode, UINT32 pc) { configure(OP_HASH, 4, mode, pc); } + void label(code_label lab) { configure(OP_LABEL, 4, lab); } + void comment(const char *string) { configure(OP_COMMENT, 4, parameter::make_string(string)); } + void mapvar(parameter mapvar, UINT32 value) { assert(mapvar.is_mapvar()); configure(OP_MAPVAR, 4, mapvar, value); } + + // control flow operations + void nop() { configure(OP_NOP, 4); } + void debug(UINT32 pc) { configure(OP_DEBUG, 4, pc); } + void exit(parameter param) { configure(OP_EXIT, 4, param); } + void exit(condition_t cond, parameter param) { configure(OP_EXIT, 4, param, cond); } + void hashjmp(parameter mode, parameter pc, code_handle &handle) { configure(OP_HASHJMP, 4, mode, pc, handle); } + void jmp(code_label label) { configure(OP_JMP, 4, label); } + void jmp(condition_t cond, code_label label) { configure(OP_JMP, 4, label, cond); } + void exh(code_handle &handle, parameter param) { configure(OP_EXH, 4, handle, param); } + void exh(condition_t cond, code_handle &handle, parameter param) { configure(OP_EXH, 4, handle, param, cond); } + void callh(code_handle &handle) { configure(OP_CALLH, 4, handle); } + void callh(condition_t cond, code_handle &handle) { configure(OP_CALLH, 4, handle, cond); } + void ret() { configure(OP_RET, 4); } + void ret(condition_t cond) { configure(OP_RET, 4, cond); } + void callc(c_function func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr)); } + void callc(condition_t cond, c_function func, void *ptr) { configure(OP_CALLC, 4, parameter::make_cfunc(func), parameter::make_memory(ptr), cond); } + void recover(parameter dst, parameter mapvar) { assert(mapvar.is_mapvar()); configure(OP_RECOVER, 4, dst, mapvar); } + + // internal register operations + void setfmod(parameter mode) { configure(OP_SETFMOD, 4, mode); } + void getfmod(parameter dst) { configure(OP_GETFMOD, 4, dst); } + void getexp(parameter dst) { configure(OP_GETEXP, 4, dst); } + void getflgs(parameter dst, UINT32 flags) { configure(OP_GETFLGS, 4, dst, flags); } + void save(drcuml_machine_state *dst) { configure(OP_SAVE, 4, parameter::make_memory(dst)); } + void restore(drcuml_machine_state *src) { configure(OP_RESTORE, 4, parameter::make_memory(src)); } + + // 32-bit integer operations + void load(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void loads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 4, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void store(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 4, parameter::make_memory(base), index, src1, parameter(size, scale)); } + void read(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 4, dst, src1, parameter(size, space)); } + void readm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 4, dst, src1, mask, parameter(size, space)); } + void write(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_WRITE, 4, dst, src1, parameter(size, space)); } + void writem(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_WRITEM, 4, dst, src1, mask, parameter(size, space)); } + void carry(parameter src, parameter bitnum) { configure(OP_CARRY, 4, src, bitnum); } + void set(condition_t cond, parameter dst) { configure(OP_SET, 4, dst, cond); } + void mov(parameter dst, parameter src1) { configure(OP_MOV, 4, dst, src1); } + void mov(condition_t cond, parameter dst, parameter src1) { configure(OP_MOV, 4, dst, src1, cond); } + void sext(parameter dst, parameter src1, operand_size size) { configure(OP_SEXT, 4, dst, src1, parameter::make_size(size)); } + void roland(parameter dst, parameter src, parameter shift, parameter mask) { configure(OP_ROLAND, 4, dst, src, shift, mask); } + void rolins(parameter dst, parameter src, parameter shift, parameter mask) { configure(OP_ROLINS, 4, dst, src, shift, mask); } + void add(parameter dst, parameter src1, parameter src2) { configure(OP_ADD, 4, dst, src1, src2); } + void addc(parameter dst, parameter src1, parameter src2) { configure(OP_ADDC, 4, dst, src1, src2); } + void sub(parameter dst, parameter src1, parameter src2) { configure(OP_SUB, 4, dst, src1, src2); } + void subb(parameter dst, parameter src1, parameter src2) { configure(OP_SUBB, 4, dst, src1, src2); } + void cmp(parameter src1, parameter src2) { configure(OP_CMP, 4, src1, src2); } + void mulu(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_MULU, 4, dst, edst, src1, src2); } + void muls(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_MULS, 4, dst, edst, src1, src2); } + void divu(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_DIVU, 4, dst, edst, src1, src2); } + void divs(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_DIVS, 4, dst, edst, src1, src2); } + void _and(parameter dst, parameter src1, parameter src2) { configure(OP_AND, 4, dst, src1, src2); } + void test(parameter src1, parameter src2) { configure(OP_TEST, 4, src1, src2); } + void _or(parameter dst, parameter src1, parameter src2) { configure(OP_OR, 4, dst, src1, src2); } + void _xor(parameter dst, parameter src1, parameter src2) { configure(OP_XOR, 4, dst, src1, src2); } + void lzcnt(parameter dst, parameter src) { configure(OP_LZCNT, 4, dst, src); } + void bswap(parameter dst, parameter src) { configure(OP_BSWAP, 4, dst, src); } + void shl(parameter dst, parameter src, parameter count) { configure(OP_SHL, 4, dst, src, count); } + void shr(parameter dst, parameter src, parameter count) { configure(OP_SHR, 4, dst, src, count); } + void sar(parameter dst, parameter src, parameter count) { configure(OP_SAR, 4, dst, src, count); } + void rol(parameter dst, parameter src, parameter count) { configure(OP_ROL, 4, dst, src, count); } + void rolc(parameter dst, parameter src, parameter count) { configure(OP_ROLC, 4, dst, src, count); } + void ror(parameter dst, parameter src, parameter count) { configure(OP_ROR, 4, dst, src, count); } + void rorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 4, dst, src, count); } + + // 64-bit integer operations + void dload(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOAD, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void dloads(parameter dst, const void *base, parameter index, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_LOADS, 8, dst, parameter::make_memory(base), index, parameter(size, scale)); } + void dstore(void *base, parameter index, parameter src1, operand_size size, memory_scale scale = SCALE_DEFAULT) { configure(OP_STORE, 8, parameter::make_memory(base), index, src1, parameter(size, scale)); } + void dread(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READ, 8, dst, src1, parameter(size, space)); } + void dreadm(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_READM, 8, dst, src1, mask, parameter(size, space)); } + void dwrite(parameter dst, parameter src1, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_WRITE, 8, dst, src1, parameter(size, space)); } + void dwritem(parameter dst, parameter src1, parameter mask, operand_size size, memory_space space = SPACE_PROGRAM) { configure(OP_WRITEM, 8, dst, src1, mask, parameter(size, space)); } + void dcarry(parameter src, parameter bitnum) { configure(OP_CARRY, 8, src, bitnum); } + void dset(condition_t cond, parameter dst) { configure(OP_SET, 8, dst, cond); } + void dmov(parameter dst, parameter src1) { configure(OP_MOV, 8, dst, src1); } + void dmov(condition_t cond, parameter dst, parameter src1) { configure(OP_MOV, 8, dst, src1, cond); } + void dsext(parameter dst, parameter src1, operand_size size) { configure(OP_SEXT, 8, dst, src1, parameter::make_size(size)); } + void droland(parameter dst, parameter src, parameter shift, parameter mask) { configure(OP_ROLAND, 8, dst, src, shift, mask); } + void drolins(parameter dst, parameter src, parameter shift, parameter mask) { configure(OP_ROLINS, 8, dst, src, shift, mask); } + void dadd(parameter dst, parameter src1, parameter src2) { configure(OP_ADD, 8, dst, src1, src2); } + void daddc(parameter dst, parameter src1, parameter src2) { configure(OP_ADDC, 8, dst, src1, src2); } + void dsub(parameter dst, parameter src1, parameter src2) { configure(OP_SUB, 8, dst, src1, src2); } + void dsubb(parameter dst, parameter src1, parameter src2) { configure(OP_SUBB, 8, dst, src1, src2); } + void dcmp(parameter src1, parameter src2) { configure(OP_CMP, 8, src1, src2); } + void dmulu(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_MULU, 8, dst, edst, src1, src2); } + void dmuls(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_MULS, 8, dst, edst, src1, src2); } + void ddivu(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_DIVU, 8, dst, edst, src1, src2); } + void ddivs(parameter dst, parameter edst, parameter src1, parameter src2) { configure(OP_DIVS, 8, dst, edst, src1, src2); } + void dand(parameter dst, parameter src1, parameter src2) { configure(OP_AND, 8, dst, src1, src2); } + void dtest(parameter src1, parameter src2) { configure(OP_TEST, 8, src1, src2); } + void dor(parameter dst, parameter src1, parameter src2) { configure(OP_OR, 8, dst, src1, src2); } + void dxor(parameter dst, parameter src1, parameter src2) { configure(OP_XOR, 8, dst, src1, src2); } + void dlzcnt(parameter dst, parameter src) { configure(OP_LZCNT, 8, dst, src); } + void dbswap(parameter dst, parameter src) { configure(OP_BSWAP, 8, dst, src); } + void dshl(parameter dst, parameter src, parameter count) { configure(OP_SHL, 8, dst, src, count); } + void dshr(parameter dst, parameter src, parameter count) { configure(OP_SHR, 8, dst, src, count); } + void dsar(parameter dst, parameter src, parameter count) { configure(OP_SAR, 8, dst, src, count); } + void drol(parameter dst, parameter src, parameter count) { configure(OP_ROL, 8, dst, src, count); } + void drolc(parameter dst, parameter src, parameter count) { configure(OP_ROLC, 8, dst, src, count); } + void dror(parameter dst, parameter src, parameter count) { configure(OP_ROR, 8, dst, src, count); } + void drorc(parameter dst, parameter src, parameter count) { configure(OP_RORC, 8, dst, src, count); } + + // 32-bit floating point operations + void fsload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 4, dst, parameter::make_memory(base), index); } + void fsstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 4, parameter::make_memory(base), index, src1); } + void fsread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 4, dst, src1, parameter(SIZE_SHORT, space)); } + void fswrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 4, dst, src1, parameter(SIZE_SHORT, space)); } + void fsmov(parameter dst, parameter src1) { configure(OP_FMOV, 4, dst, src1); } + void fsmov(condition_t cond, parameter dst, parameter src1) { configure(OP_FMOV, 4, dst, src1, cond); } + void fstoint(parameter dst, parameter src1, operand_size size, float_rounding_mode round) { configure(OP_FTOINT, 4, dst, src1, parameter::make_size(size), parameter::make_rounding(round)); } + void fsfrint(parameter dst, parameter src1, operand_size size) { configure(OP_FFRINT, 4, dst, src1, parameter::make_size(size)); } + void fsfrflt(parameter dst, parameter src1, operand_size size) { configure(OP_FFRFLT, 4, dst, src1, parameter::make_size(size)); } + void fsadd(parameter dst, parameter src1, parameter src2) { configure(OP_FADD, 4, dst, src1, src2); } + void fssub(parameter dst, parameter src1, parameter src2) { configure(OP_FSUB, 4, dst, src1, src2); } + void fscmp(parameter src1, parameter src2) { configure(OP_FCMP, 4, src1, src2); } + void fsmul(parameter dst, parameter src1, parameter src2) { configure(OP_FMUL, 4, dst, src1, src2); } + void fsdiv(parameter dst, parameter src1, parameter src2) { configure(OP_FDIV, 4, dst, src1, src2); } + void fsneg(parameter dst, parameter src1) { configure(OP_FNEG, 4, dst, src1); } + void fsabs(parameter dst, parameter src1) { configure(OP_FABS, 4, dst, src1); } + void fssqrt(parameter dst, parameter src1) { configure(OP_FSQRT, 4, dst, src1); } + void fsrecip(parameter dst, parameter src1) { configure(OP_FRECIP, 4, dst, src1); } + void fsrsqrt(parameter dst, parameter src1) { configure(OP_FRSQRT, 4, dst, src1); } + + // 64-bit floating point operations + void fdload(parameter dst, const void *base, parameter index) { configure(OP_FLOAD, 8, dst, parameter::make_memory(base), index); } + void fdstore(void *base, parameter index, parameter src1) { configure(OP_FSTORE, 8, parameter::make_memory(base), index, src1); } + void fdread(parameter dst, parameter src1, memory_space space) { configure(OP_FREAD, 8, dst, src1, parameter(SIZE_DOUBLE, space)); } + void fdwrite(parameter dst, parameter src1, memory_space space) { configure(OP_FWRITE, 8, dst, src1, parameter(SIZE_DOUBLE, space)); } + void fdmov(parameter dst, parameter src1) { configure(OP_FMOV, 8, dst, src1); } + void fdmov(condition_t cond, parameter dst, parameter src1) { configure(OP_FMOV, 8, dst, src1, cond); } + void fdtoint(parameter dst, parameter src1, operand_size size, float_rounding_mode round) { configure(OP_FTOINT, 8, dst, src1, parameter::make_size(size), parameter::make_rounding(round)); } + void fdfrint(parameter dst, parameter src1, operand_size size) { configure(OP_FFRINT, 8, dst, src1, parameter::make_size(size)); } + void fdfrflt(parameter dst, parameter src1, operand_size size) { configure(OP_FFRFLT, 8, dst, src1, parameter::make_size(size)); } + void fdrnds(parameter dst, parameter src1) { configure(OP_FRNDS, 8, dst, src1); } + void fdadd(parameter dst, parameter src1, parameter src2) { configure(OP_FADD, 8, dst, src1, src2); } + void fdsub(parameter dst, parameter src1, parameter src2) { configure(OP_FSUB, 8, dst, src1, src2); } + void fdcmp(parameter src1, parameter src2) { configure(OP_FCMP, 8, src1, src2); } + void fdmul(parameter dst, parameter src1, parameter src2) { configure(OP_FMUL, 8, dst, src1, src2); } + void fddiv(parameter dst, parameter src1, parameter src2) { configure(OP_FDIV, 8, dst, src1, src2); } + void fdneg(parameter dst, parameter src1) { configure(OP_FNEG, 8, dst, src1); } + void fdabs(parameter dst, parameter src1) { configure(OP_FABS, 8, dst, src1); } + void fdsqrt(parameter dst, parameter src1) { configure(OP_FSQRT, 8, dst, src1); } + void fdrecip(parameter dst, parameter src1) { configure(OP_FRECIP, 8, dst, src1); } + void fdrsqrt(parameter dst, parameter src1) { configure(OP_FRSQRT, 8, dst, src1); } + + // constants + static const int MAX_PARAMS = 4; + + private: + // internal configuration + void configure(opcode_t op, UINT8 size, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, UINT8 size, parameter p0, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, UINT8 size, parameter p0, parameter p1, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, UINT8 size, parameter p0, parameter p1, parameter p2, condition_t cond = COND_ALWAYS); + void configure(opcode_t op, UINT8 size, parameter p0, parameter p1, parameter p2, parameter p3, condition_t cond = COND_ALWAYS); + + // opcode validation and simplification + void validate(); + void convert_to_mov_immediate(UINT64 immediate) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = immediate; } + void convert_to_mov_param(int pnum) { m_opcode = OP_MOV; m_numparams = 2; m_param[1] = m_param[pnum]; } + + // internal state + opcode_t m_opcode; // opcode + condition_t m_condition; // condition + UINT8 m_flags; // flags + UINT8 m_size; // operation size + UINT8 m_numparams; // number of parameters + parameter m_param[MAX_PARAMS];// up to 4 parameters + + static const opcode_info s_opcode_info_table[OP_MAX]; + }; + + // structure describing rules for parameter encoding + struct parameter_info + { + UINT8 output; // input or output? + UINT8 size; // size of the parameter + UINT16 typemask; // types allowed + }; + + // global inline functions to specify a register parameter by index + inline parameter ireg(int n) { return parameter::make_ireg(REG_I0 + n); } + inline parameter freg(int n) { return parameter::make_freg(REG_F0 + n); } + inline parameter vreg(int n) { return parameter::make_vreg(REG_V0 + n); } + inline parameter mapvar(int n) { return parameter::make_mapvar(MAPVAR_M0 + n); } + + // global register objects for direct access + const parameter I0(parameter::make_ireg(REG_I0 + 0)); + const parameter I1(parameter::make_ireg(REG_I0 + 1)); + const parameter I2(parameter::make_ireg(REG_I0 + 2)); + const parameter I3(parameter::make_ireg(REG_I0 + 3)); + const parameter I4(parameter::make_ireg(REG_I0 + 4)); + const parameter I5(parameter::make_ireg(REG_I0 + 5)); + const parameter I6(parameter::make_ireg(REG_I0 + 6)); + const parameter I7(parameter::make_ireg(REG_I0 + 7)); + const parameter I8(parameter::make_ireg(REG_I0 + 8)); + const parameter I9(parameter::make_ireg(REG_I0 + 9)); + + const parameter F0(parameter::make_freg(REG_F0 + 0)); + const parameter F1(parameter::make_freg(REG_F0 + 1)); + const parameter F2(parameter::make_freg(REG_F0 + 2)); + const parameter F3(parameter::make_freg(REG_F0 + 3)); + const parameter F4(parameter::make_freg(REG_F0 + 4)); + const parameter F5(parameter::make_freg(REG_F0 + 5)); + const parameter F6(parameter::make_freg(REG_F0 + 6)); + const parameter F7(parameter::make_freg(REG_F0 + 7)); + const parameter F8(parameter::make_freg(REG_F0 + 8)); + const parameter F9(parameter::make_freg(REG_F0 + 9)); + + const parameter V0(parameter::make_vreg(REG_V0 + 0)); + const parameter V1(parameter::make_vreg(REG_V0 + 1)); + const parameter V2(parameter::make_vreg(REG_V0 + 2)); + const parameter V3(parameter::make_vreg(REG_V0 + 3)); + const parameter V4(parameter::make_vreg(REG_V0 + 4)); + const parameter V5(parameter::make_vreg(REG_V0 + 5)); + const parameter V6(parameter::make_vreg(REG_V0 + 6)); + const parameter V7(parameter::make_vreg(REG_V0 + 7)); + const parameter V8(parameter::make_vreg(REG_V0 + 8)); + const parameter V9(parameter::make_vreg(REG_V0 + 9)); + + const parameter M0(parameter::make_mapvar(MAPVAR_M0 + 0)); + const parameter M1(parameter::make_mapvar(MAPVAR_M0 + 1)); + const parameter M2(parameter::make_mapvar(MAPVAR_M0 + 2)); + const parameter M3(parameter::make_mapvar(MAPVAR_M0 + 3)); + const parameter M4(parameter::make_mapvar(MAPVAR_M0 + 4)); + const parameter M5(parameter::make_mapvar(MAPVAR_M0 + 5)); + const parameter M6(parameter::make_mapvar(MAPVAR_M0 + 6)); + const parameter M7(parameter::make_mapvar(MAPVAR_M0 + 7)); + const parameter M8(parameter::make_mapvar(MAPVAR_M0 + 8)); + const parameter M9(parameter::make_mapvar(MAPVAR_M0 + 9)); +}; + + +#endif /* __UML_H__ */ diff --git a/src/emu/cpu/x86emit.h b/src/emu/cpu/x86emit.h index eca16538e1d..49dfe8256d4 100644 --- a/src/emu/cpu/x86emit.h +++ b/src/emu/cpu/x86emit.h @@ -4,9 +4,36 @@ Generic x86/x64 code emitters. +**************************************************************************** + Copyright Aaron Giles - Released for general use under the MAME license - Visit http://mamedev.org for licensing and usage restrictions. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. **************************************************************************** @@ -18,1154 +45,1182 @@ ***************************************************************************/ -#pragma once + +//************************************************************************** +// SHARED DEFINITIONS +//************************************************************************** #ifndef __X86EMIT_H__ #define __X86EMIT_H__ +// use x86code * to reference generated code +typedef UINT8 x86code; -/*************************************************************************** - CONSTANTS -***************************************************************************/ +// this structure tracks information about a link +struct emit_link +{ + x86code * target; + UINT8 size; +}; -/* opcode size flag; low 4 bits must match REX low 4 bits, hence the odd numbers here */ -#define OP_16BIT 0x10 -#define OP_32BIT 0x00 -#define OP_64BIT 0x08 +// structure for describing memory references +class x86_memref +{ +public: + x86_memref(UINT8 basereg, UINT8 indreg, UINT8 scale, INT32 disp) + : m_base(basereg), + m_index(indreg), + m_scale(scale), + m_disp(disp) { } + + x86_memref operator+(INT32 offset) { return x86_memref(m_base, m_index, m_scale, m_disp + offset); } + + UINT8 m_base; + UINT8 m_index; + UINT8 m_scale; + INT32 m_disp; +}; -/* 16 registers on x64, only 8 on x86 */ -#ifdef PTR64 -#define REG_MAX 16 -#else -#define REG_MAX 8 #endif -/* invalid register index for "none" */ -#define REG_NONE REG_MAX - -/* 8-bit registers -- note that we assume a flat model for 64-bit */ -#define REG_AL 0 -#define REG_CL 1 -#define REG_DL 2 -#define REG_BL 3 -#ifndef PTR64 -#define REG_AH 4 -#define REG_CH 5 -#define REG_DH 6 -#define REG_BH 7 -#else -#define REG_SPL 4 -#define REG_BPL 5 -#define REG_SIL 6 -#define REG_DIL 7 -#define REG_R8L 8 -#define REG_R9L 9 -#define REG_R10L 10 -#define REG_R11L 11 -#define REG_R12L 12 -#define REG_R13L 13 -#define REG_R14L 14 -#define REG_R15L 15 -#endif -/* 16-bit registers */ -#define REG_AX 0 -#define REG_CX 1 -#define REG_DX 2 -#define REG_BX 3 -#define REG_SP 4 -#define REG_BP 5 -#define REG_SI 6 -#define REG_DI 7 -#ifdef PTR64 -#define REG_R8W 8 -#define REG_R9W 9 -#define REG_R10W 10 -#define REG_R11W 11 -#define REG_R12W 12 -#define REG_R13W 13 -#define REG_R14W 14 -#define REG_R15W 15 -#endif -/* 32-bit registers */ -#define REG_EAX 0 -#define REG_ECX 1 -#define REG_EDX 2 -#define REG_EBX 3 -#define REG_ESP 4 -#define REG_EBP 5 -#define REG_ESI 6 -#define REG_EDI 7 -#ifdef PTR64 -#define REG_R8D 8 -#define REG_R9D 9 -#define REG_R10D 10 -#define REG_R11D 11 -#define REG_R12D 12 -#define REG_R13D 13 -#define REG_R14D 14 -#define REG_R15D 15 -#endif +//************************************************************************** +// 32-BIT and 64-BIT SPECIFIC DEFINITIONS +//************************************************************************** -/* 64-bit registers */ -#ifdef PTR64 -#define REG_RAX 0 -#define REG_RCX 1 -#define REG_RDX 2 -#define REG_RBX 3 -#define REG_RSP 4 -#define REG_RBP 5 -#define REG_RSI 6 -#define REG_RDI 7 -#define REG_R8 8 -#define REG_R9 9 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_R13 13 -#define REG_R14 14 -#define REG_R15 15 -#endif +#ifdef X86EMIT_SIZE -/* 64-bit MMX registers */ -#define REG_MM0 0 -#define REG_MM1 1 -#define REG_MM2 2 -#define REG_MM3 3 -#define REG_MM4 4 -#define REG_MM5 5 -#define REG_MM6 6 -#define REG_MM7 7 -#ifdef PTR64 -#define REG_MM8 8 -#define REG_MM9 9 -#define REG_MM10 10 -#define REG_MM11 11 -#define REG_MM12 12 -#define REG_MM13 13 -#define REG_MM14 14 -#define REG_MM15 15 +#if (X86EMIT_SIZE != 32 && X86EMIT_SIZE != 64) +#error Must specify X86EMIT_SIZE as either 32 or 64! #endif -/* 128-bit XMM registers */ -#define REG_XMM0 0 -#define REG_XMM1 1 -#define REG_XMM2 2 -#define REG_XMM3 3 -#define REG_XMM4 4 -#define REG_XMM5 5 -#define REG_XMM6 6 -#define REG_XMM7 7 -#ifdef PTR64 -#define REG_XMM8 8 -#define REG_XMM9 9 -#define REG_XMM10 10 -#define REG_XMM11 11 -#define REG_XMM12 12 -#define REG_XMM13 13 -#define REG_XMM14 14 -#define REG_XMM15 15 +// put emitters into their own namespace so they don't clash +#if (X86EMIT_SIZE == 32) +namespace x86emit +#else +namespace x64emit #endif +{ -/* conditions */ -#define COND_A 7 -#define COND_AE 3 -#define COND_B 2 -#define COND_BE 6 -#define COND_C 2 -#define COND_E 4 -#define COND_Z 4 -#define COND_G 15 -#define COND_GE 13 -#define COND_L 12 -#define COND_LE 14 -#define COND_NA 6 -#define COND_NAE 2 -#define COND_NB 3 -#define COND_NBE 7 -#define COND_NC 3 -#define COND_NE 5 -#define COND_NG 14 -#define COND_NGE 12 -#define COND_NL 13 -#define COND_NLE 15 -#define COND_NO 1 -#define COND_NP 11 -#define COND_NS 9 -#define COND_NZ 5 -#define COND_O 0 -#define COND_P 10 -#define COND_PE 10 -#define COND_PO 11 -#define COND_S 8 -#define COND_Z 4 - -/* floating point rounding modes */ -#define FPRND_NEAR 0 -#define FPRND_DOWN 1 -#define FPRND_UP 2 -#define FPRND_CHOP 3 - - - -/*************************************************************************** - OPCODE DEFINITIONS -***************************************************************************/ - -/* opcode flags (in upper 8 bits of opcode) */ -#define OPFLAG_8BITREG (1 << 24) -#define OPFLAG_8BITRM (1 << 25) - -/* single byte opcodes */ -#define OP_ADD_Eb_Gb (0x00 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_ADD_Ev_Gv 0x01 -#define OP_ADD_Gb_Eb (0x02 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_ADD_Gv_Ev 0x03 -#define OP_ADD_AL_Ib 0x04 -#define OP_ADD_rAX_Iz 0x05 -#define OP_PUSH_ES 0x06 -#define OP_POP_ES 0x07 -#define OP_OR_Eb_Gb (0x08 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_OR_Ev_Gv 0x09 -#define OP_OR_Gb_Eb (0x0a | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_OR_Gv_Ev 0x0b -#define OP_OR_AL_Ib 0x0c -#define OP_OR_eAX_Iv 0x0d -#define OP_PUSH_CS 0x0e -#define OP_EXTENDED 0x0f - -#define OP_ADC_Eb_Gb (0x10 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_ADC_Ev_Gv 0x11 -#define OP_ADC_Gb_Eb (0x12 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_ADC_Gv_Ev 0x13 -#define OP_ADC_AL_Ib 0x14 -#define OP_ADC_rAX_Iz 0x15 -#define OP_PUSH_SS 0x16 -#define OP_POP_SS 0x17 -#define OP_SBB_Eb_Gb (0x18 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_SBB_Ev_Gv 0x19 -#define OP_SBB_Gb_Eb (0x1a | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_SBB_Gv_Ev 0x1b -#define OP_SBB_AL_Ib 0x1c -#define OP_SBB_eAX_Iv 0x1d -#define OP_PUSH_DS 0x1e -#define OP_POP_DS 0x1f - -#define OP_AND_Eb_Gb (0x20 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_AND_Ev_Gv 0x21 -#define OP_AND_Gb_Eb (0x22 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_AND_Gv_Ev 0x23 -#define OP_AND_AL_Ib 0x24 -#define OP_AND_rAX_Iz 0x25 -#define PREFIX_ES 0x26 -#define OP_DAA 0x27 -#define OP_SUB_Eb_Gb (0x28 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_SUB_Ev_Gv 0x29 -#define OP_SUB_Gb_Eb (0x2a | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_SUB_Gv_Ev 0x2b -#define OP_SUB_AL_Ib 0x2c -#define OP_SUB_eAX_Iv 0x2d -#define PREFIX_CS 0x2e -#define OP_DAS 0x2f - -#define OP_XOR_Eb_Gb (0x30 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_XOR_Ev_Gv 0x31 -#define OP_XOR_Gb_Eb (0x32 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_XOR_Gv_Ev 0x33 -#define OP_XOR_AL_Ib 0x34 -#define OP_XOR_rAX_Iz 0x35 -#define PREFIX_SS 0x36 -#define OP_AAA 0x37 -#define OP_CMP_Eb_Gb (0x38 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_CMP_Ev_Gv 0x39 -#define OP_CMP_Gb_Eb (0x3a | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_CMP_Gv_Ev 0x3b -#define OP_CMP_AL_Ib 0x3c -#define OP_CMP_eAX_Iv 0x3d -#define PREFIX_DS 0x3e -#define OP_AAS 0x3f - -#define OP_REX 0x40 -#define OP_REX_B 0x41 -#define OP_REX_X 0x42 -#define OP_REX_XB 0x43 -#define OP_REX_R 0x44 -#define OP_REX_RB 0x45 -#define OP_REX_RX 0x46 -#define OP_REX_RXB 0x47 -#define OP_REX_W 0x48 -#define OP_REX_WB 0x49 -#define OP_REX_WX 0x4a -#define OP_REX_WXB 0x4b -#define OP_REX_WR 0x4c -#define OP_REX_WRB 0x4d -#define OP_REX_WRX 0x4e -#define OP_REX_WRXB 0x4f - -#define OP_PUSH_rAX 0x50 -#define OP_PUSH_rCX 0x51 -#define OP_PUSH_rDX 0x52 -#define OP_PUSH_rBX 0x53 -#define OP_PUSH_rSP 0x54 -#define OP_PUSH_rBP 0x55 -#define OP_PUSH_rSI 0x56 -#define OP_PUSH_rDI 0x57 -#define OP_POP_rAX 0x58 -#define OP_POP_rCX 0x59 -#define OP_POP_rDX 0x5a -#define OP_POP_rBX 0x5b -#define OP_POP_rSP 0x5c -#define OP_POP_rBP 0x5d -#define OP_POP_rSI 0x5e -#define OP_POP_rDI 0x5f - -#define OP_PUSHA 0x60 -#define OP_POPA 0x61 -#define OP_BOUND_Gv_Ma 0x62 -#define OP_ARPL_Ew_Gw 0x63 -#define OP_MOVSXD_Gv_Ev 0x63 -#define PREFIX_FS 0x64 -#define PREFIX_GS 0x65 -#define PREFIX_OPSIZE 0x66 -#define PREFIX_ADSIZE 0x67 -#define OP_PUSH_Iz 0x68 -#define OP_IMUL_Gv_Ev_Iz 0x69 -#define OP_PUSH_Ib 0x6a -#define OP_IMUL_Gv_Ev_Ib 0x6b -#define OP_INS_Yb_DX 0x6c -#define OP_INS_Yz_DX 0x6d -#define OP_OUTS_DX_Xb 0x6e -#define OP_OUTS_DX_Xz 0x6f - -#define OP_JCC_O_Jb 0x70 -#define OP_JCC_NO_Jb 0x71 -#define OP_JCC_B_Jb 0x72 -#define OP_JCC_C_Jb 0x72 -#define OP_JCC_NAE_Jb 0x72 -#define OP_JCC_AE_Jb 0x73 -#define OP_JCC_NB_Jb 0x73 -#define OP_JCC_NC_Jb 0x73 -#define OP_JCC_E_Jb 0x74 -#define OP_JCC_Z_Jb 0x74 -#define OP_JCC_NE_Jb 0x75 -#define OP_JCC_NZ_Jb 0x75 -#define OP_JCC_BE_Jb 0x76 -#define OP_JCC_NA_Jb 0x76 -#define OP_JCC_A_Jb 0x77 -#define OP_JCC_NBE_Jb 0x77 -#define OP_JCC_S_Jb 0x78 -#define OP_JCC_NS_Jb 0x79 -#define OP_JCC_P_Jb 0x7a -#define OP_JCC_PE_Jb 0x7a -#define OP_JCC_NP_Jb 0x7b -#define OP_JCC_PO_Jb 0x7b -#define OP_JCC_L_Jb 0x7c -#define OP_JCC_NGE_Jb 0x7c -#define OP_JCC_NL_Jb 0x7d -#define OP_JCC_GE_Jb 0x7d -#define OP_JCC_LE_Jb 0x7e -#define OP_JCC_NG_Jb 0x7e -#define OP_JCC_NLE_Jb 0x7f -#define OP_JCC_G_Jb 0x7f - -#define OP_G1_Eb_Ib (0x80 | OPFLAG_8BITRM) -#define OP_G1_Ev_Iz 0x81 -#define OP_G1_Eb_Ibx (0x82 | OPFLAG_8BITRM) -#define OP_G1_Ev_Ib 0x83 -#define OP_TEST_Eb_Gb (0x84 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_TEST_Ev_Gv 0x85 -#define OP_XCHG_Eb_Gb (0x86 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_XCHG_Ev_Gv 0x87 -#define OP_MOV_Eb_Gb (0x88 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_MOV_Ev_Gv 0x89 -#define OP_MOV_Gb_Eb (0x8a | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_MOV_Gv_Ev 0x8b -#define OP_MOV_Ev_Sw 0x8c -#define OP_LEA_Gv_M 0x8d -#define OP_MOV_Sw_Ew 0x8e -#define OP_G1A_Ev 0x8f - -#define OP_NOP 0x90 -#define OP_PAUSE 0x90 -#define OP_XCHG_rCX 0x91 -#define OP_XCHG_rDX 0x92 -#define OP_XCHG_rBX 0x93 -#define OP_XCHG_rSP 0x94 -#define OP_XCHG_rBP 0x95 -#define OP_XCHG_rSI 0x96 -#define OP_XCHG_rDI 0x97 -#define OP_CBW 0x98 -#define OP_CWDE 0x98 -#define OP_CDQE 0x98 -#define OP_CWD 0x99 -#define OP_CDQ 0x99 -#define OP_CQO 0x99 -#define OP_CALLF_Ap 0x9a -#define OP_FWAIT 0x9b -#define OP_PUSHF_Fv 0x9c -#define OP_POPF_Fv 0x9d -#define OP_SAHF 0x9e -#define OP_LAHF 0x9f - -#define OP_MOV_AL_Ob 0xa0 -#define OP_MOV_rAX_Ov 0xa1 -#define OP_MOV_Ob_AL 0xa2 -#define OP_MOV_Ov_rAX 0xa3 -#define OP_MOVS_Xb_Yb 0xa4 -#define OP_MOVS_Xv_Yv 0xa5 -#define OP_CMPS_Xb_Yb 0xa6 -#define OP_CMPS_Xv_Yv 0xa7 -#define OP_TEST_AL_Ib 0xa8 -#define OP_TEST_rAX_Iz 0xa9 -#define OP_STOS_Yb_AL 0xaa -#define OP_STOS_Yv_rAX 0xab -#define OP_LODS_AL_Xb 0xac -#define OP_LODS_rAX_Xv 0xad -#define OP_SCAS_AL_Yb 0xae -#define OP_SCAC_rAX_Yv 0xaf - -#define OP_MOV_AL_Ib 0xb0 -#define OP_MOV_CL_Ib 0xb1 -#define OP_MOV_DL_Ib 0xb2 -#define OP_MOV_BL_Ib 0xb3 -#define OP_MOV_AH_Ib 0xb4 -#define OP_MOV_CH_Ib 0xb5 -#define OP_MOV_DH_Ib 0xb6 -#define OP_MOV_BH_Ib 0xb7 -#define OP_MOV_rAX_Iv 0xb8 -#define OP_MOV_rCX_Iv 0xb9 -#define OP_MOV_rDX_Iv 0xba -#define OP_MOV_rBX_Iv 0xbb -#define OP_MOV_rSP_Iv 0xbc -#define OP_MOV_rBP_Iv 0xbd -#define OP_MOV_rSI_Iv 0xbe -#define OP_MOV_rDI_Iv 0xbf - -#define OP_G2_Eb_Ib (0xc0 | OPFLAG_8BITRM) -#define OP_G2_Ev_Ib 0xc1 -#define OP_RETN_Iw 0xc2 -#define OP_RETN 0xc3 -#define OP_LES_Gz_Mp 0xc4 -#define OP_LDS_Gz_Mp 0xc5 -#define OP_G11_Eb_Ib (0xc6 | OPFLAG_8BITRM) -#define OP_G11_Ev_Iz 0xc7 -#define OP_ENTER_Iw_Ib 0xc8 -#define OP_LEAVE 0xc9 -#define OP_RETF_Iw 0xca -#define OP_RETF 0xcb -#define OP_INT_3 0xcc -#define OP_INT_Ib 0xcd -#define OP_INTO 0xce -#define OP_IRET 0xcf - -#define OP_G2_Eb_1 (0xd0 | OPFLAG_8BITRM) -#define OP_G2_Ev_1 0xd1 -#define OP_G2_Eb_CL (0xd2 | OPFLAG_8BITRM) -#define OP_G2_Ev_CL 0xd3 -#define OP_AAM 0xd4 -#define OP_AAD 0xd5 -#define OP_XLAT 0xd7 -#define OP_ESC_D8 0xd8 -#define OP_ESC_D9 0xd9 -#define OP_ESC_DA 0xda -#define OP_ESC_DB 0xdb -#define OP_ESC_DC 0xdc -#define OP_ESC_DD 0xdd -#define OP_ESC_DE 0xde -#define OP_ESC_DF 0xdf - -#define OP_LOOPNE_Jb 0xe0 -#define OP_LOOPE_Jb 0xe1 -#define OP_LOOP_Jb 0xe2 -#define OP_JrCXZ_Jb 0xe3 -#define OP_IN_AL_Ib 0xe4 -#define OP_IN_eAX_Ib 0xe5 -#define OP_OUT_Ib_AL 0xe6 -#define OP_OUT_Ib_eAX 0xe7 -#define OP_CALL_Jz 0xe8 -#define OP_JMP_Jz 0xe9 -#define OP_JMPF_AP 0xea -#define OP_JMP_Jb 0xeb -#define OP_IN_AL_DX 0xec -#define OP_IN_eAX_D 0xed -#define OP_OUT_DX_AL 0xee -#define OP_OUT_DX_eAX 0xef - -#define PREFIX_LOCK 0xf0 -#define PREFIX_REPNE 0xf2 -#define PREFIX_REPE 0xf3 -#define OP_HLT 0xf4 -#define OP_CMC 0xf5 -#define OP_G3_Eb (0xf6 | OPFLAG_8BITRM) -#define OP_G3_Ev 0xf7 -#define OP_CLC 0xf8 -#define OP_STC 0xf9 -#define OP_CLI 0xfa -#define OP_STI 0xfb -#define OP_CLD 0xfc -#define OP_STD 0xfd -#define OP_G4 0xfe -#define OP_G5 0xff - - -/* double byte opcodes */ -#define OP_G6 0x0f00 -#define OP_G7 0x0f01 -#define OP_LAR_Gv_Ew 0x0f02 -#define OP_LSL_Gv_Ew 0x0f03 -#define OP_SYSCALL 0x0f05 -#define OP_CLTS 0x0f06 -#define OP_SYSRET 0x0f07 -#define OP_INVD 0x0f08 -#define OP_WBINVD 0x0f09 -#define OP_UD2 0x0f0b -#define OP_NOP0d_Ev 0x0f0d - -#define OP_MOVUPS_Vps_Wps 0x0f10 -#define OP_MOVSS_Vss_Wss 0xf30f10 -#define OP_MOVUPD_Vpd_Wpd 0x660f10 -#define OP_MOVSD_Vsd_Wsd 0xf20f10 -#define OP_MOVUPS_Wps_Vps 0x0f11 -#define OP_MOVSS_Wss_Vss 0xf30f11 -#define OP_MOVUPD_Wpd_Vpd 0x660f11 -#define OP_MOVSD_Wsd_Vsd 0xf20f11 -#define OP_MOVLPS_Vq_Mq 0x0f12 -#define OP_MOVLPD_Vq_Mq 0x660f12 -#define OP_MOVHLPS_Vq_Uq 0x0f12 -#define OP_MOVDDUP_Vq_Wq 0xf20f12 -#define OP_MOVSLDUP_Vq_Wq 0xf30f12 -#define OP_MOVLPS_Mq_Vq 0x0f13 -#define OP_MOVLPD_Mq_Vq 0x660f13 -#define OP_UNPCKLPS_Vps_Wq 0x0f14 -#define OP_UNPCKLPD_Vpd_Wq 0x660f14 -#define OP_UNPCKHPS_Vps_Wq 0x0f15 -#define OP_UNPCKHPD_Vpd_Wq 0x660f15 -#define OP_MOVHPS_Vq_Mq 0x0f16 -#define OP_MOVHPD_Vq_Mq 0x660f16 -#define OP_MOVLHPS_Vq_Uq 0x0f16 -#define OP_MOVSHDUP_Vq_Wq 0xf30f16 -#define OP_MOVHPS_Mq_Vq 0x0f17 -#define OP_MOVHPD_Mq_Vq 0x660f17 -#define OP_PREFETCH_G16 0x0f18 -#define OP_NOP1f_Ev 0x0f1f - -#define OP_MOV_Rd_Cd 0x0f20 -#define OP_MOV_Rd_Dd 0x0f21 -#define OP_MOV_Cd_Rd 0x0f22 -#define OP_MOV_Dd_Rd 0x0f23 -#define OP_MOVAPS_Vps_Wps 0x0f28 -#define OP_MOVAPD_Vpd_Wpd 0x660f28 -#define OP_MOVAPS_Wps_Vps 0x0f29 -#define OP_MOVAPD_Wpd_Vpd 0x660f29 -#define OP_CVTPI2PS_Vps_Qq 0x0f2a -#define OP_CVTSI2SS_Vss_Ed 0xf30f2a -#define OP_CVTPI2PD_Vpd_Qq 0x660f2a -#define OP_CVTSI2SD_Vsd_Ed 0xf20f2a -#define OP_MOVNTPS_Mps_Vps 0x0f2b -#define OP_MOVNTPD_Mpd_Vpd 0x660f2b -#define OP_CVTTPS2PI_Pq_Wq 0x0f2c -#define OP_CVTTSS2SI_Gd_Wss 0xf30f2c -#define OP_CVTTPD2PI_Pq_Wpd 0x660f2c -#define OP_CVTTSD2SI_Gd_Wsd 0xf20f2c -#define OP_CVTPS2PI_Pq_Wq 0x0f2d -#define OP_CVTSS2SI_Gd_Wss 0xf30f2d -#define OP_CVTPD2PI_Pq_Wpd 0x660f2d -#define OP_CVTSD2SI_Gd_Wsd 0xf20f2d -#define OP_UCOMISS_Vss_Wss 0x0f2e -#define OP_UCOMISD_Vsd_Wsd 0x660f2e -#define OP_COMISS_Vss_Wss 0x0f2f -#define OP_COMISD_Vsd_Wsd 0x660f2f - -#define OP_WRMSR 0x0f30 -#define OP_RDTSC 0x0f31 -#define OP_RDMSR 0x0f32 -#define OP_RDPMC 0x0f33 -#define OP_SYSENTER 0x0f34 -#define OP_SYSEXIT 0x0f35 -#define OP_GETSEC 0x0f37 - -#define OP_CMOV_O_Gv_Ev 0x0f40 -#define OP_CMOV_NO_Gv_Ev 0x0f41 -#define OP_CMOV_B_Gv_Ev 0x0f42 -#define OP_CMOV_C_Gv_Ev 0x0f42 -#define OP_CMOV_AE_Gv_Ev 0x0f43 -#define OP_CMOV_NC_Gv_Ev 0x0f43 -#define OP_CMOV_E_Gv_Ev 0x0f44 -#define OP_CMOV_Z_Gv_Ev 0x0f44 -#define OP_CMOV_NE_Gv_Ev 0x0f45 -#define OP_CMOV_NZ_Gv_Ev 0x0f45 -#define OP_CMOV_BE_Gv_Ev 0x0f46 -#define OP_CMOV_A_Gv_Ev 0x0f47 -#define OP_CMOV_S_Gv_Ev 0x0f48 -#define OP_CMOV_NS_Gv_Ev 0x0f49 -#define OP_CMOV_P_Gv_Ev 0x0f4a -#define OP_CMOV_PE_Gv_Ev 0x0f4a -#define OP_CMOV_NP_Gv_Ev 0x0f4b -#define OP_CMOV_PO_Gv_Ev 0x0f4b -#define OP_CMOV_L_Gv_Ev 0x0f4c -#define OP_CMOV_NGE_Gv_Ev 0x0f4c -#define OP_CMOV_NL_Gv_Ev 0x0f4d -#define OP_CMOV_GE_Gv_Ev 0x0f4d -#define OP_CMOV_LE_Gv_Ev 0x0f4e -#define OP_CMOV_NG_Gv_Ev 0x0f4e -#define OP_CMOV_NLE_Gv_Ev 0x0f4f -#define OP_CMOV_G_Gv_Ev 0x0f4f - -#define OP_MOVMSKPS_Gd_Ups 0x0f50 -#define OP_MOVMSKPD_Gd_Upd 0x660f50 -#define OP_SQRTPS_Vps_Wps 0x0f51 -#define OP_SQRTSS_Vss_Wss 0xf30f51 -#define OP_SQRTPD_Vpd_Wpd 0x660f51 -#define OP_SQRTSD_Vsd_Wsd 0xf20f51 -#define OP_RSQRTPS_Vps_Wps 0x0f52 -#define OP_RSQRTSS_Vss_Wss 0xf30f52 -#define OP_RCPPS_Vps_Wps 0x0f53 -#define OP_RCPSS_Vss_Wss 0xf30f53 -#define OP_ANDPS_Vps_Wps 0x0f54 -#define OP_ANDPD_Vpd_Wpd 0x660f54 -#define OP_ANDNPS_Vps_Wps 0x0f55 -#define OP_ANDNPD_Vpd_Wpd 0x660f55 -#define OP_ORPS_Vps_Wps 0x0f56 -#define OP_ORPD_Vpd_Wpd 0x660f56 -#define OP_XORPS_Vps_Wps 0x0f57 -#define OP_XORPD_Vpd_Wpd 0x660f57 -#define OP_ADDPS_Vps_Wps 0x0f58 -#define OP_ADDSS_Vss_Wss 0xf30f58 -#define OP_ADDPD_Vpd_Wpd 0x660f58 -#define OP_ADDSD_Vsd_Wsd 0xf20f58 -#define OP_MULPS_Vps_Wps 0x0f59 -#define OP_MULSS_Vss_Wss 0xf30f59 -#define OP_MULPD_Vpd_Wpd 0x660f59 -#define OP_MULSD_Vsd_Wsd 0xf20f59 -#define OP_CVTPS2PD_Vpd_Wq 0x0f5a -#define OP_CVTSS2SD_Vsd_Wss 0xf30f5a -#define OP_CVTPD2PS_Vps_Wpd 0x660f5a -#define OP_CVTSD2SS_Vss_Wsd 0xf20f5a -#define OP_CVTDQ2PS_Vps_Wdq 0x0f5b -#define OP_CVTPS2DQ_Vdq_Wps 0x660f5b -#define OP_CVTTPS2DQ_Vdq_Wps 0xf30f5b -#define OP_SUBPS_Vps_Wps 0x0f5c -#define OP_SUBSS_Vss_Wss 0xf30f5c -#define OP_SUBPD_Vpd_Wpd 0x660f5c -#define OP_SUBSD_Vsd_Wsd 0xf20f5c -#define OP_MINPS_Vps_Wps 0x0f5d -#define OP_MINSS_Vss_Wss 0xf30f5d -#define OP_MINPD_Vpd_Wpd 0x660f5d -#define OP_MINSD_Vsd_Wsd 0xf20f5d -#define OP_DIVPS_Vps_Wps 0x0f5e -#define OP_DIVSS_Vss_Wss 0xf30f5e -#define OP_DIVPD_Vpd_Wpd 0x660f5e -#define OP_DIVSD_Vsd_Wsd 0xf20f5e -#define OP_MAXPS_Vps_Wps 0x0f5f -#define OP_MAXSS_Vss_Wss 0xf30f5f -#define OP_MAXPD_Vpd_Wpd 0x660f5f -#define OP_MAXSD_Vsd_Wsd 0xf20f5f - -#define OP_PUNPCKLBW_Pq_Qd 0x0f60 -#define OP_PUNPCKLBW_Vdq_Wdq 0x660f60 -#define OP_PUNPCKLWD_Pq_Qd 0x0f61 -#define OP_PUNPCKLWD_Vdq_Wdq 0x660f61 -#define OP_PUNPCKLDQ_Pq_Qd 0x0f62 -#define OP_PUNPCKLDQ_Vdq_Wdq 0x660f62 -#define OP_PACKSSWB_Pq_Qq 0x0f63 -#define OP_PACKSSWB_Vdq_Wdq 0x660f63 -#define OP_PCMPGTB_Pq_Qq 0x0f64 -#define OP_PCMPGTB_Vdq_Wdq 0x660f64 -#define OP_PCMPGTW_Pq_Qq 0x0f65 -#define OP_PCMPGTW_Vdq_Wdq 0x660f65 -#define OP_PCMPGTD_Pq_Qq 0x0f66 -#define OP_PCMPGTD_Vdq_Wdq 0x660f66 -#define OP_PACKUSWB_Pq_Qq 0x0f67 -#define OP_PACKUSWB_Vdq_Wdq 0x660f67 -#define OP_PUNPCKHBW_Pq_Qq 0x0f68 -#define OP_PUNPCKHBW_Vdq_Qdq 0x660f68 -#define OP_PUNPCKHWD_Pq_Qq 0x0f69 -#define OP_PUNPCKHWD_Vdq_Qdq 0x660f69 -#define OP_PUNPCKHDQ_Pq_Qq 0x0f6a -#define OP_PUNPCKHDQ_Vdq_Qdq 0x660f6a -#define OP_PACKSSDW_Pq_Qq 0x0f6b -#define OP_PACKSSDW_Vdq_Qdq 0x660f6b -#define OP_PUNPCKLQDQ_Vdq_Wdq 0x660f6c -#define OP_PUNPCKHQDQ_Vdq_Wdq 0x660f6d -#define OP_MOVD_Pd_Ed 0x0f6e -#define OP_MOVD_Vd_Ed 0x660f6e -#define OP_MOVQ_Pq_Qq 0x0f6f -#define OP_MOVDQA_Vdq_Wdq 0x660f6f -#define OP_MOVDQU_Vdq_Wdq 0xf30f6f - -#define OP_PSHUFW_Pq_Qq_Ib 0x0f70 -#define OP_PSHUFD_Vdq_Wdq_Ib 0x660f70 -#define OP_PSHUFHW_Vdq_Wdq_Ib 0xf30f70 -#define OP_PSHUFLW_Vdq_Wdq_Ib 0xf20f70 -#define OP_G12 0x0f71 -#define OP_G13 0x0f72 -#define OP_G14 0x0f73 -#define OP_PCMPEQB_Pq_Qq 0x0f74 -#define OP_PCMPEQB_Vdq_Wdq 0x660f74 -#define OP_PCMPEQW_Pq_Qq 0x0f75 -#define OP_PCMPEQW_Vdq_Wdq 0x660f75 -#define OP_PCMPEQD_Pq_Qq 0x0f76 -#define OP_PCMPEQD_Vdq_Wdq 0x660f76 -#define OP_EMMS 0x0f77 -#define OP_VMREAD_Ed_Gd 0x0f78 -#define OP_VMWRITE_Gd_Ed 0x0f79 -#define OP_HADDPD_Vpd_Wpd 0x660f7c -#define OP_HADDPS_Vps_Wps 0xf20f7c -#define OP_HSUBPD_Vpd_Wpd 0x660f7d -#define OP_HSUBPS_Vps_Wps 0xf20f7d -#define OP_MOVD_Ed_Pd 0x0f7e -#define OP_MOVD_Ed_Vd 0x660f7e -#define OP_MOVQ_Vq_Wq 0xf30f7e -#define OP_MOVQ_Qq_Pq 0x0f7f -#define OP_MOVDQA_Wdq_Vdq 0x660f7f -#define OP_MOVDQU_Wdq_Vdq 0xf30f7f - -#define OP_JCC_O_Jv 0x0f80 -#define OP_JCC_NO_Jv 0x0f81 -#define OP_JCC_B_Jv 0x0f82 -#define OP_JCC_C_Jv 0x0f82 -#define OP_JCC_NAE_Jv 0x0f82 -#define OP_JCC_AE_Jv 0x0f83 -#define OP_JCC_NB_Jv 0x0f83 -#define OP_JCC_NC_Jv 0x0f83 -#define OP_JCC_E_Jv 0x0f84 -#define OP_JCC_Z_Jv 0x0f84 -#define OP_JCC_NE_Jv 0x0f85 -#define OP_JCC_NZ_Jv 0x0f85 -#define OP_JCC_BE_Jv 0x0f86 -#define OP_JCC_NA_Jv 0x0f86 -#define OP_JCC_A_Jv 0x0f87 -#define OP_JCC_NBE_Jv 0x0f87 -#define OP_JCC_S_Jv 0x0f88 -#define OP_JCC_NS_Jv 0x0f89 -#define OP_JCC_P_Jv 0x0f8a -#define OP_JCC_PE_Jv 0x0f8a -#define OP_JCC_NP_Jv 0x0f8b -#define OP_JCC_PO_Jv 0x0f8b -#define OP_JCC_L_Jv 0x0f8c -#define OP_JCC_NGE_Jv 0x0f8c -#define OP_JCC_NL_Jv 0x0f8d -#define OP_JCC_GE_Jv 0x0f8d -#define OP_JCC_LE_Jv 0x0f8e -#define OP_JCC_NG_Jv 0x0f8e -#define OP_JCC_NLE_Jv 0x0f8f -#define OP_JCC_G_Jv 0x0f8f - -#define OP_SETCC_O_Eb (0x0f90 | OPFLAG_8BITRM) -#define OP_SETCC_NO_Eb (0x0f91 | OPFLAG_8BITRM) -#define OP_SETCC_B_Eb (0x0f92 | OPFLAG_8BITRM) -#define OP_SETCC_C_Eb (0x0f92 | OPFLAG_8BITRM) -#define OP_SETCC_NAE_Eb (0x0f92 | OPFLAG_8BITRM) -#define OP_SETCC_AE_Eb (0x0f93 | OPFLAG_8BITRM) -#define OP_SETCC_NB_Eb (0x0f93 | OPFLAG_8BITRM) -#define OP_SETCC_NC_Eb (0x0f93 | OPFLAG_8BITRM) -#define OP_SETCC_E_Eb (0x0f94 | OPFLAG_8BITRM) -#define OP_SETCC_Z_Eb (0x0f94 | OPFLAG_8BITRM) -#define OP_SETCC_NE_Eb (0x0f95 | OPFLAG_8BITRM) -#define OP_SETCC_NZ_Eb (0x0f95 | OPFLAG_8BITRM) -#define OP_SETCC_BE_Eb (0x0f96 | OPFLAG_8BITRM) -#define OP_SETCC_NA_Eb (0x0f96 | OPFLAG_8BITRM) -#define OP_SETCC_A_Eb (0x0f97 | OPFLAG_8BITRM) -#define OP_SETCC_NBE_Eb (0x0f97 | OPFLAG_8BITRM) -#define OP_SETCC_S_Eb (0x0f98 | OPFLAG_8BITRM) -#define OP_SETCC_NS_Eb (0x0f99 | OPFLAG_8BITRM) -#define OP_SETCC_P_Eb (0x0f9a | OPFLAG_8BITRM) -#define OP_SETCC_PE_Eb (0x0f9a | OPFLAG_8BITRM) -#define OP_SETCC_NP_Eb (0x0f9b | OPFLAG_8BITRM) -#define OP_SETCC_PO_Eb (0x0f9b | OPFLAG_8BITRM) -#define OP_SETCC_L_Eb (0x0f9c | OPFLAG_8BITRM) -#define OP_SETCC_NGE_Eb (0x0f9c | OPFLAG_8BITRM) -#define OP_SETCC_NL_Eb (0x0f9d | OPFLAG_8BITRM) -#define OP_SETCC_GE_Eb (0x0f9d | OPFLAG_8BITRM) -#define OP_SETCC_LE_Eb (0x0f9e | OPFLAG_8BITRM) -#define OP_SETCC_NG_Eb (0x0f9e | OPFLAG_8BITRM) -#define OP_SETCC_NLE_Eb (0x0f9f | OPFLAG_8BITRM) -#define OP_SETCC_G_Eb (0x0f9f | OPFLAG_8BITRM) - -#define OP_PUSH_FS 0x0fa0 -#define OP_POP_FS 0x0fa1 -#define OP_CPUID 0x0fa2 -#define OP_BT_Ev_Gv 0x0fa3 -#define OP_SHLD_Ev_Gv_Ib 0x0fa4 -#define OP_SHLD_Ev_Gv_CL 0x0fa5 -#define OP_PUSH_GS 0x0fa8 -#define OP_POP_GS 0x0fa9 -#define OP_RSM 0x0faa -#define OP_BTS_Ev_Gv 0x0fab -#define OP_SHRD_Ev_Gv_Ib 0x0fac -#define OP_SHRD_Ev_Gv_CL 0x0fad -#define OP_G16 0x0fae -#define OP_IMUL_Gv_Ev 0x0faf - -#define OP_CMPXCHG_Eb_Gb (0x0fb0 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_CMPXCHG_Ev_Gv 0x0fb1 -#define OP_LSS_Mp 0x0fb2 -#define OP_BTR_Ev_Gv 0x0fb3 -#define OP_LFS_Mp 0x0fb4 -#define OP_LGS_Mp 0x0fb5 -#define OP_MOVZX_Gv_Eb (0x0fb6 | OPFLAG_8BITRM) -#define OP_MOVZX_Gv_Ew 0x0fb7 -#define OP_JMPE 0x0fb8 -#define OP_POPCNT_Gv_Ev 0xf30fb8 -#define OP_G10_INVALID 0x0fb9 -#define OP_G8_Ev_Ib 0x0fba -#define OP_BTC_Ev_Gv 0x0fbb -#define OP_BSF_Gv_Ev 0x0fbc -#define OP_BSR_Gv_Ev 0x0fbd -#define OP_MOVSX_Gv_Eb (0x0fbe | OPFLAG_8BITRM) -#define OP_MOVSX_Gv_Ew 0x0fbf - -#define OP_XADD_Eb_Gb (0x0fc0 | OPFLAG_8BITRM | OPFLAG_8BITREG) -#define OP_XADD_Ev_Gv 0x0fc1 -#define OP_CMPPS_Vps_Wps_Ib 0x0fc2 -#define OP_CMPSS_Vss_Wss_Ib 0xf30fc2 -#define OP_CMPPD_Vpd_Wpd_Ib 0x660fc2 -#define OP_CMPSD_Vsd_Wsd_Ib 0xf20fc2 -#define OP_MOVNTI_Md_Gd 0x0fc3 -#define OP_PINSRW_Pw_Ew_Ib 0x0fc4 -#define OP_PINSRW_Vw_Ew_Ib 0x660fc4 -#define OP_PEXTRW_Gw_Pw_Ib 0x0fc5 -#define OP_PEXTRW_Gw_Vw_Ib 0x660fc5 -#define OP_SHUFPS_Vps_Wps_Ib 0x0fc6 -#define OP_SHUFPD_Vpd_Wpd_Ib 0x660fc6 -#define OP_G9 0x0fc7 -#define OP_BSWAP_EAX 0x0fc8 -#define OP_BSWAP_ECX 0x0fc9 -#define OP_BSWAP_EDX 0x0fca -#define OP_BSWAP_EBX 0x0fcb -#define OP_BSWAP_ESP 0x0fcc -#define OP_BSWAP_EBP 0x0fcd -#define OP_BSWAP_ESI 0x0fce -#define OP_BSWAP_EDI 0x0fcf - -#define OP_ADDSUBPD_Vpd_Wpd 0x0fd0 -#define OP_ADDSUBPS_Vps_Wps 0xf20fd0 -#define OP_PSRLW_Pq_Qq 0x0fd1 -#define OP_PSRLW_Vdq_Wdq 0x660fd1 -#define OP_PSRLD_Pq_Qq 0x0fd2 -#define OP_PSRLD_Vdq_Wdq 0x660fd2 -#define OP_PSRLQ_Pq_Qq 0x0fd3 -#define OP_PSRLQ_Vdq_Wdq 0x660fd3 -#define OP_PADDQ_Pq_Qq 0x0fd4 -#define OP_PADDQ_Vdq_Wdq 0x660fd4 -#define OP_PMULLW_Pq_Qq 0x0fd5 -#define OP_PMULLW_Vdq_Wdq 0x660fd5 -#define OP_MOVQ_Wq_Vq 0x0fd6 -#define OP_MOVQ2DQ_Vdq_Qq 0xf30fd6 -#define OP_MOVDQ2Q_Pq_Vq 0xf20fd6 -#define OP_PMOVMSKB_Gd_Pq 0x0fd7 -#define OP_PMOVMSKB_Gd_Vdq 0x660fd7 -#define OP_PSUBUSB_Pq_Qq 0x0fd8 -#define OP_PSUBUSB_Vdq_Wdq 0x660fd8 -#define OP_PSUBUSW_Pq_Qq 0x0fd9 -#define OP_PSUBUSW_Vdq_Wdq 0x660fd9 -#define OP_PMINUB_Pq_Qq 0x0fda -#define OP_PMINUB_Vdq_Wdq 0x660fda -#define OP_PAND_Pq_Qq 0x0fdb -#define OP_PAND_Vdq_Wdq 0x660fdb -#define OP_PADDUSB_Pq_Qq 0x0fdc -#define OP_PADDUSB_Vdq_Wdq 0x660fdc -#define OP_PADDUSW_Pq_Qq 0x0fdd -#define OP_PADDUSW_Vdq_Wdq 0x660fdd -#define OP_PMAXUB_Pq_Qq 0x0fde -#define OP_PMAXUB_Vdq_Wdq 0x660fde -#define OP_PANDN_Pq_Qq 0x0fdf -#define OP_PANDN_Vdq_Wdq 0x660fdf - -#define OP_PAVGB_Pq_Qq 0x0fe0 -#define OP_PAVGB_Vdq_Wdq 0x660fe0 -#define OP_PSRAW_Pq_Qq 0x0fe1 -#define OP_PSRAW_Vdq_Wdq 0x660fe1 -#define OP_PSRAD_Pq_Qq 0x0fe2 -#define OP_PSRAD_Vdq_Wdq 0x660fe2 -#define OP_PAVGW_Pq_Qq 0x0fe3 -#define OP_PAVGW_Vdq_Wdq 0x660fe3 -#define OP_PMULHUW_Pq_Qq 0x0fe4 -#define OP_PMULHUW_Vdq_Wdq 0x660fe4 -#define OP_PMULHW_Pq_Qq 0x0fe5 -#define OP_PMULHW_Vdq_Wdq 0x660fe5 -#define OP_CVTPD2DQ_Vdq_Wpd 0xf20fe6 -#define OP_CVTTPD2DQ_Vdq_Wpd 0x660fe6 -#define OP_CVTDQ2PD_Vpd_Wq 0xf30fe6 -#define OP_MOVNTQ_Mq_Vq 0x0fe7 -#define OP_MOVNTDQ_Mdq_Vdq 0x660fe7 -#define OP_PSUBSB_Pq_Qq 0x0fe8 -#define OP_PSUBSB_Vdq_Wdq 0x660fe8 -#define OP_PSUBSW_Pq_Qq 0x0fe9 -#define OP_PSUBSW_Vdq_Wdq 0x660fe9 -#define OP_PMINSW_Pq_Qq 0x0fea -#define OP_PMINSW_Vdq_Wdq 0x660fea -#define OP_POR_Pq_Qq 0x0feb -#define OP_POR_Vdq_Wdq 0x660feb -#define OP_PADDSB_Pq_Qq 0x0fec -#define OP_PADDSB_Vdq_Wdq 0x660fec -#define OP_PADDSW_Pq_Qq 0x0fed -#define OP_PADDSW_Vdq_Wdq 0x660fed -#define OP_PMAXSW_Pq_Qq 0x0fee -#define OP_PMAXSW_Vdq_Wdq 0x660fee -#define OP_PXOR_Pq_Qq 0x0fef -#define OP_PXOR_Vdq_Wdq 0x660fef - -#define OP_LDDQU_Vdq_Mdq 0xf20ff0 -#define OP_PSLLW_Pq_Qq 0x0ff1 -#define OP_PSLLW_Vdq_Wdq 0x660ff1 -#define OP_PSLLD_Pq_Qq 0x0ff2 -#define OP_PSLLD_Vdq_Wdq 0x660ff2 -#define OP_PSLLQ_Pq_Qq 0x0ff3 -#define OP_PSLLQ_Vdq_Wdq 0x660ff3 -#define OP_PMULUDQ_Pq_Qq 0x0ff4 -#define OP_PMULUDQ_Vdq_Wdq 0x660ff4 -#define OP_PMADDWD_Pq_Qq 0x0ff5 -#define OP_PMADDWD_Vdq_Wdq 0x660ff5 -#define OP_PSADBW_Pq_Qq 0x0ff6 -#define OP_PSADBW_Vdq_Wdq 0x660ff6 -#define OP_MASKMOVQ_Pq_Qq 0x0ff7 -#define OP_MASKMOVDQU_Vdq_Wdq 0x660ff7 -#define OP_PSUBB_Pq_Qq 0x0ff8 -#define OP_PSUBB_Vdq_Wdq 0x660ff8 -#define OP_PSUBW_Pq_Qq 0x0ff9 -#define OP_PSUBW_Vdq_Wdq 0x660ff9 -#define OP_PSUBD_Pq_Qq 0x0ffa -#define OP_PSUBD_Vdq_Wdq 0x660ffa -#define OP_PSUBQ_Pq_Qq 0x0ffb -#define OP_PSUBQ_Vdq_Wdq 0x660ffb -#define OP_PADDB_Pq_Qq 0x0ffc -#define OP_PADDB_Vdq_Wdq 0x660ffc -#define OP_PADDW_Pq_Qq 0x0ffd -#define OP_PADDW_Vdq_Wdq 0x660ffd -#define OP_PADDD_Pq_Qq 0x0ffe -#define OP_PADDD_Vdq_Wdq 0x660ffe - - -/* triple byte opcodes (0f 38) */ -#define OP_PSHUFB_Pq_Qq 0x0f3800 -#define OP_PSHUFB_Vdq_Wdq 0x660f3800 -#define OP_PHADDW_Pq_Qq 0x0f3801 -#define OP_PHADDW_Vdq_Wdq 0x660f3801 -#define OP_PHADDD_Pq_Qq 0x0f3802 -#define OP_PHADDD_Vdq_Wdq 0x660f3802 -#define OP_PHADDSW_Pq_Qq 0x0f3803 -#define OP_PHADDSW_Vdq_Wdq 0x660f3803 -#define OP_PMADDUBSW_Pq_Qq 0x0f3804 -#define OP_PMADDUBSW_Vdq_Wdq 0x660f3804 -#define OP_PHSUBW_Pq_Qq 0x0f3805 -#define OP_PHSUBW_Vdq_Wdq 0x660f3805 -#define OP_PHSUBD_Pq_Qq 0x0f3806 -#define OP_PHSUBD_Vdq_Wdq 0x660f3806 -#define OP_PHSUBSW_Pq_Qq 0x0f3807 -#define OP_PHSUBSW_Vdq_Wdq 0x660f3807 -#define OP_PSIGNB_Pq_Qq 0x0f3808 -#define OP_PSIGNB_Vdq_Wdq 0x660f3808 -#define OP_PSIGNW_Pq_Qq 0x0f3809 -#define OP_PSIGNW_Vdq_Wdq 0x660f3809 -#define OP_PSIGND_Pq_Qq 0x0f380a -#define OP_PSIGND_Vdq_Wdq 0x660f380a -#define OP_PMULHRSW_Pq_Qq 0x0f380b -#define OP_PMULHRSW_Vdq_Wdq 0x660f380b - -#define OP_PBLENDVB_Vdq_Wdq 0x660f3810 -#define OP_PBLENDVPS_Vdq_Wdq 0x660f3814 -#define OP_PBLENDVPD_Vdq_Wdq 0x660f3815 -#define OP_PTEST_Vdq_Wdq 0x660f3817 -#define OP_PABSB_Pq_Qq 0x0f381c -#define OP_PABSB_Vdq_Wdq 0x660f381c -#define OP_PABSW_Pq_Qq 0x0f381d -#define OP_PABSW_Vdq_Wdq 0x660f381d -#define OP_PABSD_Pq_Qq 0x0f381e -#define OP_PABSD_Vdq_Wdq 0x660f381e - -#define OP_PMOVSXBW_Vdq_Udq 0x660f3820 -#define OP_PMOVSXBD_Vdq_Udq 0x660f3821 -#define OP_PMOVSXBQ_Vdq_Udq 0x660f3822 -#define OP_PMOVSXWD_Vdq_Udq 0x660f3823 -#define OP_PMOVSXWQ_Vdq_Udq 0x660f3824 -#define OP_PMOVSXDQ_Vdq_Udq 0x660f3825 -#define OP_PMULDQ_Vdq_Udq 0x660f3828 -#define OP_PCMPEQQ_Vdq_Udq 0x660f3829 -#define OP_MOVNTDQA_Vdq_Udq 0x660f382a -#define OP_PACKUSDW_Vdq_Udq 0x660f382b - -#define OP_PMOVZXBW_Vdq_Udq 0x660f3830 -#define OP_PMOVZXBD_Vdq_Udq 0x660f3831 -#define OP_PMOVZXBQ_Vdq_Udq 0x660f3832 -#define OP_PMOVZXWD_Vdq_Udq 0x660f3833 -#define OP_PMOVZXWQ_Vdq_Udq 0x660f3834 -#define OP_PMOVZXDQ_Vdq_Udq 0x660f3835 -#define OP_PMINSB_Vdq_Udq 0x660f3838 -#define OP_PMINSD_Vdq_Udq 0x660f3839 -#define OP_PMINUW_Vdq_Udq 0x660f383a -#define OP_PMINUD_Vdq_Udq 0x660f383b -#define OP_PMAXSB_Vdq_Udq 0x660f383c -#define OP_PMAXSD_Vdq_Udq 0x660f383d -#define OP_PMAXUW_Vdq_Udq 0x660f383e -#define OP_PMAXUD_Vdq_Udq 0x660f383f - -#define OP_MULLD_Vdq_Wdq 0x660f3840 -#define OP_PHMINPOSUW_Vdq_Wdq 0x660f3841 - -#define OP_NVEPT_Gd_Mdq 0x660f3880 -#define OP_NVVPID_Gd_Mdq 0x660f3881 - -#define OP_MOVBE_Gv_Mv 0x0f38f0 -#define OP_CRC32_Gd_Eb 0xf20f38f0 -#define OP_MOVBE_Mv_Gv 0x0f38f1 -#define OP_CRC32_Gd_Ev 0xf20f38f1 - - -/* triple byte opcodes (0f 3a) */ -#define OP_ROUNDPS_Vdq_Wdq_Ib 0x660f3a08 -#define OP_ROUNDPD_Vdq_Wdq_Ib 0x660f3a09 -#define OP_ROUNDSS_Vss_Wss_Ib 0x660f3a0a -#define OP_ROUNDSD_Vsd_Wsd_Ib 0x660f3a0b -#define OP_BLENDPS_Vdq_Wdq_Ib 0x660f3a0c -#define OP_BLENDPD_Vdq_Wdq_Ib 0x660f3a0d -#define OP_PBLENDW_Vdq_Wdq_Ib 0x660f3a0e -#define OP_PALIGNR_Pq_Qq_Ib 0x0f3a0f -#define OP_PALIGNR_Vdq_Wdq_Ib 0x660f3a0f - -#define OP_EXTRB_Rd_Vdq_Ib 0x660f3a14 -#define OP_EXTRW_Rd_Vdq_Ib 0x660f3a15 -#define OP_EXTRD_Rd_Vdq_Ib 0x660f3a16 -#define OP_EXTRACTPS_Ed_Vdq_Ib 0x660f3a17 - -#define OP_PINSRB_Vdq_Rd_Ib 0x660f3a20 -#define OP_INSERTPS_Vdq_Udq_Ib 0x660f3a21 -#define OP_PINSRD_Vdq_Ed_Ib 0x660f3a22 - -#define OP_DPPS_Vdq_Wdq_Ib 0x660f3a40 -#define OP_DPPD_Vdq_Wdq_Ib 0x660f3a41 -#define OP_MPSADBW_Vdq_Wdq_Ib 0x660f3a42 - -#define OP_PCMPESTRM_Vdq_Wdq_Ib 0x660f3a60 -#define OP_PCMPESTRI_Vdq_Wdq_Ib 0x660f3a61 -#define OP_PCMPISTRM_Vdq_Wdq_Ib 0x660f3a62 -#define OP_PCMPISTRI_Vdq_Wdq_Ib 0x660f3a63 - - -/* floating point opcodes */ -#define OP_FADD_ST0_STn 0xd8c0 -#define OP_FMUL_ST0_STn 0xd8c8 -#define OP_FCOM_ST0_STn 0xd8d0 -#define OP_FCOMP_ST0_STn 0xd8d8 -#define OP_FSUB_ST0_STn 0xd8e0 -#define OP_FSUBR_ST0_STn 0xd8e8 -#define OP_FDIV_ST0_STn 0xd8f0 -#define OP_FDIVR_ST0_STn 0xd8f8 -#define OP_FLD_ST0_STn 0xd9c0 -#define OP_FXCH_ST0_STn 0xd9c8 -#define OP_FNOP 0xd9d0 -#define OP_FCHS 0xd9e0 -#define OP_FABS 0xd9e1 -#define OP_FTST 0xd9e4 -#define OP_FXAM 0xd9e5 -#define OP_FLD1 0xd9e8 -#define OP_FLDL2T 0xd9e9 -#define OP_FLDL2E 0xd9ea -#define OP_FLDPI 0xd9eb -#define OP_FLDLG2 0xd9ec -#define OP_FLDLN2 0xd9ed -#define OP_FLDZ 0xd9ee -#define OP_F2XM1 0xd9f0 -#define OP_FYL2X 0xd9f1 -#define OP_FPTAN 0xd9f2 -#define OP_FPATAN 0xd9f3 -#define OP_FXTRACT 0xd9f4 -#define OP_FPREM1 0xd9f5 -#define OP_FDECSTP 0xd9f6 -#define OP_FINCSTP 0xd9f7 -#define OP_FPREM 0xd9f8 -#define OP_FYL2XP1 0xd9f9 -#define OP_FSQRT 0xd9fa -#define OP_FSINCOS 0xd9fb -#define OP_FRNDINT 0xd9fc -#define OP_FSCALE 0xd9fd -#define OP_FSIN 0xd9fe -#define OP_FCOS 0xd9ff -#define OP_FCMOVB_ST0_STn 0xdac0 -#define OP_FCMOVE_ST0_STn 0xdac8 -#define OP_FCMOVBE_ST0_STn 0xdad0 -#define OP_FCMOVU_ST0_STn 0xdad8 -#define OP_FUCOMPP 0xdae9 -#define OP_FCMOVNB_ST0_STn 0xdbc0 -#define OP_FCMOVNE_ST0_STn 0xdbc8 -#define OP_FCMOVNBE_ST0_STn 0xdbd0 -#define OP_FCMOVNU_ST0_STn 0xdbd8 -#define OP_FCLEX 0xdbe2 -#define OP_FINIT 0xdbe3 -#define OP_FUCOMI_ST0_STn 0xdbe8 -#define OP_FCOMI_ST0_STn 0xdbf0 -#define OP_FADD_STn_ST0 0xdcc0 -#define OP_FMUL_STn_ST0 0xdcc8 -#define OP_FSUBR_STn_ST0 0xdce0 -#define OP_FSUB_STn_ST0 0xdce8 -#define OP_FDIVR_STn_ST0 0xdcf0 -#define OP_FDIV_STn_ST0 0xdcf8 -#define OP_FFREE_STn 0xddc0 -#define OP_FST_STn 0xddd0 -#define OP_FSTP_STn 0xddd8 -#define OP_FUCOM_STn_ST0 0xdde0 -#define OP_FUCOMP_STn 0xdde8 -#define OP_FADDP_STn_ST0 0xdec0 -#define OP_FMULP_STn_ST0 0xdec8 -#define OP_FCOMPP 0xded9 -#define OP_FSUBRP_STn_ST0 0xdee0 -#define OP_FSUBP_STn_ST0 0xdee8 -#define OP_FDIVRP_STn_ST0 0xdef0 -#define OP_FDIVP_STn_ST0 0xdef8 -#define OP_FSTSW_AX 0xdfe0 -#define OP_FCOMIP_ST0_STn 0xdff0 - +//************************************************************************** +// CONSTANTS +//************************************************************************** +// opcode size flag; low 4 bits must match REX low 4 bits, hence the odd numbers here +const UINT8 OP_16BIT = 0x10; +const UINT8 OP_32BIT = 0x00; +const UINT8 OP_64BIT = 0x08; -/*************************************************************************** - TYPE DEFINITIONS -***************************************************************************/ - -/* use x86code * to reference generated code */ -typedef UINT8 x86code; +// 16 registers on x64, only 8 on x86 +#if (X86EMIT_SIZE == 64) +const int REG_MAX = 16; +#else +const int REG_MAX = 8; +#endif +// invalid register index for "none" +const UINT8 REG_NONE = REG_MAX; + +// 8-bit registers -- note that we assume a flat model for 64-bit +const UINT8 REG_AL = 0; +const UINT8 REG_CL = 1; +const UINT8 REG_DL = 2; +const UINT8 REG_BL = 3; +#if (X86EMIT_SIZE == 32) +const UINT8 REG_AH = 4; +const UINT8 REG_CH = 5; +const UINT8 REG_DH = 6; +const UINT8 REG_BH = 7; +#else +const UINT8 REG_SPL = 4; +const UINT8 REG_BPL = 5; +const UINT8 REG_SIL = 6; +const UINT8 REG_DIL = 7; +const UINT8 REG_R8L = 8; +const UINT8 REG_R9L = 9; +const UINT8 REG_R10L = 10; +const UINT8 REG_R11L = 11; +const UINT8 REG_R12L = 12; +const UINT8 REG_R13L = 13; +const UINT8 REG_R14L = 14; +const UINT8 REG_R15L = 15; +#endif -/* this structure tracks information about a link */ -typedef struct _emit_link emit_link; -struct _emit_link -{ - x86code * target; - UINT8 size; -}; +// 16-bit registers +const UINT8 REG_AX = 0; +const UINT8 REG_CX = 1; +const UINT8 REG_DX = 2; +const UINT8 REG_BX = 3; +const UINT8 REG_SP = 4; +const UINT8 REG_BP = 5; +const UINT8 REG_SI = 6; +const UINT8 REG_DI = 7; +#if (X86EMIT_SIZE == 64) +const UINT8 REG_R8W = 8; +const UINT8 REG_R9W = 9; +const UINT8 REG_R10W = 10; +const UINT8 REG_R11W = 11; +const UINT8 REG_R12W = 12; +const UINT8 REG_R13W = 13; +const UINT8 REG_R14W = 14; +const UINT8 REG_R15W = 15; +#endif +// 32-bit registers +const UINT8 REG_EAX = 0; +const UINT8 REG_ECX = 1; +const UINT8 REG_EDX = 2; +const UINT8 REG_EBX = 3; +const UINT8 REG_ESP = 4; +const UINT8 REG_EBP = 5; +const UINT8 REG_ESI = 6; +const UINT8 REG_EDI = 7; +#if (X86EMIT_SIZE == 64) +const UINT8 REG_R8D = 8; +const UINT8 REG_R9D = 9; +const UINT8 REG_R10D = 10; +const UINT8 REG_R11D = 11; +const UINT8 REG_R12D = 12; +const UINT8 REG_R13D = 13; +const UINT8 REG_R14D = 14; +const UINT8 REG_R15D = 15; +#endif +// 64-bit registers +#if (X86EMIT_SIZE == 64) +const UINT8 REG_RAX = 0; +const UINT8 REG_RCX = 1; +const UINT8 REG_RDX = 2; +const UINT8 REG_RBX = 3; +const UINT8 REG_RSP = 4; +const UINT8 REG_RBP = 5; +const UINT8 REG_RSI = 6; +const UINT8 REG_RDI = 7; +const UINT8 REG_R8 = 8; +const UINT8 REG_R9 = 9; +const UINT8 REG_R10 = 10; +const UINT8 REG_R11 = 11; +const UINT8 REG_R12 = 12; +const UINT8 REG_R13 = 13; +const UINT8 REG_R14 = 14; +const UINT8 REG_R15 = 15; +#endif -/*************************************************************************** - MACROS -***************************************************************************/ +// 64-bit MMX registers +const UINT8 REG_MM0 = 0; +const UINT8 REG_MM1 = 1; +const UINT8 REG_MM2 = 2; +const UINT8 REG_MM3 = 3; +const UINT8 REG_MM4 = 4; +const UINT8 REG_MM5 = 5; +const UINT8 REG_MM6 = 6; +const UINT8 REG_MM7 = 7; +#if (X86EMIT_SIZE == 64) +const UINT8 REG_MM8 = 8; +const UINT8 REG_MM9 = 9; +const UINT8 REG_MM10 = 10; +const UINT8 REG_MM11 = 11; +const UINT8 REG_MM12 = 12; +const UINT8 REG_MM13 = 13; +const UINT8 REG_MM14 = 14; +const UINT8 REG_MM15 = 15; +#endif -#define DECLARE_MEMPARAMS UINT8 base, UINT8 index, UINT8 scale, INT32 disp -#define MEMPARAMS base, index, scale, disp +// 128-bit XMM registers +const UINT8 REG_XMM0 = 0; +const UINT8 REG_XMM1 = 1; +const UINT8 REG_XMM2 = 2; +const UINT8 REG_XMM3 = 3; +const UINT8 REG_XMM4 = 4; +const UINT8 REG_XMM5 = 5; +const UINT8 REG_XMM6 = 6; +const UINT8 REG_XMM7 = 7; +#if (X86EMIT_SIZE == 64) +const UINT8 REG_XMM8 = 8; +const UINT8 REG_XMM9 = 9; +const UINT8 REG_XMM10 = 10; +const UINT8 REG_XMM11 = 11; +const UINT8 REG_XMM12 = 12; +const UINT8 REG_XMM13 = 13; +const UINT8 REG_XMM14 = 14; +const UINT8 REG_XMM15 = 15; +#endif -#ifndef PTR64 -#define MBISD(base, index, scale, disp) (base), (index), (scale), (INT32)(disp) -#define MABS(addr) MBISD(REG_NONE, REG_NONE, 1, (addr)) -#define MBD(base, disp) MBISD((base), REG_NONE, 1, (disp)) -#define MISD(index, scale, disp) MBISD(REG_NONE, (index), (scale), (disp)) -#else -#define MBISD(base, index, scale, disp) (base), (index), (scale), (disp) -#define MBD(base, disp) MBISD((base), REG_NONE, 1, (disp)) -#define MISD(index, scale, disp) MBISD(REG_NONE, (index), (scale), (disp)) +// conditions +const UINT8 COND_A = 7; +const UINT8 COND_AE = 3; +const UINT8 COND_B = 2; +const UINT8 COND_BE = 6; +const UINT8 COND_C = 2; +const UINT8 COND_E = 4; +const UINT8 COND_Z = 4; +const UINT8 COND_G = 15; +const UINT8 COND_GE = 13; +const UINT8 COND_L = 12; +const UINT8 COND_LE = 14; +const UINT8 COND_NA = 6; +const UINT8 COND_NAE = 2; +const UINT8 COND_NB = 3; +const UINT8 COND_NBE = 7; +const UINT8 COND_NC = 3; +const UINT8 COND_NE = 5; +const UINT8 COND_NG = 14; +const UINT8 COND_NGE = 12; +const UINT8 COND_NL = 13; +const UINT8 COND_NLE = 15; +const UINT8 COND_NO = 1; +const UINT8 COND_NP = 11; +const UINT8 COND_NS = 9; +const UINT8 COND_NZ = 5; +const UINT8 COND_O = 0; +const UINT8 COND_P = 10; +const UINT8 COND_PE = 10; +const UINT8 COND_PO = 11; +const UINT8 COND_S = 8; + +// floating point rounding modes +const UINT8 FPRND_NEAR = 0; +const UINT8 FPRND_DOWN = 1; +const UINT8 FPRND_UP = 2; +const UINT8 FPRND_CHOP = 3; + + + +//************************************************************************** +// OPCODE DEFINITIONS +//************************************************************************** + +// opcode flags (in upper 8 bits of opcode) +const UINT32 OPFLAG_8BITREG = (1 << 24); +const UINT32 OPFLAG_8BITRM = (1 << 25); + +// single byte opcodes +const UINT32 OP_ADD_Eb_Gb = (0x00 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_ADD_Ev_Gv = 0x01; +const UINT32 OP_ADD_Gb_Eb = (0x02 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_ADD_Gv_Ev = 0x03; +const UINT32 OP_ADD_AL_Ib = 0x04; +const UINT32 OP_ADD_rAX_Iz = 0x05; +const UINT32 OP_PUSH_ES = 0x06; +const UINT32 OP_POP_ES = 0x07; +const UINT32 OP_OR_Eb_Gb = (0x08 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_OR_Ev_Gv = 0x09; +const UINT32 OP_OR_Gb_Eb = (0x0a | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_OR_Gv_Ev = 0x0b; +const UINT32 OP_OR_AL_Ib = 0x0c; +const UINT32 OP_OR_eAX_Iv = 0x0d; +const UINT32 OP_PUSH_CS = 0x0e; +const UINT32 OP_EXTENDED = 0x0f; + +const UINT32 OP_ADC_Eb_Gb = (0x10 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_ADC_Ev_Gv = 0x11; +const UINT32 OP_ADC_Gb_Eb = (0x12 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_ADC_Gv_Ev = 0x13; +const UINT32 OP_ADC_AL_Ib = 0x14; +const UINT32 OP_ADC_rAX_Iz = 0x15; +const UINT32 OP_PUSH_SS = 0x16; +const UINT32 OP_POP_SS = 0x17; +const UINT32 OP_SBB_Eb_Gb = (0x18 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_SBB_Ev_Gv = 0x19; +const UINT32 OP_SBB_Gb_Eb = (0x1a | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_SBB_Gv_Ev = 0x1b; +const UINT32 OP_SBB_AL_Ib = 0x1c; +const UINT32 OP_SBB_eAX_Iv = 0x1d; +const UINT32 OP_PUSH_DS = 0x1e; +const UINT32 OP_POP_DS = 0x1f; + +const UINT32 OP_AND_Eb_Gb = (0x20 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_AND_Ev_Gv = 0x21; +const UINT32 OP_AND_Gb_Eb = (0x22 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_AND_Gv_Ev = 0x23; +const UINT32 OP_AND_AL_Ib = 0x24; +const UINT32 OP_AND_rAX_Iz = 0x25; +const UINT32 PREFIX_ES = 0x26; +const UINT32 OP_DAA = 0x27; +const UINT32 OP_SUB_Eb_Gb = (0x28 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_SUB_Ev_Gv = 0x29; +const UINT32 OP_SUB_Gb_Eb = (0x2a | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_SUB_Gv_Ev = 0x2b; +const UINT32 OP_SUB_AL_Ib = 0x2c; +const UINT32 OP_SUB_eAX_Iv = 0x2d; +const UINT32 PREFIX_CS = 0x2e; +const UINT32 OP_DAS = 0x2f; + +const UINT32 OP_XOR_Eb_Gb = (0x30 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_XOR_Ev_Gv = 0x31; +const UINT32 OP_XOR_Gb_Eb = (0x32 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_XOR_Gv_Ev = 0x33; +const UINT32 OP_XOR_AL_Ib = 0x34; +const UINT32 OP_XOR_rAX_Iz = 0x35; +const UINT32 PREFIX_SS = 0x36; +const UINT32 OP_AAA = 0x37; +const UINT32 OP_CMP_Eb_Gb = (0x38 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_CMP_Ev_Gv = 0x39; +const UINT32 OP_CMP_Gb_Eb = (0x3a | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_CMP_Gv_Ev = 0x3b; +const UINT32 OP_CMP_AL_Ib = 0x3c; +const UINT32 OP_CMP_eAX_Iv = 0x3d; +const UINT32 PREFIX_DS = 0x3e; +const UINT32 OP_AAS = 0x3f; + +const UINT32 OP_REX = 0x40; +const UINT32 OP_REX_B = 0x41; +const UINT32 OP_REX_X = 0x42; +const UINT32 OP_REX_XB = 0x43; +const UINT32 OP_REX_R = 0x44; +const UINT32 OP_REX_RB = 0x45; +const UINT32 OP_REX_RX = 0x46; +const UINT32 OP_REX_RXB = 0x47; +const UINT32 OP_REX_W = 0x48; +const UINT32 OP_REX_WB = 0x49; +const UINT32 OP_REX_WX = 0x4a; +const UINT32 OP_REX_WXB = 0x4b; +const UINT32 OP_REX_WR = 0x4c; +const UINT32 OP_REX_WRB = 0x4d; +const UINT32 OP_REX_WRX = 0x4e; +const UINT32 OP_REX_WRXB = 0x4f; + +const UINT32 OP_PUSH_rAX = 0x50; +const UINT32 OP_PUSH_rCX = 0x51; +const UINT32 OP_PUSH_rDX = 0x52; +const UINT32 OP_PUSH_rBX = 0x53; +const UINT32 OP_PUSH_rSP = 0x54; +const UINT32 OP_PUSH_rBP = 0x55; +const UINT32 OP_PUSH_rSI = 0x56; +const UINT32 OP_PUSH_rDI = 0x57; +const UINT32 OP_POP_rAX = 0x58; +const UINT32 OP_POP_rCX = 0x59; +const UINT32 OP_POP_rDX = 0x5a; +const UINT32 OP_POP_rBX = 0x5b; +const UINT32 OP_POP_rSP = 0x5c; +const UINT32 OP_POP_rBP = 0x5d; +const UINT32 OP_POP_rSI = 0x5e; +const UINT32 OP_POP_rDI = 0x5f; + +const UINT32 OP_PUSHA = 0x60; +const UINT32 OP_POPA = 0x61; +const UINT32 OP_BOUND_Gv_Ma = 0x62; +const UINT32 OP_ARPL_Ew_Gw = 0x63; +const UINT32 OP_MOVSXD_Gv_Ev = 0x63; +const UINT32 PREFIX_FS = 0x64; +const UINT32 PREFIX_GS = 0x65; +const UINT32 PREFIX_OPSIZE = 0x66; +const UINT32 PREFIX_ADSIZE = 0x67; +const UINT32 OP_PUSH_Iz = 0x68; +const UINT32 OP_IMUL_Gv_Ev_Iz = 0x69; +const UINT32 OP_PUSH_Ib = 0x6a; +const UINT32 OP_IMUL_Gv_Ev_Ib = 0x6b; +const UINT32 OP_INS_Yb_DX = 0x6c; +const UINT32 OP_INS_Yz_DX = 0x6d; +const UINT32 OP_OUTS_DX_Xb = 0x6e; +const UINT32 OP_OUTS_DX_Xz = 0x6f; + +const UINT32 OP_JCC_O_Jb = 0x70; +const UINT32 OP_JCC_NO_Jb = 0x71; +const UINT32 OP_JCC_B_Jb = 0x72; +const UINT32 OP_JCC_C_Jb = 0x72; +const UINT32 OP_JCC_NAE_Jb = 0x72; +const UINT32 OP_JCC_AE_Jb = 0x73; +const UINT32 OP_JCC_NB_Jb = 0x73; +const UINT32 OP_JCC_NC_Jb = 0x73; +const UINT32 OP_JCC_E_Jb = 0x74; +const UINT32 OP_JCC_Z_Jb = 0x74; +const UINT32 OP_JCC_NE_Jb = 0x75; +const UINT32 OP_JCC_NZ_Jb = 0x75; +const UINT32 OP_JCC_BE_Jb = 0x76; +const UINT32 OP_JCC_NA_Jb = 0x76; +const UINT32 OP_JCC_A_Jb = 0x77; +const UINT32 OP_JCC_NBE_Jb = 0x77; +const UINT32 OP_JCC_S_Jb = 0x78; +const UINT32 OP_JCC_NS_Jb = 0x79; +const UINT32 OP_JCC_P_Jb = 0x7a; +const UINT32 OP_JCC_PE_Jb = 0x7a; +const UINT32 OP_JCC_NP_Jb = 0x7b; +const UINT32 OP_JCC_PO_Jb = 0x7b; +const UINT32 OP_JCC_L_Jb = 0x7c; +const UINT32 OP_JCC_NGE_Jb = 0x7c; +const UINT32 OP_JCC_NL_Jb = 0x7d; +const UINT32 OP_JCC_GE_Jb = 0x7d; +const UINT32 OP_JCC_LE_Jb = 0x7e; +const UINT32 OP_JCC_NG_Jb = 0x7e; +const UINT32 OP_JCC_NLE_Jb = 0x7f; +const UINT32 OP_JCC_G_Jb = 0x7f; + +const UINT32 OP_G1_Eb_Ib = (0x80 | OPFLAG_8BITRM); +const UINT32 OP_G1_Ev_Iz = 0x81; +const UINT32 OP_G1_Eb_Ibx = (0x82 | OPFLAG_8BITRM); +const UINT32 OP_G1_Ev_Ib = 0x83; +const UINT32 OP_TEST_Eb_Gb = (0x84 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_TEST_Ev_Gv = 0x85; +const UINT32 OP_XCHG_Eb_Gb = (0x86 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_XCHG_Ev_Gv = 0x87; +const UINT32 OP_MOV_Eb_Gb = (0x88 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_MOV_Ev_Gv = 0x89; +const UINT32 OP_MOV_Gb_Eb = (0x8a | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_MOV_Gv_Ev = 0x8b; +const UINT32 OP_MOV_Ev_Sw = 0x8c; +const UINT32 OP_LEA_Gv_M = 0x8d; +const UINT32 OP_MOV_Sw_Ew = 0x8e; +const UINT32 OP_G1A_Ev = 0x8f; + +const UINT32 OP_NOP = 0x90; +const UINT32 OP_PAUSE = 0x90; +const UINT32 OP_XCHG_rCX = 0x91; +const UINT32 OP_XCHG_rDX = 0x92; +const UINT32 OP_XCHG_rBX = 0x93; +const UINT32 OP_XCHG_rSP = 0x94; +const UINT32 OP_XCHG_rBP = 0x95; +const UINT32 OP_XCHG_rSI = 0x96; +const UINT32 OP_XCHG_rDI = 0x97; +const UINT32 OP_CBW = 0x98; +const UINT32 OP_CWDE = 0x98; +const UINT32 OP_CDQE = 0x98; +const UINT32 OP_CWD = 0x99; +const UINT32 OP_CDQ = 0x99; +const UINT32 OP_CQO = 0x99; +const UINT32 OP_CALLF_Ap = 0x9a; +const UINT32 OP_FWAIT = 0x9b; +const UINT32 OP_PUSHF_Fv = 0x9c; +const UINT32 OP_POPF_Fv = 0x9d; +const UINT32 OP_SAHF = 0x9e; +const UINT32 OP_LAHF = 0x9f; + +const UINT32 OP_MOV_AL_Ob = 0xa0; +const UINT32 OP_MOV_rAX_Ov = 0xa1; +const UINT32 OP_MOV_Ob_AL = 0xa2; +const UINT32 OP_MOV_Ov_rAX = 0xa3; +const UINT32 OP_MOVS_Xb_Yb = 0xa4; +const UINT32 OP_MOVS_Xv_Yv = 0xa5; +const UINT32 OP_CMPS_Xb_Yb = 0xa6; +const UINT32 OP_CMPS_Xv_Yv = 0xa7; +const UINT32 OP_TEST_AL_Ib = 0xa8; +const UINT32 OP_TEST_rAX_Iz = 0xa9; +const UINT32 OP_STOS_Yb_AL = 0xaa; +const UINT32 OP_STOS_Yv_rAX = 0xab; +const UINT32 OP_LODS_AL_Xb = 0xac; +const UINT32 OP_LODS_rAX_Xv = 0xad; +const UINT32 OP_SCAS_AL_Yb = 0xae; +const UINT32 OP_SCAC_rAX_Yv = 0xaf; + +const UINT32 OP_MOV_AL_Ib = 0xb0; +const UINT32 OP_MOV_CL_Ib = 0xb1; +const UINT32 OP_MOV_DL_Ib = 0xb2; +const UINT32 OP_MOV_BL_Ib = 0xb3; +const UINT32 OP_MOV_AH_Ib = 0xb4; +const UINT32 OP_MOV_CH_Ib = 0xb5; +const UINT32 OP_MOV_DH_Ib = 0xb6; +const UINT32 OP_MOV_BH_Ib = 0xb7; +const UINT32 OP_MOV_rAX_Iv = 0xb8; +const UINT32 OP_MOV_rCX_Iv = 0xb9; +const UINT32 OP_MOV_rDX_Iv = 0xba; +const UINT32 OP_MOV_rBX_Iv = 0xbb; +const UINT32 OP_MOV_rSP_Iv = 0xbc; +const UINT32 OP_MOV_rBP_Iv = 0xbd; +const UINT32 OP_MOV_rSI_Iv = 0xbe; +const UINT32 OP_MOV_rDI_Iv = 0xbf; + +const UINT32 OP_G2_Eb_Ib = (0xc0 | OPFLAG_8BITRM); +const UINT32 OP_G2_Ev_Ib = 0xc1; +const UINT32 OP_RETN_Iw = 0xc2; +const UINT32 OP_RETN = 0xc3; +const UINT32 OP_LES_Gz_Mp = 0xc4; +const UINT32 OP_LDS_Gz_Mp = 0xc5; +const UINT32 OP_G11_Eb_Ib = (0xc6 | OPFLAG_8BITRM); +const UINT32 OP_G11_Ev_Iz = 0xc7; +const UINT32 OP_ENTER_Iw_Ib = 0xc8; +const UINT32 OP_LEAVE = 0xc9; +const UINT32 OP_RETF_Iw = 0xca; +const UINT32 OP_RETF = 0xcb; +const UINT32 OP_INT_3 = 0xcc; +const UINT32 OP_INT_Ib = 0xcd; +const UINT32 OP_INTO = 0xce; +const UINT32 OP_IRET = 0xcf; + +const UINT32 OP_G2_Eb_1 = (0xd0 | OPFLAG_8BITRM); +const UINT32 OP_G2_Ev_1 = 0xd1; +const UINT32 OP_G2_Eb_CL = (0xd2 | OPFLAG_8BITRM); +const UINT32 OP_G2_Ev_CL = 0xd3; +const UINT32 OP_AAM = 0xd4; +const UINT32 OP_AAD = 0xd5; +const UINT32 OP_XLAT = 0xd7; +const UINT32 OP_ESC_D8 = 0xd8; +const UINT32 OP_ESC_D9 = 0xd9; +const UINT32 OP_ESC_DA = 0xda; +const UINT32 OP_ESC_DB = 0xdb; +const UINT32 OP_ESC_DC = 0xdc; +const UINT32 OP_ESC_DD = 0xdd; +const UINT32 OP_ESC_DE = 0xde; +const UINT32 OP_ESC_DF = 0xdf; + +const UINT32 OP_LOOPNE_Jb = 0xe0; +const UINT32 OP_LOOPE_Jb = 0xe1; +const UINT32 OP_LOOP_Jb = 0xe2; +const UINT32 OP_JrCXZ_Jb = 0xe3; +const UINT32 OP_IN_AL_Ib = 0xe4; +const UINT32 OP_IN_eAX_Ib = 0xe5; +const UINT32 OP_OUT_Ib_AL = 0xe6; +const UINT32 OP_OUT_Ib_eAX = 0xe7; +const UINT32 OP_CALL_Jz = 0xe8; +const UINT32 OP_JMP_Jz = 0xe9; +const UINT32 OP_JMPF_AP = 0xea; +const UINT32 OP_JMP_Jb = 0xeb; +const UINT32 OP_IN_AL_DX = 0xec; +const UINT32 OP_IN_eAX_D = 0xed; +const UINT32 OP_OUT_DX_AL = 0xee; +const UINT32 OP_OUT_DX_eAX = 0xef; + +const UINT32 PREFIX_LOCK = 0xf0; +const UINT32 PREFIX_REPNE = 0xf2; +const UINT32 PREFIX_REPE = 0xf3; +const UINT32 OP_HLT = 0xf4; +const UINT32 OP_CMC = 0xf5; +const UINT32 OP_G3_Eb = (0xf6 | OPFLAG_8BITRM); +const UINT32 OP_G3_Ev = 0xf7; +const UINT32 OP_CLC = 0xf8; +const UINT32 OP_STC = 0xf9; +const UINT32 OP_CLI = 0xfa; +const UINT32 OP_STI = 0xfb; +const UINT32 OP_CLD = 0xfc; +const UINT32 OP_STD = 0xfd; +const UINT32 OP_G4 = 0xfe; +const UINT32 OP_G5 = 0xff; + + +// double byte opcodes +const UINT32 OP_G6 = 0x0f00; +const UINT32 OP_G7 = 0x0f01; +const UINT32 OP_LAR_Gv_Ew = 0x0f02; +const UINT32 OP_LSL_Gv_Ew = 0x0f03; +const UINT32 OP_SYSCALL = 0x0f05; +const UINT32 OP_CLTS = 0x0f06; +const UINT32 OP_SYSRET = 0x0f07; +const UINT32 OP_INVD = 0x0f08; +const UINT32 OP_WBINVD = 0x0f09; +const UINT32 OP_UD2 = 0x0f0b; +const UINT32 OP_NOP0d_Ev = 0x0f0d; + +const UINT32 OP_MOVUPS_Vps_Wps = 0x0f10; +const UINT32 OP_MOVSS_Vss_Wss = 0xf30f10; +const UINT32 OP_MOVUPD_Vpd_Wpd = 0x660f10; +const UINT32 OP_MOVSD_Vsd_Wsd = 0xf20f10; +const UINT32 OP_MOVUPS_Wps_Vps = 0x0f11; +const UINT32 OP_MOVSS_Wss_Vss = 0xf30f11; +const UINT32 OP_MOVUPD_Wpd_Vpd = 0x660f11; +const UINT32 OP_MOVSD_Wsd_Vsd = 0xf20f11; +const UINT32 OP_MOVLPS_Vq_Mq = 0x0f12; +const UINT32 OP_MOVLPD_Vq_Mq = 0x660f12; +const UINT32 OP_MOVHLPS_Vq_Uq = 0x0f12; +const UINT32 OP_MOVDDUP_Vq_Wq = 0xf20f12; +const UINT32 OP_MOVSLDUP_Vq_Wq = 0xf30f12; +const UINT32 OP_MOVLPS_Mq_Vq = 0x0f13; +const UINT32 OP_MOVLPD_Mq_Vq = 0x660f13; +const UINT32 OP_UNPCKLPS_Vps_Wq = 0x0f14; +const UINT32 OP_UNPCKLPD_Vpd_Wq = 0x660f14; +const UINT32 OP_UNPCKHPS_Vps_Wq = 0x0f15; +const UINT32 OP_UNPCKHPD_Vpd_Wq = 0x660f15; +const UINT32 OP_MOVHPS_Vq_Mq = 0x0f16; +const UINT32 OP_MOVHPD_Vq_Mq = 0x660f16; +const UINT32 OP_MOVLHPS_Vq_Uq = 0x0f16; +const UINT32 OP_MOVSHDUP_Vq_Wq = 0xf30f16; +const UINT32 OP_MOVHPS_Mq_Vq = 0x0f17; +const UINT32 OP_MOVHPD_Mq_Vq = 0x660f17; +const UINT32 OP_PREFETCH_G16 = 0x0f18; +const UINT32 OP_NOP1f_Ev = 0x0f1f; + +const UINT32 OP_MOV_Rd_Cd = 0x0f20; +const UINT32 OP_MOV_Rd_Dd = 0x0f21; +const UINT32 OP_MOV_Cd_Rd = 0x0f22; +const UINT32 OP_MOV_Dd_Rd = 0x0f23; +const UINT32 OP_MOVAPS_Vps_Wps = 0x0f28; +const UINT32 OP_MOVAPD_Vpd_Wpd = 0x660f28; +const UINT32 OP_MOVAPS_Wps_Vps = 0x0f29; +const UINT32 OP_MOVAPD_Wpd_Vpd = 0x660f29; +const UINT32 OP_CVTPI2PS_Vps_Qq = 0x0f2a; +const UINT32 OP_CVTSI2SS_Vss_Ed = 0xf30f2a; +const UINT32 OP_CVTPI2PD_Vpd_Qq = 0x660f2a; +const UINT32 OP_CVTSI2SD_Vsd_Ed = 0xf20f2a; +const UINT32 OP_MOVNTPS_Mps_Vps = 0x0f2b; +const UINT32 OP_MOVNTPD_Mpd_Vpd = 0x660f2b; +const UINT32 OP_CVTTPS2PI_Pq_Wq = 0x0f2c; +const UINT32 OP_CVTTSS2SI_Gd_Wss = 0xf30f2c; +const UINT32 OP_CVTTPD2PI_Pq_Wpd = 0x660f2c; +const UINT32 OP_CVTTSD2SI_Gd_Wsd = 0xf20f2c; +const UINT32 OP_CVTPS2PI_Pq_Wq = 0x0f2d; +const UINT32 OP_CVTSS2SI_Gd_Wss = 0xf30f2d; +const UINT32 OP_CVTPD2PI_Pq_Wpd = 0x660f2d; +const UINT32 OP_CVTSD2SI_Gd_Wsd = 0xf20f2d; +const UINT32 OP_UCOMISS_Vss_Wss = 0x0f2e; +const UINT32 OP_UCOMISD_Vsd_Wsd = 0x660f2e; +const UINT32 OP_COMISS_Vss_Wss = 0x0f2f; +const UINT32 OP_COMISD_Vsd_Wsd = 0x660f2f; + +const UINT32 OP_WRMSR = 0x0f30; +const UINT32 OP_RDTSC = 0x0f31; +const UINT32 OP_RDMSR = 0x0f32; +const UINT32 OP_RDPMC = 0x0f33; +const UINT32 OP_SYSENTER = 0x0f34; +const UINT32 OP_SYSEXIT = 0x0f35; +const UINT32 OP_GETSEC = 0x0f37; + +const UINT32 OP_CMOV_O_Gv_Ev = 0x0f40; +const UINT32 OP_CMOV_NO_Gv_Ev = 0x0f41; +const UINT32 OP_CMOV_B_Gv_Ev = 0x0f42; +const UINT32 OP_CMOV_C_Gv_Ev = 0x0f42; +const UINT32 OP_CMOV_AE_Gv_Ev = 0x0f43; +const UINT32 OP_CMOV_NC_Gv_Ev = 0x0f43; +const UINT32 OP_CMOV_E_Gv_Ev = 0x0f44; +const UINT32 OP_CMOV_Z_Gv_Ev = 0x0f44; +const UINT32 OP_CMOV_NE_Gv_Ev = 0x0f45; +const UINT32 OP_CMOV_NZ_Gv_Ev = 0x0f45; +const UINT32 OP_CMOV_BE_Gv_Ev = 0x0f46; +const UINT32 OP_CMOV_A_Gv_Ev = 0x0f47; +const UINT32 OP_CMOV_S_Gv_Ev = 0x0f48; +const UINT32 OP_CMOV_NS_Gv_Ev = 0x0f49; +const UINT32 OP_CMOV_P_Gv_Ev = 0x0f4a; +const UINT32 OP_CMOV_PE_Gv_Ev = 0x0f4a; +const UINT32 OP_CMOV_NP_Gv_Ev = 0x0f4b; +const UINT32 OP_CMOV_PO_Gv_Ev = 0x0f4b; +const UINT32 OP_CMOV_L_Gv_Ev = 0x0f4c; +const UINT32 OP_CMOV_NGE_Gv_Ev = 0x0f4c; +const UINT32 OP_CMOV_NL_Gv_Ev = 0x0f4d; +const UINT32 OP_CMOV_GE_Gv_Ev = 0x0f4d; +const UINT32 OP_CMOV_LE_Gv_Ev = 0x0f4e; +const UINT32 OP_CMOV_NG_Gv_Ev = 0x0f4e; +const UINT32 OP_CMOV_NLE_Gv_Ev = 0x0f4f; +const UINT32 OP_CMOV_G_Gv_Ev = 0x0f4f; + +const UINT32 OP_MOVMSKPS_Gd_Ups = 0x0f50; +const UINT32 OP_MOVMSKPD_Gd_Upd = 0x660f50; +const UINT32 OP_SQRTPS_Vps_Wps = 0x0f51; +const UINT32 OP_SQRTSS_Vss_Wss = 0xf30f51; +const UINT32 OP_SQRTPD_Vpd_Wpd = 0x660f51; +const UINT32 OP_SQRTSD_Vsd_Wsd = 0xf20f51; +const UINT32 OP_RSQRTPS_Vps_Wps = 0x0f52; +const UINT32 OP_RSQRTSS_Vss_Wss = 0xf30f52; +const UINT32 OP_RCPPS_Vps_Wps = 0x0f53; +const UINT32 OP_RCPSS_Vss_Wss = 0xf30f53; +const UINT32 OP_ANDPS_Vps_Wps = 0x0f54; +const UINT32 OP_ANDPD_Vpd_Wpd = 0x660f54; +const UINT32 OP_ANDNPS_Vps_Wps = 0x0f55; +const UINT32 OP_ANDNPD_Vpd_Wpd = 0x660f55; +const UINT32 OP_ORPS_Vps_Wps = 0x0f56; +const UINT32 OP_ORPD_Vpd_Wpd = 0x660f56; +const UINT32 OP_XORPS_Vps_Wps = 0x0f57; +const UINT32 OP_XORPD_Vpd_Wpd = 0x660f57; +const UINT32 OP_ADDPS_Vps_Wps = 0x0f58; +const UINT32 OP_ADDSS_Vss_Wss = 0xf30f58; +const UINT32 OP_ADDPD_Vpd_Wpd = 0x660f58; +const UINT32 OP_ADDSD_Vsd_Wsd = 0xf20f58; +const UINT32 OP_MULPS_Vps_Wps = 0x0f59; +const UINT32 OP_MULSS_Vss_Wss = 0xf30f59; +const UINT32 OP_MULPD_Vpd_Wpd = 0x660f59; +const UINT32 OP_MULSD_Vsd_Wsd = 0xf20f59; +const UINT32 OP_CVTPS2PD_Vpd_Wq = 0x0f5a; +const UINT32 OP_CVTSS2SD_Vsd_Wss = 0xf30f5a; +const UINT32 OP_CVTPD2PS_Vps_Wpd = 0x660f5a; +const UINT32 OP_CVTSD2SS_Vss_Wsd = 0xf20f5a; +const UINT32 OP_CVTDQ2PS_Vps_Wdq = 0x0f5b; +const UINT32 OP_CVTPS2DQ_Vdq_Wps = 0x660f5b; +const UINT32 OP_CVTTPS2DQ_Vdq_Wps = 0xf30f5b; +const UINT32 OP_SUBPS_Vps_Wps = 0x0f5c; +const UINT32 OP_SUBSS_Vss_Wss = 0xf30f5c; +const UINT32 OP_SUBPD_Vpd_Wpd = 0x660f5c; +const UINT32 OP_SUBSD_Vsd_Wsd = 0xf20f5c; +const UINT32 OP_MINPS_Vps_Wps = 0x0f5d; +const UINT32 OP_MINSS_Vss_Wss = 0xf30f5d; +const UINT32 OP_MINPD_Vpd_Wpd = 0x660f5d; +const UINT32 OP_MINSD_Vsd_Wsd = 0xf20f5d; +const UINT32 OP_DIVPS_Vps_Wps = 0x0f5e; +const UINT32 OP_DIVSS_Vss_Wss = 0xf30f5e; +const UINT32 OP_DIVPD_Vpd_Wpd = 0x660f5e; +const UINT32 OP_DIVSD_Vsd_Wsd = 0xf20f5e; +const UINT32 OP_MAXPS_Vps_Wps = 0x0f5f; +const UINT32 OP_MAXSS_Vss_Wss = 0xf30f5f; +const UINT32 OP_MAXPD_Vpd_Wpd = 0x660f5f; +const UINT32 OP_MAXSD_Vsd_Wsd = 0xf20f5f; + +const UINT32 OP_PUNPCKLBW_Pq_Qd = 0x0f60; +const UINT32 OP_PUNPCKLBW_Vdq_Wdq = 0x660f60; +const UINT32 OP_PUNPCKLWD_Pq_Qd = 0x0f61; +const UINT32 OP_PUNPCKLWD_Vdq_Wdq = 0x660f61; +const UINT32 OP_PUNPCKLDQ_Pq_Qd = 0x0f62; +const UINT32 OP_PUNPCKLDQ_Vdq_Wdq = 0x660f62; +const UINT32 OP_PACKSSWB_Pq_Qq = 0x0f63; +const UINT32 OP_PACKSSWB_Vdq_Wdq = 0x660f63; +const UINT32 OP_PCMPGTB_Pq_Qq = 0x0f64; +const UINT32 OP_PCMPGTB_Vdq_Wdq = 0x660f64; +const UINT32 OP_PCMPGTW_Pq_Qq = 0x0f65; +const UINT32 OP_PCMPGTW_Vdq_Wdq = 0x660f65; +const UINT32 OP_PCMPGTD_Pq_Qq = 0x0f66; +const UINT32 OP_PCMPGTD_Vdq_Wdq = 0x660f66; +const UINT32 OP_PACKUSWB_Pq_Qq = 0x0f67; +const UINT32 OP_PACKUSWB_Vdq_Wdq = 0x660f67; +const UINT32 OP_PUNPCKHBW_Pq_Qq = 0x0f68; +const UINT32 OP_PUNPCKHBW_Vdq_Qdq = 0x660f68; +const UINT32 OP_PUNPCKHWD_Pq_Qq = 0x0f69; +const UINT32 OP_PUNPCKHWD_Vdq_Qdq = 0x660f69; +const UINT32 OP_PUNPCKHDQ_Pq_Qq = 0x0f6a; +const UINT32 OP_PUNPCKHDQ_Vdq_Qdq = 0x660f6a; +const UINT32 OP_PACKSSDW_Pq_Qq = 0x0f6b; +const UINT32 OP_PACKSSDW_Vdq_Qdq = 0x660f6b; +const UINT32 OP_PUNPCKLQDQ_Vdq_Wdq = 0x660f6c; +const UINT32 OP_PUNPCKHQDQ_Vdq_Wdq = 0x660f6d; +const UINT32 OP_MOVD_Pd_Ed = 0x0f6e; +const UINT32 OP_MOVD_Vd_Ed = 0x660f6e; +const UINT32 OP_MOVQ_Pq_Qq = 0x0f6f; +const UINT32 OP_MOVDQA_Vdq_Wdq = 0x660f6f; +const UINT32 OP_MOVDQU_Vdq_Wdq = 0xf30f6f; + +const UINT32 OP_PSHUFW_Pq_Qq_Ib = 0x0f70; +const UINT32 OP_PSHUFD_Vdq_Wdq_Ib = 0x660f70; +const UINT32 OP_PSHUFHW_Vdq_Wdq_Ib = 0xf30f70; +const UINT32 OP_PSHUFLW_Vdq_Wdq_Ib = 0xf20f70; +const UINT32 OP_G12 = 0x0f71; +const UINT32 OP_G13 = 0x0f72; +const UINT32 OP_G14 = 0x0f73; +const UINT32 OP_PCMPEQB_Pq_Qq = 0x0f74; +const UINT32 OP_PCMPEQB_Vdq_Wdq = 0x660f74; +const UINT32 OP_PCMPEQW_Pq_Qq = 0x0f75; +const UINT32 OP_PCMPEQW_Vdq_Wdq = 0x660f75; +const UINT32 OP_PCMPEQD_Pq_Qq = 0x0f76; +const UINT32 OP_PCMPEQD_Vdq_Wdq = 0x660f76; +const UINT32 OP_EMMS = 0x0f77; +const UINT32 OP_VMREAD_Ed_Gd = 0x0f78; +const UINT32 OP_VMWRITE_Gd_Ed = 0x0f79; +const UINT32 OP_HADDPD_Vpd_Wpd = 0x660f7c; +const UINT32 OP_HADDPS_Vps_Wps = 0xf20f7c; +const UINT32 OP_HSUBPD_Vpd_Wpd = 0x660f7d; +const UINT32 OP_HSUBPS_Vps_Wps = 0xf20f7d; +const UINT32 OP_MOVD_Ed_Pd = 0x0f7e; +const UINT32 OP_MOVD_Ed_Vd = 0x660f7e; +const UINT32 OP_MOVQ_Vq_Wq = 0xf30f7e; +const UINT32 OP_MOVQ_Qq_Pq = 0x0f7f; +const UINT32 OP_MOVDQA_Wdq_Vdq = 0x660f7f; +const UINT32 OP_MOVDQU_Wdq_Vdq = 0xf30f7f; + +const UINT32 OP_JCC_O_Jv = 0x0f80; +const UINT32 OP_JCC_NO_Jv = 0x0f81; +const UINT32 OP_JCC_B_Jv = 0x0f82; +const UINT32 OP_JCC_C_Jv = 0x0f82; +const UINT32 OP_JCC_NAE_Jv = 0x0f82; +const UINT32 OP_JCC_AE_Jv = 0x0f83; +const UINT32 OP_JCC_NB_Jv = 0x0f83; +const UINT32 OP_JCC_NC_Jv = 0x0f83; +const UINT32 OP_JCC_E_Jv = 0x0f84; +const UINT32 OP_JCC_Z_Jv = 0x0f84; +const UINT32 OP_JCC_NE_Jv = 0x0f85; +const UINT32 OP_JCC_NZ_Jv = 0x0f85; +const UINT32 OP_JCC_BE_Jv = 0x0f86; +const UINT32 OP_JCC_NA_Jv = 0x0f86; +const UINT32 OP_JCC_A_Jv = 0x0f87; +const UINT32 OP_JCC_NBE_Jv = 0x0f87; +const UINT32 OP_JCC_S_Jv = 0x0f88; +const UINT32 OP_JCC_NS_Jv = 0x0f89; +const UINT32 OP_JCC_P_Jv = 0x0f8a; +const UINT32 OP_JCC_PE_Jv = 0x0f8a; +const UINT32 OP_JCC_NP_Jv = 0x0f8b; +const UINT32 OP_JCC_PO_Jv = 0x0f8b; +const UINT32 OP_JCC_L_Jv = 0x0f8c; +const UINT32 OP_JCC_NGE_Jv = 0x0f8c; +const UINT32 OP_JCC_NL_Jv = 0x0f8d; +const UINT32 OP_JCC_GE_Jv = 0x0f8d; +const UINT32 OP_JCC_LE_Jv = 0x0f8e; +const UINT32 OP_JCC_NG_Jv = 0x0f8e; +const UINT32 OP_JCC_NLE_Jv = 0x0f8f; +const UINT32 OP_JCC_G_Jv = 0x0f8f; + +const UINT32 OP_SETCC_O_Eb = (0x0f90 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NO_Eb = (0x0f91 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_B_Eb = (0x0f92 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_C_Eb = (0x0f92 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NAE_Eb = (0x0f92 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_AE_Eb = (0x0f93 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NB_Eb = (0x0f93 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NC_Eb = (0x0f93 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_E_Eb = (0x0f94 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_Z_Eb = (0x0f94 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NE_Eb = (0x0f95 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NZ_Eb = (0x0f95 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_BE_Eb = (0x0f96 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NA_Eb = (0x0f96 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_A_Eb = (0x0f97 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NBE_Eb = (0x0f97 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_S_Eb = (0x0f98 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NS_Eb = (0x0f99 | OPFLAG_8BITRM); +const UINT32 OP_SETCC_P_Eb = (0x0f9a | OPFLAG_8BITRM); +const UINT32 OP_SETCC_PE_Eb = (0x0f9a | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NP_Eb = (0x0f9b | OPFLAG_8BITRM); +const UINT32 OP_SETCC_PO_Eb = (0x0f9b | OPFLAG_8BITRM); +const UINT32 OP_SETCC_L_Eb = (0x0f9c | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NGE_Eb = (0x0f9c | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NL_Eb = (0x0f9d | OPFLAG_8BITRM); +const UINT32 OP_SETCC_GE_Eb = (0x0f9d | OPFLAG_8BITRM); +const UINT32 OP_SETCC_LE_Eb = (0x0f9e | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NG_Eb = (0x0f9e | OPFLAG_8BITRM); +const UINT32 OP_SETCC_NLE_Eb = (0x0f9f | OPFLAG_8BITRM); +const UINT32 OP_SETCC_G_Eb = (0x0f9f | OPFLAG_8BITRM); + +const UINT32 OP_PUSH_FS = 0x0fa0; +const UINT32 OP_POP_FS = 0x0fa1; +const UINT32 OP_CPUID = 0x0fa2; +const UINT32 OP_BT_Ev_Gv = 0x0fa3; +const UINT32 OP_SHLD_Ev_Gv_Ib = 0x0fa4; +const UINT32 OP_SHLD_Ev_Gv_CL = 0x0fa5; +const UINT32 OP_PUSH_GS = 0x0fa8; +const UINT32 OP_POP_GS = 0x0fa9; +const UINT32 OP_RSM = 0x0faa; +const UINT32 OP_BTS_Ev_Gv = 0x0fab; +const UINT32 OP_SHRD_Ev_Gv_Ib = 0x0fac; +const UINT32 OP_SHRD_Ev_Gv_CL = 0x0fad; +const UINT32 OP_G16 = 0x0fae; +const UINT32 OP_IMUL_Gv_Ev = 0x0faf; + +const UINT32 OP_CMPXCHG_Eb_Gb = (0x0fb0 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_CMPXCHG_Ev_Gv = 0x0fb1; +const UINT32 OP_LSS_Mp = 0x0fb2; +const UINT32 OP_BTR_Ev_Gv = 0x0fb3; +const UINT32 OP_LFS_Mp = 0x0fb4; +const UINT32 OP_LGS_Mp = 0x0fb5; +const UINT32 OP_MOVZX_Gv_Eb = (0x0fb6 | OPFLAG_8BITRM); +const UINT32 OP_MOVZX_Gv_Ew = 0x0fb7; +const UINT32 OP_JMPE = 0x0fb8; +const UINT32 OP_POPCNT_Gv_Ev = 0xf30fb8; +const UINT32 OP_G10_INVALID = 0x0fb9; +const UINT32 OP_G8_Ev_Ib = 0x0fba; +const UINT32 OP_BTC_Ev_Gv = 0x0fbb; +const UINT32 OP_BSF_Gv_Ev = 0x0fbc; +const UINT32 OP_BSR_Gv_Ev = 0x0fbd; +const UINT32 OP_MOVSX_Gv_Eb = (0x0fbe | OPFLAG_8BITRM); +const UINT32 OP_MOVSX_Gv_Ew = 0x0fbf; + +const UINT32 OP_XADD_Eb_Gb = (0x0fc0 | OPFLAG_8BITRM | OPFLAG_8BITREG); +const UINT32 OP_XADD_Ev_Gv = 0x0fc1; +const UINT32 OP_CMPPS_Vps_Wps_Ib = 0x0fc2; +const UINT32 OP_CMPSS_Vss_Wss_Ib = 0xf30fc2; +const UINT32 OP_CMPPD_Vpd_Wpd_Ib = 0x660fc2; +const UINT32 OP_CMPSD_Vsd_Wsd_Ib = 0xf20fc2; +const UINT32 OP_MOVNTI_Md_Gd = 0x0fc3; +const UINT32 OP_PINSRW_Pw_Ew_Ib = 0x0fc4; +const UINT32 OP_PINSRW_Vw_Ew_Ib = 0x660fc4; +const UINT32 OP_PEXTRW_Gw_Pw_Ib = 0x0fc5; +const UINT32 OP_PEXTRW_Gw_Vw_Ib = 0x660fc5; +const UINT32 OP_SHUFPS_Vps_Wps_Ib = 0x0fc6; +const UINT32 OP_SHUFPD_Vpd_Wpd_Ib = 0x660fc6; +const UINT32 OP_G9 = 0x0fc7; +const UINT32 OP_BSWAP_EAX = 0x0fc8; +const UINT32 OP_BSWAP_ECX = 0x0fc9; +const UINT32 OP_BSWAP_EDX = 0x0fca; +const UINT32 OP_BSWAP_EBX = 0x0fcb; +const UINT32 OP_BSWAP_ESP = 0x0fcc; +const UINT32 OP_BSWAP_EBP = 0x0fcd; +const UINT32 OP_BSWAP_ESI = 0x0fce; +const UINT32 OP_BSWAP_EDI = 0x0fcf; + +const UINT32 OP_ADDSUBPD_Vpd_Wpd = 0x0fd0; +const UINT32 OP_ADDSUBPS_Vps_Wps = 0xf20fd0; +const UINT32 OP_PSRLW_Pq_Qq = 0x0fd1; +const UINT32 OP_PSRLW_Vdq_Wdq = 0x660fd1; +const UINT32 OP_PSRLD_Pq_Qq = 0x0fd2; +const UINT32 OP_PSRLD_Vdq_Wdq = 0x660fd2; +const UINT32 OP_PSRLQ_Pq_Qq = 0x0fd3; +const UINT32 OP_PSRLQ_Vdq_Wdq = 0x660fd3; +const UINT32 OP_PADDQ_Pq_Qq = 0x0fd4; +const UINT32 OP_PADDQ_Vdq_Wdq = 0x660fd4; +const UINT32 OP_PMULLW_Pq_Qq = 0x0fd5; +const UINT32 OP_PMULLW_Vdq_Wdq = 0x660fd5; +const UINT32 OP_MOVQ_Wq_Vq = 0x0fd6; +const UINT32 OP_MOVQ2DQ_Vdq_Qq = 0xf30fd6; +const UINT32 OP_MOVDQ2Q_Pq_Vq = 0xf20fd6; +const UINT32 OP_PMOVMSKB_Gd_Pq = 0x0fd7; +const UINT32 OP_PMOVMSKB_Gd_Vdq = 0x660fd7; +const UINT32 OP_PSUBUSB_Pq_Qq = 0x0fd8; +const UINT32 OP_PSUBUSB_Vdq_Wdq = 0x660fd8; +const UINT32 OP_PSUBUSW_Pq_Qq = 0x0fd9; +const UINT32 OP_PSUBUSW_Vdq_Wdq = 0x660fd9; +const UINT32 OP_PMINUB_Pq_Qq = 0x0fda; +const UINT32 OP_PMINUB_Vdq_Wdq = 0x660fda; +const UINT32 OP_PAND_Pq_Qq = 0x0fdb; +const UINT32 OP_PAND_Vdq_Wdq = 0x660fdb; +const UINT32 OP_PADDUSB_Pq_Qq = 0x0fdc; +const UINT32 OP_PADDUSB_Vdq_Wdq = 0x660fdc; +const UINT32 OP_PADDUSW_Pq_Qq = 0x0fdd; +const UINT32 OP_PADDUSW_Vdq_Wdq = 0x660fdd; +const UINT32 OP_PMAXUB_Pq_Qq = 0x0fde; +const UINT32 OP_PMAXUB_Vdq_Wdq = 0x660fde; +const UINT32 OP_PANDN_Pq_Qq = 0x0fdf; +const UINT32 OP_PANDN_Vdq_Wdq = 0x660fdf; + +const UINT32 OP_PAVGB_Pq_Qq = 0x0fe0; +const UINT32 OP_PAVGB_Vdq_Wdq = 0x660fe0; +const UINT32 OP_PSRAW_Pq_Qq = 0x0fe1; +const UINT32 OP_PSRAW_Vdq_Wdq = 0x660fe1; +const UINT32 OP_PSRAD_Pq_Qq = 0x0fe2; +const UINT32 OP_PSRAD_Vdq_Wdq = 0x660fe2; +const UINT32 OP_PAVGW_Pq_Qq = 0x0fe3; +const UINT32 OP_PAVGW_Vdq_Wdq = 0x660fe3; +const UINT32 OP_PMULHUW_Pq_Qq = 0x0fe4; +const UINT32 OP_PMULHUW_Vdq_Wdq = 0x660fe4; +const UINT32 OP_PMULHW_Pq_Qq = 0x0fe5; +const UINT32 OP_PMULHW_Vdq_Wdq = 0x660fe5; +const UINT32 OP_CVTPD2DQ_Vdq_Wpd = 0xf20fe6; +const UINT32 OP_CVTTPD2DQ_Vdq_Wpd = 0x660fe6; +const UINT32 OP_CVTDQ2PD_Vpd_Wq = 0xf30fe6; +const UINT32 OP_MOVNTQ_Mq_Vq = 0x0fe7; +const UINT32 OP_MOVNTDQ_Mdq_Vdq = 0x660fe7; +const UINT32 OP_PSUBSB_Pq_Qq = 0x0fe8; +const UINT32 OP_PSUBSB_Vdq_Wdq = 0x660fe8; +const UINT32 OP_PSUBSW_Pq_Qq = 0x0fe9; +const UINT32 OP_PSUBSW_Vdq_Wdq = 0x660fe9; +const UINT32 OP_PMINSW_Pq_Qq = 0x0fea; +const UINT32 OP_PMINSW_Vdq_Wdq = 0x660fea; +const UINT32 OP_POR_Pq_Qq = 0x0feb; +const UINT32 OP_POR_Vdq_Wdq = 0x660feb; +const UINT32 OP_PADDSB_Pq_Qq = 0x0fec; +const UINT32 OP_PADDSB_Vdq_Wdq = 0x660fec; +const UINT32 OP_PADDSW_Pq_Qq = 0x0fed; +const UINT32 OP_PADDSW_Vdq_Wdq = 0x660fed; +const UINT32 OP_PMAXSW_Pq_Qq = 0x0fee; +const UINT32 OP_PMAXSW_Vdq_Wdq = 0x660fee; +const UINT32 OP_PXOR_Pq_Qq = 0x0fef; +const UINT32 OP_PXOR_Vdq_Wdq = 0x660fef; + +const UINT32 OP_LDDQU_Vdq_Mdq = 0xf20ff0; +const UINT32 OP_PSLLW_Pq_Qq = 0x0ff1; +const UINT32 OP_PSLLW_Vdq_Wdq = 0x660ff1; +const UINT32 OP_PSLLD_Pq_Qq = 0x0ff2; +const UINT32 OP_PSLLD_Vdq_Wdq = 0x660ff2; +const UINT32 OP_PSLLQ_Pq_Qq = 0x0ff3; +const UINT32 OP_PSLLQ_Vdq_Wdq = 0x660ff3; +const UINT32 OP_PMULUDQ_Pq_Qq = 0x0ff4; +const UINT32 OP_PMULUDQ_Vdq_Wdq = 0x660ff4; +const UINT32 OP_PMADDWD_Pq_Qq = 0x0ff5; +const UINT32 OP_PMADDWD_Vdq_Wdq = 0x660ff5; +const UINT32 OP_PSADBW_Pq_Qq = 0x0ff6; +const UINT32 OP_PSADBW_Vdq_Wdq = 0x660ff6; +const UINT32 OP_MASKMOVQ_Pq_Qq = 0x0ff7; +const UINT32 OP_MASKMOVDQU_Vdq_Wdq = 0x660ff7; +const UINT32 OP_PSUBB_Pq_Qq = 0x0ff8; +const UINT32 OP_PSUBB_Vdq_Wdq = 0x660ff8; +const UINT32 OP_PSUBW_Pq_Qq = 0x0ff9; +const UINT32 OP_PSUBW_Vdq_Wdq = 0x660ff9; +const UINT32 OP_PSUBD_Pq_Qq = 0x0ffa; +const UINT32 OP_PSUBD_Vdq_Wdq = 0x660ffa; +const UINT32 OP_PSUBQ_Pq_Qq = 0x0ffb; +const UINT32 OP_PSUBQ_Vdq_Wdq = 0x660ffb; +const UINT32 OP_PADDB_Pq_Qq = 0x0ffc; +const UINT32 OP_PADDB_Vdq_Wdq = 0x660ffc; +const UINT32 OP_PADDW_Pq_Qq = 0x0ffd; +const UINT32 OP_PADDW_Vdq_Wdq = 0x660ffd; +const UINT32 OP_PADDD_Pq_Qq = 0x0ffe; +const UINT32 OP_PADDD_Vdq_Wdq = 0x660ffe; + + +// triple byte opcodes (0f 38) +const UINT32 OP_PSHUFB_Pq_Qq = 0x0f3800; +const UINT32 OP_PSHUFB_Vdq_Wdq = 0x660f3800; +const UINT32 OP_PHADDW_Pq_Qq = 0x0f3801; +const UINT32 OP_PHADDW_Vdq_Wdq = 0x660f3801; +const UINT32 OP_PHADDD_Pq_Qq = 0x0f3802; +const UINT32 OP_PHADDD_Vdq_Wdq = 0x660f3802; +const UINT32 OP_PHADDSW_Pq_Qq = 0x0f3803; +const UINT32 OP_PHADDSW_Vdq_Wdq = 0x660f3803; +const UINT32 OP_PMADDUBSW_Pq_Qq = 0x0f3804; +const UINT32 OP_PMADDUBSW_Vdq_Wdq = 0x660f3804; +const UINT32 OP_PHSUBW_Pq_Qq = 0x0f3805; +const UINT32 OP_PHSUBW_Vdq_Wdq = 0x660f3805; +const UINT32 OP_PHSUBD_Pq_Qq = 0x0f3806; +const UINT32 OP_PHSUBD_Vdq_Wdq = 0x660f3806; +const UINT32 OP_PHSUBSW_Pq_Qq = 0x0f3807; +const UINT32 OP_PHSUBSW_Vdq_Wdq = 0x660f3807; +const UINT32 OP_PSIGNB_Pq_Qq = 0x0f3808; +const UINT32 OP_PSIGNB_Vdq_Wdq = 0x660f3808; +const UINT32 OP_PSIGNW_Pq_Qq = 0x0f3809; +const UINT32 OP_PSIGNW_Vdq_Wdq = 0x660f3809; +const UINT32 OP_PSIGND_Pq_Qq = 0x0f380a; +const UINT32 OP_PSIGND_Vdq_Wdq = 0x660f380a; +const UINT32 OP_PMULHRSW_Pq_Qq = 0x0f380b; +const UINT32 OP_PMULHRSW_Vdq_Wdq = 0x660f380b; + +const UINT32 OP_PBLENDVB_Vdq_Wdq = 0x660f3810; +const UINT32 OP_PBLENDVPS_Vdq_Wdq = 0x660f3814; +const UINT32 OP_PBLENDVPD_Vdq_Wdq = 0x660f3815; +const UINT32 OP_PTEST_Vdq_Wdq = 0x660f3817; +const UINT32 OP_PABSB_Pq_Qq = 0x0f381c; +const UINT32 OP_PABSB_Vdq_Wdq = 0x660f381c; +const UINT32 OP_PABSW_Pq_Qq = 0x0f381d; +const UINT32 OP_PABSW_Vdq_Wdq = 0x660f381d; +const UINT32 OP_PABSD_Pq_Qq = 0x0f381e; +const UINT32 OP_PABSD_Vdq_Wdq = 0x660f381e; + +const UINT32 OP_PMOVSXBW_Vdq_Udq = 0x660f3820; +const UINT32 OP_PMOVSXBD_Vdq_Udq = 0x660f3821; +const UINT32 OP_PMOVSXBQ_Vdq_Udq = 0x660f3822; +const UINT32 OP_PMOVSXWD_Vdq_Udq = 0x660f3823; +const UINT32 OP_PMOVSXWQ_Vdq_Udq = 0x660f3824; +const UINT32 OP_PMOVSXDQ_Vdq_Udq = 0x660f3825; +const UINT32 OP_PMULDQ_Vdq_Udq = 0x660f3828; +const UINT32 OP_PCMPEQQ_Vdq_Udq = 0x660f3829; +const UINT32 OP_MOVNTDQA_Vdq_Udq = 0x660f382a; +const UINT32 OP_PACKUSDW_Vdq_Udq = 0x660f382b; + +const UINT32 OP_PMOVZXBW_Vdq_Udq = 0x660f3830; +const UINT32 OP_PMOVZXBD_Vdq_Udq = 0x660f3831; +const UINT32 OP_PMOVZXBQ_Vdq_Udq = 0x660f3832; +const UINT32 OP_PMOVZXWD_Vdq_Udq = 0x660f3833; +const UINT32 OP_PMOVZXWQ_Vdq_Udq = 0x660f3834; +const UINT32 OP_PMOVZXDQ_Vdq_Udq = 0x660f3835; +const UINT32 OP_PMINSB_Vdq_Udq = 0x660f3838; +const UINT32 OP_PMINSD_Vdq_Udq = 0x660f3839; +const UINT32 OP_PMINUW_Vdq_Udq = 0x660f383a; +const UINT32 OP_PMINUD_Vdq_Udq = 0x660f383b; +const UINT32 OP_PMAXSB_Vdq_Udq = 0x660f383c; +const UINT32 OP_PMAXSD_Vdq_Udq = 0x660f383d; +const UINT32 OP_PMAXUW_Vdq_Udq = 0x660f383e; +const UINT32 OP_PMAXUD_Vdq_Udq = 0x660f383f; + +const UINT32 OP_MULLD_Vdq_Wdq = 0x660f3840; +const UINT32 OP_PHMINPOSUW_Vdq_Wdq = 0x660f3841; + +const UINT32 OP_NVEPT_Gd_Mdq = 0x660f3880; +const UINT32 OP_NVVPID_Gd_Mdq = 0x660f3881; + +const UINT32 OP_MOVBE_Gv_Mv = 0x0f38f0; +const UINT32 OP_CRC32_Gd_Eb = 0xf20f38f0; +const UINT32 OP_MOVBE_Mv_Gv = 0x0f38f1; +const UINT32 OP_CRC32_Gd_Ev = 0xf20f38f1; + + +// triple byte opcodes (0f 3a) +const UINT32 OP_ROUNDPS_Vdq_Wdq_Ib = 0x660f3a08; +const UINT32 OP_ROUNDPD_Vdq_Wdq_Ib = 0x660f3a09; +const UINT32 OP_ROUNDSS_Vss_Wss_Ib = 0x660f3a0a; +const UINT32 OP_ROUNDSD_Vsd_Wsd_Ib = 0x660f3a0b; +const UINT32 OP_BLENDPS_Vdq_Wdq_Ib = 0x660f3a0c; +const UINT32 OP_BLENDPD_Vdq_Wdq_Ib = 0x660f3a0d; +const UINT32 OP_PBLENDW_Vdq_Wdq_Ib = 0x660f3a0e; +const UINT32 OP_PALIGNR_Pq_Qq_Ib = 0x0f3a0f; +const UINT32 OP_PALIGNR_Vdq_Wdq_Ib = 0x660f3a0f; + +const UINT32 OP_EXTRB_Rd_Vdq_Ib = 0x660f3a14; +const UINT32 OP_EXTRW_Rd_Vdq_Ib = 0x660f3a15; +const UINT32 OP_EXTRD_Rd_Vdq_Ib = 0x660f3a16; +const UINT32 OP_EXTRACTPS_Ed_Vdq_Ib = 0x660f3a17; + +const UINT32 OP_PINSRB_Vdq_Rd_Ib = 0x660f3a20; +const UINT32 OP_INSERTPS_Vdq_Udq_Ib = 0x660f3a21; +const UINT32 OP_PINSRD_Vdq_Ed_Ib = 0x660f3a22; + +const UINT32 OP_DPPS_Vdq_Wdq_Ib = 0x660f3a40; +const UINT32 OP_DPPD_Vdq_Wdq_Ib = 0x660f3a41; +const UINT32 OP_MPSADBW_Vdq_Wdq_Ib = 0x660f3a42; + +const UINT32 OP_PCMPESTRM_Vdq_Wdq_Ib = 0x660f3a60; +const UINT32 OP_PCMPESTRI_Vdq_Wdq_Ib = 0x660f3a61; +const UINT32 OP_PCMPISTRM_Vdq_Wdq_Ib = 0x660f3a62; +const UINT32 OP_PCMPISTRI_Vdq_Wdq_Ib = 0x660f3a63; + + +// floating point opcodes +const UINT32 OP_FADD_ST0_STn = 0xd8c0; +const UINT32 OP_FMUL_ST0_STn = 0xd8c8; +const UINT32 OP_FCOM_ST0_STn = 0xd8d0; +const UINT32 OP_FCOMP_ST0_STn = 0xd8d8; +const UINT32 OP_FSUB_ST0_STn = 0xd8e0; +const UINT32 OP_FSUBR_ST0_STn = 0xd8e8; +const UINT32 OP_FDIV_ST0_STn = 0xd8f0; +const UINT32 OP_FDIVR_ST0_STn = 0xd8f8; +const UINT32 OP_FLD_ST0_STn = 0xd9c0; +const UINT32 OP_FXCH_ST0_STn = 0xd9c8; +const UINT32 OP_FNOP = 0xd9d0; +const UINT32 OP_FCHS = 0xd9e0; +const UINT32 OP_FABS = 0xd9e1; +const UINT32 OP_FTST = 0xd9e4; +const UINT32 OP_FXAM = 0xd9e5; +const UINT32 OP_FLD1 = 0xd9e8; +const UINT32 OP_FLDL2T = 0xd9e9; +const UINT32 OP_FLDL2E = 0xd9ea; +const UINT32 OP_FLDPI = 0xd9eb; +const UINT32 OP_FLDLG2 = 0xd9ec; +const UINT32 OP_FLDLN2 = 0xd9ed; +const UINT32 OP_FLDZ = 0xd9ee; +const UINT32 OP_F2XM1 = 0xd9f0; +const UINT32 OP_FYL2X = 0xd9f1; +const UINT32 OP_FPTAN = 0xd9f2; +const UINT32 OP_FPATAN = 0xd9f3; +const UINT32 OP_FXTRACT = 0xd9f4; +const UINT32 OP_FPREM1 = 0xd9f5; +const UINT32 OP_FDECSTP = 0xd9f6; +const UINT32 OP_FINCSTP = 0xd9f7; +const UINT32 OP_FPREM = 0xd9f8; +const UINT32 OP_FYL2XP1 = 0xd9f9; +const UINT32 OP_FSQRT = 0xd9fa; +const UINT32 OP_FSINCOS = 0xd9fb; +const UINT32 OP_FRNDINT = 0xd9fc; +const UINT32 OP_FSCALE = 0xd9fd; +const UINT32 OP_FSIN = 0xd9fe; +const UINT32 OP_FCOS = 0xd9ff; +const UINT32 OP_FCMOVB_ST0_STn = 0xdac0; +const UINT32 OP_FCMOVE_ST0_STn = 0xdac8; +const UINT32 OP_FCMOVBE_ST0_STn = 0xdad0; +const UINT32 OP_FCMOVU_ST0_STn = 0xdad8; +const UINT32 OP_FUCOMPP = 0xdae9; +const UINT32 OP_FCMOVNB_ST0_STn = 0xdbc0; +const UINT32 OP_FCMOVNE_ST0_STn = 0xdbc8; +const UINT32 OP_FCMOVNBE_ST0_STn = 0xdbd0; +const UINT32 OP_FCMOVNU_ST0_STn = 0xdbd8; +const UINT32 OP_FCLEX = 0xdbe2; +const UINT32 OP_FINIT = 0xdbe3; +const UINT32 OP_FUCOMI_ST0_STn = 0xdbe8; +const UINT32 OP_FCOMI_ST0_STn = 0xdbf0; +const UINT32 OP_FADD_STn_ST0 = 0xdcc0; +const UINT32 OP_FMUL_STn_ST0 = 0xdcc8; +const UINT32 OP_FSUBR_STn_ST0 = 0xdce0; +const UINT32 OP_FSUB_STn_ST0 = 0xdce8; +const UINT32 OP_FDIVR_STn_ST0 = 0xdcf0; +const UINT32 OP_FDIV_STn_ST0 = 0xdcf8; +const UINT32 OP_FFREE_STn = 0xddc0; +const UINT32 OP_FST_STn = 0xddd0; +const UINT32 OP_FSTP_STn = 0xddd8; +const UINT32 OP_FUCOM_STn_ST0 = 0xdde0; +const UINT32 OP_FUCOMP_STn = 0xdde8; +const UINT32 OP_FADDP_STn_ST0 = 0xdec0; +const UINT32 OP_FMULP_STn_ST0 = 0xdec8; +const UINT32 OP_FCOMPP = 0xded9; +const UINT32 OP_FSUBRP_STn_ST0 = 0xdee0; +const UINT32 OP_FSUBP_STn_ST0 = 0xdee8; +const UINT32 OP_FDIVRP_STn_ST0 = 0xdef0; +const UINT32 OP_FDIVP_STn_ST0 = 0xdef8; +const UINT32 OP_FSTSW_AX = 0xdfe0; +const UINT32 OP_FCOMIP_ST0_STn = 0xdff0; + + + +//************************************************************************** +// MEMORY REFERENCES +//************************************************************************** + +inline x86_memref MBD(UINT8 base, INT32 disp) { return x86_memref(base, REG_NONE, 1, disp); } +inline x86_memref MBISD(UINT8 base, UINT8 ind, UINT8 scale, INT32 disp) { return x86_memref(base, ind, scale, disp); } + +#if (X86EMIT_SIZE == 32) +inline x86_memref MABS(const void *mem) { return x86_memref(REG_NONE, REG_NONE, 1, reinterpret_cast<FPTR>(const_cast<void *>(mem))); } +inline x86_memref MABSI(const void *mem, UINT8 index) { return x86_memref(index, REG_NONE, 1, reinterpret_cast<FPTR>(const_cast<void *>(mem))); } +inline x86_memref MABSI(const void *mem, UINT8 index, UINT8 scale) { return x86_memref(REG_NONE, index, scale, reinterpret_cast<FPTR>(const_cast<void *>(mem))); } #endif -/*************************************************************************** - CORE FUNCTIONS -***************************************************************************/ +//************************************************************************** +// CORE FUNCTIONS +//************************************************************************** -/*------------------------------------------------- - make_modrm - assemble a modrm byte from the - three components --------------------------------------------------*/ +//------------------------------------------------- +// make_modrm - assemble a modrm byte from the +// three components +//------------------------------------------------- -INLINE UINT8 make_modrm(UINT8 mode, UINT8 reg, UINT8 rm) +inline UINT8 make_modrm(UINT8 mode, UINT8 reg, UINT8 rm) { assert(mode < 4); assert(reg < REG_MAX); @@ -1174,12 +1229,12 @@ INLINE UINT8 make_modrm(UINT8 mode, UINT8 reg, UINT8 rm) } -/*------------------------------------------------- - make_sib - assemble an sib byte from the - three components --------------------------------------------------*/ +//------------------------------------------------- +// make_sib - assemble an sib byte from the +// three components +//------------------------------------------------- -INLINE UINT8 make_sib(UINT8 scale, UINT8 index, UINT8 base) +inline UINT8 make_sib(UINT8 scale, UINT8 index, UINT8 base) { static const UINT8 scale_lookup[9] = { 0<<6, 0<<6, 1<<6, 0<<6, 2<<6, 0<<6, 0<<6, 0<<6, 3<<6 }; assert(scale == 1 || scale == 2 || scale == 4 || scale == 8); @@ -1189,66 +1244,66 @@ INLINE UINT8 make_sib(UINT8 scale, UINT8 index, UINT8 base) } -/*------------------------------------------------- - emit_byte - emit a byte --------------------------------------------------*/ +//------------------------------------------------- +// emit_byte - emit a byte +//------------------------------------------------- -INLINE void emit_byte(x86code **emitptr, UINT8 byte) +inline void emit_byte(x86code *&emitptr, UINT8 byte) { - *((UINT8 *)*emitptr) = byte; - *emitptr += 1; + *((UINT8 *)emitptr) = byte; + emitptr += 1; } -/*------------------------------------------------- - emit_word - emit a word --------------------------------------------------*/ +//------------------------------------------------- +// emit_word - emit a word +//------------------------------------------------- -INLINE void emit_word(x86code **emitptr, UINT16 word) +inline void emit_word(x86code *&emitptr, UINT16 word) { - *((UINT16 *)*emitptr) = word; - *emitptr += 2; + *((UINT16 *)emitptr) = word; + emitptr += 2; } -/*------------------------------------------------- - emit_dword - emit a dword --------------------------------------------------*/ +//------------------------------------------------- +// emit_dword - emit a dword +//------------------------------------------------- -INLINE void emit_dword(x86code **emitptr, UINT32 dword) +inline void emit_dword(x86code *&emitptr, UINT32 dword) { - *((UINT32 *)*emitptr) = dword; - *emitptr += 4; + *((UINT32 *)emitptr) = dword; + emitptr += 4; } -/*------------------------------------------------- - emit_qword - emit a dword --------------------------------------------------*/ +//------------------------------------------------- +// emit_qword - emit a dword +//------------------------------------------------- -INLINE void emit_qword(x86code **emitptr, UINT64 qword) +inline void emit_qword(x86code *&emitptr, UINT64 qword) { - *((UINT64 *)*emitptr) = qword; - *emitptr += 8; + *((UINT64 *)emitptr) = qword; + emitptr += 8; } -/*************************************************************************** - GENERIC OPCODE EMITTERS -***************************************************************************/ +//************************************************************************** +// GENERIC OPCODE EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_op - emit a 1, 2, or 3-byte opcode, - along with any necessary REX prefixes for x64 --------------------------------------------------*/ +//------------------------------------------------- +// emit_op - emit a 1, 2, or 3-byte opcode, +// along with any necessary REX prefixes for x64 +//------------------------------------------------- -INLINE void emit_op(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 sib, UINT8 rm) +inline void emit_op(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 sib, UINT8 rm) { if (opsize == OP_16BIT) emit_byte(emitptr, PREFIX_OPSIZE); -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) { UINT8 rex; @@ -1270,33 +1325,33 @@ INLINE void emit_op(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 } -/*------------------------------------------------- - emit_op_simple - emit a simple opcode --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_simple - emit a simple opcode +//------------------------------------------------- -INLINE void emit_op_simple(x86code **emitptr, UINT32 op, UINT8 opsize) +inline void emit_op_simple(x86code *&emitptr, UINT32 op, UINT8 opsize) { emit_op(emitptr, op, opsize, 0, 0, 0); } -/*------------------------------------------------- - emit_op_reg - emit a simple opcode that has - a register parameter --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_reg - emit a simple opcode that has +// a register parameter +//------------------------------------------------- -INLINE void emit_op_reg(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg) +inline void emit_op_reg(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg) { emit_op(emitptr, op, opsize, 0, 0, reg); } -/*------------------------------------------------- - emit_op_modrm_reg - emit an opcode with a - register modrm byte --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg - emit an opcode with a +// register modrm byte +//------------------------------------------------- -INLINE void emit_op_modrm_reg(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm) +inline void emit_op_modrm_reg(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm) { assert(reg < REG_MAX); assert(rm < REG_MAX); @@ -1306,160 +1361,160 @@ INLINE void emit_op_modrm_reg(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 } -/*------------------------------------------------- - emit_op_modrm_mem - emit an opcode with a - memory modrm byte --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem - emit an opcode with a +// memory modrm byte +//------------------------------------------------- -INLINE void emit_op_modrm_mem(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS) +inline void emit_op_modrm_mem(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, x86_memref memref) { assert(reg < REG_MAX); - assert(base < REG_MAX || base == REG_NONE); - assert(index < REG_MAX || index == REG_NONE); + assert(memref.m_base < REG_MAX || memref.m_base == REG_NONE); + assert(memref.m_index < REG_MAX || memref.m_index == REG_NONE); - /* turn off the OPFLAG_8BITRM flag since it only applies to register operands */ + // turn off the OPFLAG_8BITRM flag since it only applies to register operands op &= ~OPFLAG_8BITRM; - /* displacement only case */ - if (base == REG_NONE && index == REG_NONE) + // displacement only case + if (memref.m_base == REG_NONE && memref.m_index == REG_NONE) { -#ifndef PTR64 +#if (X86EMIT_SIZE == 32) emit_op(emitptr, op, opsize, reg, 0, 5); emit_byte(emitptr, make_modrm(0, reg, 5)); - emit_dword(emitptr, disp); + emit_dword(emitptr, memref.m_disp); #else fatalerror("Invalid absolute mode in 64-bits!\n"); #endif } - /* base only case */ - else if (index == REG_NONE && (base & 7) != REG_ESP) + // base only case + else if (memref.m_index == REG_NONE && (memref.m_base & 7) != REG_ESP) { - emit_op(emitptr, op, opsize, reg, 0, base); + emit_op(emitptr, op, opsize, reg, 0, memref.m_base); - /* mode 0 for no offset */ - if (disp == 0 && (base & 7) != REG_EBP) - emit_byte(emitptr, make_modrm(0, reg, base)); + // mode 0 for no offset + if (memref.m_disp == 0 && (memref.m_base & 7) != REG_EBP) + emit_byte(emitptr, make_modrm(0, reg, memref.m_base)); - /* mode 1 for 1-byte offset */ - else if ((INT8)disp == disp) + // mode 1 for 1-byte offset + else if ((INT8)memref.m_disp == memref.m_disp) { - emit_byte(emitptr, make_modrm(1, reg, base)); - emit_byte(emitptr, (INT8)disp); + emit_byte(emitptr, make_modrm(1, reg, memref.m_base)); + emit_byte(emitptr, (INT8)memref.m_disp); } - /* mode 2 for 4-byte offset */ + // mode 2 for 4-byte offset else { - emit_byte(emitptr, make_modrm(2, reg, base)); - emit_dword(emitptr, disp); + emit_byte(emitptr, make_modrm(2, reg, memref.m_base)); + emit_dword(emitptr, memref.m_disp); } } - /* full BISD case */ + // full BISD case else { - assert(index != REG_ESP); - emit_op(emitptr, op, opsize, reg, index, base); + assert(memref.m_index != REG_ESP); + emit_op(emitptr, op, opsize, reg, memref.m_index, memref.m_base); - /* a "none" index == REG_ESP */ - if (index == REG_NONE) - index = REG_ESP; + // a "none" index == REG_ESP + if (memref.m_index == REG_NONE) + memref.m_index = REG_ESP; - /* no base is a special case */ - if (base == REG_NONE) + // no base is a special case + if (memref.m_base == REG_NONE) { emit_byte(emitptr, make_modrm(0, reg, 4)); - emit_byte(emitptr, make_sib(scale, index, REG_EBP)); - emit_dword(emitptr, disp); + emit_byte(emitptr, make_sib(memref.m_scale, memref.m_index, REG_EBP)); + emit_dword(emitptr, memref.m_disp); } - /* mode 0 for no offset */ - else if (disp == 0 && (base & 7) != REG_EBP) + // mode 0 for no offset + else if (memref.m_disp == 0 && (memref.m_base & 7) != REG_EBP) { emit_byte(emitptr, make_modrm(0, reg, 4)); - emit_byte(emitptr, make_sib(scale, index, base)); + emit_byte(emitptr, make_sib(memref.m_scale, memref.m_index, memref.m_base)); } - /* mode 1 for 1-byte offset */ - else if ((INT8)disp == disp) + // mode 1 for 1-byte offset + else if ((INT8)memref.m_disp == memref.m_disp) { emit_byte(emitptr, make_modrm(1, reg, 4)); - emit_byte(emitptr, make_sib(scale, index, base)); - emit_byte(emitptr, (INT8)disp); + emit_byte(emitptr, make_sib(memref.m_scale, memref.m_index, memref.m_base)); + emit_byte(emitptr, (INT8)memref.m_disp); } - /* mode 2 for 4-byte offset */ + // mode 2 for 4-byte offset else { emit_byte(emitptr, make_modrm(2, reg, 4)); - emit_byte(emitptr, make_sib(scale, index, base)); - emit_dword(emitptr, disp); + emit_byte(emitptr, make_sib(memref.m_scale, memref.m_index, memref.m_base)); + emit_dword(emitptr, memref.m_disp); } } } -/*************************************************************************** - GENERIC OPCODE + IMMEDIATE EMITTERS -***************************************************************************/ +//************************************************************************** +// GENERIC OPCODE + IMMEDIATE EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_op_modrm_reg_imm8 - emit an opcode with a - register modrm byte and an 8-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg_imm8 - emit an opcode with a +// register modrm byte and an 8-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_reg_imm8(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT8 imm) +inline void emit_op_modrm_reg_imm8(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT8 imm) { emit_op_modrm_reg(emitptr, op, opsize, reg, rm); emit_byte(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_mem_imm8 - emit an opcode with a - memory modrm byte and an 8-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem_imm8 - emit an opcode with a +// memory modrm byte and an 8-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_mem_imm8(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS, UINT8 imm) +inline void emit_op_modrm_mem_imm8(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, x86_memref memref, UINT8 imm) { - emit_op_modrm_mem(emitptr, op, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op, opsize, reg, memref); emit_byte(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_reg_imm16 - emit an opcode with a - register modrm byte and a 16-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg_imm16 - emit an opcode with a +// register modrm byte and a 16-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_reg_imm16(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT16 imm) +inline void emit_op_modrm_reg_imm16(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT16 imm) { emit_op_modrm_reg(emitptr, op, opsize, reg, rm); emit_word(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_mem_imm16 - emit an opcode with a - memory modrm byte and a 16-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem_imm16 - emit an opcode with a +// memory modrm byte and a 16-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_mem_imm16(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS, UINT16 imm) +inline void emit_op_modrm_mem_imm16(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, x86_memref memref, UINT16 imm) { - emit_op_modrm_mem(emitptr, op, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op, opsize, reg, memref); emit_word(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_reg_imm816 - emit an opcode with - a register modrm byte and an 8-bit or 16-bit - immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg_imm816 - emit an opcode with +// a register modrm byte and an 8-bit or 16-bit +// immediate +//------------------------------------------------- -INLINE void emit_op_modrm_reg_imm816(x86code **emitptr, UINT32 op8, UINT32 op16, UINT8 opsize, UINT8 reg, UINT8 rm, UINT16 imm) +inline void emit_op_modrm_reg_imm816(x86code *&emitptr, UINT32 op8, UINT32 op16, UINT8 opsize, UINT8 reg, UINT8 rm, UINT16 imm) { if ((INT8)imm == (INT16)imm) { @@ -1474,58 +1529,58 @@ INLINE void emit_op_modrm_reg_imm816(x86code **emitptr, UINT32 op8, UINT32 op16, } -/*------------------------------------------------- - emit_op_modrm_mem_imm816 - emit an opcode with - a memory modrm byte and an 8-bit or 16-bit - immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem_imm816 - emit an opcode with +// a memory modrm byte and an 8-bit or 16-bit +// immediate +//------------------------------------------------- -INLINE void emit_op_modrm_mem_imm816(x86code **emitptr, UINT32 op8, UINT32 op16, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS, UINT16 imm) +inline void emit_op_modrm_mem_imm816(x86code *&emitptr, UINT32 op8, UINT32 op16, UINT8 opsize, UINT8 reg, x86_memref memref, UINT16 imm) { if ((INT8)imm == (INT16)imm) { - emit_op_modrm_mem(emitptr, op8, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op8, opsize, reg, memref); emit_byte(emitptr, imm); } else { - emit_op_modrm_mem(emitptr, op16, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op16, opsize, reg, memref); emit_word(emitptr, imm); } } -/*------------------------------------------------- - emit_op_modrm_reg_imm32 - emit an opcode with a - register modrm byte and a 32-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg_imm32 - emit an opcode with a +// register modrm byte and a 32-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_reg_imm32(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT32 imm) +inline void emit_op_modrm_reg_imm32(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, UINT8 rm, UINT32 imm) { emit_op_modrm_reg(emitptr, op, opsize, reg, rm); emit_dword(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_mem_imm32 - emit an opcode with a - memory modrm byte and a 32-bit immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem_imm32 - emit an opcode with a +// memory modrm byte and a 32-bit immediate +//------------------------------------------------- -INLINE void emit_op_modrm_mem_imm32(x86code **emitptr, UINT32 op, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS, UINT32 imm) +inline void emit_op_modrm_mem_imm32(x86code *&emitptr, UINT32 op, UINT8 opsize, UINT8 reg, x86_memref memref, UINT32 imm) { - emit_op_modrm_mem(emitptr, op, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op, opsize, reg, memref); emit_dword(emitptr, imm); } -/*------------------------------------------------- - emit_op_modrm_reg_imm832 - emit an opcode with - a register modrm byte and an 8-bit or 32-bit - immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_reg_imm832 - emit an opcode with +// a register modrm byte and an 8-bit or 32-bit +// immediate +//------------------------------------------------- -INLINE void emit_op_modrm_reg_imm832(x86code **emitptr, UINT32 op8, UINT32 op32, UINT8 opsize, UINT8 reg, UINT8 rm, UINT32 imm) +inline void emit_op_modrm_reg_imm832(x86code *&emitptr, UINT32 op8, UINT32 op32, UINT8 opsize, UINT8 reg, UINT8 rm, UINT32 imm) { if ((INT8)imm == (INT32)imm) { @@ -1540,233 +1595,233 @@ INLINE void emit_op_modrm_reg_imm832(x86code **emitptr, UINT32 op8, UINT32 op32, } -/*------------------------------------------------- - emit_op_modrm_mem_imm832 - emit an opcode with - a memory modrm byte and an 8-bit or 32-bit - immediate --------------------------------------------------*/ +//------------------------------------------------- +// emit_op_modrm_mem_imm832 - emit an opcode with +// a memory modrm byte and an 8-bit or 32-bit +// immediate +//------------------------------------------------- -INLINE void emit_op_modrm_mem_imm832(x86code **emitptr, UINT32 op8, UINT32 op32, UINT8 opsize, UINT8 reg, DECLARE_MEMPARAMS, UINT32 imm) +inline void emit_op_modrm_mem_imm832(x86code *&emitptr, UINT32 op8, UINT32 op32, UINT8 opsize, UINT8 reg, x86_memref memref, UINT32 imm) { if ((INT8)imm == (INT32)imm) { - emit_op_modrm_mem(emitptr, op8, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op8, opsize, reg, memref); emit_byte(emitptr, imm); } else { - emit_op_modrm_mem(emitptr, op32, opsize, reg, MEMPARAMS); + emit_op_modrm_mem(emitptr, op32, opsize, reg, memref); emit_dword(emitptr, imm); } } -/*************************************************************************** - SIMPLE OPCODE EMITTERS -***************************************************************************/ +//************************************************************************** +// SIMPLE OPCODE EMITTERS +//************************************************************************** -INLINE void emit_nop(x86code **emitptr) { emit_op_simple(emitptr, OP_NOP, OP_32BIT); } -INLINE void emit_int_3(x86code **emitptr) { emit_op_simple(emitptr, OP_INT_3, OP_32BIT); } -INLINE void emit_ret(x86code **emitptr) { emit_op_simple(emitptr, OP_RETN, OP_32BIT); } -INLINE void emit_cdq(x86code **emitptr) { emit_op_simple(emitptr, OP_CDQ, OP_32BIT); } -INLINE void emit_clc(x86code **emitptr) { emit_op_simple(emitptr, OP_CLC, OP_32BIT); } -INLINE void emit_stc(x86code **emitptr) { emit_op_simple(emitptr, OP_STC, OP_32BIT); } -INLINE void emit_cmc(x86code **emitptr) { emit_op_simple(emitptr, OP_CMC, OP_32BIT); } -INLINE void emit_pushf(x86code **emitptr) { emit_op_simple(emitptr, OP_PUSHF_Fv, OP_32BIT); } -INLINE void emit_popf(x86code **emitptr) { emit_op_simple(emitptr, OP_POPF_Fv, OP_32BIT); } -INLINE void emit_cpuid(x86code **emitptr) { emit_op_simple(emitptr, OP_CPUID, OP_32BIT); } - -#ifndef PTR64 -INLINE void emit_pushad(x86code **emitptr) { emit_op_simple(emitptr, OP_PUSHA, OP_32BIT); } -INLINE void emit_popad(x86code **emitptr) { emit_op_simple(emitptr, OP_POPA, OP_32BIT); } -INLINE void emit_lahf(x86code **emitptr) { emit_op_simple(emitptr, OP_LAHF, OP_32BIT); } -INLINE void emit_sahf(x86code **emitptr) { emit_op_simple(emitptr, OP_SAHF, OP_32BIT); } +inline void emit_nop(x86code *&emitptr) { emit_op_simple(emitptr, OP_NOP, OP_32BIT); } +inline void emit_int_3(x86code *&emitptr) { emit_op_simple(emitptr, OP_INT_3, OP_32BIT); } +inline void emit_ret(x86code *&emitptr) { emit_op_simple(emitptr, OP_RETN, OP_32BIT); } +inline void emit_cdq(x86code *&emitptr) { emit_op_simple(emitptr, OP_CDQ, OP_32BIT); } +inline void emit_clc(x86code *&emitptr) { emit_op_simple(emitptr, OP_CLC, OP_32BIT); } +inline void emit_stc(x86code *&emitptr) { emit_op_simple(emitptr, OP_STC, OP_32BIT); } +inline void emit_cmc(x86code *&emitptr) { emit_op_simple(emitptr, OP_CMC, OP_32BIT); } +inline void emit_pushf(x86code *&emitptr) { emit_op_simple(emitptr, OP_PUSHF_Fv, OP_32BIT); } +inline void emit_popf(x86code *&emitptr) { emit_op_simple(emitptr, OP_POPF_Fv, OP_32BIT); } +inline void emit_cpuid(x86code *&emitptr) { emit_op_simple(emitptr, OP_CPUID, OP_32BIT); } + +#if (X86EMIT_SIZE == 32) +inline void emit_pushad(x86code *&emitptr) { emit_op_simple(emitptr, OP_PUSHA, OP_32BIT); } +inline void emit_popad(x86code *&emitptr) { emit_op_simple(emitptr, OP_POPA, OP_32BIT); } +inline void emit_lahf(x86code *&emitptr) { emit_op_simple(emitptr, OP_LAHF, OP_32BIT); } +inline void emit_sahf(x86code *&emitptr) { emit_op_simple(emitptr, OP_SAHF, OP_32BIT); } #endif -#ifdef PTR64 -INLINE void emit_cqo(x86code **emitptr) { emit_op_simple(emitptr, OP_CQO, OP_64BIT); } +#if (X86EMIT_SIZE == 64) +inline void emit_cqo(x86code *&emitptr) { emit_op_simple(emitptr, OP_CQO, OP_64BIT); } #endif -/*************************************************************************** - CALL/JUMP EMITTERS -***************************************************************************/ +//************************************************************************** +// CALL/JUMP EMITTERS +//************************************************************************** -/*------------------------------------------------- - resolve_link - resolve a link in a jump - instruction --------------------------------------------------*/ +//------------------------------------------------- +// resolve_link - resolve a link in a jump +// instruction +//------------------------------------------------- -INLINE void resolve_link(x86code **destptr, const emit_link *linkinfo) +inline void resolve_link(x86code *&destptr, const emit_link &linkinfo) { - INT64 delta = *destptr - linkinfo->target; - if (linkinfo->size == 1) + INT64 delta = destptr - linkinfo.target; + if (linkinfo.size == 1) { assert((INT8)delta == delta); - ((INT8 *)linkinfo->target)[-1] = (INT8)delta; + ((INT8 *)linkinfo.target)[-1] = (INT8)delta; } - else if (linkinfo->size == 2) + else if (linkinfo.size == 2) { assert((INT16)delta == delta); - ((INT16 *)linkinfo->target)[-1] = (INT16)delta; + ((INT16 *)linkinfo.target)[-1] = (INT16)delta; } else { assert((INT32)delta == delta); - ((INT32 *)linkinfo->target)[-1] = (INT32)delta; + ((INT32 *)linkinfo.target)[-1] = (INT32)delta; } } -/*------------------------------------------------- - emit_call_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_call_* +//------------------------------------------------- -INLINE void emit_call_link(x86code **emitptr, emit_link *linkinfo) +inline void emit_call_link(x86code *&emitptr, emit_link &linkinfo) { emit_op_simple(emitptr, OP_CALL_Jz, OP_32BIT); emit_dword(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 4; + linkinfo.target = emitptr; + linkinfo.size = 4; } -INLINE void emit_call(x86code **emitptr, x86code *target) +inline void emit_call(x86code *&emitptr, x86code *target) { emit_link link; - emit_call_link(emitptr, &link); - resolve_link(&target, &link); + emit_call_link(emitptr, link); + resolve_link(target, link); } -/*------------------------------------------------- - emit_jmp_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_jmp_* +//------------------------------------------------- -INLINE void emit_jmp_short_link(x86code **emitptr, emit_link *linkinfo) +inline void emit_jmp_short_link(x86code *&emitptr, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JMP_Jb, OP_32BIT); emit_byte(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 1; + linkinfo.target = emitptr; + linkinfo.size = 1; } -INLINE void emit_jmp_near_link(x86code **emitptr, emit_link *linkinfo) +inline void emit_jmp_near_link(x86code *&emitptr, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JMP_Jz, OP_32BIT); emit_dword(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 4; + linkinfo.target = emitptr; + linkinfo.size = 4; } -INLINE void emit_jmp(x86code **emitptr, x86code *target) +inline void emit_jmp(x86code *&emitptr, x86code *target) { - INT32 delta = target - (*emitptr + 2); + INT32 delta = target - (emitptr + 2); emit_link link; if ((INT8)delta == delta) - emit_jmp_short_link(emitptr, &link); + emit_jmp_short_link(emitptr, link); else - emit_jmp_near_link(emitptr, &link); - resolve_link(&target, &link); + emit_jmp_near_link(emitptr, link); + resolve_link(target, link); } -/*------------------------------------------------- - emit_jcc_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_jcc_* +//------------------------------------------------- -INLINE void emit_jcc_short_link(x86code **emitptr, UINT8 cond, emit_link *linkinfo) +inline void emit_jcc_short_link(x86code *&emitptr, UINT8 cond, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JCC_O_Jb + cond, OP_32BIT); emit_byte(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 1; + linkinfo.target = emitptr; + linkinfo.size = 1; } -INLINE void emit_jcc_near_link(x86code **emitptr, UINT8 cond, emit_link *linkinfo) +inline void emit_jcc_near_link(x86code *&emitptr, UINT8 cond, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JCC_O_Jv + cond, OP_32BIT); emit_dword(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 4; + linkinfo.target = emitptr; + linkinfo.size = 4; } -INLINE void emit_jcc(x86code **emitptr, UINT8 cond, x86code *target) +inline void emit_jcc(x86code *&emitptr, UINT8 cond, x86code *target) { - INT32 delta = *emitptr + 2 - target; + INT32 delta = emitptr + 2 - target; emit_link link; if ((INT8)delta == delta) - emit_jcc_short_link(emitptr, cond, &link); + emit_jcc_short_link(emitptr, cond, link); else - emit_jcc_near_link(emitptr, cond, &link); - resolve_link(&target, &link); + emit_jcc_near_link(emitptr, cond, link); + resolve_link(target, link); } -/*------------------------------------------------- - emit_jecxz_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_jecxz_* +//------------------------------------------------- -INLINE void emit_jecxz_link(x86code **emitptr, emit_link *linkinfo) +inline void emit_jecxz_link(x86code *&emitptr, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JrCXZ_Jb, OP_32BIT); emit_byte(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 1; + linkinfo.target = emitptr; + linkinfo.size = 1; } -INLINE void emit_jecxz(x86code **emitptr, x86code *target) +inline void emit_jecxz(x86code *&emitptr, x86code *target) { emit_link link; - emit_jecxz_link(emitptr, &link); - resolve_link(&target, &link); + emit_jecxz_link(emitptr, link); + resolve_link(target, link); } -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_jrcxz_link(x86code **emitptr, emit_link *linkinfo) +inline void emit_jrcxz_link(x86code *&emitptr, emit_link &linkinfo) { emit_op_simple(emitptr, OP_JrCXZ_Jb, OP_64BIT); emit_byte(emitptr, 0); - linkinfo->target = *emitptr; - linkinfo->size = 1; + linkinfo.target = emitptr; + linkinfo.size = 1; } -INLINE void emit_jrcxz(x86code **emitptr, x86code *target) +inline void emit_jrcxz(x86code *&emitptr, x86code *target) { emit_link link; - emit_jrcxz_link(emitptr, &link); - resolve_link(&target, &link); + emit_jrcxz_link(emitptr, link); + resolve_link(target, link); } #endif -/*------------------------------------------------- - emit_call/jmp_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_call/jmp_* +//------------------------------------------------- -#ifndef PTR64 -INLINE void emit_call_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 2, dreg); } -INLINE void emit_call_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_jmp_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 4, dreg); } -INLINE void emit_jmp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 4, MEMPARAMS); } +#if (X86EMIT_SIZE == 32) +inline void emit_call_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 2, dreg); } +inline void emit_call_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 2, memref); } +inline void emit_jmp_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 4, dreg); } +inline void emit_jmp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 4, memref); } #else -INLINE void emit_call_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 2, dreg); } -INLINE void emit_call_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_jmp_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 4, dreg); } -INLINE void emit_jmp_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 4, MEMPARAMS); } +inline void emit_call_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 2, dreg); } +inline void emit_call_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 2, memref); } +inline void emit_jmp_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G5, OP_32BIT, 4, dreg); } +inline void emit_jmp_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 4, memref); } #endif -/*------------------------------------------------- - emit_ret_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_ret_* +//------------------------------------------------- -INLINE void emit_ret_imm(x86code **emitptr, UINT16 imm) +inline void emit_ret_imm(x86code *&emitptr, UINT16 imm) { emit_op_simple(emitptr, OP_RETN_Iw, OP_32BIT); emit_word(emitptr, imm); @@ -1774,11 +1829,11 @@ INLINE void emit_ret_imm(x86code **emitptr, UINT16 imm) -/*************************************************************************** - PUSH/POP EMITTERS -***************************************************************************/ +//************************************************************************** +// PUSH/POP EMITTERS +//************************************************************************** -INLINE void emit_push_imm(x86code **emitptr, INT32 imm) +inline void emit_push_imm(x86code *&emitptr, INT32 imm) { if ((INT8)imm == imm) { @@ -1792,49 +1847,49 @@ INLINE void emit_push_imm(x86code **emitptr, INT32 imm) } } -#ifndef PTR64 +#if (X86EMIT_SIZE == 32) -INLINE void emit_push_r32(x86code **emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_PUSH_rAX + (reg & 7), OP_32BIT, reg); } -INLINE void emit_push_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_pop_r32(x86code **emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_POP_rAX + (reg & 7), OP_32BIT, reg); } -INLINE void emit_pop_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G1A_Ev, OP_32BIT, 0, MEMPARAMS); } +inline void emit_push_r32(x86code *&emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_PUSH_rAX + (reg & 7), OP_32BIT, reg); } +inline void emit_push_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 6, memref); } +inline void emit_pop_r32(x86code *&emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_POP_rAX + (reg & 7), OP_32BIT, reg); } +inline void emit_pop_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G1A_Ev, OP_32BIT, 0, memref); } #else -INLINE void emit_push_r64(x86code **emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_PUSH_rAX + (reg & 7), OP_32BIT, reg); } -INLINE void emit_push_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_pop_r64(x86code **emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_POP_rAX + (reg & 7), OP_32BIT, reg); } -INLINE void emit_pop_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G1A_Ev, OP_32BIT, 0, MEMPARAMS); } +inline void emit_push_r64(x86code *&emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_PUSH_rAX + (reg & 7), OP_32BIT, reg); } +inline void emit_push_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G5, OP_32BIT, 6, memref); } +inline void emit_pop_r64(x86code *&emitptr, UINT8 reg) { emit_op_reg(emitptr, OP_POP_rAX + (reg & 7), OP_32BIT, reg); } +inline void emit_pop_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G1A_Ev, OP_32BIT, 0, memref); } #endif -/*************************************************************************** - MOVE EMITTERS -***************************************************************************/ +//************************************************************************** +// MOVE EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_mov_r8_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r8_* +//------------------------------------------------- -INLINE void emit_mov_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) +inline void emit_mov_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_reg(emitptr, OP_MOV_AL_Ib | (dreg & 7), OP_32BIT, dreg); emit_byte(emitptr, imm); } -INLINE void emit_mov_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_mov_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOV_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_mov_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_mov_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G11_Eb_Ib, OP_32BIT, 0, MEMPARAMS, imm); } +inline void emit_mov_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_mov_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOV_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_mov_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Eb_Gb, OP_32BIT, sreg, memref); } +inline void emit_mov_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G11_Eb_Ib, OP_32BIT, 0, memref, imm); } -/*------------------------------------------------- - emit_xchg_r8_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_xchg_r8_* +//------------------------------------------------- -INLINE void emit_xchg_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) +inline void emit_xchg_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { if (dreg == REG_EAX) emit_op_reg(emitptr, OP_NOP | (sreg & 7), OP_32BIT, sreg); @@ -1845,33 +1900,33 @@ INLINE void emit_xchg_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) } -/*------------------------------------------------- - emit_mov_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r16_* +//------------------------------------------------- -INLINE void emit_mov_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) +inline void emit_mov_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_reg(emitptr, OP_MOV_rAX_Iv | (dreg & 7), OP_16BIT, dreg); emit_word(emitptr, imm); } -INLINE void emit_mov_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_mov_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_mov_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm16(emitptr, OP_G11_Ev_Iz, OP_16BIT, 0, MEMPARAMS, imm); } -INLINE void emit_mov_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } -INLINE void emit_movsx_r16_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_16BIT, dreg, sreg); } -INLINE void emit_movsx_r16_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_movzx_r16_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Eb, OP_16BIT, dreg, sreg); } -INLINE void emit_movzx_r16_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_cmovcc_r16_r16(x86code **emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_16BIT, dreg, sreg); } -INLINE void emit_cmovcc_r16_m16(x86code **emitptr, UINT8 cond, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_16BIT, dreg, MEMPARAMS); } +inline void emit_mov_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_mov_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_mov_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm16(emitptr, OP_G11_Ev_Iz, OP_16BIT, 0, memref, imm); } +inline void emit_mov_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_16BIT, sreg, memref); } +inline void emit_movsx_r16_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_16BIT, dreg, sreg); } +inline void emit_movsx_r16_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_16BIT, dreg, memref); } +inline void emit_movzx_r16_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Eb, OP_16BIT, dreg, sreg); } +inline void emit_movzx_r16_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_16BIT, dreg, memref); } +inline void emit_cmovcc_r16_r16(x86code *&emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_16BIT, dreg, sreg); } +inline void emit_cmovcc_r16_m16(x86code *&emitptr, UINT8 cond, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_16BIT, dreg, memref); } -/*------------------------------------------------- - emit_xchg_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_xchg_r16_* +//------------------------------------------------- -INLINE void emit_xchg_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) +inline void emit_xchg_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { if (dreg == REG_EAX) emit_op_reg(emitptr, OP_NOP | (sreg & 7), OP_16BIT, sreg); @@ -1882,27 +1937,27 @@ INLINE void emit_xchg_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) } -/*------------------------------------------------- - emit_mov_r32_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r32_* +//------------------------------------------------- -INLINE void emit_mov_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) +inline void emit_mov_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_reg(emitptr, OP_MOV_rAX_Iv | (dreg & 7), OP_32BIT, dreg); emit_dword(emitptr, imm); } -INLINE void emit_mov_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_mov_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_mov_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G11_Ev_Iz, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_mov_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_movsx_r32_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_movsx_r32_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movsx_r32_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Ew, OP_32BIT, dreg, sreg); } -INLINE void emit_movsx_r32_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Ew, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movzx_r32_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) +inline void emit_mov_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_mov_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_mov_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G11_Ev_Iz, OP_32BIT, 0, memref, imm); } +inline void emit_mov_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_32BIT, sreg, memref); } +inline void emit_movsx_r32_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_32BIT, dreg, sreg); } +inline void emit_movsx_r32_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_32BIT, dreg, memref); } +inline void emit_movsx_r32_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Ew, OP_32BIT, dreg, sreg); } +inline void emit_movsx_r32_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Ew, OP_32BIT, dreg, memref); } +inline void emit_movzx_r32_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { -#ifndef PTR64 +#if (X86EMIT_SIZE == 32) if (sreg >= 4) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_32BIT, dreg, sreg); // mov dreg,sreg @@ -1912,18 +1967,18 @@ INLINE void emit_movzx_r32_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) #endif emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_movzx_r32_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movzx_r32_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Ew, OP_32BIT, dreg, sreg); } -INLINE void emit_movzx_r32_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Ew, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_cmovcc_r32_r32(x86code **emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_32BIT, dreg, sreg); } -INLINE void emit_cmovcc_r32_m32(x86code **emitptr, UINT8 cond, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_movzx_r32_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_32BIT, dreg, memref); } +inline void emit_movzx_r32_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Ew, OP_32BIT, dreg, sreg); } +inline void emit_movzx_r32_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Ew, OP_32BIT, dreg, memref); } +inline void emit_cmovcc_r32_r32(x86code *&emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_32BIT, dreg, sreg); } +inline void emit_cmovcc_r32_m32(x86code *&emitptr, UINT8 cond, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_32BIT, dreg, memref); } -/*------------------------------------------------- - emit_xchg_r32_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_xchg_r32_* +//------------------------------------------------- -INLINE void emit_xchg_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) +inline void emit_xchg_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { if (dreg == REG_EAX) emit_op_reg(emitptr, OP_NOP | (sreg & 7), OP_32BIT, sreg); @@ -1934,13 +1989,13 @@ INLINE void emit_xchg_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) } -/*------------------------------------------------- - emit_mov_r64_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_mov_r64_* +//------------------------------------------------- -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_mov_r64_imm(x86code **emitptr, UINT8 dreg, UINT64 imm) +inline void emit_mov_r64_imm(x86code *&emitptr, UINT8 dreg, UINT64 imm) { if ((UINT32)imm == imm) { @@ -1956,29 +2011,29 @@ INLINE void emit_mov_r64_imm(x86code **emitptr, UINT8 dreg, UINT64 imm) } } -INLINE void emit_mov_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_mov_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_mov_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G11_Ev_Iz, OP_64BIT, 0, MEMPARAMS, imm); } -INLINE void emit_mov_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } -INLINE void emit_movsx_r64_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_64BIT, dreg, sreg); } -INLINE void emit_movsx_r64_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_movsx_r64_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Ew, OP_64BIT, dreg, sreg); } -INLINE void emit_movsx_r64_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Ew, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_movsxd_r64_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSXD_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_movsxd_r64_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSXD_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_movzx_r64_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Eb, OP_64BIT, dreg, sreg); } -INLINE void emit_movzx_r64_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_movzx_r64_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Ew, OP_64BIT, dreg, sreg); } -INLINE void emit_movzx_r64_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Ew, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_cmovcc_r64_r64(x86code **emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_64BIT, dreg, sreg); } -INLINE void emit_cmovcc_r64_m64(x86code **emitptr, UINT8 cond, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_64BIT, dreg, MEMPARAMS); } - - -/*------------------------------------------------- - emit_xchg_r64_* --------------------------------------------------*/ - -INLINE void emit_xchg_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) +inline void emit_mov_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOV_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_mov_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOV_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_mov_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G11_Ev_Iz, OP_64BIT, 0, memref, imm); } +inline void emit_mov_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOV_Ev_Gv, OP_64BIT, sreg, memref); } +inline void emit_movsx_r64_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Eb, OP_64BIT, dreg, sreg); } +inline void emit_movsx_r64_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Eb, OP_64BIT, dreg, memref); } +inline void emit_movsx_r64_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSX_Gv_Ew, OP_64BIT, dreg, sreg); } +inline void emit_movsx_r64_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSX_Gv_Ew, OP_64BIT, dreg, memref); } +inline void emit_movsxd_r64_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSXD_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_movsxd_r64_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSXD_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_movzx_r64_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Eb, OP_64BIT, dreg, sreg); } +inline void emit_movzx_r64_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Eb, OP_64BIT, dreg, memref); } +inline void emit_movzx_r64_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVZX_Gv_Ew, OP_64BIT, dreg, sreg); } +inline void emit_movzx_r64_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVZX_Gv_Ew, OP_64BIT, dreg, memref); } +inline void emit_cmovcc_r64_r64(x86code *&emitptr, UINT8 cond, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_64BIT, dreg, sreg); } +inline void emit_cmovcc_r64_m64(x86code *&emitptr, UINT8 cond, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMOV_O_Gv_Ev + cond, OP_64BIT, dreg, memref); } + + +//------------------------------------------------- +// emit_xchg_r64_* +//------------------------------------------------- + +inline void emit_xchg_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { if (dreg == REG_EAX) emit_op_reg(emitptr, OP_NOP | (sreg & 7), OP_64BIT, sreg); @@ -1991,256 +2046,256 @@ INLINE void emit_xchg_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) #endif -/*************************************************************************** - ARITHMETIC EMITTERS -***************************************************************************/ - -/*------------------------------------------------- - emit_arith_r8_* --------------------------------------------------*/ - -INLINE void emit_add_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 0, dreg, imm); } -INLINE void emit_add_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_add_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_add_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADD_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_add_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_or_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 1, dreg, imm); } -INLINE void emit_or_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 1, MEMPARAMS, imm); } -INLINE void emit_or_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_or_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_OR_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_or_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_adc_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 2, dreg, imm); } -INLINE void emit_adc_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 2, MEMPARAMS, imm); } -INLINE void emit_adc_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_adc_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADC_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_adc_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_sbb_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 3, dreg, imm); } -INLINE void emit_sbb_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 3, MEMPARAMS, imm); } -INLINE void emit_sbb_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_sbb_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SBB_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_sbb_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_and_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 4, dreg, imm); } -INLINE void emit_and_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 4, MEMPARAMS, imm); } -INLINE void emit_and_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_and_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_AND_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_and_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_sub_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 5, dreg, imm); } -INLINE void emit_sub_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 5, MEMPARAMS, imm); } -INLINE void emit_sub_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_sub_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUB_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_sub_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_xor_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 6, dreg, imm); } -INLINE void emit_xor_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 6, MEMPARAMS, imm); } -INLINE void emit_xor_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_xor_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XOR_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_xor_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_cmp_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 7, dreg, imm); } -INLINE void emit_cmp_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 7, MEMPARAMS, imm); } -INLINE void emit_cmp_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gb_Eb, OP_32BIT, dreg, sreg); } -INLINE void emit_cmp_r8_m8(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMP_Gb_Eb, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_cmp_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_test_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G3_Eb, OP_32BIT, 0, dreg, imm); } -INLINE void emit_test_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G3_Eb, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_test_r8_r8(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Eb_Gb, OP_32BIT, sreg, dreg); } -INLINE void emit_test_m8_r8(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Eb_Gb, OP_32BIT, sreg, MEMPARAMS); } - - -/*------------------------------------------------- - emit_arith_r16_* --------------------------------------------------*/ - -INLINE void emit_add_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 0, dreg, imm); } -INLINE void emit_add_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 0, MEMPARAMS, imm); } -INLINE void emit_add_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_add_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_add_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_or_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 1, dreg, imm); } -INLINE void emit_or_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 1, MEMPARAMS, imm); } -INLINE void emit_or_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_or_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_or_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_adc_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 2, dreg, imm); } -INLINE void emit_adc_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 2, MEMPARAMS, imm); } -INLINE void emit_adc_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_adc_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_adc_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_sbb_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 3, dreg, imm); } -INLINE void emit_sbb_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 3, MEMPARAMS, imm); } -INLINE void emit_sbb_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_sbb_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_sbb_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_and_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 4, dreg, imm); } -INLINE void emit_and_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 4, MEMPARAMS, imm); } -INLINE void emit_and_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_and_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_and_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_sub_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 5, dreg, imm); } -INLINE void emit_sub_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 5, MEMPARAMS, imm); } -INLINE void emit_sub_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_sub_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_sub_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_xor_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 6, dreg, imm); } -INLINE void emit_xor_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 6, MEMPARAMS, imm); } -INLINE void emit_xor_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_xor_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_xor_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_cmp_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 7, dreg, imm); } -INLINE void emit_cmp_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 7, MEMPARAMS, imm); } -INLINE void emit_cmp_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_cmp_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_cmp_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - -INLINE void emit_test_r16_imm(x86code **emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm16(emitptr, OP_G3_Ev, OP_16BIT, 0, dreg, imm); } -INLINE void emit_test_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT16 imm) { emit_op_modrm_mem_imm16(emitptr, OP_G3_Ev, OP_16BIT, 0, MEMPARAMS, imm); } -INLINE void emit_test_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_16BIT, sreg, dreg); } -INLINE void emit_test_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } - - -/*------------------------------------------------- - emit_arith_r32_* --------------------------------------------------*/ - -INLINE void emit_add_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 0, dreg, imm); } -INLINE void emit_add_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_add_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_add_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_add_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_or_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 1, dreg, imm); } -INLINE void emit_or_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 1, MEMPARAMS, imm); } -INLINE void emit_or_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_or_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_or_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_adc_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 2, dreg, imm); } -INLINE void emit_adc_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 2, MEMPARAMS, imm); } -INLINE void emit_adc_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_adc_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_adc_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_sbb_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 3, dreg, imm); } -INLINE void emit_sbb_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 3, MEMPARAMS, imm); } -INLINE void emit_sbb_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_sbb_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_sbb_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_and_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 4, dreg, imm); } -INLINE void emit_and_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 4, MEMPARAMS, imm); } -INLINE void emit_and_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_and_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_and_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_sub_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 5, dreg, imm); } -INLINE void emit_sub_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 5, MEMPARAMS, imm); } -INLINE void emit_sub_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_sub_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_sub_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_xor_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 6, dreg, imm); } -INLINE void emit_xor_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 6, MEMPARAMS, imm); } -INLINE void emit_xor_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_xor_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_xor_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_cmp_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 7, dreg, imm); } -INLINE void emit_cmp_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 7, MEMPARAMS, imm); } -INLINE void emit_cmp_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_cmp_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_cmp_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_test_r32_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm32(emitptr, OP_G3_Ev, OP_32BIT, 0, dreg, imm); } -INLINE void emit_test_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G3_Ev, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_test_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_32BIT, sreg, dreg); } -INLINE void emit_test_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } - - -/*------------------------------------------------- - emit_arith_r64_* --------------------------------------------------*/ - -#ifdef PTR64 - -INLINE void emit_add_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 0, dreg, imm); } -INLINE void emit_add_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 0, MEMPARAMS, imm); } -INLINE void emit_add_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_add_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_add_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_or_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 1, dreg, imm); } -INLINE void emit_or_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 1, MEMPARAMS, imm); } -INLINE void emit_or_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_or_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_or_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_adc_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 2, dreg, imm); } -INLINE void emit_adc_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 2, MEMPARAMS, imm); } -INLINE void emit_adc_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_adc_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_adc_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_sbb_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 3, dreg, imm); } -INLINE void emit_sbb_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 3, MEMPARAMS, imm); } -INLINE void emit_sbb_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_sbb_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_sbb_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_and_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 4, dreg, imm); } -INLINE void emit_and_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 4, MEMPARAMS, imm); } -INLINE void emit_and_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_and_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_and_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_sub_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 5, dreg, imm); } -INLINE void emit_sub_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 5, MEMPARAMS, imm); } -INLINE void emit_sub_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_sub_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_sub_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_xor_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 6, dreg, imm); } -INLINE void emit_xor_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 6, MEMPARAMS, imm); } -INLINE void emit_xor_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_xor_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_xor_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_cmp_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 7, dreg, imm); } -INLINE void emit_cmp_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 7, MEMPARAMS, imm); } -INLINE void emit_cmp_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_cmp_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_cmp_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_test_r64_imm(x86code **emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm32(emitptr, OP_G3_Ev, OP_64BIT, 0, dreg, imm); } -INLINE void emit_test_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G3_Ev, OP_64BIT, 0, MEMPARAMS, imm); } -INLINE void emit_test_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_64BIT, sreg, dreg); } -INLINE void emit_test_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } +//************************************************************************** +// ARITHMETIC EMITTERS +//************************************************************************** + +//------------------------------------------------- +// emit_arith_r8_* +//------------------------------------------------- + +inline void emit_add_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 0, dreg, imm); } +inline void emit_add_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 0, memref, imm); } +inline void emit_add_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_add_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADD_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_add_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_or_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 1, dreg, imm); } +inline void emit_or_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 1, memref, imm); } +inline void emit_or_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_or_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_OR_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_or_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_adc_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 2, dreg, imm); } +inline void emit_adc_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 2, memref, imm); } +inline void emit_adc_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_adc_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADC_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_adc_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_sbb_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 3, dreg, imm); } +inline void emit_sbb_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 3, memref, imm); } +inline void emit_sbb_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_sbb_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SBB_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_sbb_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_and_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 4, dreg, imm); } +inline void emit_and_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 4, memref, imm); } +inline void emit_and_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_and_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_AND_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_and_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_sub_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 5, dreg, imm); } +inline void emit_sub_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 5, memref, imm); } +inline void emit_sub_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_sub_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUB_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_sub_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_xor_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 6, dreg, imm); } +inline void emit_xor_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 6, memref, imm); } +inline void emit_xor_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_xor_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XOR_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_xor_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_cmp_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 7, dreg, imm); } +inline void emit_cmp_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G1_Eb_Ib, OP_32BIT, 7, memref, imm); } +inline void emit_cmp_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gb_Eb, OP_32BIT, dreg, sreg); } +inline void emit_cmp_r8_m8(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMP_Gb_Eb, OP_32BIT, dreg, memref); } +inline void emit_cmp_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Eb_Gb, OP_32BIT, sreg, memref); } + +inline void emit_test_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G3_Eb, OP_32BIT, 0, dreg, imm); } +inline void emit_test_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G3_Eb, OP_32BIT, 0, memref, imm); } +inline void emit_test_r8_r8(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Eb_Gb, OP_32BIT, sreg, dreg); } +inline void emit_test_m8_r8(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Eb_Gb, OP_32BIT, sreg, memref); } + + +//------------------------------------------------- +// emit_arith_r16_* +//------------------------------------------------- + +inline void emit_add_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 0, dreg, imm); } +inline void emit_add_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 0, memref, imm); } +inline void emit_add_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_add_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_add_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_or_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 1, dreg, imm); } +inline void emit_or_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 1, memref, imm); } +inline void emit_or_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_or_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_or_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_adc_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 2, dreg, imm); } +inline void emit_adc_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 2, memref, imm); } +inline void emit_adc_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_adc_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_adc_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_sbb_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 3, dreg, imm); } +inline void emit_sbb_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 3, memref, imm); } +inline void emit_sbb_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_sbb_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_sbb_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_and_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 4, dreg, imm); } +inline void emit_and_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 4, memref, imm); } +inline void emit_and_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_and_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_and_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_sub_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 5, dreg, imm); } +inline void emit_sub_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 5, memref, imm); } +inline void emit_sub_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_sub_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_sub_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_xor_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 6, dreg, imm); } +inline void emit_xor_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 6, memref, imm); } +inline void emit_xor_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_xor_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_xor_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_cmp_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 7, dreg, imm); } +inline void emit_cmp_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_16BIT, 7, memref, imm); } +inline void emit_cmp_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_cmp_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_cmp_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_16BIT, sreg, memref); } + +inline void emit_test_r16_imm(x86code *&emitptr, UINT8 dreg, UINT16 imm) { emit_op_modrm_reg_imm16(emitptr, OP_G3_Ev, OP_16BIT, 0, dreg, imm); } +inline void emit_test_m16_imm(x86code *&emitptr, x86_memref memref, UINT16 imm) { emit_op_modrm_mem_imm16(emitptr, OP_G3_Ev, OP_16BIT, 0, memref, imm); } +inline void emit_test_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_16BIT, sreg, dreg); } +inline void emit_test_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_16BIT, sreg, memref); } + + +//------------------------------------------------- +// emit_arith_r32_* +//------------------------------------------------- + +inline void emit_add_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 0, dreg, imm); } +inline void emit_add_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 0, memref, imm); } +inline void emit_add_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_add_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_add_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_or_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 1, dreg, imm); } +inline void emit_or_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 1, memref, imm); } +inline void emit_or_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_or_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_or_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_adc_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 2, dreg, imm); } +inline void emit_adc_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 2, memref, imm); } +inline void emit_adc_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_adc_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_adc_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_sbb_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 3, dreg, imm); } +inline void emit_sbb_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 3, memref, imm); } +inline void emit_sbb_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_sbb_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_sbb_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_and_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 4, dreg, imm); } +inline void emit_and_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 4, memref, imm); } +inline void emit_and_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_and_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_and_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_sub_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 5, dreg, imm); } +inline void emit_sub_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 5, memref, imm); } +inline void emit_sub_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_sub_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_sub_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_xor_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 6, dreg, imm); } +inline void emit_xor_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 6, memref, imm); } +inline void emit_xor_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_xor_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_xor_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_cmp_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 7, dreg, imm); } +inline void emit_cmp_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_32BIT, 7, memref, imm); } +inline void emit_cmp_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_cmp_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_cmp_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_32BIT, sreg, memref); } + +inline void emit_test_r32_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm32(emitptr, OP_G3_Ev, OP_32BIT, 0, dreg, imm); } +inline void emit_test_m32_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G3_Ev, OP_32BIT, 0, memref, imm); } +inline void emit_test_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_32BIT, sreg, dreg); } +inline void emit_test_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_32BIT, sreg, memref); } + + +//------------------------------------------------- +// emit_arith_r64_* +//------------------------------------------------- + +#if (X86EMIT_SIZE == 64) + +inline void emit_add_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 0, dreg, imm); } +inline void emit_add_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 0, memref, imm); } +inline void emit_add_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADD_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_add_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADD_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_add_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADD_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_or_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 1, dreg, imm); } +inline void emit_or_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 1, memref, imm); } +inline void emit_or_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_OR_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_or_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_OR_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_or_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_OR_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_adc_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 2, dreg, imm); } +inline void emit_adc_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 2, memref, imm); } +inline void emit_adc_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADC_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_adc_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADC_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_adc_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_ADC_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_sbb_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 3, dreg, imm); } +inline void emit_sbb_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 3, memref, imm); } +inline void emit_sbb_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SBB_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_sbb_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SBB_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_sbb_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SBB_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_and_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 4, dreg, imm); } +inline void emit_and_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 4, memref, imm); } +inline void emit_and_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_AND_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_and_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_AND_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_and_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_AND_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_sub_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 5, dreg, imm); } +inline void emit_sub_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 5, memref, imm); } +inline void emit_sub_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUB_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_sub_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUB_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_sub_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SUB_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_xor_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 6, dreg, imm); } +inline void emit_xor_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 6, memref, imm); } +inline void emit_xor_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XOR_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_xor_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XOR_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_xor_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_XOR_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_cmp_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 7, dreg, imm); } +inline void emit_cmp_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_G1_Ev_Ib, OP_G1_Ev_Iz, OP_64BIT, 7, memref, imm); } +inline void emit_cmp_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CMP_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_cmp_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CMP_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_cmp_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_CMP_Ev_Gv, OP_64BIT, sreg, memref); } + +inline void emit_test_r64_imm(x86code *&emitptr, UINT8 dreg, UINT32 imm) { emit_op_modrm_reg_imm32(emitptr, OP_G3_Ev, OP_64BIT, 0, dreg, imm); } +inline void emit_test_m64_imm(x86code *&emitptr, x86_memref memref, UINT32 imm) { emit_op_modrm_mem_imm32(emitptr, OP_G3_Ev, OP_64BIT, 0, memref, imm); } +inline void emit_test_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_TEST_Ev_Gv, OP_64BIT, sreg, dreg); } +inline void emit_test_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_TEST_Ev_Gv, OP_64BIT, sreg, memref); } #endif -/*************************************************************************** - SHIFT EMITTERS -***************************************************************************/ +//************************************************************************** +// SHIFT EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_shift_reg_imm --------------------------------------------------*/ +//------------------------------------------------- +// emit_shift_reg_imm +//------------------------------------------------- -INLINE void emit_shift_reg_imm(x86code **emitptr, UINT32 op1, UINT32 opn, UINT8 opsize, UINT8 opindex, UINT8 dreg, UINT8 imm) +inline void emit_shift_reg_imm(x86code *&emitptr, UINT32 op1, UINT32 opn, UINT8 opsize, UINT8 opindex, UINT8 dreg, UINT8 imm) { if (imm == 1) emit_op_modrm_reg(emitptr, op1, opsize, opindex, dreg); @@ -2248,912 +2303,916 @@ INLINE void emit_shift_reg_imm(x86code **emitptr, UINT32 op1, UINT32 opn, UINT8 emit_op_modrm_reg_imm8(emitptr, opn, opsize, opindex, dreg, imm); } -INLINE void emit_shift_mem_imm(x86code **emitptr, UINT32 op1, UINT32 opn, UINT8 opsize, UINT8 opindex, DECLARE_MEMPARAMS, UINT8 imm) +inline void emit_shift_mem_imm(x86code *&emitptr, UINT32 op1, UINT32 opn, UINT8 opsize, UINT8 opindex, x86_memref memref, UINT8 imm) { if (imm == 1) - emit_op_modrm_mem(emitptr, op1, opsize, opindex, MEMPARAMS); + emit_op_modrm_mem(emitptr, op1, opsize, opindex, memref); else - emit_op_modrm_mem_imm8(emitptr, opn, opsize, opindex, MEMPARAMS, imm); + emit_op_modrm_mem_imm8(emitptr, opn, opsize, opindex, memref, imm); } -/*------------------------------------------------- - emit_shift_r8_* --------------------------------------------------*/ - -INLINE void emit_rol_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 0, dreg, imm); } -INLINE void emit_rol_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_rol_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 0, dreg); } -INLINE void emit_rol_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 0, MEMPARAMS); } - -INLINE void emit_ror_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 1, dreg, imm); } -INLINE void emit_ror_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 1, MEMPARAMS, imm); } -INLINE void emit_ror_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 1, dreg); } -INLINE void emit_ror_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 1, MEMPARAMS); } - -INLINE void emit_rcl_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 2, dreg, imm); } -INLINE void emit_rcl_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 2, MEMPARAMS, imm); } -INLINE void emit_rcl_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 2, dreg); } -INLINE void emit_rcl_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 2, MEMPARAMS); } - -INLINE void emit_rcr_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 3, dreg, imm); } -INLINE void emit_rcr_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 3, MEMPARAMS, imm); } -INLINE void emit_rcr_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 3, dreg); } -INLINE void emit_rcr_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 3, MEMPARAMS); } - -INLINE void emit_shl_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 4, dreg, imm); } -INLINE void emit_shl_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 4, MEMPARAMS, imm); } -INLINE void emit_shl_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 4, dreg); } -INLINE void emit_shl_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 4, MEMPARAMS); } - -INLINE void emit_shr_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 5, dreg, imm); } -INLINE void emit_shr_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 5, MEMPARAMS, imm); } -INLINE void emit_shr_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 5, dreg); } -INLINE void emit_shr_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 5, MEMPARAMS); } - -INLINE void emit_sar_r8_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 7, dreg, imm); } -INLINE void emit_sar_m8_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 7, MEMPARAMS, imm); } -INLINE void emit_sar_r8_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 7, dreg); } -INLINE void emit_sar_m8_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 7, MEMPARAMS); } - - -/*------------------------------------------------- - emit_shift_r16_* --------------------------------------------------*/ - -INLINE void emit_rol_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 0, dreg, imm); } -INLINE void emit_rol_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 0, MEMPARAMS, imm); } -INLINE void emit_rol_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 0, dreg); } -INLINE void emit_rol_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 0, MEMPARAMS); } - -INLINE void emit_ror_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 1, dreg, imm); } -INLINE void emit_ror_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 1, MEMPARAMS, imm); } -INLINE void emit_ror_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 1, dreg); } -INLINE void emit_ror_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 1, MEMPARAMS); } - -INLINE void emit_rcl_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 2, dreg, imm); } -INLINE void emit_rcl_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 2, MEMPARAMS, imm); } -INLINE void emit_rcl_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 2, dreg); } -INLINE void emit_rcl_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 2, MEMPARAMS); } - -INLINE void emit_rcr_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 3, dreg, imm); } -INLINE void emit_rcr_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 3, MEMPARAMS, imm); } -INLINE void emit_rcr_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 3, dreg); } -INLINE void emit_rcr_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 3, MEMPARAMS); } - -INLINE void emit_shl_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 4, dreg, imm); } -INLINE void emit_shl_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 4, MEMPARAMS, imm); } -INLINE void emit_shl_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 4, dreg); } -INLINE void emit_shl_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 4, MEMPARAMS); } - -INLINE void emit_shr_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 5, dreg, imm); } -INLINE void emit_shr_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 5, MEMPARAMS, imm); } -INLINE void emit_shr_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 5, dreg); } -INLINE void emit_shr_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 5, MEMPARAMS); } - -INLINE void emit_sar_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 7, dreg, imm); } -INLINE void emit_sar_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 7, MEMPARAMS, imm); } -INLINE void emit_sar_r16_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 7, dreg); } -INLINE void emit_sar_m16_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 7, MEMPARAMS); } - - -/*------------------------------------------------- - emit_shift_r32_* --------------------------------------------------*/ - -INLINE void emit_rol_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 0, dreg, imm); } -INLINE void emit_rol_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 0, MEMPARAMS, imm); } -INLINE void emit_rol_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 0, dreg); } -INLINE void emit_rol_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 0, MEMPARAMS); } - -INLINE void emit_ror_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 1, dreg, imm); } -INLINE void emit_ror_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 1, MEMPARAMS, imm); } -INLINE void emit_ror_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 1, dreg); } -INLINE void emit_ror_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 1, MEMPARAMS); } - -INLINE void emit_rcl_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 2, dreg, imm); } -INLINE void emit_rcl_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 2, MEMPARAMS, imm); } -INLINE void emit_rcl_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 2, dreg); } -INLINE void emit_rcl_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 2, MEMPARAMS); } - -INLINE void emit_rcr_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 3, dreg, imm); } -INLINE void emit_rcr_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 3, MEMPARAMS, imm); } -INLINE void emit_rcr_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 3, dreg); } -INLINE void emit_rcr_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 3, MEMPARAMS); } - -INLINE void emit_shl_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 4, dreg, imm); } -INLINE void emit_shl_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 4, MEMPARAMS, imm); } -INLINE void emit_shl_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 4, dreg); } -INLINE void emit_shl_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 4, MEMPARAMS); } - -INLINE void emit_shr_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 5, dreg, imm); } -INLINE void emit_shr_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 5, MEMPARAMS, imm); } -INLINE void emit_shr_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 5, dreg); } -INLINE void emit_shr_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 5, MEMPARAMS); } - -INLINE void emit_sar_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 7, dreg, imm); } -INLINE void emit_sar_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 7, MEMPARAMS, imm); } -INLINE void emit_sar_r32_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 7, dreg); } -INLINE void emit_sar_m32_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_shld_r32_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_32BIT, sreg, dreg, imm); } -INLINE void emit_shld_m32_r32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_32BIT, sreg, MEMPARAMS, imm); } -INLINE void emit_shld_r32_r32_cl(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHLD_Ev_Gv_CL, OP_32BIT, sreg, dreg); } -INLINE void emit_shld_m32_r32_cl(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHLD_Ev_Gv_CL, OP_32BIT, sreg, MEMPARAMS); } - -INLINE void emit_shrd_r32_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_32BIT, sreg, dreg, imm); } -INLINE void emit_shrd_m32_r32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_32BIT, sreg, MEMPARAMS, imm); } -INLINE void emit_shrd_r32_r32_cl(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHRD_Ev_Gv_CL, OP_32BIT, sreg, dreg); } -INLINE void emit_shrd_m32_r32_cl(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHRD_Ev_Gv_CL, OP_32BIT, sreg, MEMPARAMS); } - - -/*------------------------------------------------- - emit_shift_r64_* --------------------------------------------------*/ - -#ifdef PTR64 - -INLINE void emit_rol_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 0, dreg, imm); } -INLINE void emit_rol_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 0, MEMPARAMS, imm); } -INLINE void emit_rol_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 0, dreg); } -INLINE void emit_rol_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 0, MEMPARAMS); } - -INLINE void emit_ror_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 1, dreg, imm); } -INLINE void emit_ror_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 1, MEMPARAMS, imm); } -INLINE void emit_ror_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 1, dreg); } -INLINE void emit_ror_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 1, MEMPARAMS); } - -INLINE void emit_rcl_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 2, dreg, imm); } -INLINE void emit_rcl_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 2, MEMPARAMS, imm); } -INLINE void emit_rcl_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 2, dreg); } -INLINE void emit_rcl_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 2, MEMPARAMS); } - -INLINE void emit_rcr_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 3, dreg, imm); } -INLINE void emit_rcr_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 3, MEMPARAMS, imm); } -INLINE void emit_rcr_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 3, dreg); } -INLINE void emit_rcr_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 3, MEMPARAMS); } - -INLINE void emit_shl_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 4, dreg, imm); } -INLINE void emit_shl_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 4, MEMPARAMS, imm); } -INLINE void emit_shl_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 4, dreg); } -INLINE void emit_shl_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 4, MEMPARAMS); } - -INLINE void emit_shr_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 5, dreg, imm); } -INLINE void emit_shr_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 5, MEMPARAMS, imm); } -INLINE void emit_shr_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 5, dreg); } -INLINE void emit_shr_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 5, MEMPARAMS); } - -INLINE void emit_sar_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 7, dreg, imm); } -INLINE void emit_sar_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 7, MEMPARAMS, imm); } -INLINE void emit_sar_r64_cl(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 7, dreg); } -INLINE void emit_sar_m64_cl(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 7, MEMPARAMS); } - -INLINE void emit_shld_r64_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_64BIT, sreg, dreg, imm); } -INLINE void emit_shld_m64_r64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_64BIT, sreg, MEMPARAMS, imm); } -INLINE void emit_shld_r64_r64_cl(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHLD_Ev_Gv_CL, OP_64BIT, sreg, dreg); } -INLINE void emit_shld_m64_r64_cl(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHLD_Ev_Gv_CL, OP_64BIT, sreg, MEMPARAMS); } - -INLINE void emit_shrd_r64_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_64BIT, sreg, dreg, imm); } -INLINE void emit_shrd_m64_r64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_64BIT, sreg, MEMPARAMS, imm); } -INLINE void emit_shrd_r64_r64_cl(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHRD_Ev_Gv_CL, OP_64BIT, sreg, dreg); } -INLINE void emit_shrd_m64_r64_cl(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHRD_Ev_Gv_CL, OP_64BIT, sreg, MEMPARAMS); } +//------------------------------------------------- +// emit_shift_r8_* +//------------------------------------------------- + +inline void emit_rol_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 0, dreg, imm); } +inline void emit_rol_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 0, memref, imm); } +inline void emit_rol_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 0, dreg); } +inline void emit_rol_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 0, memref); } + +inline void emit_ror_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 1, dreg, imm); } +inline void emit_ror_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 1, memref, imm); } +inline void emit_ror_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 1, dreg); } +inline void emit_ror_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 1, memref); } + +inline void emit_rcl_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 2, dreg, imm); } +inline void emit_rcl_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 2, memref, imm); } +inline void emit_rcl_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 2, dreg); } +inline void emit_rcl_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 2, memref); } + +inline void emit_rcr_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 3, dreg, imm); } +inline void emit_rcr_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 3, memref, imm); } +inline void emit_rcr_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 3, dreg); } +inline void emit_rcr_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 3, memref); } + +inline void emit_shl_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 4, dreg, imm); } +inline void emit_shl_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 4, memref, imm); } +inline void emit_shl_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 4, dreg); } +inline void emit_shl_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 4, memref); } + +inline void emit_shr_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 5, dreg, imm); } +inline void emit_shr_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 5, memref, imm); } +inline void emit_shr_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 5, dreg); } +inline void emit_shr_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 5, memref); } + +inline void emit_sar_r8_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 7, dreg, imm); } +inline void emit_sar_m8_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Eb_1, OP_G2_Eb_Ib, OP_32BIT, 7, memref, imm); } +inline void emit_sar_r8_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Eb_CL, OP_32BIT, 7, dreg); } +inline void emit_sar_m8_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Eb_CL, OP_32BIT, 7, memref); } + + +//------------------------------------------------- +// emit_shift_r16_* +//------------------------------------------------- + +inline void emit_rol_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 0, dreg, imm); } +inline void emit_rol_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 0, memref, imm); } +inline void emit_rol_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 0, dreg); } +inline void emit_rol_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 0, memref); } + +inline void emit_ror_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 1, dreg, imm); } +inline void emit_ror_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 1, memref, imm); } +inline void emit_ror_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 1, dreg); } +inline void emit_ror_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 1, memref); } + +inline void emit_rcl_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 2, dreg, imm); } +inline void emit_rcl_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 2, memref, imm); } +inline void emit_rcl_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 2, dreg); } +inline void emit_rcl_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 2, memref); } + +inline void emit_rcr_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 3, dreg, imm); } +inline void emit_rcr_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 3, memref, imm); } +inline void emit_rcr_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 3, dreg); } +inline void emit_rcr_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 3, memref); } + +inline void emit_shl_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 4, dreg, imm); } +inline void emit_shl_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 4, memref, imm); } +inline void emit_shl_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 4, dreg); } +inline void emit_shl_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 4, memref); } + +inline void emit_shr_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 5, dreg, imm); } +inline void emit_shr_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 5, memref, imm); } +inline void emit_shr_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 5, dreg); } +inline void emit_shr_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 5, memref); } + +inline void emit_sar_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 7, dreg, imm); } +inline void emit_sar_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_16BIT, 7, memref, imm); } +inline void emit_sar_r16_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_16BIT, 7, dreg); } +inline void emit_sar_m16_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_16BIT, 7, memref); } + + +//------------------------------------------------- +// emit_shift_r32_* +//------------------------------------------------- + +inline void emit_rol_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 0, dreg, imm); } +inline void emit_rol_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 0, memref, imm); } +inline void emit_rol_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 0, dreg); } +inline void emit_rol_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 0, memref); } + +inline void emit_ror_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 1, dreg, imm); } +inline void emit_ror_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 1, memref, imm); } +inline void emit_ror_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 1, dreg); } +inline void emit_ror_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 1, memref); } + +inline void emit_rcl_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 2, dreg, imm); } +inline void emit_rcl_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 2, memref, imm); } +inline void emit_rcl_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 2, dreg); } +inline void emit_rcl_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 2, memref); } + +inline void emit_rcr_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 3, dreg, imm); } +inline void emit_rcr_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 3, memref, imm); } +inline void emit_rcr_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 3, dreg); } +inline void emit_rcr_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 3, memref); } + +inline void emit_shl_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 4, dreg, imm); } +inline void emit_shl_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 4, memref, imm); } +inline void emit_shl_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 4, dreg); } +inline void emit_shl_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 4, memref); } + +inline void emit_shr_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 5, dreg, imm); } +inline void emit_shr_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 5, memref, imm); } +inline void emit_shr_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 5, dreg); } +inline void emit_shr_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 5, memref); } + +inline void emit_sar_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 7, dreg, imm); } +inline void emit_sar_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_32BIT, 7, memref, imm); } +inline void emit_sar_r32_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_32BIT, 7, dreg); } +inline void emit_sar_m32_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_32BIT, 7, memref); } + +inline void emit_shld_r32_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_32BIT, sreg, dreg, imm); } +inline void emit_shld_m32_r32_imm(x86code *&emitptr, x86_memref memref, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_32BIT, sreg, memref, imm); } +inline void emit_shld_r32_r32_cl(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHLD_Ev_Gv_CL, OP_32BIT, sreg, dreg); } +inline void emit_shld_m32_r32_cl(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHLD_Ev_Gv_CL, OP_32BIT, sreg, memref); } + +inline void emit_shrd_r32_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_32BIT, sreg, dreg, imm); } +inline void emit_shrd_m32_r32_imm(x86code *&emitptr, x86_memref memref, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_32BIT, sreg, memref, imm); } +inline void emit_shrd_r32_r32_cl(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHRD_Ev_Gv_CL, OP_32BIT, sreg, dreg); } +inline void emit_shrd_m32_r32_cl(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHRD_Ev_Gv_CL, OP_32BIT, sreg, memref); } + + +//------------------------------------------------- +// emit_shift_r64_* +//------------------------------------------------- + +#if (X86EMIT_SIZE == 64) + +inline void emit_rol_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 0, dreg, imm); } +inline void emit_rol_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 0, memref, imm); } +inline void emit_rol_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 0, dreg); } +inline void emit_rol_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 0, memref); } + +inline void emit_ror_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 1, dreg, imm); } +inline void emit_ror_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 1, memref, imm); } +inline void emit_ror_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 1, dreg); } +inline void emit_ror_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 1, memref); } + +inline void emit_rcl_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 2, dreg, imm); } +inline void emit_rcl_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 2, memref, imm); } +inline void emit_rcl_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 2, dreg); } +inline void emit_rcl_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 2, memref); } + +inline void emit_rcr_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 3, dreg, imm); } +inline void emit_rcr_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 3, memref, imm); } +inline void emit_rcr_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 3, dreg); } +inline void emit_rcr_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 3, memref); } + +inline void emit_shl_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 4, dreg, imm); } +inline void emit_shl_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 4, memref, imm); } +inline void emit_shl_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 4, dreg); } +inline void emit_shl_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 4, memref); } + +inline void emit_shr_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 5, dreg, imm); } +inline void emit_shr_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 5, memref, imm); } +inline void emit_shr_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 5, dreg); } +inline void emit_shr_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 5, memref); } + +inline void emit_sar_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_shift_reg_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 7, dreg, imm); } +inline void emit_sar_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_shift_mem_imm(emitptr, OP_G2_Ev_1, OP_G2_Ev_Ib, OP_64BIT, 7, memref, imm); } +inline void emit_sar_r64_cl(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G2_Ev_CL, OP_64BIT, 7, dreg); } +inline void emit_sar_m64_cl(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G2_Ev_CL, OP_64BIT, 7, memref); } + +inline void emit_shld_r64_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_64BIT, sreg, dreg, imm); } +inline void emit_shld_m64_r64_imm(x86code *&emitptr, x86_memref memref, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHLD_Ev_Gv_Ib, OP_64BIT, sreg, memref, imm); } +inline void emit_shld_r64_r64_cl(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHLD_Ev_Gv_CL, OP_64BIT, sreg, dreg); } +inline void emit_shld_m64_r64_cl(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHLD_Ev_Gv_CL, OP_64BIT, sreg, memref); } + +inline void emit_shrd_r64_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_64BIT, sreg, dreg, imm); } +inline void emit_shrd_m64_r64_imm(x86code *&emitptr, x86_memref memref, UINT8 sreg, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_SHRD_Ev_Gv_Ib, OP_64BIT, sreg, memref, imm); } +inline void emit_shrd_r64_r64_cl(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SHRD_Ev_Gv_CL, OP_64BIT, sreg, dreg); } +inline void emit_shrd_m64_r64_cl(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_SHRD_Ev_Gv_CL, OP_64BIT, sreg, memref); } #endif -/*************************************************************************** - GROUP3 EMITTERS -***************************************************************************/ +//************************************************************************** +// GROUP3 EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_group3_r8_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_group3_r8_* +//------------------------------------------------- -INLINE void emit_not_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 2, dreg); } -INLINE void emit_not_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 2, MEMPARAMS); } +inline void emit_not_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 2, dreg); } +inline void emit_not_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 2, memref); } -INLINE void emit_neg_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 3, dreg); } -INLINE void emit_neg_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 3, MEMPARAMS); } +inline void emit_neg_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 3, dreg); } +inline void emit_neg_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 3, memref); } -INLINE void emit_mul_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 4, dreg); } -INLINE void emit_mul_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 4, MEMPARAMS); } +inline void emit_mul_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 4, dreg); } +inline void emit_mul_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 4, memref); } -INLINE void emit_imul_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 5, dreg); } -INLINE void emit_imul_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 5, MEMPARAMS); } +inline void emit_imul_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 5, dreg); } +inline void emit_imul_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 5, memref); } -INLINE void emit_div_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 6, dreg); } -INLINE void emit_div_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 6, MEMPARAMS); } +inline void emit_div_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 6, dreg); } +inline void emit_div_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 6, memref); } -INLINE void emit_idiv_r8(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 7, dreg); } -INLINE void emit_idiv_m8(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 7, MEMPARAMS); } +inline void emit_idiv_r8(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 7, dreg); } +inline void emit_idiv_m8(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 7, memref); } -/*------------------------------------------------- - emit_group3_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_group3_r16_* +//------------------------------------------------- -INLINE void emit_not_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 2, dreg); } -INLINE void emit_not_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 2, MEMPARAMS); } +inline void emit_not_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 2, dreg); } +inline void emit_not_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 2, memref); } -INLINE void emit_neg_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 3, dreg); } -INLINE void emit_neg_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 3, MEMPARAMS); } +inline void emit_neg_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 3, dreg); } +inline void emit_neg_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 3, memref); } -INLINE void emit_mul_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 4, dreg); } -INLINE void emit_mul_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 4, MEMPARAMS); } +inline void emit_mul_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 4, dreg); } +inline void emit_mul_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 4, memref); } -INLINE void emit_imul_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 5, dreg); } -INLINE void emit_imul_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 5, MEMPARAMS); } +inline void emit_imul_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 5, dreg); } +inline void emit_imul_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 5, memref); } -INLINE void emit_div_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 6, dreg); } -INLINE void emit_div_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 6, MEMPARAMS); } +inline void emit_div_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 6, dreg); } +inline void emit_div_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 6, memref); } -INLINE void emit_idiv_r16(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 7, dreg); } -INLINE void emit_idiv_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 7, MEMPARAMS); } +inline void emit_idiv_r16(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_16BIT, 7, dreg); } +inline void emit_idiv_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_16BIT, 7, memref); } -/*------------------------------------------------- - emit_group3_r32_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_group3_r32_* +//------------------------------------------------- -INLINE void emit_not_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 2, dreg); } -INLINE void emit_not_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 2, MEMPARAMS); } +inline void emit_not_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 2, dreg); } +inline void emit_not_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 2, memref); } -INLINE void emit_neg_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 3, dreg); } -INLINE void emit_neg_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 3, MEMPARAMS); } +inline void emit_neg_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 3, dreg); } +inline void emit_neg_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 3, memref); } -INLINE void emit_mul_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 4, dreg); } -INLINE void emit_mul_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 4, MEMPARAMS); } +inline void emit_mul_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 4, dreg); } +inline void emit_mul_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 4, memref); } -INLINE void emit_imul_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 5, dreg); } -INLINE void emit_imul_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 5, MEMPARAMS); } +inline void emit_imul_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 5, dreg); } +inline void emit_imul_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 5, memref); } -INLINE void emit_div_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 6, dreg); } -INLINE void emit_div_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 6, MEMPARAMS); } +inline void emit_div_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 6, dreg); } +inline void emit_div_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 6, memref); } -INLINE void emit_idiv_r32(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 7, dreg); } -INLINE void emit_idiv_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 7, MEMPARAMS); } +inline void emit_idiv_r32(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_32BIT, 7, dreg); } +inline void emit_idiv_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_32BIT, 7, memref); } -/*------------------------------------------------- - emit_group3_r64_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_group3_r64_* +//------------------------------------------------- -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_not_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 2, dreg); } -INLINE void emit_not_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 2, MEMPARAMS); } +inline void emit_not_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 2, dreg); } +inline void emit_not_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 2, memref); } -INLINE void emit_neg_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 3, dreg); } -INLINE void emit_neg_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 3, MEMPARAMS); } +inline void emit_neg_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 3, dreg); } +inline void emit_neg_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 3, memref); } -INLINE void emit_mul_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 4, dreg); } -INLINE void emit_mul_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 4, MEMPARAMS); } +inline void emit_mul_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 4, dreg); } +inline void emit_mul_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 4, memref); } -INLINE void emit_imul_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 5, dreg); } -INLINE void emit_imul_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 5, MEMPARAMS); } +inline void emit_imul_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 5, dreg); } +inline void emit_imul_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 5, memref); } -INLINE void emit_div_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 6, dreg); } -INLINE void emit_div_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 6, MEMPARAMS); } +inline void emit_div_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 6, dreg); } +inline void emit_div_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 6, memref); } -INLINE void emit_idiv_r64(x86code **emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 7, dreg); } -INLINE void emit_idiv_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 7, MEMPARAMS); } +inline void emit_idiv_r64(x86code *&emitptr, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_G3_Ev, OP_64BIT, 7, dreg); } +inline void emit_idiv_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G3_Ev, OP_64BIT, 7, memref); } #endif -/*************************************************************************** - IMUL EMITTERS -***************************************************************************/ +//************************************************************************** +// IMUL EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_imul_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_imul_r16_* +//------------------------------------------------- -INLINE void emit_imul_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_imul_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_imul_r16_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, INT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_16BIT, dreg, sreg, imm); } -INLINE void emit_imul_r16_m16_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, INT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_16BIT, dreg, MEMPARAMS, imm); } +inline void emit_imul_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_imul_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_imul_r16_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, INT16 imm) { emit_op_modrm_reg_imm816(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_16BIT, dreg, sreg, imm); } +inline void emit_imul_r16_m16_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, INT16 imm) { emit_op_modrm_mem_imm816(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_16BIT, dreg, memref, imm); } -INLINE void emit_imul_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_imul_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_imul_r32_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, INT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_32BIT, dreg, sreg, imm); } -INLINE void emit_imul_r32_m32_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, INT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_32BIT, dreg, MEMPARAMS, imm); } +inline void emit_imul_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_imul_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_imul_r32_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, INT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_32BIT, dreg, sreg, imm); } +inline void emit_imul_r32_m32_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, INT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_32BIT, dreg, memref, imm); } -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_imul_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_imul_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_imul_r64_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, INT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_64BIT, dreg, sreg, imm); } -INLINE void emit_imul_r64_m64_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, INT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_64BIT, dreg, MEMPARAMS, imm); } +inline void emit_imul_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_IMUL_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_imul_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_IMUL_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_imul_r64_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, INT32 imm) { emit_op_modrm_reg_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_64BIT, dreg, sreg, imm); } +inline void emit_imul_r64_m64_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, INT32 imm) { emit_op_modrm_mem_imm832(emitptr, OP_IMUL_Gv_Ev_Ib, OP_IMUL_Gv_Ev_Iz, OP_64BIT, dreg, memref, imm); } #endif -/*************************************************************************** - BIT OPERATION EMITTERS -***************************************************************************/ +//************************************************************************** +// BIT OPERATION EMITTERS +//************************************************************************** -/*------------------------------------------------- - emit_bswap_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_bswap_* +//------------------------------------------------- -INLINE void emit_bswap_r32(x86code **emitptr, UINT8 dreg) { emit_op_reg(emitptr, OP_BSWAP_EAX + (dreg & 7), OP_32BIT, dreg); } -INLINE void emit_bswap_r64(x86code **emitptr, UINT8 dreg) { emit_op_reg(emitptr, OP_BSWAP_EAX + (dreg & 7), OP_64BIT, dreg); } +inline void emit_bswap_r32(x86code *&emitptr, UINT8 dreg) { emit_op_reg(emitptr, OP_BSWAP_EAX + (dreg & 7), OP_32BIT, dreg); } +inline void emit_bswap_r64(x86code *&emitptr, UINT8 dreg) { emit_op_reg(emitptr, OP_BSWAP_EAX + (dreg & 7), OP_64BIT, dreg); } -/*------------------------------------------------- - emit_bsr/bsf_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_bsr/bsf_r16_* +//------------------------------------------------- -INLINE void emit_bsf_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_bsf_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } -INLINE void emit_bsr_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_16BIT, dreg, sreg); } -INLINE void emit_bsr_r16_m16(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_16BIT, dreg, MEMPARAMS); } +inline void emit_bsf_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_bsf_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_16BIT, dreg, memref); } +inline void emit_bsr_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_16BIT, dreg, sreg); } +inline void emit_bsr_r16_m16(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_16BIT, dreg, memref); } -INLINE void emit_bsf_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_bsf_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_bsr_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_32BIT, dreg, sreg); } -INLINE void emit_bsr_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_bsf_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_bsf_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_32BIT, dreg, memref); } +inline void emit_bsr_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_32BIT, dreg, sreg); } +inline void emit_bsr_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_bsf_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_bsf_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_bsr_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_64BIT, dreg, sreg); } -INLINE void emit_bsr_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_bsf_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSF_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_bsf_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSF_Gv_Ev, OP_64BIT, dreg, memref); } +inline void emit_bsr_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BSR_Gv_Ev, OP_64BIT, dreg, sreg); } +inline void emit_bsr_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_BSR_Gv_Ev, OP_64BIT, dreg, memref); } #endif -/*------------------------------------------------- - emit_bit_r16_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_bit_r16_* +//------------------------------------------------- -INLINE void emit_bt_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_16BIT, sreg, dreg); } -INLINE void emit_bt_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } -INLINE void emit_bt_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 4, dreg, imm); } -INLINE void emit_bt_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 4, MEMPARAMS, imm); } +inline void emit_bt_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_16BIT, sreg, dreg); } +inline void emit_bt_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_16BIT, sreg, memref); } +inline void emit_bt_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 4, dreg, imm); } +inline void emit_bt_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 4, memref, imm); } -INLINE void emit_bts_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_16BIT, sreg, dreg); } -INLINE void emit_bts_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } -INLINE void emit_bts_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 5, dreg, imm); } -INLINE void emit_bts_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 5, MEMPARAMS, imm); } +inline void emit_bts_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_16BIT, sreg, dreg); } +inline void emit_bts_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_16BIT, sreg, memref); } +inline void emit_bts_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 5, dreg, imm); } +inline void emit_bts_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 5, memref, imm); } -INLINE void emit_btr_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_16BIT, sreg, dreg); } -INLINE void emit_btr_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } -INLINE void emit_btr_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 6, dreg, imm); } -INLINE void emit_btr_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 6, MEMPARAMS, imm); } +inline void emit_btr_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_16BIT, sreg, dreg); } +inline void emit_btr_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_16BIT, sreg, memref); } +inline void emit_btr_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 6, dreg, imm); } +inline void emit_btr_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 6, memref, imm); } -INLINE void emit_btc_r16_r16(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_16BIT, sreg, dreg); } -INLINE void emit_btc_m16_r16(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_16BIT, sreg, MEMPARAMS); } -INLINE void emit_btc_r16_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 7, dreg, imm); } -INLINE void emit_btc_m16_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 7, MEMPARAMS, imm); } +inline void emit_btc_r16_r16(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_16BIT, sreg, dreg); } +inline void emit_btc_m16_r16(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_16BIT, sreg, memref); } +inline void emit_btc_r16_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 7, dreg, imm); } +inline void emit_btc_m16_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_16BIT, 7, memref, imm); } -/*------------------------------------------------- - emit_bit_r32_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_bit_r32_* +//------------------------------------------------- -INLINE void emit_bt_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_32BIT, sreg, dreg); } -INLINE void emit_bt_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_bt_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 4, dreg, imm); } -INLINE void emit_bt_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 4, MEMPARAMS, imm); } +inline void emit_bt_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_32BIT, sreg, dreg); } +inline void emit_bt_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_32BIT, sreg, memref); } +inline void emit_bt_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 4, dreg, imm); } +inline void emit_bt_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 4, memref, imm); } -INLINE void emit_bts_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_32BIT, sreg, dreg); } -INLINE void emit_bts_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_bts_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 5, dreg, imm); } -INLINE void emit_bts_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 5, MEMPARAMS, imm); } +inline void emit_bts_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_32BIT, sreg, dreg); } +inline void emit_bts_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_32BIT, sreg, memref); } +inline void emit_bts_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 5, dreg, imm); } +inline void emit_bts_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 5, memref, imm); } -INLINE void emit_btr_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_32BIT, sreg, dreg); } -INLINE void emit_btr_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_btr_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 6, dreg, imm); } -INLINE void emit_btr_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 6, MEMPARAMS, imm); } +inline void emit_btr_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_32BIT, sreg, dreg); } +inline void emit_btr_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_32BIT, sreg, memref); } +inline void emit_btr_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 6, dreg, imm); } +inline void emit_btr_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 6, memref, imm); } -INLINE void emit_btc_r32_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_32BIT, sreg, dreg); } -INLINE void emit_btc_m32_r32(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_32BIT, sreg, MEMPARAMS); } -INLINE void emit_btc_r32_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 7, dreg, imm); } -INLINE void emit_btc_m32_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 7, MEMPARAMS, imm); } +inline void emit_btc_r32_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_32BIT, sreg, dreg); } +inline void emit_btc_m32_r32(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_32BIT, sreg, memref); } +inline void emit_btc_r32_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 7, dreg, imm); } +inline void emit_btc_m32_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_32BIT, 7, memref, imm); } -/*------------------------------------------------- - emit_bit_r64_* --------------------------------------------------*/ +//------------------------------------------------- +// emit_bit_r64_* +//------------------------------------------------- -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_bt_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_64BIT, sreg, dreg); } -INLINE void emit_bt_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } -INLINE void emit_bt_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 4, dreg, imm); } -INLINE void emit_bt_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 4, MEMPARAMS, imm); } +inline void emit_bt_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BT_Ev_Gv, OP_64BIT, sreg, dreg); } +inline void emit_bt_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BT_Ev_Gv, OP_64BIT, sreg, memref); } +inline void emit_bt_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 4, dreg, imm); } +inline void emit_bt_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 4, memref, imm); } -INLINE void emit_bts_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_64BIT, sreg, dreg); } -INLINE void emit_bts_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } -INLINE void emit_bts_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 5, dreg, imm); } -INLINE void emit_bts_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 5, MEMPARAMS, imm); } +inline void emit_bts_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTS_Ev_Gv, OP_64BIT, sreg, dreg); } +inline void emit_bts_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTS_Ev_Gv, OP_64BIT, sreg, memref); } +inline void emit_bts_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 5, dreg, imm); } +inline void emit_bts_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 5, memref, imm); } -INLINE void emit_btr_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_64BIT, sreg, dreg); } -INLINE void emit_btr_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } -INLINE void emit_btr_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 6, dreg, imm); } -INLINE void emit_btr_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 6, MEMPARAMS, imm); } +inline void emit_btr_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTR_Ev_Gv, OP_64BIT, sreg, dreg); } +inline void emit_btr_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTR_Ev_Gv, OP_64BIT, sreg, memref); } +inline void emit_btr_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 6, dreg, imm); } +inline void emit_btr_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 6, memref, imm); } -INLINE void emit_btc_r64_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_64BIT, sreg, dreg); } -INLINE void emit_btc_m64_r64(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_64BIT, sreg, MEMPARAMS); } -INLINE void emit_btc_r64_imm(x86code **emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 7, dreg, imm); } -INLINE void emit_btc_m64_imm(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 7, MEMPARAMS, imm); } +inline void emit_btc_r64_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_BTC_Ev_Gv, OP_64BIT, sreg, dreg); } +inline void emit_btc_m64_r64(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_BTC_Ev_Gv, OP_64BIT, sreg, memref); } +inline void emit_btc_r64_imm(x86code *&emitptr, UINT8 dreg, UINT8 imm) { emit_op_modrm_reg_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 7, dreg, imm); } +inline void emit_btc_m64_imm(x86code *&emitptr, x86_memref memref, UINT8 imm) { emit_op_modrm_mem_imm8(emitptr, OP_G8_Ev_Ib, OP_64BIT, 7, memref, imm); } #endif -/*************************************************************************** - LEA EMITTERS -***************************************************************************/ +//************************************************************************** +// LEA EMITTERS +//************************************************************************** -INLINE void emit_lea_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_LEA_Gv_M, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_lea_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_LEA_Gv_M, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_lea_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_LEA_Gv_M, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_lea_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_LEA_Gv_M, OP_64BIT, dreg, memref); } #endif -/*************************************************************************** - SET EMITTERS -***************************************************************************/ - -/*------------------------------------------------- - emit_setcc_* --------------------------------------------------*/ - -INLINE void emit_setcc_r8(x86code **emitptr, UINT8 cond, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_SETCC_O_Eb + cond, OP_32BIT, 0, dreg); } -INLINE void emit_setcc_m8(x86code **emitptr, UINT8 cond, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SETCC_O_Eb + cond, OP_32BIT, 0, MEMPARAMS); } - - - -/*************************************************************************** - SIMPLE FPU EMITTERS -***************************************************************************/ - -#ifndef PTR64 - -INLINE void emit_fnop(x86code **emitptr) { emit_op_simple(emitptr, OP_FNOP, OP_32BIT); } -INLINE void emit_fchs(x86code **emitptr) { emit_op_simple(emitptr, OP_FCHS, OP_32BIT); } -INLINE void emit_fabs(x86code **emitptr) { emit_op_simple(emitptr, OP_FABS, OP_32BIT); } -INLINE void emit_ftst(x86code **emitptr) { emit_op_simple(emitptr, OP_FTST, OP_32BIT); } -INLINE void emit_fxam(x86code **emitptr) { emit_op_simple(emitptr, OP_FXAM, OP_32BIT); } -INLINE void emit_fld1(x86code **emitptr) { emit_op_simple(emitptr, OP_FLD1, OP_32BIT); } -INLINE void emit_fldl2t(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDL2T, OP_32BIT); } -INLINE void emit_fldl2e(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDL2E, OP_32BIT); } -INLINE void emit_fldpi(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDPI, OP_32BIT); } -INLINE void emit_fldlg2(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDLG2, OP_32BIT); } -INLINE void emit_fldln2(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDLN2, OP_32BIT); } -INLINE void emit_fldz(x86code **emitptr) { emit_op_simple(emitptr, OP_FLDZ, OP_32BIT); } -INLINE void emit_f2xm1(x86code **emitptr) { emit_op_simple(emitptr, OP_F2XM1, OP_32BIT); } -INLINE void emit_fyl2x(x86code **emitptr) { emit_op_simple(emitptr, OP_FYL2X, OP_32BIT); } -INLINE void emit_fptan(x86code **emitptr) { emit_op_simple(emitptr, OP_FPTAN, OP_32BIT); } -INLINE void emit_fpatan(x86code **emitptr) { emit_op_simple(emitptr, OP_FPATAN, OP_32BIT); } -INLINE void emit_fxtract(x86code **emitptr) { emit_op_simple(emitptr, OP_FXTRACT, OP_32BIT); } -INLINE void emit_fprem1(x86code **emitptr) { emit_op_simple(emitptr, OP_FPREM1, OP_32BIT); } -INLINE void emit_fdecstp(x86code **emitptr) { emit_op_simple(emitptr, OP_FDECSTP, OP_32BIT); } -INLINE void emit_fincstp(x86code **emitptr) { emit_op_simple(emitptr, OP_FINCSTP, OP_32BIT); } -INLINE void emit_fprem(x86code **emitptr) { emit_op_simple(emitptr, OP_FPREM, OP_32BIT); } -INLINE void emit_fyl2xp1(x86code **emitptr) { emit_op_simple(emitptr, OP_FYL2XP1, OP_32BIT); } -INLINE void emit_fsqrt(x86code **emitptr) { emit_op_simple(emitptr, OP_FSQRT, OP_32BIT); } -INLINE void emit_fsincos(x86code **emitptr) { emit_op_simple(emitptr, OP_FSINCOS, OP_32BIT); } -INLINE void emit_frndint(x86code **emitptr) { emit_op_simple(emitptr, OP_FRNDINT, OP_32BIT); } -INLINE void emit_fscale(x86code **emitptr) { emit_op_simple(emitptr, OP_FSCALE, OP_32BIT); } -INLINE void emit_fsin(x86code **emitptr) { emit_op_simple(emitptr, OP_FSIN, OP_32BIT); } -INLINE void emit_fcos(x86code **emitptr) { emit_op_simple(emitptr, OP_FCOS, OP_32BIT); } -INLINE void emit_fucompp(x86code **emitptr) { emit_op_simple(emitptr, OP_FUCOMPP, OP_32BIT); } -INLINE void emit_fclex(x86code **emitptr) { emit_op_simple(emitptr, OP_FCLEX, OP_32BIT); } -INLINE void emit_finit(x86code **emitptr) { emit_op_simple(emitptr, OP_FINIT, OP_32BIT); } -INLINE void emit_fcompp(x86code **emitptr) { emit_op_simple(emitptr, OP_FCOMPP, OP_32BIT); } -INLINE void emit_fstsw_ax(x86code **emitptr) { emit_op_simple(emitptr, OP_FSTSW_AX, OP_32BIT); } +//************************************************************************** +// SET EMITTERS +//************************************************************************** + +//------------------------------------------------- +// emit_setcc_* +//------------------------------------------------- + +inline void emit_setcc_r8(x86code *&emitptr, UINT8 cond, UINT8 dreg) { emit_op_modrm_reg(emitptr, OP_SETCC_O_Eb + cond, OP_32BIT, 0, dreg); } +inline void emit_setcc_m8(x86code *&emitptr, UINT8 cond, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SETCC_O_Eb + cond, OP_32BIT, 0, memref); } + + + +//************************************************************************** +// SIMPLE FPU EMITTERS +//************************************************************************** + +#if (X86EMIT_SIZE == 32) + +inline void emit_fnop(x86code *&emitptr) { emit_op_simple(emitptr, OP_FNOP, OP_32BIT); } +inline void emit_fchs(x86code *&emitptr) { emit_op_simple(emitptr, OP_FCHS, OP_32BIT); } +inline void emit_fabs(x86code *&emitptr) { emit_op_simple(emitptr, OP_FABS, OP_32BIT); } +inline void emit_ftst(x86code *&emitptr) { emit_op_simple(emitptr, OP_FTST, OP_32BIT); } +inline void emit_fxam(x86code *&emitptr) { emit_op_simple(emitptr, OP_FXAM, OP_32BIT); } +inline void emit_fld1(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLD1, OP_32BIT); } +inline void emit_fldl2t(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDL2T, OP_32BIT); } +inline void emit_fldl2e(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDL2E, OP_32BIT); } +inline void emit_fldpi(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDPI, OP_32BIT); } +inline void emit_fldlg2(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDLG2, OP_32BIT); } +inline void emit_fldln2(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDLN2, OP_32BIT); } +inline void emit_fldz(x86code *&emitptr) { emit_op_simple(emitptr, OP_FLDZ, OP_32BIT); } +inline void emit_f2xm1(x86code *&emitptr) { emit_op_simple(emitptr, OP_F2XM1, OP_32BIT); } +inline void emit_fyl2x(x86code *&emitptr) { emit_op_simple(emitptr, OP_FYL2X, OP_32BIT); } +inline void emit_fptan(x86code *&emitptr) { emit_op_simple(emitptr, OP_FPTAN, OP_32BIT); } +inline void emit_fpatan(x86code *&emitptr) { emit_op_simple(emitptr, OP_FPATAN, OP_32BIT); } +inline void emit_fxtract(x86code *&emitptr) { emit_op_simple(emitptr, OP_FXTRACT, OP_32BIT); } +inline void emit_fprem1(x86code *&emitptr) { emit_op_simple(emitptr, OP_FPREM1, OP_32BIT); } +inline void emit_fdecstp(x86code *&emitptr) { emit_op_simple(emitptr, OP_FDECSTP, OP_32BIT); } +inline void emit_fincstp(x86code *&emitptr) { emit_op_simple(emitptr, OP_FINCSTP, OP_32BIT); } +inline void emit_fprem(x86code *&emitptr) { emit_op_simple(emitptr, OP_FPREM, OP_32BIT); } +inline void emit_fyl2xp1(x86code *&emitptr) { emit_op_simple(emitptr, OP_FYL2XP1, OP_32BIT); } +inline void emit_fsqrt(x86code *&emitptr) { emit_op_simple(emitptr, OP_FSQRT, OP_32BIT); } +inline void emit_fsincos(x86code *&emitptr) { emit_op_simple(emitptr, OP_FSINCOS, OP_32BIT); } +inline void emit_frndint(x86code *&emitptr) { emit_op_simple(emitptr, OP_FRNDINT, OP_32BIT); } +inline void emit_fscale(x86code *&emitptr) { emit_op_simple(emitptr, OP_FSCALE, OP_32BIT); } +inline void emit_fsin(x86code *&emitptr) { emit_op_simple(emitptr, OP_FSIN, OP_32BIT); } +inline void emit_fcos(x86code *&emitptr) { emit_op_simple(emitptr, OP_FCOS, OP_32BIT); } +inline void emit_fucompp(x86code *&emitptr) { emit_op_simple(emitptr, OP_FUCOMPP, OP_32BIT); } +inline void emit_fclex(x86code *&emitptr) { emit_op_simple(emitptr, OP_FCLEX, OP_32BIT); } +inline void emit_finit(x86code *&emitptr) { emit_op_simple(emitptr, OP_FINIT, OP_32BIT); } +inline void emit_fcompp(x86code *&emitptr) { emit_op_simple(emitptr, OP_FCOMPP, OP_32BIT); } +inline void emit_fstsw_ax(x86code *&emitptr) { emit_op_simple(emitptr, OP_FSTSW_AX, OP_32BIT); } #endif -/*************************************************************************** - REGISTER-BASED FPU EMITTERS -***************************************************************************/ - -#ifndef PTR64 - -INLINE void emit_ffree_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FFREE_STn + reg, OP_32BIT); } -INLINE void emit_fst_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FST_STn + reg, OP_32BIT); } -INLINE void emit_fstp_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSTP_STn + reg, OP_32BIT); } -INLINE void emit_fucomp_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOMP_STn + reg, OP_32BIT); } - -INLINE void emit_fadd_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADD_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fmul_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMUL_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcom_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOM_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcomp_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMP_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fsub_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUB_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fsubr_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBR_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fdiv_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIV_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fdivr_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVR_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fld_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FLD_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fxch_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FXCH_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovb_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVB_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmove_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVE_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovbe_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVBE_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovu_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVU_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovnb_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNB_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovne_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNE_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovnbe_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNBE_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcmovnu_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNU_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fucomi_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOMI_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcomi_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMI_ST0_STn + reg, OP_32BIT); } -INLINE void emit_fcomip_st0_stn(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMIP_ST0_STn + reg, OP_32BIT); } - -INLINE void emit_fadd_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADD_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fmul_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMUL_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fsubr_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBR_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fsub_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUB_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fdivr_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVR_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fdiv_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIV_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fucom_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOM_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_faddp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADDP_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fmulp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMULP_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fsubrp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBRP_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fsubp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBP_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fdivrp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVRP_STn_ST0 + reg, OP_32BIT); } -INLINE void emit_fdivp_stn_st0(x86code **emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVP_STn_ST0 + reg, OP_32BIT); } - -INLINE void emit_faddp(x86code **emitptr) { emit_faddp_stn_st0(emitptr, 1); } -INLINE void emit_fmulp(x86code **emitptr) { emit_fmulp_stn_st0(emitptr, 1); } -INLINE void emit_fsubrp(x86code **emitptr) { emit_fsubrp_stn_st0(emitptr, 1); } -INLINE void emit_fsubp(x86code **emitptr) { emit_fsubp_stn_st0(emitptr, 1); } -INLINE void emit_fdivrp(x86code **emitptr) { emit_fdivrp_stn_st0(emitptr, 1); } -INLINE void emit_fdivp(x86code **emitptr) { emit_fdivp_stn_st0(emitptr, 1); } +//************************************************************************** +// REGISTER-BASED FPU EMITTERS +//************************************************************************** + +#if (X86EMIT_SIZE == 32) + +inline void emit_ffree_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FFREE_STn + reg, OP_32BIT); } +inline void emit_fst_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FST_STn + reg, OP_32BIT); } +inline void emit_fstp_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSTP_STn + reg, OP_32BIT); } +inline void emit_fucomp_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOMP_STn + reg, OP_32BIT); } + +inline void emit_fadd_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADD_ST0_STn + reg, OP_32BIT); } +inline void emit_fmul_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMUL_ST0_STn + reg, OP_32BIT); } +inline void emit_fcom_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOM_ST0_STn + reg, OP_32BIT); } +inline void emit_fcomp_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMP_ST0_STn + reg, OP_32BIT); } +inline void emit_fsub_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUB_ST0_STn + reg, OP_32BIT); } +inline void emit_fsubr_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBR_ST0_STn + reg, OP_32BIT); } +inline void emit_fdiv_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIV_ST0_STn + reg, OP_32BIT); } +inline void emit_fdivr_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVR_ST0_STn + reg, OP_32BIT); } +inline void emit_fld_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FLD_ST0_STn + reg, OP_32BIT); } +inline void emit_fxch_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FXCH_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovb_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVB_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmove_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVE_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovbe_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVBE_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovu_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVU_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovnb_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNB_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovne_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNE_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovnbe_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNBE_ST0_STn + reg, OP_32BIT); } +inline void emit_fcmovnu_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCMOVNU_ST0_STn + reg, OP_32BIT); } +inline void emit_fucomi_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOMI_ST0_STn + reg, OP_32BIT); } +inline void emit_fcomi_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMI_ST0_STn + reg, OP_32BIT); } +inline void emit_fcomip_st0_stn(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FCOMIP_ST0_STn + reg, OP_32BIT); } + +inline void emit_fadd_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADD_STn_ST0 + reg, OP_32BIT); } +inline void emit_fmul_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMUL_STn_ST0 + reg, OP_32BIT); } +inline void emit_fsubr_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBR_STn_ST0 + reg, OP_32BIT); } +inline void emit_fsub_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUB_STn_ST0 + reg, OP_32BIT); } +inline void emit_fdivr_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVR_STn_ST0 + reg, OP_32BIT); } +inline void emit_fdiv_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIV_STn_ST0 + reg, OP_32BIT); } +inline void emit_fucom_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FUCOM_STn_ST0 + reg, OP_32BIT); } +inline void emit_faddp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FADDP_STn_ST0 + reg, OP_32BIT); } +inline void emit_fmulp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FMULP_STn_ST0 + reg, OP_32BIT); } +inline void emit_fsubrp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBRP_STn_ST0 + reg, OP_32BIT); } +inline void emit_fsubp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FSUBP_STn_ST0 + reg, OP_32BIT); } +inline void emit_fdivrp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVRP_STn_ST0 + reg, OP_32BIT); } +inline void emit_fdivp_stn_st0(x86code *&emitptr, UINT8 reg) { emit_op_simple(emitptr, OP_FDIVP_STn_ST0 + reg, OP_32BIT); } + +inline void emit_faddp(x86code *&emitptr) { emit_faddp_stn_st0(emitptr, 1); } +inline void emit_fmulp(x86code *&emitptr) { emit_fmulp_stn_st0(emitptr, 1); } +inline void emit_fsubrp(x86code *&emitptr) { emit_fsubrp_stn_st0(emitptr, 1); } +inline void emit_fsubp(x86code *&emitptr) { emit_fsubp_stn_st0(emitptr, 1); } +inline void emit_fdivrp(x86code *&emitptr) { emit_fdivrp_stn_st0(emitptr, 1); } +inline void emit_fdivp(x86code *&emitptr) { emit_fdivp_stn_st0(emitptr, 1); } #endif -/*************************************************************************** - MEMORY FPU EMITTERS -***************************************************************************/ - -#ifndef PTR64 - -INLINE void emit_fadd_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fmul_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_fcom_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fcomp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fsub_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fsubr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fdiv_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fdivr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fld_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fst_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fstp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fldenv_m(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fldcw_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fstenv_m(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fstcw_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fiadd_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fimul_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_ficom_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_ficomp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fisub_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fisubr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fidiv_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fidivr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fild_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fisttp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_fist_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fistp_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fld_m80(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fstp_m80(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fadd_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fmul_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_fcom_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fcomp_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fsub_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fsubr_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fdiv_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fdivr_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fld_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fisttp_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_fst_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fstp_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_frstor_m(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fsave_m(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fstsw_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fiadd_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fimul_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_ficom_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_ficomp_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fisub_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fisubr_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fidiv_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fidivr_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 7, MEMPARAMS); } - -INLINE void emit_fild_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 0, MEMPARAMS); } -INLINE void emit_fisttp_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 1, MEMPARAMS); } -INLINE void emit_fist_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_fistp_m16(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 3, MEMPARAMS); } -INLINE void emit_fbld_m80(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 4, MEMPARAMS); } -INLINE void emit_fild_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 5, MEMPARAMS); } -INLINE void emit_fbstp_m80(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 6, MEMPARAMS); } -INLINE void emit_fistp_m64(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 7, MEMPARAMS); } +//************************************************************************** +// MEMORY FPU EMITTERS +//************************************************************************** + +#if (X86EMIT_SIZE == 32) + +inline void emit_fadd_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 0, memref); } +inline void emit_fmul_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 1, memref); } +inline void emit_fcom_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 2, memref); } +inline void emit_fcomp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 3, memref); } +inline void emit_fsub_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 4, memref); } +inline void emit_fsubr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 5, memref); } +inline void emit_fdiv_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 6, memref); } +inline void emit_fdivr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D8, OP_32BIT, 7, memref); } + +inline void emit_fld_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 0, memref); } +inline void emit_fst_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 2, memref); } +inline void emit_fstp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 3, memref); } +inline void emit_fldenv_m(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 4, memref); } +inline void emit_fldcw_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 5, memref); } +inline void emit_fstenv_m(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 6, memref); } +inline void emit_fstcw_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_D9, OP_32BIT, 7, memref); } + +inline void emit_fiadd_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 0, memref); } +inline void emit_fimul_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 1, memref); } +inline void emit_ficom_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 2, memref); } +inline void emit_ficomp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 3, memref); } +inline void emit_fisub_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 4, memref); } +inline void emit_fisubr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 5, memref); } +inline void emit_fidiv_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 6, memref); } +inline void emit_fidivr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DA, OP_32BIT, 7, memref); } + +inline void emit_fild_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 0, memref); } +inline void emit_fisttp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 1, memref); } +inline void emit_fist_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 2, memref); } +inline void emit_fistp_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 3, memref); } +inline void emit_fld_m80(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 5, memref); } +inline void emit_fstp_m80(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DB, OP_32BIT, 7, memref); } + +inline void emit_fadd_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 0, memref); } +inline void emit_fmul_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 1, memref); } +inline void emit_fcom_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 2, memref); } +inline void emit_fcomp_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 3, memref); } +inline void emit_fsub_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 4, memref); } +inline void emit_fsubr_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 5, memref); } +inline void emit_fdiv_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 6, memref); } +inline void emit_fdivr_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DC, OP_32BIT, 7, memref); } + +inline void emit_fld_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 0, memref); } +inline void emit_fisttp_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 1, memref); } +inline void emit_fst_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 2, memref); } +inline void emit_fstp_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 3, memref); } +inline void emit_frstor_m(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 4, memref); } +inline void emit_fsave_m(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 6, memref); } +inline void emit_fstsw_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DD, OP_32BIT, 7, memref); } + +inline void emit_fiadd_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 0, memref); } +inline void emit_fimul_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 1, memref); } +inline void emit_ficom_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 2, memref); } +inline void emit_ficomp_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 3, memref); } +inline void emit_fisub_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 4, memref); } +inline void emit_fisubr_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 5, memref); } +inline void emit_fidiv_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 6, memref); } +inline void emit_fidivr_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DE, OP_32BIT, 7, memref); } + +inline void emit_fild_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 0, memref); } +inline void emit_fisttp_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 1, memref); } +inline void emit_fist_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 2, memref); } +inline void emit_fistp_m16(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 3, memref); } +inline void emit_fbld_m80(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 4, memref); } +inline void emit_fild_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 5, memref); } +inline void emit_fbstp_m80(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 6, memref); } +inline void emit_fistp_m64(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ESC_DF, OP_32BIT, 7, memref); } #endif -/*************************************************************************** - GROUP16 EMITTERS -***************************************************************************/ +//************************************************************************** +// GROUP16 EMITTERS +//************************************************************************** -INLINE void emit_ldmxcsr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G16, OP_32BIT, 2, MEMPARAMS); } -INLINE void emit_stmxcsr_m32(x86code **emitptr, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_G16, OP_32BIT, 3, MEMPARAMS); } +inline void emit_ldmxcsr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G16, OP_32BIT, 2, memref); } +inline void emit_stmxcsr_m32(x86code *&emitptr, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_G16, OP_32BIT, 3, memref); } -/*************************************************************************** - MISC SSE EMITTERS -***************************************************************************/ +//************************************************************************** +// MISC SSE EMITTERS +//************************************************************************** -INLINE void emit_movd_r128_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Vd_Ed, OP_32BIT, dreg, sreg); } -INLINE void emit_movd_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVD_Vd_Ed, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movd_r32_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Ed_Vd, OP_32BIT, sreg, dreg); } -INLINE void emit_movd_m32_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVD_Ed_Vd, OP_32BIT, sreg, MEMPARAMS); } +inline void emit_movd_r128_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Vd_Ed, OP_32BIT, dreg, sreg); } +inline void emit_movd_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVD_Vd_Ed, OP_32BIT, dreg, memref); } +inline void emit_movd_r32_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Ed_Vd, OP_32BIT, sreg, dreg); } +inline void emit_movd_m32_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVD_Ed_Vd, OP_32BIT, sreg, memref); } -#ifdef PTR64 +#if (X86EMIT_SIZE == 64) -INLINE void emit_movq_r128_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Vd_Ed, OP_64BIT, dreg, sreg); } -INLINE void emit_movq_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVD_Vd_Ed, OP_64BIT, dreg, MEMPARAMS); } -INLINE void emit_movq_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Ed_Vd, OP_64BIT, sreg, dreg); } -INLINE void emit_movq_m64_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVD_Ed_Vd, OP_64BIT, sreg, MEMPARAMS); } +inline void emit_movq_r128_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Vd_Ed, OP_64BIT, dreg, sreg); } +inline void emit_movq_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVD_Vd_Ed, OP_64BIT, dreg, memref); } +inline void emit_movq_r64_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVD_Ed_Vd, OP_64BIT, sreg, dreg); } +inline void emit_movq_m64_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVD_Ed_Vd, OP_64BIT, sreg, memref); } #endif -/*************************************************************************** - SSE SCALAR SINGLE EMITTERS -***************************************************************************/ +//************************************************************************** +// SSE SCALAR SINGLE EMITTERS +//************************************************************************** -INLINE void emit_movss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_movss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movss_m32_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVSS_Wss_Vss, OP_32BIT, sreg, MEMPARAMS); } +inline void emit_movss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_movss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSS_Vss_Wss, OP_32BIT, dreg, memref); } +inline void emit_movss_m32_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVSS_Wss_Vss, OP_32BIT, sreg, memref); } -INLINE void emit_addss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_addss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADDSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_addss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_addss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADDSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_subss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_subss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUBSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_subss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_subss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUBSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_mulss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_mulss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MULSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_mulss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_mulss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MULSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_divss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_divss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_DIVSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_divss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_divss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_DIVSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_rcpss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RCPSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_rcpss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_RCPSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_rcpss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RCPSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_rcpss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_RCPSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_sqrtss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_sqrtss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SQRTSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_sqrtss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_sqrtss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SQRTSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_rsqrtss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RSQRTSS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_rsqrtss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_RSQRTSS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_rsqrtss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RSQRTSS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_rsqrtss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_RSQRTSS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_comiss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_COMISS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_comiss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_COMISS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_comiss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_COMISS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_comiss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_COMISS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_ucomiss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_UCOMISS_Vss_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_ucomiss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_UCOMISS_Vss_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_ucomiss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_UCOMISS_Vss_Wss, OP_32BIT, dreg, sreg); } +inline void emit_ucomiss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_UCOMISS_Vss_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_cvtsi2ss_r128_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SS_Vss_Ed, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtsi2ss_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSI2SS_Vss_Ed, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtsi2ss_r128_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SS_Vss_Ed, OP_32BIT, dreg, sreg); } +inline void emit_cvtsi2ss_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSI2SS_Vss_Ed, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvtsi2ss_r128_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SS_Vss_Ed, OP_64BIT, dreg, sreg); } -INLINE void emit_cvtsi2ss_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSI2SS_Vss_Ed, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvtsi2ss_r128_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SS_Vss_Ed, OP_64BIT, dreg, sreg); } +inline void emit_cvtsi2ss_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSI2SS_Vss_Ed, OP_64BIT, dreg, memref); } #endif -INLINE void emit_cvtsd2ss_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SS_Vss_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtsd2ss_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSD2SS_Vss_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtsd2ss_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SS_Vss_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_cvtsd2ss_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSD2SS_Vss_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_cvtss2si_r32_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SI_Gd_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtss2si_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSS2SI_Gd_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtss2si_r32_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SI_Gd_Wss, OP_32BIT, dreg, sreg); } +inline void emit_cvtss2si_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSS2SI_Gd_Wss, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvtss2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SI_Gd_Wss, OP_64BIT, dreg, sreg); } -INLINE void emit_cvtss2si_r64_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSS2SI_Gd_Wss, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvtss2si_r64_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SI_Gd_Wss, OP_64BIT, dreg, sreg); } +inline void emit_cvtss2si_r64_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSS2SI_Gd_Wss, OP_64BIT, dreg, memref); } #endif -INLINE void emit_cvttss2si_r32_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_cvttss2si_r32_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvttss2si_r32_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_32BIT, dreg, sreg); } +inline void emit_cvttss2si_r32_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvttss2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, sreg); } -INLINE void emit_cvttss2si_r64_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvttss2si_r64_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, sreg); } +inline void emit_cvttss2si_r64_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTSS2SI_Gd_Wss, OP_64BIT, dreg, memref); } #endif -INLINE void emit_roundss_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } -INLINE void emit_roundss_r128_m32_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); } +inline void emit_roundss_r128_r128_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } +inline void emit_roundss_r128_m32_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSS_Vss_Wss_Ib, OP_32BIT, dreg, memref); emit_byte(emitptr, imm); } -/*************************************************************************** - SSE PACKED SINGLE EMITTERS -***************************************************************************/ +//************************************************************************** +// SSE PACKED SINGLE EMITTERS +//************************************************************************** -INLINE void emit_movps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVAPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_movps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVAPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movps_m128_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVAPS_Wps_Vps, OP_32BIT, sreg, MEMPARAMS); } +inline void emit_movps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVAPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_movps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVAPS_Vps_Wps, OP_32BIT, dreg, memref); } +inline void emit_movps_m128_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVAPS_Wps_Vps, OP_32BIT, sreg, memref); } -INLINE void emit_addps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_addps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADDPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_addps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_addps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADDPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_subps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_subps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUBPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_subps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_subps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUBPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_mulps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_mulps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MULPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_mulps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_mulps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MULPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_divps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_divps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_DIVPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_divps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_divps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_DIVPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_rcpps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RCPPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_rcpps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_RCPPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_rcpps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RCPPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_rcpps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_RCPPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_sqrtps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_sqrtps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SQRTPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_sqrtps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_sqrtps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SQRTPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_rsqrtps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RSQRTPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_rsqrtps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_RSQRTPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_rsqrtps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_RSQRTPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_rsqrtps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_RSQRTPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_andps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_andps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ANDPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_andps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_andps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ANDPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_andnps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDNPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_andnps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ANDNPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_andnps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDNPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_andnps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ANDNPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_orps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ORPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_orps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ORPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_orps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ORPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_orps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ORPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_xorps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XORPS_Vps_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_xorps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XORPS_Vps_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_xorps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XORPS_Vps_Wps, OP_32BIT, dreg, sreg); } +inline void emit_xorps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XORPS_Vps_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_cvtdq2ps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTDQ2PS_Vps_Wdq, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtdq2ps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTDQ2PS_Vps_Wdq, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtdq2ps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTDQ2PS_Vps_Wdq, OP_32BIT, dreg, sreg); } +inline void emit_cvtdq2ps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTDQ2PS_Vps_Wdq, OP_32BIT, dreg, memref); } -INLINE void emit_cvtpd2ps_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPD2PS_Vps_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtpd2ps_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTPD2PS_Vps_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtpd2ps_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPD2PS_Vps_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_cvtpd2ps_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTPD2PS_Vps_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_cvtps2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPS2DQ_Vdq_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtps2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTPS2DQ_Vdq_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtps2dq_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPS2DQ_Vdq_Wps, OP_32BIT, dreg, sreg); } +inline void emit_cvtps2dq_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTPS2DQ_Vdq_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_cvttps2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPS2DQ_Vdq_Wps, OP_32BIT, dreg, sreg); } -INLINE void emit_cvttps2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTPS2DQ_Vdq_Wps, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvttps2dq_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPS2DQ_Vdq_Wps, OP_32BIT, dreg, sreg); } +inline void emit_cvttps2dq_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTPS2DQ_Vdq_Wps, OP_32BIT, dreg, memref); } -INLINE void emit_roundps_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPS_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } -INLINE void emit_roundps_r128_m128_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPS_Vdq_Wdq_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); } +inline void emit_roundps_r128_r128_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPS_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } +inline void emit_roundps_r128_m128_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPS_Vdq_Wdq_Ib, OP_32BIT, dreg, memref); emit_byte(emitptr, imm); } -/*************************************************************************** - SSE SCALAR DOUBLE EMITTERS -***************************************************************************/ +//************************************************************************** +// SSE SCALAR DOUBLE EMITTERS +//************************************************************************** -INLINE void emit_movsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_movsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movsd_m64_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVSD_Wsd_Vsd, OP_32BIT, sreg, MEMPARAMS); } +inline void emit_movsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_movsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVSD_Vsd_Wsd, OP_32BIT, dreg, memref); } +inline void emit_movsd_m64_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVSD_Wsd_Vsd, OP_32BIT, sreg, memref); } -INLINE void emit_addsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_addsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADDSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_addsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_addsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADDSD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_subsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_subsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUBSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_subsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_subsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUBSD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_mulsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_mulsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MULSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_mulsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_mulsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MULSD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_divsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_divsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_DIVSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_divsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_divsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_DIVSD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_sqrtsd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_sqrtsd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SQRTSD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_sqrtsd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTSD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_sqrtsd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SQRTSD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_comisd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_COMISD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_comisd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_COMISD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_comisd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_COMISD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_comisd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_COMISD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_ucomisd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_UCOMISD_Vsd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_ucomisd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_UCOMISD_Vsd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_ucomisd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_UCOMISD_Vsd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_ucomisd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_UCOMISD_Vsd_Wsd, OP_32BIT, dreg, memref); } -INLINE void emit_cvtsi2sd_r128_r32(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtsi2sd_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtsi2sd_r128_r32(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_32BIT, dreg, sreg); } +inline void emit_cvtsi2sd_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvtsi2sd_r128_r64(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_64BIT, dreg, sreg); } -INLINE void emit_cvtsi2sd_r128_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvtsi2sd_r128_r64(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_64BIT, dreg, sreg); } +inline void emit_cvtsi2sd_r128_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSI2SD_Vsd_Ed, OP_64BIT, dreg, memref); } #endif -INLINE void emit_cvtss2sd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SD_Vsd_Wss, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtss2sd_r128_m32(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSS2SD_Vsd_Wss, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtss2sd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSS2SD_Vsd_Wss, OP_32BIT, dreg, sreg); } +inline void emit_cvtss2sd_r128_m32(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSS2SD_Vsd_Wss, OP_32BIT, dreg, memref); } -INLINE void emit_cvtsd2si_r32_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtsd2si_r32_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtsd2si_r32_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_cvtsd2si_r32_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvtsd2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_64BIT, dreg, sreg); } -INLINE void emit_cvtsd2si_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvtsd2si_r64_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_64BIT, dreg, sreg); } +inline void emit_cvtsd2si_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTSD2SI_Gd_Wsd, OP_64BIT, dreg, memref); } #endif -INLINE void emit_cvttsd2si_r32_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvttsd2si_r32_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvttsd2si_r32_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_32BIT, dreg, sreg); } +inline void emit_cvttsd2si_r32_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_32BIT, dreg, memref); } -#ifdef PTR64 -INLINE void emit_cvttsd2si_r64_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, sreg); } -INLINE void emit_cvttsd2si_r64_m64(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, MEMPARAMS); } +#if (X86EMIT_SIZE == 64) +inline void emit_cvttsd2si_r64_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, sreg); } +inline void emit_cvttsd2si_r64_m64(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTSD2SI_Gd_Wsd, OP_64BIT, dreg, memref); } #endif -INLINE void emit_roundsd_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } -INLINE void emit_roundsd_r128_m64_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); } +inline void emit_roundsd_r128_r128_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } +inline void emit_roundsd_r128_m64_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDSD_Vsd_Wsd_Ib, OP_32BIT, dreg, memref); emit_byte(emitptr, imm); } -/*************************************************************************** - SSE PACKED DOUBLE EMITTERS -***************************************************************************/ +//************************************************************************** +// SSE PACKED DOUBLE EMITTERS +//************************************************************************** + +inline void emit_movpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVAPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_movpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MOVAPD_Vpd_Wpd, OP_32BIT, dreg, memref); } +inline void emit_movpd_m128_r128(x86code *&emitptr, x86_memref memref, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVAPD_Wpd_Vpd, OP_32BIT, sreg, memref); } -INLINE void emit_movpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MOVAPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_movpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MOVAPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } -INLINE void emit_movpd_m128_r128(x86code **emitptr, DECLARE_MEMPARAMS, UINT8 sreg) { emit_op_modrm_mem(emitptr, OP_MOVAPD_Wpd_Vpd, OP_32BIT, sreg, MEMPARAMS); } +inline void emit_addpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_addpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ADDPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_addpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ADDPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_addpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ADDPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_subpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_subpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SUBPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_subpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SUBPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_subpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SUBPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_mulpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_mulpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_MULPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_mulpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_MULPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_mulpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_MULPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_divpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_divpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_DIVPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_divpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_DIVPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_divpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_DIVPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_sqrtpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_sqrtpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_SQRTPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_sqrtpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_SQRTPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_sqrtpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_SQRTPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_andpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_andpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ANDPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_andpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_andpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ANDPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_andnpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDNPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_andnpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ANDNPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_andnpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ANDNPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_andnpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ANDNPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_orpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ORPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_orpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_ORPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_orpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_ORPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_orpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_ORPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_xorpd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XORPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_xorpd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_XORPD_Vpd_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_xorpd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_XORPD_Vpd_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_xorpd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_XORPD_Vpd_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtdq2pd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTDQ2PD_Vpd_Wq, OP_32BIT, dreg, sreg); } +inline void emit_cvtdq2pd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTDQ2PD_Vpd_Wq, OP_32BIT, dreg, memref); } -INLINE void emit_cvtdq2pd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTDQ2PD_Vpd_Wq, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtdq2pd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTDQ2PD_Vpd_Wq, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtps2pd_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPS2PD_Vpd_Wq, OP_32BIT, dreg, sreg); } +inline void emit_cvtps2pd_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTPS2PD_Vpd_Wq, OP_32BIT, dreg, memref); } -INLINE void emit_cvtps2pd_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPS2PD_Vpd_Wq, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtps2pd_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTPS2PD_Vpd_Wq, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvtpd2dq_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_cvtpd2dq_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_cvtpd2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvtpd2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_cvttpd2dq_r128_r128(x86code *&emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); } +inline void emit_cvttpd2dq_r128_m128(x86code *&emitptr, UINT8 dreg, x86_memref memref) { emit_op_modrm_mem(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, memref); } -INLINE void emit_cvttpd2dq_r128_r128(x86code **emitptr, UINT8 dreg, UINT8 sreg) { emit_op_modrm_reg(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, sreg); } -INLINE void emit_cvttpd2dq_r128_m128(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS) { emit_op_modrm_mem(emitptr, OP_CVTTPD2DQ_Vdq_Wpd, OP_32BIT, dreg, MEMPARAMS); } +inline void emit_roundpd_r128_r128_imm(x86code *&emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } +inline void emit_roundpd_r128_m128_imm(x86code *&emitptr, UINT8 dreg, x86_memref memref, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, memref); emit_byte(emitptr, imm); } -INLINE void emit_roundpd_r128_r128_imm(x86code **emitptr, UINT8 dreg, UINT8 sreg, UINT8 imm) { emit_op_modrm_reg(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, sreg); emit_byte(emitptr, imm); } -INLINE void emit_roundpd_r128_m128_imm(x86code **emitptr, UINT8 dreg, DECLARE_MEMPARAMS, UINT8 imm) { emit_op_modrm_mem(emitptr, OP_ROUNDPD_Vdq_Wdq_Ib, OP_32BIT, dreg, MEMPARAMS); emit_byte(emitptr, imm); } +}; + +#undef X86EMIT_SIZE -#endif /* __X86EMIT_H__ */ +#endif diff --git a/src/lib/util/astring.h b/src/lib/util/astring.h index c39c277401b..cc0e9cb7b9d 100644 --- a/src/lib/util/astring.h +++ b/src/lib/util/astring.h @@ -350,6 +350,7 @@ public: astring &cpy(const char *src, int count) { return *astring_cpych(this, src, count); } astring &cpysubstr(const astring &src, int start, int count) { return *astring_cpysubstr(this, &src, start, count); } + astring &cat(char ch) { return *astring_insch(this, -1, &ch, 1); } astring &cat(const astring &src) { return ins(-1, src); } astring &cat(const char *src) { return ins(-1, src); } astring &cat(const char *src, int count) { return ins(-1, src, count); } diff --git a/src/osd/windows/windows.mak b/src/osd/windows/windows.mak index ad8584b9a2e..e2749fe6b90 100644 --- a/src/osd/windows/windows.mak +++ b/src/osd/windows/windows.mak @@ -137,7 +137,7 @@ endif # disable warnings and link against bufferoverflowu for 64-bit targets ifeq ($(PTR64),1) CCOMFLAGS += /wd4267 -LIBS += -lbufferoverflowu +#LIBS += -lbufferoverflowu endif # enable exception handling for C++ |