UML Integer Opcodes - JoakimLarsson/mame GitHub Wiki
Below is a detailed description of all the UML integer opcodes. For general information about the UML, please see UML Architecture.
Usage:
LOAD ''dest'',''base'',''index'',''size'' DLOAD ''dest'',''base'',''index'',''size''
Codegen Shorthand:
UML_LOAD(block, PTYPE(''dest''), ''base'', PTYPE(''index''), (BYTE_ | WORD_ | DWORD_) ## (x1 | x2 | x4 | x8)); UML_DLOAD(block, PTYPE(''dest''), ''base'', PTYPE(''index''), (BYTE_ | WORD_ | DWORD_ | QWORD_) ## (x1 | x2 | x4 | x8));
Parameters:
- dest — a 32/64-bit integer register or memory location
- base — a memory pointer to the base of the table to read from
- index — a 32/64-bit integer register, memory location, map variable, or immediate
- size_scale — the size of the memory to access, combined with the scale factor to apply to the index; the size portion can be 1, 2, or 4 (or 8 for the 64-bit form), while the scale factor can be 1, 2, 4, or 8
Description: The LOAD opcode performs a table-lookup memory read to a 32-bit destination; the DLOAD opcode does the same to a 64-bit destination. If the size specified is smaller than the destination, the result is zero-extended before being stored.
Unlike a standard memory location parameter (which must reside in the near cache), the base parameter may point anywhere in memory. The index parameter is scaled by the scale parameter prior to being added to the base.
Example:
void generate_lookup_index_i2_to_i0(drcuml_block *block) { UML_LOAD(block, IREG(0), lookup_table, IREG(2), WORD_x2); }
Usage:
LOADS ''dest'',''base'',''index'',''size_scale'' DLOADS ''dest'',''base'',''index'',''size_scale''
Codegen Shorthand:
UML_LOADS(block, PTYPE(''dest''), ''base'', PTYPE(''index''), (BYTE_ | WORD_ | DWORD_) ## (x1 | x2 | x4 | x8)); UML_DLOADS(block, PTYPE(''dest''), ''base'', PTYPE(''index''), (BYTE_ | WORD_ | DWORD_ | QWORD_) ## (x1 | x2 | x4 | x8)););
Parameters:
- dest — a 32/64-bit integer register or memory location
- base — a memory pointer to the base of the table to read from
- index — a 32/64-bit integer register, memory location, map variable, or immediate
- size_scale — the size of the memory to access, combined with the scale factor to apply to the index; the size portion can be 1, 2, or 4 (or 8 for the 64-bit form), while the scale factor can be 1, 2, 4, or 8
Description: The LOADS opcode performs a table-lookup memory read to a 32-bit destination; the DLOADS opcode does the same to a 64-bit destination. If the size specified is smaller than the destination, the result is sign-extended before being stored.
Unlike a standard memory location parameter (which must reside in the near cache), the base parameter may point anywhere in memory. The index parameter is scaled by the scale parameter prior to being added to the base.
Example:
void generate_read_byte_from_array_index_i2(drcuml_block *block) { UML_LOADS(block, IREG(0), my_signed_byte_array, IREG(2), BYTE_x1); }
Usage:
STORE ''base'',''index'',''source'',''size'' DSTORE ''base'',''index'',''source'',''size''
Codegen Shorthand:
UML_STORE(block, ''base'', PTYPE(''index''), PTYPE(''source''), (BYTE_ | WORD_ | DWORD_) ## (x1 | x2 | x4 | x8)); UML_DSTORE(block, ''base'', PTYPE(''index''), PTYPE(''source''), (BYTE_ | WORD_ | DWORD_ | QWORD_) ## (x1 | x2 | x4 | x8));
Parameters:
- base — a memory pointer to the base of the table to store to
- index — a 32/64-bit integer register, memory location, map variable, or immediate
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- size_scale — the size of the memory to access, combined with the scale factor to apply to the index; the size portion can be 1, 2, or 4 (or 8 for the 64-bit form), while the scale factor can be 1, 2, 4, or 8
Description: The STORE opcode performs a table-lookup memory write from a 32-bit source; the DSTORE opcode does the same from a 64-bit source. Note that because the low 32 bits are the same regardless of whether the source is 32-bit or 64-bit, STORE and DSTORE are identical when size is 1, 2, or 4.
Unlike a standard memory location parameter (which must reside in the near cache), the base parameter may point anywhere in memory. The index parameter is scaled by the scale parameter prior to being added to the base.
Example:
void generate_store_i0_to_register_array_index_i9(drcuml_block *block) { UML_STORE(block, register_array, IREG(9), IREG(0), DWORD_x4); }
Usage:
READ ''dest'',''address'',''space-size'' DREAD ''dest'',''address'',''space-size''
Codegen Shorthand:
UML_READ(block, PTYPE(''dest''), PTYPE(''address''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD)); UML_DREAD(block, PTYPE(''dest''), PTYPE(''address''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD | QWORD));
Parameters:
- dest — a 32/64-bit integer register or memory location
- address — a 32-bit integer register, memory location, map variable, or immediate
-
space-size — the address space and size of the memory to access; can be one of these values:
- PROGRAM_BYTE/DATA_BYTE/IO_BYTE — a 1-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_WORD/DATA_WORD/IO_WORD — a 2-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_DWORD/DATA_DWORD/IO_DWORD — a 4-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_QWORD/DATA_QWORD/IO_QWORD — an 8-byte value from the PROGRAM/DATA/IO address space
Description: The READ opcode performs a read from the emulated CPU's memory system to a 32-bit destination; the DREAD opcode does the same to a 64-bit destination. If the number of bytes specified by the space-size parameter is smaller than the destination, the result is zero-extended before being stored.
Note that even in its 64-bit form, the DREAD opcode still takes a fixed 32-bit size parameter for the address.
Example:
void generate_load_qword_from_program_space_address_i0(drcuml_block *block) { UML_DLOAD(block, IREG(0), IREG(0), PROGRAM_QWORD); }
Usage:
READS ''dest'',''address'',''space-size'' DREADS ''dest'',''address'',''space-size''
Codegen Shorthand:
UML_READS(block, PTYPE(''dest''), PTYPE(''address''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD)); UML_DREADS(block, PTYPE(''dest''), PTYPE(''address''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD | QWORD));
Parameters:
- dest — a 32/64-bit integer register or memory location
- address — a 32-bit integer register, memory location, map variable, or immediate
-
space-size — the address space and size of the memory to access; can be one of these values:
- PROGRAM_BYTE/DATA_BYTE/IO_BYTE — a 1-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_WORD/DATA_WORD/IO_WORD — a 2-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_DWORD/DATA_DWORD/IO_DWORD — a 4-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_QWORD/DATA_QWORD/IO_QWORD — an 8-byte value from the PROGRAM/DATA/IO address space
Description: The READS opcode performs a read from the emulated CPU's memory system to a 32-bit destination; the DREADS opcode does the same to a 64-bit destination. If the number of bytes specified by the space-size parameter is smaller than the destination, the result is sign-extended before being stored.
Note that even in its 64-bit form, the DREADS opcode still takes a fixed 32-bit size parameter for the address.
Example:
void generate_load_signed_word_from_data_space_address_i0(drcuml_block *block) { UML_LOADS(block, IREG(0), IREG(0), DATA_WORD); }
Usage:
READM ''dest'',''address'',''mask'',''space-size'' DREADM ''dest'',''address'',''mask'',''space-size''
Codegen Shorthand:
UML_READ(block, PTYPE(''dest''), PTYPE(''address''), PTYPE(''mask''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD)); UML_DREAD(block, PTYPE(''dest''), PTYPE(''address''), PTYPE(''mask''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD | QWORD));
Parameters:
- dest — a 32/64-bit integer register or memory location
- address — a 32-bit integer register, memory location, map variable, or immediate
- mask — a 32/64-bit integer register, memory location, map variable, or immediate
-
space-size — the address space and size of the memory to access; can be one of these values:
- PROGRAM_BYTE/DATA_BYTE/IO_BYTE — a 1-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_WORD/DATA_WORD/IO_WORD — a 2-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_DWORD/DATA_DWORD/IO_DWORD — a 4-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_QWORD/DATA_QWORD/IO_QWORD — an 8-byte value from the PROGRAM/DATA/IO address space
Description: The READM opcode performs a masked read from the emulated CPU's memory system to a 32-bit destination; the DREADM opcode does the same to a 64-bit destination. These opcodes are similar to the READ and DREAD opcodes described above, with the exception that the additional parameter mask specifies which bytes within the larger access should be referenced. As with READ and DREAD, these opcodes zero-extend the result if it is smaller than the destination size.
Example:
void generate_load_upper_or_lower_word_from_i0(drcuml_block *block, int upper) { /* big-endian */ if (upper) UML_LOADM(block, IREG(0), IREG(0), IMM(0xffff0000), PROGRAM_DWORD); else UML_LOADM(block, IREG(0), IREG(0), IMM(0x0000ffff), PROGRAM_DWORD); }
Usage:
WRITE ''address'',''source'',''space-size'' DWRITE ''address'',''source'',''space-size''
Codegen Shorthand:
UML_WRITE(block, PTYPE(''address''), PTYPE(''source''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD)); UML_DWRITE(block, PTYPE(''address''), PTYPE(''source''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD | QWORD));
Parameters:
- address — a 32-bit integer register, memory location, map variable, or immediate
- source — a 32/64-bit integer register, memory location, map variable, or immediate
-
space-size — the address space and size of the memory to access; can be one of these values:
- PROGRAM_BYTE/DATA_BYTE/IO_BYTE — a 1-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_WORD/DATA_WORD/IO_WORD — a 2-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_DWORD/DATA_DWORD/IO_DWORD — a 4-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_QWORD/DATA_QWORD/IO_QWORD — an 8-byte value from the PROGRAM/DATA/IO address space
Description: The WRITE opcode performss a write to the emulated CPU's memory system from a 32-bit source; the DWRITE opcode does the same from a 64-bit source. Note that because the low 32 bits are the same regardless of whether the source is 32-bit or 64-bit, WRITE and DWRITE are identical when size is 1, 2, or 4.
Note that even in its 64-bit form, the DWRITE opcode still takes a fixed 32-bit size parameter for the address.
Example:
void generate_write_memory_to_byte(drcuml_block *block, UINT32 *memory) { UML_WRITE(block, IREG(0), MEM(memory), PROGRAM_BYTE); }
Usage:
WRITEM ''address'',''source'',''mask'',''space-size'' DWRITEM ''address'',''source'',''mask'',''space-size''
Codegen Shorthand:
UML_WRITEM(block, PTYPE(''address''), PTYPE(''source''), PTYPE(''mask''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD)); UML_DWRITEM(block, PTYPE(''address''), PTYPE(''source''), PTYPE(''mask''), (PROGRAM_ | DATA_ | IO_) ## (BYTE | WORD | DWORD | QWORD));
Parameters:
- space — an immediate describing which address space to read from
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- mask — a 32/64-bit integer register, memory location, map variable, or immediate
-
space-size — the address space and size of the memory to access; can be one of these values:
- PROGRAM_BYTE/DATA_BYTE/IO_BYTE — a 1-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_WORD/DATA_WORD/IO_WORD — a 2-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_DWORD/DATA_DWORD/IO_DWORD — a 4-byte value from the PROGRAM/DATA/IO address space
- PROGRAM_QWORD/DATA_QWORD/IO_QWORD — an 8-byte value from the PROGRAM/DATA/IO address space
Description: The WRITEM opcode performs a masked write to the emulated CPU's memory system from a 32-bit source; the DWRITEM opcode does the same from a 64-bit source. These opcodes are similar to the WRITE and DWRITE opcodes described above, with the exception that the additional parameter mask specifies which bytes within the larger access should be written.
Example:
void generate_write_store_masked_byte(drcuml_block *block, UINT8 byte, UINT32 mask) { UML_WRITEM(block, IREG(0), IMM(byte), IMM(mask), PROGRAM_DWORD); }
Usage:
CARRY ''source'',''bitnum'' DCARRY ''source'',''bitnum''
Codegen Shorthand:
UML_CARRY(block, PTYPE(''source''), PTYPE(''bitnum'')); UML_DCARRY(block, PTYPE(''source''), PTYPE(''bitnum''));
Parameters:
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- bitnum — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set to the value of the specified bitnum of the source operand
- V — undefined
- Z — undefined
- S — undefined
- U — undefined
Example:
void generate_add_with_carry(drcuml_block *block) { UML_CARRY(block, MEM(&flagsregister), IMM(CARRYBIT)); UML_ADDC(block, IREG(0), IREG(1), IREG(2)); }
Usage:
SET ''dest'',''condition'' DSET ''dest'',''condition''
Codegen Shorthand:
UML_SET(block, ''condition'', PTYPE(''dest'')); UML_DSET(block, ''condition'', PTYPE(''dest''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- condition — the condition whose value determines the result of the SET operation
Description: The SET opcode tests the provided condition and sets the dest operand to 1 if the condition is true or 0 if it is false; the DSET opcode does the same with a 64-bit operand.
Example:
void generate_set_i0_if_i1_equals_0(drcuml_block *block) { UML_CMP(block, IREG(1), IMM(0)); UML_SET(block, IF_E, IREG(0)); }
Usage:
MOV ''dest'',''source''[,''condition''] DMOV ''dest'',''source''[,''condition'']
Codegen Shorthand:
UML_MOV(block, PTYPE(''dest''), PTYPE(''source'')); UML_MOVc(block, ''condition'', PTYPE(''dest''), PTYPE(''source'')); UML_DMOV(block, PTYPE(''dest''), PTYPE(''source'')); UML_DMOVc(block, ''condition'', PTYPE(''dest''), PTYPE(''source''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- condition — an optional condition which is used to determine whether or not to perform the move
Description: The MOV opcode transfers a 32-bit value from the source operand to the dest operand; the DMOV opcode does the same with 64-bit values. An optional condition can be provided which makes the move operation dependent on the condition being true. Note that the flags are defined to remain unaffected here; MOV is one of the very few opcodes that can be reliably used between a flag-changing opcode and a flag-consuming opcode.
Example:
void generate_swap_two_values(drcuml_block *block, UINT64 *val1, UINT64 *val2) { UML_DMOV(block, IREG(0), MEM(val1)); UML_DMOV(block, MEM(val1), MEM(val2)); UML_DMOV(block, MEM(val2), IREG(0)); }
Usage:
SEXT ''dest'',''source'',''size'' DSEXT ''dest'',''source'',''size''
Codegen Shorthand:
UML_SEXT(block, PTYPE(''dest''), PTYPE(''source''), BYTE | WORD); UML_DSEXT(block, PTYPE(''dest''), PTYPE(''source''), BYTE | WORD | DWORD);
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- size — the width to sign-extend to; can be 1 or 2 (or 4 for the 64-bit form)
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that there is no equivalent ZEXT opcode; to zero-extend, just perform the equivalent AND or DAND.
Also note that if you specify a memory parameter for source, a full 32-bit value is read and truncated down to 8 or 16 bits. This means that you cannot reliably specify a 16-bit memory location for source, as it will produce different results on big-endian systems versus little-endian systems.
Example:
void generate_add_16bit_i0_to_32bit_i1(drcuml_block *block) { UML_SEXT(block, IREG(2), IREG(0)); UML_ADD(block, IREG(1), IREG(1), IREG(2)); }
Usage:
ROLAND ''dest'',''source'',''rotate'',''mask'' DROLAND ''dest'',''source'',''rotate'',''mask''
Codegen Shorthand:
UML_ROLAND(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''rotate''), PTYPE(''mask'')); UML_DROLAND(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''rotate''), PTYPE(''mask''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- rotate — a 32/64-bit integer register, memory location, map variable, or immediate
- mask — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_extract_bytes(drcuml_block *block) { /* extract from i0; high byte goes to i1, low byte goes to i4 */ UML_ROLAND(block, IREG(1), IREG(0), IMM(8), IMM(0xff)); UML_ROLAND(block, IREG(2), IREG(0), IMM(16), IMM(0xff)); UML_ROLAND(block, IREG(3), IREG(0), IMM(24), IMM(0xff)); UML_ROLAND(block, IREG(4), IREG(0), IMM(0), IMM(0xff)); }
Usage:
ROLINS ''dest'',''source'',''rotate'',''mask'' DROLINS ''dest'',''source'',''rotate'',''mask''
Codegen Shorthand:
UML_ROLINS(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''rotate''), PTYPE(''mask'')); UML_DROLINS(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''rotate''), PTYPE(''mask''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- rotate — a 32/64-bit integer register, memory location, map variable, or immediate
- mask — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_copy_bit(drcuml_block *block, int srcbitnum, dstbitnum) { /* copy a bit from srcbitnum to dstbitnum within the i0 register */ UML_DROLINS(block, IREG(0), IREG(0), IMM((dstbitnum - srcbitnum) & 63), IMM(U64(1) << dstbitnum)); }
Usage:
ADD ''dest'',''source1'',''source2'' DADD ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_ADD(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DADD(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the addition results in an unsigned overflow
- V — set if the addition results in a signed overflow
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_get_cycles_plus_10_in_i0(drcuml_block *block, UINT32 *cycles) { UML_ADD(block, IREG(0), MEM(cycles), IMM(10)); }
Usage:
ADDC ''dest'',''source1'',''source2'' DADDC ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_ADDC(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DADDC(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the addition results in an unsigned overflow
- V — set if the addition results in a signed overflow
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_add_with_carry(drcuml_block *block) { UML_CARRY(block, MEM(flags), IMM(0)); UML_ADDC(block, IREG(0), IREG(1), IREG(2)); }
Usage:
SUB ''dest'',''source1'',''source2'' DSUB ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_SUB(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DSUB(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the subtraction results in an unsigned overflow
- V — set if the subtraction results in a signed overflow
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_subtract_accumlated_cycles(drcuml_block *block, UINT32 *cycles) { UML_SUB(block, MEM(cycles), MEM(cycles), MVAR(10)); }
Usage:
SUBB ''dest'',''source1'',''source2'' DSUBB ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_SUBB(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DSUBB(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the subtraction results in an unsigned overflow
- V — set if the subtraction results in a signed overflow
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_sub_with_borrow(drcuml_block *block) { UML_CARRY(block, MEM(flags), IMM(0)); UML_SUBB(block, IREG(0), IREG(1), IREG(2)); }
Usage:
CMP ''source1'',''source2'' DCMP '''source1'',''source2''
Codegen Shorthand:
UML_CMP(block, PTYPE(''source1''), PTYPE(''source2'')); UML_DCMP(block, PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the compare results in an unsigned overflow
- V — set if the compare results in a signed overflow
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_branch_if_under_16_unsigned(drcuml_block *block, UINT32 *param, drcuml_codelabel target) { UML_CMP(block, MEM(param), IMM(16)); UML_JMPc(block, IF_B, target); }
Usage:
MULU ''dest1'',''dest2'',''source1'',''source2'' DMULU ''dest1'',''dest2'',''source1'',''source2''
Codegen Shorthand:
UML_MULU(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2'')); UML_DMULU(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest1 — a 32/64-bit integer register or memory location
- dest2 — a 32/64-bit integer register or memory location; can be the same as dest1
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — set if the upper half of the resulting value is not 0
- Z — set if the resulting value is 0 (only lower half considered if dest1 == dest2)
- S — set if the high bit of resulting value is set (only lower half considered if dest1 == dest2)
- U — undefined
Note that dest1 can be set equal to dest2; in this case, only the lower half of the final result is stored to the operand specified. The S and Z flags are also set differently, being based only on the lower half value (normally they are set based on the full double-width result).
Example:
void generate_64x64_wide_multiply(drcuml_block *block, UINT64 *src1, UINT64 *src2) { /* lower result in i0, upper result in i1 */ UML_DMULU(block, IREG(0), IREG(1), MEM(src1), MEM(src2)); }
Usage:
MULS ''dest1'',''dest2'',''source1'',''source2'' DMULS ''dest1'',''dest2'',''source1'',''source2''
Codegen Shorthand:
UML_MULS(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2'')); UML_DMULS(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest1 — a 32/64-bit integer register or memory location
- dest2 — a 32/64-bit integer register or memory location; can be the same as dest1
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — set if the upper half of the resulting value is not the sign extension of the lower half
- Z — set if the resulting value is 0 (only lower half considered if dest1 == dest2)
- S — set if the high bit of resulting value is set (only lower half considered if dest1 == dest2)
- U — undefined
As with MULU, dest1 can be set equal to dest2; in this case, only the lower half of the final result is stored to the operand specified. The S and Z flags are also set differently, being based only on the lower half value (normally they are set based on the full double-width result).
Example:
void generate_multiply_i0_by_20_and_assume_no_overflow(drcuml_block *block) { /* lower result in i0, upper result in i1 */ UML_MULS(block, IREG(0), IREG(0), IREG(0), IMM(20)); }
Usage:
DIVU ''dest1'',''dest2'',''source1'',''source2'' DDIVU ''dest1'',''dest2'',''source1'',''source2''
Codegen Shorthand:
UML_DIVU(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2'')); UML_DDIVU(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest1 — a 32/64-bit integer register or memory location
- dest2 — a 32/64-bit integer register or memory location; can be the same as dest1
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — set if the source2 parameter was 0
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that dest1 can be set equal to dest2; in this case, only the quotient is stored to the operand specified. The remainder does not need to computed.
Example:
void generate_64x32_unsigned_divide(drcuml_block *block, UINT64 *dividend, UINT32 *divisor) { UML_DSEXT(block, IREG(0), MEM(divisor), DWORD); UML_DDIVU(block, IREG(0), IREG(0), MEM(dividend), IREG(0)); }
Usage:
DIVS ''dest1'',''dest2'',''source1'',''source2'' DDIVS ''dest1'',''dest2'',''source1'',''source2''
Codegen Shorthand:
UML_DIVS(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2'')); UML_DDIVS(block, PTYPE(''dest1''), PTYPE(''dest2''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest1 — a 32/64-bit integer register or memory location
- dest2 — a 32/64-bit integer register or memory location; can be the same as dest1
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — set if the source2 parameter was 0
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that dest1 can be set equal to dest2; in this case, only the quotient is stored to the operand specified. The remainder does not need to computed.
Example:
void generate_compute_remainder_of_i0_over_i1(drcuml_block *block) { /* result in i0; we use i2 for scratch space since we cannot avoid computing the quotient */ UML_DIVS(block, IREG(2), IREG(0), IREG(0), IREG(1)); }
Usage:
AND ''dest'',''source1'',''source2'' DAND ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_AND(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DAND(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_keep_low_16_bits(drcuml_block *block, UINT32 *param) { UML_AND(block, MEM(param), MEM(param), IMM(0xffff)); }
Usage:
TEST ''source1'',''source2'' DTEST ''source1'',''source2''
Codegen Shorthand:
UML_TEST(block, PTYPE(''source1''), PTYPE(''source2'')); UML_DTEST(block, PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_branch_if_set(drcuml_block *block, int bitnum, drcuml_codelabel target) { UML_TEST(block, IREG(0), IMM(1 << bitnum)); UML_JMPc(block, IF_NZ, target); }
Usage:
OR ''dest'',''source1'',''source2'' DOR ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_OR(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DOR(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_set_bit_in_i1(drcuml_block *block, int whichbit) { UML_OR(block, IREG(1), IREG(1), IMM(1 << Whichbit)); }
Usage:
XOR ''dest'',''source1'',''source2'' DXOR ''dest'',''source1'',''source2''
Codegen Shorthand:
UML_XOR(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2'')); UML_DXOR(block, PTYPE(''dest''), PTYPE(''source1''), PTYPE(''source2''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source1 — a 32/64-bit integer register, memory location, map variable, or immediate
- source2 — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_invert_all_bits_in_i0(drcuml_block *block) { UML_DXOR(block, IREG(0), IMM(~U64(0))); }
Usage:
LZCNT ''dest'',''source'' DLZCNT ''dest'',''source''
Codegen Shorthand:
UML_LZCNT(block, PTYPE(''dest''), PTYPE(''source')); UML_DLZCNT(block, PTYPE(''dest''), PTYPE(''source''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — undefined
- U — undefined
If the source value is 0, the result is either 32 (LZCNT) or 64 (DLZCNT).
Example:
void generate_left_justify_bits_in_i0(drcuml_block *block) { UML_LZCNT(block, IREG(1), IREG(0)); UML_SHL(block, IREG(0), IREG(0), IREG(1)); }
Usage:
BSWAP ''dest'',''source'' DBSWAP ''dest'',''source''
Codegen Shorthand:
UML_BSWAP(block, PTYPE(''dest''), PTYPE(''source'')); UML_BSWAP(block, PTYPE(''dest''), PTYPE(''source''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- C — undefined
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Example:
void generate_byte_swap_16bit_value_in_i0(drcuml_block *block) { UML_BSWAP(block, IREG(0), IREG(0)); UML_SHR(block, IREG(0), IREG(0), IMM(16)); }
Usage:
SHL ''dest'',''source'',''shift'' DSHL ''dest'',''source'',''shift''
Codegen Shorthand:
UML_SHL(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DSHL(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit shifted out of the source is a 1
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For SHL, only the low 5 bits are used for the shift amount; for DSHL, only the low 6 bits are used.
Example:
void generate_multiply_i0_by_16(drcuml_block *block) { UML_SHL(block, IREG(0), IREG(0), IMM(4)); }
Usage:
SHR ''dest'',''source'',''shift'' DSHR ''dest'',''source'',''shift''
Codegen Shorthand:
UML_SHR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DSHR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit shifted out of the source is a 1
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For SHR, only the low 5 bits are used for the shift amount; for DSHR, only the low 6 bits are used.
Example:
void generate_unsigned_divide_i0_by_128(drcuml_block *block) { UML_SHR(block, IREG(0), IREG(0), IMM(7)); }
Usage:
SAR ''dest'',''source'',''shift'' DSAR ''dest'',''source'',''shift''
Codegen Shorthand:
UML_SAR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DSAR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit shifted out of the source is a 1
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For SHR, only the low 5 bits are used for the shift amount; for DSHR, only the low 6 bits are used.
Example:
void generate_get_sign_extension_of_i0_in_i1(drcuml_block *block) { UML_SAR(block, IREG(1), IREG(0), IMM(31)); }
Usage:
ROL ''dest'',''source'',''shift'' DROL ''dest'',''source'',''shift''
Codegen Shorthand:
UML_ROL(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DROL(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit rotated out of the source is a 1; equal to the new LSB
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For ROL, only the low 5 bits are used for the shift amount; for DROL, only the low 6 bits are used.
Example:
void generate_swap_words_in_i0(drcuml_block *block) { UML_ROL(block, IREG(0), IREG(0), IMM(16)); }
Usage:
ROR ''dest'',''source'',''shift'' DROR ''dest'',''source'',''shift''
Codegen Shorthand:
UML_ROR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DROR(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit rotated out of the source is a 1; equal to the new MSB
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For ROR, only the low 5 bits are used for the shift amount; for DROR, only the low 6 bits are used.
Example:
void generate_swap_dwords_in_i1(drcuml_block *block) { UML_DROR(block, IREG(1), IREG(1), IMM(32)); }
Usage:
ROLC ''dest'',''source'',''shift'' DROLC ''dest'',''source'',''shift''
Codegen Shorthand:
UML_ROLC(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DROLC(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit rotated out of the source is a 1
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For ROL, only the low 5 bits are used for the shift amount; for DROL, only the low 6 bits are used.
Example:
void generate_rotate_128bit_value_in_i0_i1(drcuml_block *block) { UML_CARRY(block, IREG(0), IMM(63)); UML_DROLC(block, IREG(1), IREG(1), IMM(1)); UML_DROLC(block, IREG(0), IREG(0), IMM(1)); }
Usage:
RORC ''dest'',''source'',''shift'' DRORC ''dest'',''source'',''shift''
Codegen Shorthand:
UML_RORC(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift'')); UML_DRORC(block, PTYPE(''dest''), PTYPE(''source''), PTYPE(''shift''));
Parameters:
- dest — a 32/64-bit integer register or memory location
- source — a 32/64-bit integer register, memory location, map variable, or immediate
- shift — a 32/64-bit integer register, memory location, map variable, or immediate
- C — set if the final bit rotated out of the source is a 1
- V — undefined
- Z — set if the resulting value is 0
- S — set if the high bit of the resulting value is set
- U — undefined
Note that only the low bits of the shift operand are considered. For ROL, only the low 5 bits are used for the shift amount; for DROL, only the low 6 bits are used.
Example:
void generate_rotate_64bit_value_in_i0_i1(drcuml_block *block) { UML_CARRY(block, IREG(1), IMM(0)); UML_RORC(block, IREG(0), IREG(0), IMM(1)); UML_RORC(block, IREG(1), IREG(1), IMM(1)); }