summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Aaron Giles <aaron@aarongiles.com>2011-01-17 03:43:54 +0000
committer Aaron Giles <aaron@aarongiles.com>2011-01-17 03:43:54 +0000
commitf5c03d12e27df20e704ae6e1af233aefabfaeaec (patch)
treef57c5ae3e0d618903b702363e06f5a2b0014e23d
parent51d7c644e0a53fe7b2c6a59360b155b5d4699b08 (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--.gitattributes5
-rw-r--r--src/emu/cpu/cpu.mak35
-rw-r--r--src/emu/cpu/drcbec.c1790
-rw-r--r--src/emu/cpu/drcbec.h87
-rw-r--r--src/emu/cpu/drcbeut.c54
-rw-r--r--src/emu/cpu/drcbeut.h12
-rw-r--r--src/emu/cpu/drcbex64.c8248
-rw-r--r--src/emu/cpu/drcbex64.h370
-rw-r--r--src/emu/cpu/drcbex86.c8021
-rw-r--r--src/emu/cpu/drcbex86.h371
-rw-r--r--src/emu/cpu/drccache.h14
-rw-r--r--src/emu/cpu/drcuml.c2395
-rw-r--r--src/emu/cpu/drcuml.h680
-rw-r--r--src/emu/cpu/drcumlsh.h333
-rw-r--r--src/emu/cpu/mips/mips3drc.c930
-rw-r--r--src/emu/cpu/powerpc/ppcdrc.c1021
-rw-r--r--src/emu/cpu/rsp/rspdrc.c364
-rw-r--r--src/emu/cpu/sh2/sh2comn.h26
-rw-r--r--src/emu/cpu/sh2/sh2drc.c570
-rw-r--r--src/emu/cpu/uml.c1059
-rw-r--r--src/emu/cpu/uml.h687
-rw-r--r--src/emu/cpu/x86emit.h4913
-rw-r--r--src/lib/util/astring.h1
-rw-r--r--src/osd/windows/windows.mak2
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 &param)
{
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 = &param.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 &param);
+ 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 &param, 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 &param)
{
- 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 &param)
{
- 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 &param)
{
- 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 &param)
{
- 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param)
{
- 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 &param)
{
- 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param)
{
- 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 &param, 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 &param)
{
- 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 &param, 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, &paramp, 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 &param) : 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 &param, 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 &param);
+ void emit_movsx_r64_p32(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param);
+ void emit_mov_p32_r32(x86code *&dst, const be_parameter &param, UINT8 reg);
+ void emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+
+ // 64-bit code emission helpers
+ void emit_mov_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_mov_p64_r64(x86code *&dst, const be_parameter &param, UINT8 reg);
+ void emit_add_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_r64_p64(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+
+ // floating-point code emission helpers
+ void emit_movss_r128_p32(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_movss_p32_r128(x86code *&dst, const be_parameter &param, UINT8 reg);
+ void emit_movsd_r128_p64(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_movsd_p64_r128(x86code *&dst, const be_parameter &param, 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 &param, 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 &param, 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 &param, 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 &param)
{
- 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 &param)
{
- 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 &param)
{
- 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param)
{
- 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 &param)
{
- 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 &param)
{
- 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param, 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 &param)
{
- 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 &param)
{
- 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, &paramp, 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 &param) : 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 &param, 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 &param, UINT8 reglo);
+ void set_last_upper_reg(x86code *&dst, const be_parameter &param, 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 &param);
+ void emit_mov_r32_p32_keepflags(x86code *&dst, UINT8 reg, const be_parameter &param);
+ void emit_mov_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param);
+ void emit_mov_p32_r32(x86code *&dst, const be_parameter &param, UINT8 reg);
+ void emit_add_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_add_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_r32_p32(x86code *&dst, UINT8 reg, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_m32_p32(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+
+ // 64-bit code emission helpers
+ void emit_mov_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param);
+ void emit_mov_r64_p64_keepflags(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param);
+ void emit_mov_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param);
+ void emit_mov_p64_r64(x86code *&dst, const be_parameter &param, UINT8 reglo, UINT8 reghi);
+ void emit_add_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_add_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_adc_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_sub_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_sbb_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_cmp_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_and_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_test_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_or_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_xor_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_shl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_shr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_sar_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_rol_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_ror_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcl_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_r64_p64(x86code *&dst, UINT8 reglo, UINT8 reghi, const be_parameter &param, const uml::instruction &inst);
+ void emit_rcr_m64_p64(x86code *&dst, x86_memref memref, const be_parameter &param, const uml::instruction &inst);
+
+ // floating-point code emission helpers
+ void emit_fld_p(x86code *&dst, int size, const be_parameter &param);
+ void emit_fstp_p(x86code *&dst, int size, const be_parameter &param);
+
+ // 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 *)&parammem[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 = &params[pnum];
+ parameter *curparam = &params[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)&parammem[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 &param = 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 &param = 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 &param) : 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 &param(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++