mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
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.
This commit is contained in:
parent
2f93065a39
commit
de40641555
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 ¶m);
|
||||
void output_parameter(drcbec_instruction **dstptr, void *immed, int immoffset, int size, const uml::parameter ¶m);
|
||||
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 ¶m = 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 ¶m)
|
||||
void drcbe_c::output_parameter(drcbec_instruction **dstptr, void *immed, int immoffset, int size, const parameter ¶m)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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())
|
||||
else
|
||||
{
|
||||
Gp const srcreg = srcp.select_register(dstreg);
|
||||
mov_reg_param(a, srcreg, srcp);
|
||||
if (sizep.size() == SIZE_BYTE)
|
||||
a.movsx(dstreg, GpbLo(srcp.ireg()));
|
||||
a.movsx(dstreg, srcreg.r8());
|
||||
else if (sizep.size() == SIZE_WORD)
|
||||
a.movsx(dstreg, Gpw(srcp.ireg()));
|
||||
a.movsx(dstreg, srcreg.r16());
|
||||
else if (sizep.size() == SIZE_DWORD)
|
||||
a.mov(dstreg, Gpd(srcp.ireg()));
|
||||
}
|
||||
else if (srcp.is_immediate())
|
||||
{
|
||||
if (sizep.size() == SIZE_BYTE)
|
||||
a.mov(dstreg, int32_t(int8_t(uint8_t(srcp.immediate()))));
|
||||
else if (sizep.size() == SIZE_WORD)
|
||||
a.mov(dstreg, int32_t(int16_t(uint16_t(srcp.immediate()))));
|
||||
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())
|
||||
else
|
||||
{
|
||||
Gp const srcreg = srcp.select_register(dstreg);
|
||||
mov_reg_param(a, srcreg, srcp);
|
||||
if (sizep.size() == SIZE_BYTE)
|
||||
a.movsx(dstreg, GpbLo(srcp.ireg()));
|
||||
a.movsx(dstreg, srcreg.r8());
|
||||
else if (sizep.size() == SIZE_WORD)
|
||||
a.movsx(dstreg, Gpw(srcp.ireg()));
|
||||
a.movsx(dstreg, srcreg.r16());
|
||||
else if (sizep.size() == SIZE_DWORD)
|
||||
a.movsxd(dstreg, Gpd(srcp.ireg()));
|
||||
a.movsxd(dstreg, srcreg.r32());
|
||||
else if (sizep.size() == SIZE_QWORD)
|
||||
a.mov(dstreg, Gpq(srcp.ireg()));
|
||||
}
|
||||
else if (srcp.is_immediate())
|
||||
{
|
||||
if (sizep.size() == SIZE_BYTE)
|
||||
a.mov(dstreg, int64_t(int8_t(uint8_t(srcp.immediate()))));
|
||||
else if (sizep.size() == SIZE_WORD)
|
||||
a.mov(dstreg, int64_t(int16_t(uint16_t(srcp.immediate()))));
|
||||
else if (sizep.size() == SIZE_DWORD)
|
||||
a.mov(dstreg, int64_t(int32_t(uint32_t(srcp.immediate()))));
|
||||
else if (sizep.size() == SIZE_QWORD)
|
||||
a.mov(dstreg, int64_t(srcp.immediate()));
|
||||
a.mov(dstreg, srcreg);
|
||||
}
|
||||
|
||||
mov_param_reg(a, dstp, dstreg);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user