* Removed explicit flag requests from the shorthand opcodes
 * Added optimization function to drcuml which is called at block end
 * Added logic to compute the necessary flags based on upcoming opcodes
    and only select those flags which are required
 * Updated the PPC and MIPS3 DRCs to no longer explicitly specify flags
This commit is contained in:
Aaron Giles 2008-06-06 07:36:36 +00:00
parent ee8162eff9
commit 1c1498b0fc
5 changed files with 273 additions and 355 deletions

View File

@ -218,7 +218,7 @@ static const drcuml_opcode_info opcode_info_source[] =
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, C, C, ALL, PINFO(IN, OP, IANY), PINFO(IN, OP, IANY))
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))
@ -294,6 +294,7 @@ static const drcuml_opcode_info *opcode_info_table[DRCUML_OP_MAX];
FUNCTION PROTOTYPES
***************************************************************************/
static void optimize_block(drcuml_block *block);
static void validate_instruction(drcuml_block *block, const drcuml_instruction *inst);
#if 0
@ -563,7 +564,7 @@ drcuml_block *drcuml_block_begin(drcuml_state *drcuml, UINT32 maxinst, jmp_buf *
0 parameters to the block
-------------------------------------------------*/
void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags)
void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition)
{
drcuml_instruction *inst = &block->inst[block->nextinst++];
@ -577,7 +578,7 @@ void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
inst->opcode = (UINT8)op;
inst->size = size;
inst->condition = condition;
inst->flags = flags;
inst->flags = 0;
inst->numparams = 0;
/* validation */
@ -590,7 +591,7 @@ void drcuml_block_append_0(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
1 parameter to the block
-------------------------------------------------*/
void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value)
void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, drcuml_ptype p0type, drcuml_pvalue p0value)
{
drcuml_instruction *inst = &block->inst[block->nextinst++];
@ -604,7 +605,7 @@ void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
inst->opcode = (UINT8)op;
inst->size = size;
inst->condition = condition;
inst->flags = flags;
inst->flags = 0;
inst->numparams = 1;
inst->param[0].type = p0type;
inst->param[0].value = p0value;
@ -619,7 +620,7 @@ void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
2 parameters to the block
-------------------------------------------------*/
void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value)
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)
{
drcuml_instruction *inst = &block->inst[block->nextinst++];
@ -633,7 +634,7 @@ void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
inst->opcode = (UINT8)op;
inst->size = size;
inst->condition = condition;
inst->flags = flags;
inst->flags = 0;
inst->numparams = 2;
inst->param[0].type = p0type;
inst->param[0].value = p0value;
@ -650,7 +651,7 @@ void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
3 parameters to the block
-------------------------------------------------*/
void drcuml_block_append_3(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value)
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++];
@ -664,7 +665,7 @@ void drcuml_block_append_3(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
inst->opcode = (UINT8)op;
inst->size = size;
inst->condition = condition;
inst->flags = flags;
inst->flags = 0;
inst->numparams = 3;
inst->param[0].type = p0type;
inst->param[0].value = p0value;
@ -683,7 +684,7 @@ void drcuml_block_append_3(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
4 parameters to the block
-------------------------------------------------*/
void drcuml_block_append_4(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value, drcuml_ptype p3type, drcuml_pvalue p3value)
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++];
@ -697,7 +698,7 @@ void drcuml_block_append_4(drcuml_block *block, drcuml_opcode op, UINT8 size, UI
inst->opcode = (UINT8)op;
inst->size = size;
inst->condition = condition;
inst->flags = flags;
inst->flags = 0;
inst->numparams = 4;
inst->param[0].type = p0type;
inst->param[0].value = p0value;
@ -723,6 +724,9 @@ 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)
@ -926,7 +930,7 @@ void drcuml_add_comment(drcuml_block *block, const char *format, ...)
strcpy(comment, buffer);
/* add an instruction with a pointer */
drcuml_block_append_1(block, DRCUML_OP_COMMENT, 4, DRCUML_COND_ALWAYS, 0, MEM(comment));
drcuml_block_append_1(block, DRCUML_OP_COMMENT, 4, DRCUML_COND_ALWAYS, MEM(comment));
}
@ -1083,6 +1087,59 @@ void drcuml_disasm(const drcuml_instruction *inst, char *buffer)
/***************************************************************************
CODE BLOCK OPTIMIZATION
***************************************************************************/
/*-------------------------------------------------
optimize_block - apply various optimizations
to a block of code
-------------------------------------------------*/
static void optimize_block(drcuml_block *block)
{
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;
/* 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 and convert to immediates here */
/* adjust commutative arguments */
/* if we don't need any flags, then we can eliminate a lot of dumb operations */
// if (inst->flags == 0)
// switch (inst->opcode)
// {
// }
}
}
/***************************************************************************
OPCODE VALIDATION
***************************************************************************/

View File

@ -444,11 +444,11 @@ void drcuml_free(drcuml_state *drcuml);
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, UINT8 flags);
void drcuml_block_append_1(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value);
void drcuml_block_append_2(drcuml_block *block, drcuml_opcode op, UINT8 size, UINT8 condition, UINT8 flags, 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, UINT8 flags, 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, UINT8 flags, drcuml_ptype p0type, drcuml_pvalue p0value, drcuml_ptype p1type, drcuml_pvalue p1value, drcuml_ptype p2type, drcuml_pvalue p2value, drcuml_ptype p3type, drcuml_pvalue p3value);
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);

View File

@ -46,33 +46,6 @@
#define IF_LE DRCUML_COND_LE
#define IF_ALWAYS DRCUML_COND_ALWAYS
/* shorthand for flags */
#define FLAGS_ALLI (DRCUML_FLAG_C | DRCUML_FLAG_V | DRCUML_FLAG_Z | DRCUML_FLAG_S)
#define FLAGS_ALLF (DRCUML_FLAG_C | DRCUML_FLAG_Z | DRCUML_FLAG_U)
#define FLAGS_NONE (0)
/* flags needed for condition codes */
#define FLAGS_Z (DRCUML_FLAG_Z)
#define FLAGS_NZ (DRCUML_FLAG_Z)
#define FLAGS_E (DRCUML_FLAG_Z)
#define FLAGS_NE (DRCUML_FLAG_Z)
#define FLAGS_S (DRCUML_FLAG_S)
#define FLAGS_NS (DRCUML_FLAG_S)
#define FLAGS_C (DRCUML_FLAG_C)
#define FLAGS_NC (DRCUML_FLAG_C)
#define FLAGS_V (DRCUML_FLAG_V)
#define FLAGS_NV (DRCUML_FLAG_V)
#define FLAGS_U (DRCUML_FLAG_U)
#define FLAGS_NU (DRCUML_FLAG_U)
#define FLAGS_A (DRCUML_FLAG_C | DRCUML_FLAG_Z)
#define FLAGS_BE (DRCUML_FLAG_C | DRCUML_FLAG_Z)
#define FLAGS_B (DRCUML_FLAG_C)
#define FLAGS_AE (DRCUML_FLAG_C)
#define FLAGS_G (DRCUML_FLAG_S | DRCUML_FLAG_V | DRCUML_FLAG_Z)
#define FLAGS_LE (DRCUML_FLAG_S | DRCUML_FLAG_V | DRCUML_FLAG_Z)
#define FLAGS_L (DRCUML_FLAG_S | DRCUML_FLAG_V)
#define FLAGS_GE (DRCUML_FLAG_S | DRCUML_FLAG_V)
/***************************************************************************
@ -95,257 +68,161 @@
***************************************************************************/
/* ----- Compile-time Opcodes ----- */
#define UML_HANDLE(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_HANDLE, 4, IF_ALWAYS, FLAGS_NONE, MEM(handle)); } while (0)
#define UML_HASH(block, mode, pc) do { drcuml_block_append_2(block, DRCUML_OP_HASH, 4, IF_ALWAYS, FLAGS_NONE, IMM(mode), IMM(pc)); } while (0)
#define UML_LABEL(block, label) do { drcuml_block_append_1(block, DRCUML_OP_LABEL, 4, IF_ALWAYS, FLAGS_NONE, IMM(label)); } while (0)
#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, FLAGS_NONE, mapvar, IMM(value)); } while (0)
#define UML_MAPVAR(block, mapvar, value) do { drcuml_block_append_2(block, DRCUML_OP_MAPVAR, 4, IF_ALWAYS, mapvar, IMM(value)); } while (0)
/* ----- Control Flow Operations ----- */
#define UML_DEBUG(block, pc) do { drcuml_block_append_1(block, DRCUML_OP_DEBUG, 4, IF_ALWAYS, FLAGS_NONE, pc); } while (0)
#define UML_EXIT(block, param) do { drcuml_block_append_1(block, DRCUML_OP_EXIT, 4, IF_ALWAYS, FLAGS_NONE, param); } while (0)
#define UML_EXITc(block, cond, param) do { drcuml_block_append_1(block, DRCUML_OP_EXIT, 4, cond, FLAGS_NONE, param); } while (0)
#define UML_HASHJMP(block, mode, pc, handle) do { drcuml_block_append_3(block, DRCUML_OP_HASHJMP, 4, IF_ALWAYS, FLAGS_NONE, mode, pc, MEM(handle)); } while (0)
#define UML_JMP(block, label) do { drcuml_block_append_1(block, DRCUML_OP_JMP, 4, IF_ALWAYS, FLAGS_NONE, IMM(label)); } while (0)
#define UML_JMPc(block, cond, label) do { drcuml_block_append_1(block, DRCUML_OP_JMP, 4, cond, FLAGS_NONE, IMM(label)); } while (0)
#define UML_JMPH(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_JMPH, 4, IF_ALWAYS, FLAGS_NONE, MEM(handle)); } while (0)
#define UML_JMPHc(block, cond, handle) do { drcuml_block_append_1(block, DRCUML_OP_JMPH, 4, cond, FLAGS_NONE, MEM(handle)); } while (0)
#define UML_EXH(block, handle, param) do { drcuml_block_append_2(block, DRCUML_OP_EXH, 4, IF_ALWAYS, FLAGS_NONE, MEM(handle), param); } while (0)
#define UML_EXHc(block, cond, handle, param) do { drcuml_block_append_2(block, DRCUML_OP_EXH, 4, cond, FLAGS_NONE, MEM(handle), param); } while (0)
#define UML_CALLH(block, handle) do { drcuml_block_append_1(block, DRCUML_OP_CALLH, 4, IF_ALWAYS, FLAGS_NONE, MEM(handle)); } while (0)
#define UML_CALLHc(block, cond, handle) do { drcuml_block_append_1(block, DRCUML_OP_CALLH, 4, cond, FLAGS_NONE, MEM(handle)); } while (0)
#define UML_RET(block) do { drcuml_block_append_0(block, DRCUML_OP_RET, 4, IF_ALWAYS, FLAGS_NONE); } while (0)
#define UML_RETc(block, cond) do { drcuml_block_append_0(block, DRCUML_OP_RET, 4, cond, FLAGS_NONE); } while (0)
#define UML_CALLC(block, func, ptr) do { drcuml_block_append_2(block, DRCUML_OP_CALLC, 4, IF_ALWAYS, FLAGS_NONE, MEM(func), MEM(ptr)); } while (0)
#define UML_CALLCc(block, cond, func, ptr) do { drcuml_block_append_2(block, DRCUML_OP_CALLC, 4, cond, FLAGS_NONE, MEM(func), MEM(ptr)); } while (0)
#define UML_RECOVER(block, dst, mapvar) do { drcuml_block_append_2(block, DRCUML_OP_RECOVER, 4, IF_ALWAYS, FLAGS_NONE, dst, mapvar); } 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)
/* ----- Internal Register Operations ----- */
#define UML_SETFMOD(block, mode) do { drcuml_block_append_1(block, DRCUML_OP_SETFMOD, 4, IF_ALWAYS, FLAGS_NONE, mode); } while (0)
#define UML_GETFMOD(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_GETFMOD, 4, IF_ALWAYS, FLAGS_NONE, dst); } while (0)
#define UML_GETEXP(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_GETEXP, 4, IF_ALWAYS, FLAGS_NONE, dst); } while (0)
#define UML_GETFLGS(block, dst, flags) do { drcuml_block_append_2(block, DRCUML_OP_GETFLGS, 4, IF_ALWAYS, FLAGS_NONE, dst, IMM(flags)); } while (0)
#define UML_SAVE(block, dst) do { drcuml_block_append_1(block, DRCUML_OP_SAVE, 4, IF_ALWAYS, FLAGS_NONE, MEM(dst)); } while (0)
#define UML_RESTORE(block, src) do { drcuml_block_append_1(block, DRCUML_OP_RESTORE, 4, IF_ALWAYS, FLAGS_NONE, MEM(src)); } while (0)
#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)
/* ----- 32-Bit Integer Operations ----- */
#define UML_LOAD(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOAD, 4, IF_ALWAYS, FLAGS_NONE, dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_LOADS(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOADS, 4, IF_ALWAYS, FLAGS_NONE, dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_STORE(block, base, index, src1, size) do { drcuml_block_append_4(block, DRCUML_OP_STORE, 4, IF_ALWAYS, FLAGS_NONE, MEM(base), index, src1, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_READ(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_READ, 4, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, src, bitnum); } while (0)
#define UML_SETc(block, cond, dst) do { drcuml_block_append_1(block, DRCUML_OP_SET, 4, cond, FLAGS_NONE, dst); } while (0)
#define UML_MOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_MOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 4, cond, FLAGS_NONE, dst, src1); } while (0)
#define UML_SEXT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_SEXT, 4, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src, shift, mask); } while (0)
#define UML_NEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_NEG, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_NEGf(block, dst, src1, flags) do { drcuml_block_append_2(block, DRCUML_OP_NEG, 4, IF_ALWAYS, flags, dst, src1); } while (0)
#define UML_ADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_ADDf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_ADDC(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_ADDCf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_SUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_SUBf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_SUBB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_SUBBf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_CMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 4, IF_ALWAYS, FLAGS_ALLI, src1, src2); } while (0)
#define UML_CMPf(block, src1, src2, flags) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 4, IF_ALWAYS, flags, src1, src2); } while (0)
#define UML_MULU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 4, IF_ALWAYS, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_MULUf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 4, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_MULSf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_MULS, 4, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DIVUf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_DIVU, 4, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DIVSf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_DIVS, 4, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_ANDf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_AND, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_TEST(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 4, IF_ALWAYS, FLAGS_S|FLAGS_Z,src1, src2); } while (0)
#define UML_TESTf(block, src1, src2, flags) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 4, IF_ALWAYS, flags, src1, src2); } while (0)
#define UML_OR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_OR, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_ORf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_OR, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_XOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_XORf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 4, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_LZCNT(block, dst, src) do { drcuml_block_append_2(block, DRCUML_OP_LZCNT, 4, IF_ALWAYS, FLAGS_NONE, dst, src); } while (0)
#define UML_BSWAP(block, dst, src) do { drcuml_block_append_2(block, DRCUML_OP_BSWAP, 4, IF_ALWAYS, FLAGS_NONE, dst, src); } while (0)
#define UML_SHL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_SHLf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_SHR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_SHRf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_SAR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_SARf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_ROL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_ROLf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_ROLC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_ROLCf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_ROR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_RORf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_RORC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 4, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_RORCf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 4, IF_ALWAYS, flags, dst, src, count); } while (0)
#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_SIZE_##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_SIZE_##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_SIZE_##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)
/* ----- 64-Bit Integer Operations ----- */
#define UML_DLOAD(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOAD, 8, IF_ALWAYS, FLAGS_NONE, dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_DLOADS(block, dst, base, index, size) do { drcuml_block_append_4(block, DRCUML_OP_LOADS, 8, IF_ALWAYS, FLAGS_NONE, dst, MEM(base), index, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_DSTORE(block, base, index, src1, size) do { drcuml_block_append_4(block, DRCUML_OP_STORE, 8, IF_ALWAYS, FLAGS_NONE, MEM(base), index, src1, IMM(DRCUML_SIZE_##size)); } while (0)
#define UML_DREAD(block, dst, src1, spsize) do { drcuml_block_append_3(block, DRCUML_OP_READ, 8, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, src, bitnum); } while (0)
#define UML_DSETc(block, cond, dst) do { drcuml_block_append_1(block, DRCUML_OP_SET, 8, cond, FLAGS_NONE, dst); } while (0)
#define UML_DMOV(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_DMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_MOV, 8, cond, FLAGS_NONE, dst, src1); } while (0)
#define UML_DSEXT(block, dst, src1, size) do { drcuml_block_append_3(block, DRCUML_OP_SEXT, 8, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src, shift, mask); } while (0)
#define UML_DNEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_NEG, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_DNEGf(block, dst, src1, flags) do { drcuml_block_append_2(block, DRCUML_OP_NEG, 8, IF_ALWAYS, flags, dst, src1); } while (0)
#define UML_DADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DADDf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_ADD, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DADDC(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DADDCf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_ADDC, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DSUBf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_SUB, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DSUBB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DSUBBf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_SUBB, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 8, IF_ALWAYS, FLAGS_ALLI, src1, src2); } while (0)
#define UML_DCMPf(block, src1, src2, flags) do { drcuml_block_append_2(block, DRCUML_OP_CMP, 8, IF_ALWAYS, flags, src1, src2); } while (0)
#define UML_DMULU(block, dst, edst, src1, src2) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 8, IF_ALWAYS, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DMULUf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_MULU, 8, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DMULSf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_MULS, 8, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DDIVUf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_DIVU, 8, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, edst, src1, src2); } while (0)
#define UML_DDIVSf(block, dst, edst, src1, src2, flags) do { drcuml_block_append_4(block, DRCUML_OP_DIVS, 8, IF_ALWAYS, flags, 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, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DANDf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_AND, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DTEST(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 8, IF_ALWAYS, FLAGS_S|FLAGS_Z,src1, src2); } while (0)
#define UML_DTESTf(block, src1, src2, flags) do { drcuml_block_append_2(block, DRCUML_OP_TEST, 8, IF_ALWAYS, flags, src1, src2); } while (0)
#define UML_DOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_OR, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DORf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_OR, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DXOR(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_DXORf(block, dst, src1, src2, flags) do { drcuml_block_append_3(block, DRCUML_OP_XOR, 8, IF_ALWAYS, flags, dst, src1, src2); } while (0)
#define UML_DSHL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DSHLf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SHL, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DSHR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DSHRf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SHR, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DSAR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DSARf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_SAR, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DROL(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DROLf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROL, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DROLC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DROLCf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROLC, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DROR(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DRORf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_ROR, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#define UML_DRORC(block, dst, src, count) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 8, IF_ALWAYS, FLAGS_NONE, dst, src, count); } while (0)
#define UML_DRORCf(block, dst, src, count, flags) do { drcuml_block_append_3(block, DRCUML_OP_RORC, 8, IF_ALWAYS, flags, dst, src, count); } while (0)
#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_SIZE_##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_SIZE_##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_SIZE_##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)
/* ----- 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 4, cond, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSTOINT(block, dst, src1, size, round) do { drcuml_block_append_4(block, DRCUML_OP_FTOINT, 4, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FSSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FSUB, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FSCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_FCMP, 4, IF_ALWAYS, FLAGS_ALLF, src1, src2); } while (0)
#define UML_FSMUL(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FMUL, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FSDIV(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FDIV, 4, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FSNEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FNEG, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSABS(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FABS, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FSQRT, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSRECIP(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRECIP, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FSRSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRSQRT, 4, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#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)
/* ----- 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDMOVc(block, cond, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FMOV, 8, cond, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDTOINT(block, dst, src1, size, round) do { drcuml_block_append_4(block, DRCUML_OP_FTOINT, 8, IF_ALWAYS, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, 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, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDADD(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FADD, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FDSUB(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FSUB, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FDCMP(block, src1, src2) do { drcuml_block_append_2(block, DRCUML_OP_FCMP, 8, IF_ALWAYS, FLAGS_ALLF, src1, src2); } while (0)
#define UML_FDMUL(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FMUL, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FDDIV(block, dst, src1, src2) do { drcuml_block_append_3(block, DRCUML_OP_FDIV, 8, IF_ALWAYS, FLAGS_NONE, dst, src1, src2); } while (0)
#define UML_FDNEG(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FNEG, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDABS(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FABS, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FSQRT, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDRECIP(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRECIP, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#define UML_FDRSQRT(block, dst, src1) do { drcuml_block_append_2(block, DRCUML_OP_FRSQRT, 8, IF_ALWAYS, FLAGS_NONE, dst, src1); } while (0)
#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)
#endif

View File

@ -917,7 +917,7 @@ static void static_generate_entry_point(drcuml_state *drcuml)
/* check for interrupts */
UML_AND(block, IREG(0), CPR032(COP0_Cause), CPR032(COP0_Status)); // and i0,[Cause],[Status]
UML_ANDf(block, IREG(0), IREG(0), IMM(0xfc00), FLAGS_Z); // and i0,i0,0xfc00,Z
UML_AND(block, IREG(0), IREG(0), IMM(0xfc00)); // and i0,i0,0xfc00,Z
UML_JMPc(block, IF_Z, skip); // jmp skip,Z
UML_TEST(block, CPR032(COP0_Status), IMM(SR_IE)); // test [Status],SR_IE
UML_JMPc(block, IF_Z, skip); // jmp skip,Z
@ -1127,7 +1127,7 @@ static void static_generate_exception(drcuml_state *drcuml, UINT8 exception, int
UML_MOVc(block, IF_Z, IREG(0), IMM(0x80000000 + offset)); // mov i0,0x80000000 + offset,z
/* adjust cycles */
UML_SUBf(block, MEM(&mips3->icount), MEM(&mips3->icount), IREG(1), FLAGS_S); // sub icount,icount,cycles,S
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_HASHJMP(block, MEM(&mips3->impstate->mode), IREG(0), mips3->impstate->nocode);// hashjmp <mode>,i0,nocode
@ -1390,7 +1390,7 @@ static void generate_update_cycles(drcuml_block *block, compiler_state *compiler
compiler->checksoftints = FALSE;
UML_AND(block, IREG(0), CPR032(COP0_Cause), CPR032(COP0_Status)); // and i0,[Cause],[Status]
UML_ANDf(block, IREG(0), IREG(0), IMM(0x0300), FLAGS_Z); // and i0,i0,0x0300,Z
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(1), IMM(compiler->cycles)); // mov i1,cycles
@ -1405,7 +1405,7 @@ static void generate_update_cycles(drcuml_block *block, compiler_state *compiler
compiler->checkints = FALSE;
UML_AND(block, IREG(0), CPR032(COP0_Cause), CPR032(COP0_Status)); // and i0,[Cause],[Status]
UML_ANDf(block, IREG(0), IREG(0), IMM(0xfc00), FLAGS_Z); // and i0,i0,0xfc00,Z
UML_AND(block, IREG(0), IREG(0), IMM(0xfc00)); // and i0,i0,0xfc00
UML_JMPc(block, IF_Z, skip = compiler->labelnum++); // jmp skip,Z
UML_TEST(block, CPR032(COP0_Status), IMM(SR_IE)); // test [Status],SR_IE
UML_JMPc(block, IF_Z, skip); // jmp skip,Z
@ -1420,8 +1420,7 @@ static void generate_update_cycles(drcuml_block *block, compiler_state *compiler
/* account for cycles */
if (compiler->cycles > 0)
{
UML_SUBf(block, MEM(&mips3->icount), MEM(&mips3->icount), MAPVAR_CYCLES, allow_exception ? FLAGS_S : 0);
// sub icount,icount,cycles,S
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));
@ -1715,14 +1714,10 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
return TRUE;
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_ADDf(block, IREG(0), R32(RSREG), IMM(SIMMVAL), FLAGS_V); // add i0,<rsreg>,SIMMVAL,V
UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0));
// exh overflow,0
}
else
UML_ADD(block, IREG(0), R32(RSREG), IMM(SIMMVAL)); // add i0,<rsreg>,SIMMVAL
if (RTREG != 0)
UML_DSEXT(block, R64(RTREG), IREG(0), DWORD); // dsext <rtreg>,i0,dword
return TRUE;
@ -1736,14 +1731,10 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
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_DADDf(block, IREG(0), R64(RSREG), IMM(SIMMVAL), FLAGS_V); // dadd i0,<rsreg>,SIMMVAL,V
UML_EXHc(block, IF_V, mips3->impstate->exception[EXCEPTION_OVERFLOW], IMM(0));
// exh overflow,0
}
else
UML_DADD(block, IREG(0), R64(RSREG), IMM(SIMMVAL)); // dadd i0,<rsreg>,SIMMVAL
if (RTREG != 0)
UML_DMOV(block, R64(RTREG), IREG(0)); // dmov <rtreg>,i0
return TRUE;
@ -2229,7 +2220,7 @@ static int generate_special(drcuml_block *block, compiler_state *compiler, const
case 0x20: /* ADD - MIPS I */
if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS)
{
UML_ADDf(block, IREG(0), R32(RSREG), R32(RTREG), FLAGS_V); // add i0,<rsreg>,<rtreg>,V
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));
// exh overflow,0,V
if (RDREG != 0)
@ -2253,7 +2244,7 @@ static int generate_special(drcuml_block *block, compiler_state *compiler, const
case 0x2c: /* DADD - MIPS III */
if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS)
{
UML_DADDf(block, IREG(0), R64(RSREG), R64(RTREG), FLAGS_V); // dadd i0,<rsreg>,<rtreg>,V
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));
// exh overflow,0,V
if (RDREG != 0)
@ -2271,7 +2262,7 @@ static int generate_special(drcuml_block *block, compiler_state *compiler, const
case 0x22: /* SUB - MIPS I */
if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS)
{
UML_SUBf(block, IREG(0), R32(RSREG), R32(RTREG), FLAGS_V); // sub i0,<rsreg>,<rtreg>,V
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));
// exh overflow,0,V
if (RDREG != 0)
@ -2295,7 +2286,7 @@ static int generate_special(drcuml_block *block, compiler_state *compiler, const
case 0x2e: /* DSUB - MIPS III */
if (mips3->impstate->drcoptions & MIPS3DRC_CHECK_OVERFLOWS)
{
UML_DSUBf(block, IREG(0), R64(RSREG), R64(RTREG), FLAGS_V); // dsub i0,<rsreg>,<rtreg>,V
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));
// exh overflow,0,V
if (RDREG != 0)
@ -2607,7 +2598,7 @@ static int generate_idt(drcuml_block *block, compiler_state *compiler, const opc
if (RSREG != 0 && RTREG != 0)
{
UML_MULS(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // muls i0,i1,rsreg,rtreg
UML_ADDf(block, FLAGS_C, IREG(0), IREG(0), LO32); // add i0,i0,lo
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
@ -2618,7 +2609,7 @@ static int generate_idt(drcuml_block *block, compiler_state *compiler, const opc
if (RSREG != 0 && RTREG != 0)
{
UML_MULU(block, IREG(0), IREG(1), R32(RSREG), R32(RTREG)); // mulu i0,i1,rsreg,rtreg
UML_ADDf(block, FLAGS_C, IREG(0), IREG(0), LO32); // add i0,i0,lo
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
@ -2737,7 +2728,7 @@ static int generate_get_cop0_reg(drcuml_block *block, compiler_state *compiler,
UML_DSUB(block, IREG(0), MEM(&mips3->impstate->numcycles), MEM(&mips3->count_zero_time));
// dsub i0,[numcycles],[count_zero_time]
UML_AND(block, IREG(1), CPR032(COP0_Wired), IMM(0x3f)); // and i1,[Wired],0x3f
UML_SUBf(block, IREG(2), IMM(48), IREG(1), FLAGS_BE); // sub i2,48,i1,ALL
UML_SUB(block, IREG(2), IMM(48), IREG(1)); // sub i2,48,i1
UML_JMPc(block, IF_BE, link1 = compiler->labelnum++); // jmp link1,BE
UML_DAND(block, IREG(2), IREG(2), IMM(0xffffffff)); // dand i2,i2,0xffffffff
UML_DDIVU(block, IREG(0), IREG(2), IREG(0), IREG(2)); // ddivu i0,i2,i0,i2

View File

@ -1387,7 +1387,7 @@ static void static_generate_exception(drcuml_state *drcuml, UINT8 exception, int
}
/* adjust cycles */
UML_SUBf(block, MEM(&ppc->icount), MEM(&ppc->icount), IREG(1), FLAGS_S); // sub icount,icount,cycles,S
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
@ -1860,8 +1860,7 @@ static void generate_update_cycles(drcuml_block *block, compiler_state *compiler
/* account for cycles */
if (compiler->cycles > 0)
{
UML_SUBf(block, MEM(&ppc->icount), MEM(&ppc->icount), MAPVAR_CYCLES, allow_exception ? FLAGS_S : 0);
// sub icount,icount,cycles,S
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
@ -2154,7 +2153,7 @@ static void generate_branch_bo(drcuml_block *block, compiler_state *compiler, co
if (!(bo & 0x04))
{
UML_SUBf(block, SPR32(SPR_CTR), SPR32(SPR_CTR), IMM(1), FLAGS_Z); // sub [ctr],[ctr],1,z
UML_SUB(block, SPR32(SPR_CTR), SPR32(SPR_CTR), IMM(1)); // sub [ctr],[ctr],1
UML_JMPc(block, (bo & 0x02) ? IF_NZ : IF_Z, skip); // jmp skip,nz/z
}
if (!(bo & 0x10))
@ -2228,17 +2227,17 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
return TRUE;
case 0x08: /* SUBFIC */
UML_SUBf(block, R32(G_RD(op)), IMM((INT16)G_SIMM(op)), R32(G_RA(op)), FLAGS_C); // sub rd,simm,ra,c
UML_SUB(block, R32(G_RD(op)), IMM((INT16)G_SIMM(op)), R32(G_RA(op))); // sub rd,simm,ra
generate_compute_flags(block, FALSE, XER_CA, TRUE); // <update flags>
return TRUE;
case 0x0c: /* ADDIC */
UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op)), FLAGS_C); // add rd,ra,simm,c
UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add rd,ra,simm
generate_compute_flags(block, FALSE, XER_CA, FALSE); // <update flags>
return TRUE;
case 0x0d: /* ADDIC. */
UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op)), FLAGS_C); // add rd,ra,simm,c
UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), IMM((INT16)G_SIMM(op))); // add rd,ra,simm
generate_compute_flags(block, TRUE, XER_CA, FALSE); // <update flags>
return TRUE;
@ -2304,12 +2303,12 @@ static int generate_opcode(drcuml_block *block, compiler_state *compiler, const
return TRUE;
case 0x1c: /* ANDI. */
UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op)), FLAGS_RC(op)); // and ra,rs,uimm,FLAGS_RC
UML_AND(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op))); // and ra,rs,uimm
generate_compute_flags(block, TRUE, 0, FALSE); // <update flags>
return TRUE;
case 0x1d: /* ANDIS. */
UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op) << 16), FLAGS_RC(op));// and ra,rs,uimm << 16,FLAGS_RC
UML_AND(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_UIMM(op) << 16)); // and ra,rs,uimm << 16
generate_compute_flags(block, TRUE, 0, FALSE); // <update flags>
return TRUE;
@ -2753,46 +2752,46 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x10a: /* ADDx */
case 0x30a: /* ADDOx */
UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op)); // add rd,ra,rb,FLAGS_RCOE(op)
UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // add rd,ra,rb
generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE); // <update flags>
return TRUE;
case 0x00a: /* ADDCx */
case 0x20a: /* ADDCOx */
UML_ADDf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOECA(op)); // add rd,ra,rb,FLAGS_RCOECA(op)
UML_ADD(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // add rd,ra,rb
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
return TRUE;
case 0x08a: /* ADDEx */
case 0x28a: /* ADDEOx */
UML_CARRY(block, SPR32(SPR_XER), IMM(29)); // carry [xer],XER_CA
UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOECA(op));// addc rd,ra,rb,FLAGS_RCOECA(op)
UML_ADDC(block, R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // addc rd,ra,rb
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
return TRUE;
case 0x0ca: /* ADDZEx */
case 0x2ca: /* ADDZEOx */
UML_CARRY(block, SPR32(SPR_XER), IMM(29)); // carry [xer],XER_CA
UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), IMM(0), FLAGS_RCOECA(op)); // addc rd,ra,0,FLAGS_RCOECA(op)
UML_ADDC(block, R32(G_RD(op)), R32(G_RA(op)), IMM(0)); // addc rd,ra,0
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
return TRUE;
case 0x0ea: /* ADDMEx */
case 0x2ea: /* ADDMEOx */
UML_CARRY(block, SPR32(SPR_XER), IMM(29)); // carry [xer],XER_CA
UML_ADDCf(block, R32(G_RD(op)), R32(G_RA(op)), IMM(-1), FLAGS_RCOE(op)); // addc rd,ra,-1,FLAGS_RCOECA(op)
UML_ADDC(block, R32(G_RD(op)), R32(G_RA(op)), IMM(-1)); // addc rd,ra,-1
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), FALSE);// <update flags>
return TRUE;
case 0x028: /* SUBFx */
case 0x228: /* SUBFOx */
UML_SUBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOE(op)); // sub rd,rb,ra,FLAGS_RCOE(op)
UML_SUB(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op))); // sub rd,rb,ra
generate_compute_flags(block, op & M_RC, (op & M_OE) ? XER_OV : 0, TRUE); // <update flags>
return TRUE;
case 0x008: /* SUBFCx */
case 0x208: /* SUBFCOx */
UML_SUBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOECA(op)); // sub rd,rb,ra,FLAGS_RCOECA(op)
UML_SUB(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op))); // sub rd,rb,ra
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
return TRUE;
@ -2800,7 +2799,7 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x288: /* SUBFEOx */
UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA)); // xor i0,[xer],XER_CA
UML_CARRY(block, IREG(0), IMM(29)); // carry i0,XER_CA
UML_SUBBf(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op)), FLAGS_RCOECA(op));// subc rd,rb,ra,FLAGS_RCOECA(op)
UML_SUBB(block, R32(G_RD(op)), R32(G_RB(op)), R32(G_RA(op))); // subc rd,rb,ra
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
return TRUE;
@ -2808,7 +2807,7 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x2c8: /* SUBFZEOx */
UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA)); // xor i0,[xer],XER_CA
UML_CARRY(block, IREG(0), IMM(29)); // carry i0,XER_CA
UML_SUBBf(block, R32(G_RD(op)), IMM(0), R32(G_RA(op)), FLAGS_RCOECA(op)); // subc rd,0,ra,FLAGS_RCOECA(op)
UML_SUBB(block, R32(G_RD(op)), IMM(0), R32(G_RA(op))); // subc rd,0,ra
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
return TRUE;
@ -2816,13 +2815,13 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x2e8: /* SUBFMEOx */
UML_XOR(block, IREG(0), SPR32(SPR_XER), IMM(XER_CA)); // xor i0,[xer],XER_CA
UML_CARRY(block, IREG(0), IMM(29)); // carry i0,XER_CA
UML_SUBBf(block, R32(G_RD(op)), IMM(-1), R32(G_RA(op)), FLAGS_RCOECA(op)); // subc rd,-1,ra,,FLAGS_RCOECA(op)
UML_SUBB(block, R32(G_RD(op)), IMM(-1), R32(G_RA(op))); // subc rd,-1,ra
generate_compute_flags(block, op & M_RC, XER_CA | ((op & M_OE) ? XER_OV : 0), TRUE);// <update flags>
return TRUE;
case 0x068: /* NEGx */
case 0x268: /* NEGOx */
UML_SUBf(block, R32(G_RD(op)), IMM(0), R32(G_RA(op)), FLAGS_RCOE(op)); // sub rd,0,ra,FLAGS_RCOE(op)
UML_SUB(block, R32(G_RD(op)), IMM(0), R32(G_RA(op))); // sub rd,0,ra
generate_compute_flags(block, op & M_RC, (op & M_OE) ? XER_OV : 0, TRUE); // <update flags>
return TRUE;
@ -2841,14 +2840,12 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x00b: /* MULHWUx */
UML_MULUf(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
// mulu i0,rd,ra,rb,FLAGS_RC(op)
UML_MULU(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // mulu i0,rd,ra,rb,FLAGS_RC(op)
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x04b: /* MULHWx */
UML_MULSf(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
// muls i0,rd,ra,rb,,FLAGS_RC(op)
UML_MULS(block, IREG(0), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // muls i0,rd,ra,rb,,FLAGS_RC(op)
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
@ -2856,19 +2853,17 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x2eb: /* MULLWOx */
if (!(op & M_OE))
{
UML_MULSf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
// muls rd,rd,ra,rb,FLAGS_RC(op)
UML_MULS(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)));// muls rd,rd,ra,rb,FLAGS_RC(op)
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
}
else
{
UML_MULSf(block, IREG(0), IREG(1), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RC(op));
// muls i0,i1,ra,rb
UML_MULS(block, IREG(0), IREG(1), R32(G_RA(op)), R32(G_RB(op))); // muls i0,i1,ra,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
UML_MOV(block, R32(G_RD(op)), IREG(0)); // mov rd,i0
UML_SAR(block, IREG(0), IREG(0), IMM(31)); // sar i0,i0,31
UML_AND(block, SPR32(SPR_XER), SPR32(SPR_XER), IMM(XER_OV)); // and [xer],[xer],XER_OV
UML_XORf(block, IREG(0), IREG(0), IREG(1), FLAGS_Z); // xor i0,i0,i1,Z
UML_XOR(block, IREG(0), IREG(0), IREG(1)); // xor i0,i0,i1
UML_MOVc(block, IF_NZ, IREG(0), IMM(XER_OV | XER_SO)); // mov i0,XER_OV | XER_SO,NZ
UML_OR(block, SPR32(SPR_XER), SPR32(SPR_XER), IREG(0)); // or [xer],[xer],i0
}
@ -2876,60 +2871,58 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
case 0x1cb: /* DIVWUx */
case 0x3cb: /* DIVWUOx */
UML_DIVUf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op));
// divu rd,rd,ra,rb,FLAGS_RCOE(op)
UML_DIVU(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // divu rd,rd,ra,rb
generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE); // <update flags>
return TRUE;
case 0x1eb: /* DIVWx */
case 0x3eb: /* DIVWOx */
UML_DIVSf(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op)), FLAGS_RCOE(op));
// divs rd,rd,ra,rb,FLAGS_RCOE(op)
UML_DIVS(block, R32(G_RD(op)), R32(G_RD(op)), R32(G_RA(op)), R32(G_RB(op))); // divs rd,rd,ra,rb
generate_compute_flags(block, op & M_RC, ((op & M_OE) ? XER_OV : 0), FALSE); // <update flags>
return TRUE;
case 0x01c: /* ANDx */
UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op)); // and ra,rs,rb,FLAGS_RC(op)
UML_AND(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // and ra,rs,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x03c: /* ANDCx */
UML_XOR(block, IREG(0), R32(G_RB(op)), IMM(~0)); // xor i0,rb,~0
UML_ANDf(block, R32(G_RA(op)), R32(G_RS(op)), IREG(0), FLAGS_RC(op)); // and ra,rs,i0,FLAGS_RC(op)
UML_AND(block, R32(G_RA(op)), R32(G_RS(op)), IREG(0)); // and ra,rs,i0
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x1dc: /* NANDx */
UML_AND(block, IREG(0), R32(G_RS(op)), R32(G_RB(op))); // and i0,rs,rb
UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op)); // xor ra,i0,~0,FLAGS_RC(op)
UML_XOR(block, R32(G_RA(op)), IREG(0), IMM(~0)); // xor ra,i0,~0
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x1bc: /* ORx */
UML_ORf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op)); // or ra,rs,rb,FLAGS_RC(op)
UML_OR(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // or ra,rs,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x19c: /* ORCx */
UML_XORf(block, IREG(0), R32(G_RB(op)), IMM(~0), FLAGS_RC(op)); // xor i0,rb,~0,FLAGS_RC(op)
UML_XOR(block, IREG(0), R32(G_RB(op)), IMM(~0)); // xor i0,rb,~0
UML_OR(block, R32(G_RA(op)), R32(G_RS(op)), IREG(0)); // or ra,rs,i0
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x07c: /* NORx */
UML_OR(block, IREG(0), R32(G_RS(op)), R32(G_RB(op))); // or i0,rs,rb
UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op)); // xor ra,i0,~0,FLAGS_RC(op)
UML_XOR(block, R32(G_RA(op)), IREG(0), IMM(~0)); // xor ra,i0,~0
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x13c: /* XORx */
UML_XORf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op)); // xor ra,rs,rb,FLAGS_RC(op)
UML_XOR(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // xor ra,rs,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x11c: /* EQVx */
UML_XOR(block, IREG(0), R32(G_RS(op)), R32(G_RB(op))); // xor i0,rs,rb
UML_XORf(block, R32(G_RA(op)), IREG(0), IMM(~0), FLAGS_RC(op)); // xor ra,i0,~0,FLAGS_RC(op)
UML_XOR(block, R32(G_RA(op)), IREG(0), IMM(~0)); // xor ra,i0,~0
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
@ -2939,7 +2932,7 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
return TRUE;
case 0x218: /* SRWx */
UML_SHRf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op)); // shr ra,rs,rb,FLAGS_RC(op)
UML_SHR(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // shr ra,rs,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
@ -2948,20 +2941,20 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_XOR(block, IREG(1), IREG(1), IMM(~0)); // xor i1,i1,~0
UML_AND(block, IREG(0), R32(G_RS(op)), IREG(1)); // and i0,rs,i1
UML_SAR(block, IREG(1), R32(G_RS(op)), IMM(31)); // sar i1,rs,31
UML_ANDf(block, IREG(0), IREG(0), IREG(1), DRCUML_FLAG_Z); // and i0,i0,i1,z
UML_AND(block, IREG(0), IREG(0), IREG(1)); // and i0,i0,i1
UML_SETc(block, IF_NZ, IREG(0)); // set i0,nz
UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(XER_CA)); // rolins [xer],i0,29,XER_CA
UML_SARf(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op)), FLAGS_RC(op)); // sar ra,rs,rb,FLAGS_RC(op)
UML_SAR(block, R32(G_RA(op)), R32(G_RS(op)), R32(G_RB(op))); // sar ra,rs,rb
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
case 0x338: /* SRAWIx */
UML_AND(block, IREG(0), R32(G_RS(op)), IMM(~(0xffffffff << (G_SH(op) & 31)))); // and i0,rs,~(0xffffffff << (sh & 31))
UML_SAR(block, IREG(1), R32(G_RS(op)), IMM(31)); // sar i1,rs,31
UML_ANDf(block, IREG(0), IREG(0), IREG(1), DRCUML_FLAG_Z); // and i0,i0,i1,z
UML_AND(block, IREG(0), IREG(0), IREG(1)); // and i0,i0,i1
UML_SETc(block, IF_NZ, IREG(0)); // set i0,nz
UML_ROLINS(block, SPR32(SPR_XER), IREG(0), IMM(29), IMM(XER_CA)); // rolins [xer],i0,29,XER_CA
UML_SARf(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_SH(op)), FLAGS_RC(op)); // sar ra,rs,sh,FLAGS_RC(op)
UML_SAR(block, R32(G_RA(op)), R32(G_RS(op)), IMM(G_SH(op))); // sar ra,rs,sh
generate_compute_flags(block, op & M_RC, 0, FALSE); // <update flags>
return TRUE;
@ -3144,15 +3137,15 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f)); // and [swreg],i2,0x7f
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0))); // xor i1,i1,be_xor(0)
UML_STORE(block, &ppc->r[0], IREG(1), IREG(0), BYTE); // store &r0,i1,i0,byte
UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
// sub [swcount],[swcount],1,Z
UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1));
// sub [swcount],[swcount],1
UML_JMPc(block, IF_NZ, swloop); // jmp swloop,NZ
load_fast_iregs(block); // <load fastregs>
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles>
return TRUE;
case 0x215: /* LSWX */
UML_ANDf(block, FLAGS_Z, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f));// and [swcount],[xer],0x7f,Z
UML_AND(block, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f)); // and [swcount],[xer],0x7f
UML_JMPc(block, IF_Z, swloopend = compiler->labelnum++); // jmp swloopend,Z
UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb
UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RD(op))); // mov [swreg],4*G_RD(op)
@ -3167,8 +3160,8 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_AND(block, MEM(&ppc->impstate->swreg), IREG(2), IMM(0x7f)); // and [swreg],i2,0x7f
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0))); // xor i1,i1,be_xor(0)
UML_STORE(block, &ppc->r[0], IREG(1), IREG(0), BYTE); // store &r0,i1,i0,byte
UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
// sub [swcount],[swcount],1,Z
UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1));
// sub [swcount],[swcount],1
UML_JMPc(block, IF_NZ, swloop); // jmp swloop,NZ
UML_LABEL(block, swloopend); // swloopend:
load_fast_iregs(block); // <load fastregs>
@ -3324,14 +3317,14 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0))); // xor i1,i1,be_xor(0)
UML_LOAD(block, IREG(1), &ppc->r[0], IREG(1), BYTE); // load i1,&r0,i1,byte
UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]); // callh write8
UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
// sub [swcount],[swcount],1,Z
UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1));
// sub [swcount],[swcount],1
UML_JMPc(block, IF_NZ, swloop); // jmp swloop,NZ
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles>
return TRUE;
case 0x295: /* STSWX */
UML_ANDf(block, FLAGS_Z, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f));// and [swcount],[xer],0x7f,Z
UML_AND(block, MEM(&ppc->impstate->swcount), SPR32(SPR_XER), IMM(0x7f)); // and [swcount],[xer],0x7f
UML_JMPc(block, IF_Z, swloopend = compiler->labelnum++); // jmp swloopend,Z
UML_ADD(block, MEM(&ppc->impstate->updateaddr), R32Z(G_RA(op)), R32(G_RB(op))); // add [updateaddr],ra,rb
UML_MOV(block, MEM(&ppc->impstate->swreg), IMM(4 * G_RS(op))); // mov [swreg],4*G_RS(op)
@ -3346,8 +3339,8 @@ static int generate_instruction_1f(drcuml_block *block, compiler_state *compiler
UML_XOR(block, IREG(1), IREG(1), IMM(BYTE4_XOR_BE(0))); // xor i1,i1,be_xor(0)
UML_LOAD(block, IREG(1), &ppc->r[0], IREG(1), BYTE); // load i1,&r0,i1,byte
UML_CALLH(block, ppc->impstate->write8[ppc->impstate->mode & 3]); // callh write8
UML_SUBf(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1), FLAGS_Z);
// sub [swcount],[swcount],1,Z
UML_SUB(block, MEM(&ppc->impstate->swcount), MEM(&ppc->impstate->swcount), IMM(1));
// sub [swcount],[swcount],1
UML_JMPc(block, IF_NZ, swloop); // jmp swloop,NZ
UML_LABEL(block, swloopend); // swloopend:
generate_update_cycles(block, compiler, IMM(desc->pc + 4), TRUE); // <update cycles>