summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2025-04-12 13:22:51 +1000
committer Vas Crabb <vas@vastheman.com>2025-04-12 13:25:58 +1000
commitde4064155569540b15c1f56bd99c2ceae54fa44f (patch)
tree1acf2bc767923b8a923924c91099f69be0c9a11f
parent2f93065a39cdc17e3b8d64e1cb7c7a543e704d2e (diff)
More recompiler fixes:
* cpu/drcbec.cpp: Interpret index operand for load/store instructions as a signed value for consistency with other back-ends. * cpu/drcbec.cpp: Honour alignment rules when packing immediate values. * cpu/drcbex64.cpp: Don't special-case SEXT with an immediate source - the simplifier takes care of this. * cpu/drcbex86.cpp: Be explicit about preserving flags in load/store instructions. * docs: Added a couple more UML data movement instructions.
-rw-r--r--docs/source/techspecs/uml_instructions.rst82
-rw-r--r--src/devices/cpu/drcbearm64.cpp1
-rw-r--r--src/devices/cpu/drcbec.cpp260
-rw-r--r--src/devices/cpu/drcbex64.cpp42
-rw-r--r--src/devices/cpu/drcbex86.cpp28
5 files changed, 248 insertions, 165 deletions
diff --git a/docs/source/techspecs/uml_instructions.rst b/docs/source/techspecs/uml_instructions.rst
index 771ff64974d..5d379dd1c60 100644
--- a/docs/source/techspecs/uml_instructions.rst
+++ b/docs/source/techspecs/uml_instructions.rst
@@ -751,6 +751,88 @@ Simplification rules
* Converted to :ref:`NOP <umlinst-nop>` if the ``src`` and ``dst``
operands refer to the same memory location or register.
+.. _umlinst-fcopyi:
+
+FCOPYI
+~~~~~~
+
+Reinterpret an integer value as a floating point value. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number.
+
++---------------------+-----------------------------------+
+| Disassembly | Usage |
++=====================+===================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fscopyi dst,src | UML_FSCOPYI(block, dst, src); |
+| fdcopyi dst,src | UML_FDCOPYI(block, dst, src); |
++---------------------+-----------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, floating point register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, integer register)
+ The source value to copy.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-icopyf:
+
+ICOPYF
+~~~~~~
+
+Reinterpret a floating point value as an integer value. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number.
+
++---------------------+-----------------------------------+
+| Disassembly | Usage |
++=====================+===================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| icopyfs dst,src | UML_ICOPYFS(block, dst, src); |
+| icopyfd dst,src | UML_ICOPYFD(block, dst, src); |
++---------------------+-----------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, floating point register)
+ The source value to copy.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
.. _umlinst-load:
LOAD
diff --git a/src/devices/cpu/drcbearm64.cpp b/src/devices/cpu/drcbearm64.cpp
index f323396729a..a8a679c3d07 100644
--- a/src/devices/cpu/drcbearm64.cpp
+++ b/src/devices/cpu/drcbearm64.cpp
@@ -3089,6 +3089,7 @@ void drcbe_arm64::op_sext(a64::Assembler &a, const uml::instruction &inst)
{
if (srcp.is_memory())
{
+ // FIXME: need to mangle addresses for big Endian hosts
if (size == SIZE_BYTE)
emit_ldrsb_mem(a, dstreg.x(), srcp.memory());
else if (size == SIZE_WORD)
diff --git a/src/devices/cpu/drcbec.cpp b/src/devices/cpu/drcbec.cpp
index 757ba9b28e9..7b2b9818db2 100644
--- a/src/devices/cpu/drcbec.cpp
+++ b/src/devices/cpu/drcbec.cpp
@@ -171,6 +171,11 @@ enum
#define PARAM2 (*inst[2].puint32)
#define PARAM3 (*inst[3].puint32)
+#define SPARAM0 (*inst[0].pint32)
+#define SPARAM1 (*inst[1].pint32)
+#define SPARAM2 (*inst[2].pint32)
+#define SPARAM3 (*inst[3].pint32)
+
#define DPARAM0 (*inst[0].puint64)
#define DPARAM1 (*inst[1].puint64)
#define DPARAM2 (*inst[2].puint64)
@@ -373,7 +378,7 @@ public:
private:
// helpers
- void output_parameter(drcbec_instruction **dstptr, void **immedptr, int size, const uml::parameter &param);
+ void output_parameter(drcbec_instruction **dstptr, void *immed, int immoffset, int size, const uml::parameter &param);
void fixup_label(void *parameter, drccodeptr labelcodeptr);
// internal state
@@ -516,6 +521,7 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
{
const instruction &inst = instlist[inum];
uint8_t psize[instruction::MAX_PARAMS];
+ int8_t immoffset[instruction::MAX_PARAMS];
// handle most instructions generally, but a few special cases
opcode_t opcode = inst.opcode();
@@ -581,35 +587,49 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
// 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());
+ 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());
+ 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());
+ 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());
+ opcode = opcode_t(OP_READ1 + inst.param(2).size());
if (opcode == OP_READM)
- opcode = (opcode_t)(OP_READM1 + inst.param(3).size());
+ opcode = opcode_t(OP_READM1 + inst.param(3).size());
if (opcode == OP_WRITE)
- opcode = (opcode_t)(OP_WRITE1 + inst.param(2).size());
+ opcode = opcode_t(OP_WRITE1 + inst.param(2).size());
if (opcode == OP_WRITEM)
- opcode = (opcode_t)(OP_WRITEM1 + inst.param(3).size());
+ opcode = opcode_t(OP_WRITEM1 + inst.param(3).size());
if (opcode == OP_SEXT)
- opcode = (opcode_t)(OP_SEXT1 + inst.param(2).size());
+ 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());
+ 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));
+ opcode = opcode_t(OP_FFRI4 + (inst.param(2).size() - 2));
if (opcode == OP_FFRFLT)
- opcode = (opcode_t)(OP_FFRFS + (inst.param(2).size() - 2));
+ 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))
+ {
+ auto const &param = inst.param(pnum);
+ if (param.is_mapvar() ||
+ (param.is_immediate() && (param.immediate() != 0)) ||
+ (param.is_size_space() && (param.space() != 0)))
+ {
+ int const align = (psize[pnum] == 4) ? alignof(uint32_t) : alignof(uint64_t);
+ int const misalign = immedbytes % align;
+ if (misalign)
+ immedbytes += align - misalign;
+ immoffset[pnum] = immedbytes;
immedbytes += psize[pnum];
+ }
+ else
+ {
+ immoffset[pnum] = -1;
+ }
+ }
// compute how many instruction words we need for that
int immedwords = (immedbytes + sizeof(drcbec_instruction) - 1) / sizeof(drcbec_instruction);
@@ -622,7 +642,7 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
// output each of the parameters
for (int pnum = 0; pnum < inst.numparams(); pnum++)
- output_parameter(&dst, &immed, psize[pnum], inst.param(pnum));
+ output_parameter(&dst, immed, immoffset[pnum], psize[pnum], inst.param(pnum));
// point past the end of the immediates
dst += immedwords;
@@ -640,9 +660,9 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
immed = dst + 3;
- output_parameter(&dst, &immed, 8, inst.param(pnum));
- output_parameter(&dst, &immed, 8, inst.param(pnum));
- output_parameter(&dst, &immed, 8, 0xffffffff);
+ output_parameter(&dst, immed, -1, 8, inst.param(pnum));
+ output_parameter(&dst, immed, -1, 8, inst.param(pnum));
+ output_parameter(&dst, immed, 0, 8, 0xffffffff);
dst += immedwords;
@@ -655,9 +675,7 @@ void drcbe_c::generate(drcuml_block &block, const instruction *instlist, uint32_
for (int pnum = 0; pnum < inst.numparams(); pnum++)
{
if (inst.is_param_out(pnum) && inst.param(pnum).is_int_register())
- {
ireg_needs_clearing[inst.param(pnum).ireg() - REG_I0] = true;
- }
}
}
@@ -869,147 +887,147 @@ int drcbe_c::execute(code_handle &entry)
// ----------------------- 32-Bit Integer Operations -----------------------
case MAKE_OPCODE_SHORT(OP_LOAD1, 4, 0): // LOAD dst,base,index,BYTE
- PARAM0 = inst[1].puint8[PARAM2];
+ PARAM0 = inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x2, 4, 0): // LOAD dst,base,index,BYTE_x2
- PARAM0 = *(uint8_t *)&inst[1].puint16[PARAM2];
+ PARAM0 = *(uint8_t *)&inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x4, 4, 0): // LOAD dst,base,index,BYTE_x4
- PARAM0 = *(uint8_t *)&inst[1].puint32[PARAM2];
+ PARAM0 = *(uint8_t *)&inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x8, 4, 0): // LOAD dst,base,index,BYTE_x8
- PARAM0 = *(uint8_t *)&inst[1].puint64[PARAM2];
+ PARAM0 = *(uint8_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x1, 4, 0): // LOAD dst,base,index,WORD_x1
- PARAM0 = *(uint16_t *)&inst[1].puint8[PARAM2];
+ PARAM0 = *(uint16_t *)&inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2, 4, 0): // LOAD dst,base,index,WORD
- PARAM0 = inst[1].puint16[PARAM2];
+ PARAM0 = inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x4, 4, 0): // LOAD dst,base,index,WORD_x4
- PARAM0 = *(uint16_t *)&inst[1].puint32[PARAM2];
+ PARAM0 = *(uint16_t *)&inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x8, 4, 0): // LOAD dst,base,index,WORD_x8
- PARAM0 = *(uint16_t *)&inst[1].puint64[PARAM2];
+ PARAM0 = *(uint16_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x1, 4, 0): // LOAD dst,base,index,DWORD_x1
- PARAM0 = *(uint32_t *)&inst[1].puint8[PARAM2];
+ PARAM0 = *(uint32_t *)&inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x2, 4, 0): // LOAD dst,base,index,DWORD_x2
- PARAM0 = *(uint32_t *)&inst[1].puint16[PARAM2];
+ PARAM0 = *(uint32_t *)&inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4, 4, 0): // LOAD dst,base,index,DWORD
- PARAM0 = inst[1].puint32[PARAM2];
+ PARAM0 = inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x8, 4, 0): // LOAD dst,base,index,DWORD_x8
- PARAM0 = *(uint32_t *)&inst[1].puint64[PARAM2];
+ PARAM0 = *(uint32_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1, 4, 0): // LOADS dst,base,index,BYTE
- PARAM0 = inst[1].pint8[PARAM2];
+ PARAM0 = inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x2, 4, 0): // LOADS dst,base,index,BYTE_x2
- PARAM0 = *(int8_t *)&inst[1].pint16[PARAM2];
+ PARAM0 = *(int8_t *)&inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x4, 4, 0): // LOADS dst,base,index,BYTE_x4
- PARAM0 = *(int8_t *)&inst[1].pint32[PARAM2];
+ PARAM0 = *(int8_t *)&inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x8, 4, 0): // LOADS dst,base,index,BYTE_x8
- PARAM0 = *(int8_t *)&inst[1].pint64[PARAM2];
+ PARAM0 = *(int8_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x1, 4, 0): // LOADS dst,base,index,WORD_x1
- PARAM0 = *(int16_t *)&inst[1].pint8[PARAM2];
+ PARAM0 = *(int16_t *)&inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2, 4, 0): // LOADS dst,base,index,WORD
- PARAM0 = inst[1].pint16[PARAM2];
+ PARAM0 = inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x4, 4, 0): // LOADS dst,base,index,WORD_x4
- PARAM0 = *(int16_t *)&inst[1].pint32[PARAM2];
+ PARAM0 = *(int16_t *)&inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x8, 4, 0): // LOADS dst,base,index,WORD_x8
- PARAM0 = *(int16_t *)&inst[1].pint64[PARAM2];
+ PARAM0 = *(int16_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x1, 4, 0): // LOADS dst,base,index,DWORD_x1
- PARAM0 = *(int32_t *)&inst[1].pint8[PARAM2];
+ PARAM0 = *(int32_t *)&inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x2, 4, 0): // LOADS dst,base,index,DWORD_x2
- PARAM0 = *(int32_t *)&inst[1].pint16[PARAM2];
+ PARAM0 = *(int32_t *)&inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4, 4, 0): // LOADS dst,base,index,DWORD
- PARAM0 = inst[1].pint32[PARAM2];
+ PARAM0 = inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x8, 4, 0): // LOADS dst,base,index,DWORD_x8
- PARAM0 = *(int32_t *)&inst[1].pint64[PARAM2];
+ PARAM0 = *(int32_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_STORE1, 4, 0): // STORE dst,base,index,BYTE
- inst[0].puint8[PARAM1] = PARAM2;
+ inst[0].puint8[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x2, 4, 0): // STORE dst,base,index,BYTE_x2
- *(uint8_t *)&inst[0].puint16[PARAM1] = PARAM2;
+ *(uint8_t *)&inst[0].puint16[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x4, 4, 0): // STORE dst,base,index,BYTE_x4
- *(uint8_t *)&inst[0].puint32[PARAM1] = PARAM2;
+ *(uint8_t *)&inst[0].puint32[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x8, 4, 0): // STORE dst,base,index,BYTE_x8
- *(uint8_t *)&inst[0].puint64[PARAM1] = PARAM2;
+ *(uint8_t *)&inst[0].puint64[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x1, 4, 0): // STORE dst,base,index,WORD_x1
- *(uint16_t *)&inst[0].puint8[PARAM1] = PARAM2;
+ *(uint16_t *)&inst[0].puint8[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2, 4, 0): // STORE dst,base,index,WORD
- inst[0].puint16[PARAM1] = PARAM2;
+ inst[0].puint16[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x4, 4, 0): // STORE dst,base,index,WORD_x4
- *(uint16_t *)&inst[0].puint32[PARAM1] = PARAM2;
+ *(uint16_t *)&inst[0].puint32[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x8, 4, 0): // STORE dst,base,index,WORD_x8
- *(uint16_t *)&inst[0].puint64[PARAM1] = PARAM2;
+ *(uint16_t *)&inst[0].puint64[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x1, 4, 0): // STORE dst,base,index,DWORD_x1
- *(uint32_t *)&inst[0].puint8[PARAM1] = PARAM2;
+ *(uint32_t *)&inst[0].puint8[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x2, 4, 0): // STORE dst,base,index,DWORD_x2
- *(uint32_t *)&inst[0].puint16[PARAM1] = PARAM2;
+ *(uint32_t *)&inst[0].puint16[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4, 4, 0): // STORE dst,base,index,DWORD
- inst[0].puint32[PARAM1] = PARAM2;
+ inst[0].puint32[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x8, 4, 0): // STORE dst,base,index,DWORD_x8
- *(uint32_t *)&inst[0].puint64[PARAM1] = PARAM2;
+ *(uint32_t *)&inst[0].puint64[SPARAM1] = PARAM2;
break;
case MAKE_OPCODE_SHORT(OP_READ1, 4, 0): // READ dst,src1,space_BYTE
@@ -1172,7 +1190,6 @@ int drcbe_c::execute(code_handle &entry)
case MAKE_OPCODE_SHORT(OP_CMP, 4, 1): // CMP src1,src2[,f]
temp32 = PARAM0 - PARAM1;
flags = FLAGS32_NZCV_SUB(temp32, PARAM0, PARAM1);
-// printf("CMP: %08x - %08x = flags %x\n", PARAM0, PARAM1, flags);
break;
case MAKE_OPCODE_SHORT(OP_MULU, 4, 0): // MULU dst,edst,src1,src2[,f]
@@ -1454,195 +1471,195 @@ int drcbe_c::execute(code_handle &entry)
// ----------------------- 64-Bit Integer Operations -----------------------
case MAKE_OPCODE_SHORT(OP_LOAD1, 8, 0): // DLOAD dst,base,index,BYTE
- DPARAM0 = inst[1].puint8[PARAM2];
+ DPARAM0 = inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x2, 8, 0): // DLOAD dst,base,index,BYTE_x2
- DPARAM0 = *(uint8_t *)&inst[1].puint16[PARAM2];
+ DPARAM0 = *(uint8_t *)&inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x4, 8, 0): // DLOAD dst,base,index,BYTE_x4
- DPARAM0 = *(uint8_t *)&inst[1].puint32[PARAM2];
+ DPARAM0 = *(uint8_t *)&inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD1x8, 8, 0): // DLOAD dst,base,index,BYTE_x8
- DPARAM0 = *(uint8_t *)&inst[1].puint64[PARAM2];
+ DPARAM0 = *(uint8_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x1, 8, 0): // DLOAD dst,base,index,WORD_x1
- DPARAM0 = *(uint16_t *)&inst[1].puint8[PARAM2];
+ DPARAM0 = *(uint16_t *)&inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2, 8, 0): // DLOAD dst,base,index,WORD
- DPARAM0 = inst[1].puint16[PARAM2];
+ DPARAM0 = inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x4, 8, 0): // DLOAD dst,base,index,WORD_x4
- DPARAM0 = *(uint16_t *)&inst[1].puint32[PARAM2];
+ DPARAM0 = *(uint16_t *)&inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD2x8, 8, 0): // DLOAD dst,base,index,WORD_x8
- DPARAM0 = *(uint16_t *)&inst[1].puint64[PARAM2];
+ DPARAM0 = *(uint16_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x1, 8, 0): // DLOAD dst,base,index,DWORD_x1
- DPARAM0 = *(uint32_t *)&inst[1].puint8[PARAM2];
+ DPARAM0 = *(uint32_t *)&inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x2, 8, 0): // DLOAD dst,base,index,DWORD_x2
- DPARAM0 = *(uint32_t *)&inst[1].puint16[PARAM2];
+ DPARAM0 = *(uint32_t *)&inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4, 8, 0): // DLOAD dst,base,index,DWORD
- DPARAM0 = inst[1].puint32[PARAM2];
+ DPARAM0 = inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD4x8, 8, 0): // DLOAD dst,base,index,DWORD_x8
- DPARAM0 = *(uint32_t *)&inst[1].puint64[PARAM2];
+ DPARAM0 = *(uint32_t *)&inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD8x1, 8, 0): // DLOAD dst,base,index,QWORD_x1
- DPARAM0 = *(uint64_t *)&inst[1].puint8[PARAM2];
+ DPARAM0 = *(uint64_t *)&inst[1].puint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD8x2, 8, 0): // DLOAD dst,base,index,QWORD_x2
- DPARAM0 = *(uint64_t *)&inst[1].puint16[PARAM2];
+ DPARAM0 = *(uint64_t *)&inst[1].puint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD8x4, 8, 0): // DLOAD dst,base,index,QWORD_x4
- DPARAM0 = *(uint64_t *)&inst[1].puint32[PARAM2];
+ DPARAM0 = *(uint64_t *)&inst[1].puint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOAD8, 8, 0): // DLOAD dst,base,index,QWORD
- DPARAM0 = inst[1].puint64[PARAM2];
+ DPARAM0 = inst[1].puint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1, 8, 0): // DLOADS dst,base,index,BYTE
- DPARAM0 = inst[1].pint8[PARAM2];
+ DPARAM0 = inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x2, 8, 0): // DLOADS dst,base,index,BYTE_x2
- DPARAM0 = *(int8_t *)&inst[1].pint16[PARAM2];
+ DPARAM0 = *(int8_t *)&inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x4, 8, 0): // DLOADS dst,base,index,BYTE_x4
- DPARAM0 = *(int8_t *)&inst[1].pint32[PARAM2];
+ DPARAM0 = *(int8_t *)&inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS1x8, 8, 0): // DLOADS dst,base,index,BYTE_x8
- DPARAM0 = *(int8_t *)&inst[1].pint64[PARAM2];
+ DPARAM0 = *(int8_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x1, 8, 0): // DLOADS dst,base,index,WORD_x1
- DPARAM0 = *(int16_t *)&inst[1].pint8[PARAM2];
+ DPARAM0 = *(int16_t *)&inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2, 8, 0): // DLOADS dst,base,index,WORD
- DPARAM0 = inst[1].pint16[PARAM2];
+ DPARAM0 = inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x4, 8, 0): // DLOADS dst,base,index,WORD_x4
- DPARAM0 = *(int16_t *)&inst[1].pint32[PARAM2];
+ DPARAM0 = *(int16_t *)&inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS2x8, 8, 0): // DLOADS dst,base,index,WORD_x8
- DPARAM0 = *(int16_t *)&inst[1].pint64[PARAM2];
+ DPARAM0 = *(int16_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x1, 8, 0): // DLOADS dst,base,index,DWORD_x1
- DPARAM0 = *(int32_t *)&inst[1].pint8[PARAM2];
+ DPARAM0 = *(int32_t *)&inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x2, 8, 0): // DLOADS dst,base,index,DWORD_x2
- DPARAM0 = *(int32_t *)&inst[1].pint16[PARAM2];
+ DPARAM0 = *(int32_t *)&inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4, 8, 0): // DLOADS dst,base,index,DWORD
- DPARAM0 = inst[1].pint32[PARAM2];
+ DPARAM0 = inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS4x8, 8, 0): // DLOADS dst,base,index,DWORD_x8
- DPARAM0 = *(int32_t *)&inst[1].pint64[PARAM2];
+ DPARAM0 = *(int32_t *)&inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS8x1, 8, 0): // DLOADS dst,base,index,QWORD_x1
- DPARAM0 = *(int64_t *)&inst[1].pint8[PARAM2];
+ DPARAM0 = *(int64_t *)&inst[1].pint8[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS8x2, 8, 0): // DLOADS dst,base,index,QWORD_x2
- DPARAM0 = *(int64_t *)&inst[1].pint16[PARAM2];
+ DPARAM0 = *(int64_t *)&inst[1].pint16[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS8x4, 8, 0): // DLOADS dst,base,index,QWORD_x4
- DPARAM0 = *(int64_t *)&inst[1].pint32[PARAM2];
+ DPARAM0 = *(int64_t *)&inst[1].pint32[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_LOADS8, 8, 0): // DLOADS dst,base,index,QWORD
- DPARAM0 = inst[1].pint64[PARAM2];
+ DPARAM0 = inst[1].pint64[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_STORE1, 8, 0): // DSTORE dst,base,index,BYTE
- inst[0].puint8[PARAM1] = DPARAM2;
+ inst[0].puint8[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x2, 8, 0): // DSTORE dst,base,index,BYTE_x2
- *(uint8_t *)&inst[0].puint16[PARAM1] = DPARAM2;
+ *(uint8_t *)&inst[0].puint16[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x4, 8, 0): // DSTORE dst,base,index,BYTE_x4
- *(uint8_t *)&inst[0].puint32[PARAM1] = DPARAM2;
+ *(uint8_t *)&inst[0].puint32[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE1x8, 8, 0): // DSTORE dst,base,index,BYTE_x8
- *(uint8_t *)&inst[0].puint64[PARAM1] = DPARAM2;
+ *(uint8_t *)&inst[0].puint64[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x1, 8, 0): // DSTORE dst,base,index,WORD_x1
- *(uint16_t *)&inst[0].puint8[PARAM1] = DPARAM2;
+ *(uint16_t *)&inst[0].puint8[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2, 8, 0): // DSTORE dst,base,index,WORD
- inst[0].puint16[PARAM1] = DPARAM2;
+ inst[0].puint16[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x4, 8, 0): // DSTORE dst,base,index,WORD_x4
- *(uint16_t *)&inst[0].puint32[PARAM1] = DPARAM2;
+ *(uint16_t *)&inst[0].puint32[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE2x8, 8, 0): // DSTORE dst,base,index,WORD_x8
- *(uint16_t *)&inst[0].puint64[PARAM1] = DPARAM2;
+ *(uint16_t *)&inst[0].puint64[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x1, 8, 0): // DSTORE dst,base,index,DWORD_x1
- *(uint32_t *)&inst[0].puint8[PARAM1] = DPARAM2;
+ *(uint32_t *)&inst[0].puint8[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x2, 8, 0): // DSTORE dst,base,index,DWORD_x2
- *(uint32_t *)&inst[0].puint16[PARAM1] = DPARAM2;
+ *(uint32_t *)&inst[0].puint16[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4, 8, 0): // DSTORE dst,base,index,DWORD
- inst[0].puint32[PARAM1] = DPARAM2;
+ inst[0].puint32[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE4x8, 8, 0): // DSTORE dst,base,index,DWORD_x8
- *(uint32_t *)&inst[0].puint64[PARAM1] = DPARAM2;
+ *(uint32_t *)&inst[0].puint64[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE8x1, 8, 0): // DSTORE dst,base,index,QWORD_x1
- *(uint64_t *)&inst[0].puint8[PARAM1] = DPARAM2;
+ *(uint64_t *)&inst[0].puint8[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE8x2, 8, 0): // DSTORE dst,base,index,QWORD_x2
- *(uint64_t *)&inst[0].puint16[PARAM1] = DPARAM2;
+ *(uint64_t *)&inst[0].puint16[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE8x4, 8, 0): // DSTORE dst,base,index,QWORD_x4
- *(uint64_t *)&inst[0].puint32[PARAM1] = DPARAM2;
+ *(uint64_t *)&inst[0].puint32[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_STORE8, 8, 0): // DSTORE dst,base,index,QWORD
- inst[0].puint64[PARAM1] = DPARAM2;
+ inst[0].puint64[SPARAM1] = DPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_READ1, 8, 0): // DREAD dst,src1,space_BYTE
@@ -2072,11 +2089,11 @@ int drcbe_c::execute(code_handle &entry)
// ----------------------- 32-Bit Floating Point Operations -----------------------
case MAKE_OPCODE_SHORT(OP_FLOAD, 4, 0): // FSLOAD dst,base,index
- FSPARAM0 = inst[1].pfloat[PARAM2];
+ FSPARAM0 = inst[1].pfloat[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_FSTORE, 4, 0): // FSSTORE dst,base,index
- inst[0].pfloat[PARAM1] = FSPARAM2;
+ inst[0].pfloat[SPARAM1] = FSPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_FREAD, 4, 0): // FSREAD dst,src1,space
@@ -2215,11 +2232,11 @@ int drcbe_c::execute(code_handle &entry)
// ----------------------- 64-Bit Floating Point Operations -----------------------
case MAKE_OPCODE_SHORT(OP_FLOAD, 8, 0): // FDLOAD dst,base,index
- FDPARAM0 = inst[1].pdouble[PARAM2];
+ FDPARAM0 = inst[1].pdouble[SPARAM2];
break;
case MAKE_OPCODE_SHORT(OP_FSTORE, 8, 0): // FDSTORE dst,base,index
- inst[0].pdouble[PARAM1] = FDPARAM2;
+ inst[0].pdouble[SPARAM1] = FDPARAM2;
break;
case MAKE_OPCODE_SHORT(OP_FREAD, 8, 0): // FDREAD dst,src1,space
@@ -2375,25 +2392,27 @@ int drcbe_c::execute(code_handle &entry)
// output_parameter - output a parameter
//-------------------------------------------------
-void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int size, const parameter &param)
+void drcbe_c::output_parameter(drcbec_instruction **dstptr, void *immed, int immoffset, int size, const parameter &param)
{
drcbec_instruction *dst = *dstptr;
- void *immed = *immedptr;
switch (param.type())
{
// 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;
+ assert(immoffset >= 0);
+ auto const thisimmed = reinterpret_cast<uint8_t *>(immed) + immoffset;
+ (dst++)->v = thisimmed;
if (size == 4)
- *(uint32_t *)immed = (uint32_t)param.immediate();
+ *(uint32_t *)thisimmed = (uint32_t)param.immediate();
else
- *(uint64_t *)immed = (uint64_t)param.immediate();
- immed = (uint8_t *)immed + size;
+ *(uint64_t *)thisimmed = (uint64_t)param.immediate();
}
break;
@@ -2415,7 +2434,7 @@ void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int
// convert mapvars to immediates
case parameter::PTYPE_MAPVAR:
- return output_parameter(dstptr, immedptr, size, param.mapvar());
+ return output_parameter(dstptr, immed, immoffset, size, param.mapvar());
// memory just points to the memory
case parameter::PTYPE_MEMORY:
@@ -2427,11 +2446,11 @@ void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int
case parameter::PTYPE_SIZE_SCALE:
case parameter::PTYPE_ROUNDING:
case parameter::PTYPE_STRING:
- return output_parameter(dstptr, immedptr, size, 0);
+ return output_parameter(dstptr, immed, immoffset, 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());
+ return output_parameter(dstptr, immed, immoffset, size, param.space());
// code handle just points to the handle
case parameter::PTYPE_CODE_HANDLE:
@@ -2440,7 +2459,7 @@ void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int
// code label just contains the label value
case parameter::PTYPE_CODE_LABEL:
- return output_parameter(dstptr, immedptr, size, uint32_t(param.label()));
+ return output_parameter(dstptr, immed, immoffset, size, uint32_t(param.label()));
// c_function just points to the C function
case parameter::PTYPE_C_FUNCTION:
@@ -2452,7 +2471,6 @@ void drcbe_c::output_parameter(drcbec_instruction **dstptr, void **immedptr, int
}
*dstptr = dst;
- *immedptr = immed;
}
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index 7b870ece35a..b3c51da2a01 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -3744,23 +3744,16 @@ void drcbe_x64::op_sext(Assembler &a, const instruction &inst)
else if (sizep.size() == SIZE_DWORD)
a.mov(dstreg, MABS(srcp.memory()));
}
- else if (srcp.is_int_register())
- {
- if (sizep.size() == SIZE_BYTE)
- a.movsx(dstreg, GpbLo(srcp.ireg()));
- else if (sizep.size() == SIZE_WORD)
- a.movsx(dstreg, Gpw(srcp.ireg()));
- else if (sizep.size() == SIZE_DWORD)
- a.mov(dstreg, Gpd(srcp.ireg()));
- }
- else if (srcp.is_immediate())
+ else
{
+ Gp const srcreg = srcp.select_register(dstreg);
+ mov_reg_param(a, srcreg, srcp);
if (sizep.size() == SIZE_BYTE)
- a.mov(dstreg, int32_t(int8_t(uint8_t(srcp.immediate()))));
+ a.movsx(dstreg, srcreg.r8());
else if (sizep.size() == SIZE_WORD)
- a.mov(dstreg, int32_t(int16_t(uint16_t(srcp.immediate()))));
+ a.movsx(dstreg, srcreg.r16());
else if (sizep.size() == SIZE_DWORD)
- a.mov(dstreg, int32_t(uint32_t(srcp.immediate())));
+ a.mov(dstreg, srcreg);
}
mov_param_reg(a, dstp, dstreg);
@@ -3779,27 +3772,18 @@ void drcbe_x64::op_sext(Assembler &a, const instruction &inst)
else if (sizep.size() == SIZE_QWORD)
a.mov(dstreg, MABS(srcp.memory()));
}
- else if (srcp.is_int_register())
- {
- if (sizep.size() == SIZE_BYTE)
- a.movsx(dstreg, GpbLo(srcp.ireg()));
- else if (sizep.size() == SIZE_WORD)
- a.movsx(dstreg, Gpw(srcp.ireg()));
- else if (sizep.size() == SIZE_DWORD)
- a.movsxd(dstreg, Gpd(srcp.ireg()));
- else if (sizep.size() == SIZE_QWORD)
- a.mov(dstreg, Gpq(srcp.ireg()));
- }
- else if (srcp.is_immediate())
+ else
{
+ Gp const srcreg = srcp.select_register(dstreg);
+ mov_reg_param(a, srcreg, srcp);
if (sizep.size() == SIZE_BYTE)
- a.mov(dstreg, int64_t(int8_t(uint8_t(srcp.immediate()))));
+ a.movsx(dstreg, srcreg.r8());
else if (sizep.size() == SIZE_WORD)
- a.mov(dstreg, int64_t(int16_t(uint16_t(srcp.immediate()))));
+ a.movsx(dstreg, srcreg.r16());
else if (sizep.size() == SIZE_DWORD)
- a.mov(dstreg, int64_t(int32_t(uint32_t(srcp.immediate()))));
+ a.movsxd(dstreg, srcreg.r32());
else if (sizep.size() == SIZE_QWORD)
- a.mov(dstreg, int64_t(srcp.immediate()));
+ a.mov(dstreg, srcreg);
}
mov_param_reg(a, dstp, dstreg);
diff --git a/src/devices/cpu/drcbex86.cpp b/src/devices/cpu/drcbex86.cpp
index 24de0549334..43f4c69b233 100644
--- a/src/devices/cpu/drcbex86.cpp
+++ b/src/devices/cpu/drcbex86.cpp
@@ -3659,7 +3659,7 @@ void drcbe_x86::op_load(Assembler &a, const instruction &inst)
{
// other index
Gp const indreg = indp.select_register(ecx);
- emit_mov_r32_p32(a, indreg, indp);
+ emit_mov_r32_p32_keepflags(a, indreg, indp);
if (size == SIZE_BYTE)
a.movzx(dstreg, ptr(uintptr_t(basep.memory()), indreg, scalesizep.scale(), 1)); // movzx dstreg,[basep + scale*indp]
else if (size == SIZE_WORD)
@@ -3679,18 +3679,17 @@ void drcbe_x86::op_load(Assembler &a, const instruction &inst)
// 64-bit form stores upper 32 bits
if (inst.size() == 8)
{
- // 1, 2, or 4-byte case
if (size != SIZE_QWORD)
{
+ // 1, 2, or 4-byte case
if (dstp.is_memory())
a.mov(MABS(dstp.memory(4), 4), 0); // mov [dstp+4],0
else if (dstp.is_int_register())
a.mov(MABS(m_reghi[dstp.ireg()], 4), 0); // mov [reghi],0
}
-
- // 8-byte case
else
{
+ // 8-byte case
if (dstp.is_memory())
a.mov(MABS(dstp.memory(4)), edx); // mov [dstp+4],edx
else if (dstp.is_int_register())
@@ -3745,7 +3744,7 @@ void drcbe_x86::op_loads(Assembler &a, const instruction &inst)
{
// other index
Gp const indreg = indp.select_register(ecx);
- emit_mov_r32_p32(a, indreg, indp);
+ emit_mov_r32_p32_keepflags(a, indreg, indp);
if (size == SIZE_BYTE)
a.movsx(dstreg, ptr(uintptr_t(basep.memory()), indreg, scalesizep.scale(), 1)); // movsx dstreg,[basep + scale*indp]
else if (size == SIZE_WORD)
@@ -3829,9 +3828,9 @@ void drcbe_x86::op_store(Assembler &a, const instruction &inst)
{
// variable source
if (size != SIZE_QWORD)
- emit_mov_r32_p32(a, srcreg, srcp); // mov srcreg,srcp
+ emit_mov_r32_p32_keepflags(a, srcreg, srcp); // mov srcreg,srcp
else
- emit_mov_r64_p64(a, srcreg, edx, srcp); // mov edx:srcreg,srcp
+ emit_mov_r64_p64_keepflags(a, srcreg, edx, srcp); // mov edx:srcreg,srcp
if (size == SIZE_BYTE)
a.mov(MABS(basep.memory(scale*indp.immediate())), srcreg.r8()); // mov [basep + scale*indp],srcreg
@@ -3850,7 +3849,7 @@ void drcbe_x86::op_store(Assembler &a, const instruction &inst)
{
// normal case: variable index
Gp const indreg = indp.select_register(ecx);
- emit_mov_r32_p32(a, indreg, indp); // mov indreg,indp
+ emit_mov_r32_p32_keepflags(a, indreg, indp); // mov indreg,indp
if (srcp.is_immediate())
{
@@ -3872,9 +3871,9 @@ void drcbe_x86::op_store(Assembler &a, const instruction &inst)
{
// variable source
if (size != SIZE_QWORD)
- emit_mov_r32_p32(a, srcreg, srcp); // mov srcreg,srcp
+ emit_mov_r32_p32_keepflags(a, srcreg, srcp); // mov srcreg,srcp
else
- emit_mov_r64_p64(a, srcreg, edx, srcp); // mov edx:srcreg,srcp
+ emit_mov_r64_p64_keepflags(a, srcreg, edx, srcp); // mov edx:srcreg,srcp
if (size == SIZE_BYTE)
a.mov(ptr(uintptr_t(basep.memory()), indreg, scalesizep.scale()), srcreg.r8()); // mov [basep + 1*ecx],srcreg
else if (size == SIZE_WORD)
@@ -6534,19 +6533,18 @@ void drcbe_x86::op_fload(Assembler &a, const instruction &inst)
be_parameter basep(*this, inst.param(1), PTYPE_M);
be_parameter indp(*this, inst.param(2), PTYPE_MRI);
- // immediate index
if (indp.is_immediate())
{
+ // immediate index
a.mov(eax, MABS(basep.memory(inst.size()*indp.immediate())));
if (inst.size() == 8)
a.mov(edx, MABS(basep.memory(4 + inst.size()*indp.immediate())));
}
-
- // other index
else
{
+ // other index
Gp const indreg = indp.select_register(ecx);
- emit_mov_r32_p32(a, indreg, indp);
+ emit_mov_r32_p32_keepflags(a, indreg, indp);
a.mov(eax, ptr(uintptr_t(basep.memory(0)), indreg, (inst.size() == 8) ? 3 : 2));
if (inst.size() == 8)
a.mov(edx, ptr(uintptr_t(basep.memory(4)), indreg, (inst.size() == 8) ? 3 : 2));
@@ -6590,7 +6588,7 @@ void drcbe_x86::op_fstore(Assembler &a, const instruction &inst)
{
// other index
Gp const indreg = indp.select_register(ecx);
- emit_mov_r32_p32(a, indreg, indp);
+ emit_mov_r32_p32_keepflags(a, indreg, indp);
a.mov(ptr(uintptr_t(basep.memory(0)), indreg, (inst.size() == 8) ? 3 : 2), eax);
if (inst.size() == 8)
a.mov(ptr(uintptr_t(basep.memory(4)), indreg, (inst.size() == 8) ? 3 : 2), edx);