Backend Ops
These are the supported operations as implemented by the TCG backend for the host cpu (where QEMU executes; not what QEMU executes). This information is useful for people who want to port QEMU run on a new processor.
Math
ADD
|
Add two operands
|
ret = arg1 + arg2
|
DIV
|
Divide two signed operands and return the quotient
|
ret = arg1 / arg2
|
DIVU
|
Divide two unsigned operands and return the quotient
|
ret = arg1 / arg2
|
MOV
|
Assign one operand to another
|
ret = arg1
|
MUL
|
Multiply two signed operands
|
ret = arg1 * arg2
|
MULU
|
Multiply two unsigned operands
|
ret = arg1 * arg2
|
NEG
|
Negate the sign of an operand
|
ret = -arg1
|
REM
|
Divide two signed operands and return the remainder
|
ret = arg1 % arg2
|
REMU
|
Divide two unsigned operands and return the remainder
|
ret = arg1 % arg2
|
SUB
|
Subtract two operands
|
ret = arg1 - arg2
|
Bit
AND
|
Logical AND two operands
|
ret = arg1 & arg2
|
ANDC
|
Logical AND one operand with the complement of another
|
ret = arg1 & ~arg2
|
EQV
|
Compute logical equivalent of two operands
|
ret = !(arg1 ^ arg2)
|
NAND
|
Logical NAND two operands
|
ret = arg1 ↑ arg2
|
NOR
|
Logical NOR two operands
|
ret = arg1 ↓ arg2
|
NOT
|
Logical NOT an operand
|
ret = !arg1
|
OR
|
Logical OR two operands
|
ret = arg1 | arg2
|
ORC
|
Logical OR one operand with the complement of another
|
ret = arg1 | ~arg2
|
ROTL
|
Rotate left one operand by magnitude of another
|
ret = arg1 rotl arg2
|
ROTR
|
Rotate right one operand by magnitude of another
|
ret = arg1 rotr arg2
|
SAR
|
Arithmetic shift right one operand by magnitude of another
|
ret = arg1 >> arg2 /* Sign bit used to fill vacant bits */
|
SHL
|
Logical shift left one operand by magnitude of another
|
ret = arg1 << arg2
|
SHR
|
Logical shift right one operand by magnitude of another
|
ret = arg1 >> arg2
|
XOR
|
Logical XOR two operands
|
ret = arg1 ^ arg2
|
Byte
BSWAP16
|
Byte swap a 16bit quantity
|
ret = ((arg1 & 0xff00) >> 8) | ((arg1 & 0xff) << 8)
|
BSWAP32
|
Byte swap a 32bit quantity
|
ret = ...see bswap16 and extend to 32bits...
|
BSWAP64
|
Byte swap a 64bit quantity
|
ret = ...see bswap32 and extend to 64bits...
|
EXT8S
|
Sign extend an 8bit operand
|
ret = (int8_t)arg1
|
EXT8U
|
Zero extend an 8bit operand
|
ret = (uint8_t)arg1
|
EXT16S
|
Sign extend an 16bit operand
|
ret = (int16_t)arg1
|
EXT16U
|
Zero extend an 16bit operand
|
ret = (uint16_t)arg1
|
EXT32S
|
Sign extend an 32bit operand
|
ret = (int32_t)arg1
|
EXT32U
|
Zero extend an 32bit operand
|
ret = (uint32_t)arg1
|
Load/Store
These are for moving data between registers and arbitrary host memory. Typically used for funky CPU state that is not represented by dedicated registers already and thus infrequently used. These are not for accessing the target's memory space; see the QEMU_XX helpers below for that.
LD8S
|
Load an 8bit quantity from host memory and sign extend
|
LD8U
|
Load an 8bit quantity from host memory and zero extend
|
LD16S
|
Load a 16bit quantity from host memory and sign extend
|
LD16U
|
Load a 16bit quantity from host memory and zero extend
|
LD32S
|
Load a 32bit quantity from host memory and sign extend
|
LD32U
|
Load a 32bit quantity from host memory and zero extend
|
LD64
|
Load a 64bit quantity from host memory
|
LD
|
Alias to target native sized load
|
ST8
|
Store a 8bit quantity to host memory
|
ST16
|
Store a 16bit quantity to host memory
|
ST32
|
Store a 32bit quantity to host memory
|
ST
|
Alias to target native sized store
|
These are for moving data between registers and arbitrary target memory. The address to load/store via is always the second argument while the first argument is always the value to be loaded/stored. The third argument (memory index) only makes sense for system targets; user targets will simply specify 0 all the time.
QEMU_LD8S
|
Load an 8bit quantity from target memory and sign extend
|
ret = *(int8_t *)arg1
|
QEMU_LD8U
|
Load an 8bit quantity from target memory and zero extend
|
ret = *(uint8_t *)arg1
|
QEMU_LD16S
|
Load a 16bit quantity from target memory and sign extend
|
ret = *(int8_t *)arg1
|
QEMU_LD16U
|
Load a 16bit quantity from target memory and zero extend
|
ret = *(uint8_t *)arg1
|
QEMU_LD32S
|
Load a 32bit quantity from target memory and sign extend
|
ret = *(int8_t *)arg1
|
QEMU_LD32U
|
Load a 32bit quantity from target memory and zero extend
|
ret = *(uint8_t *)arg1
|
QEMU_LD64
|
Load a 64bit quantity from target memory
|
ret = *(uint64_t *)arg1
|
QEMU_ST8
|
Store an 8bit quantity to target memory
|
*(uint8_t *)addr = arg
|
QEMU_ST16
|
Store a 16bit quantity to target memory
|
*(uint16_t *)addr = arg
|
QEMU_ST32
|
Store a 32bit quantity to target memory
|
*(uint32_t *)addr = arg
|
QEMU_ST64
|
Store a 64bit quantity to target memory
|
*(uint64_t *)addr = arg
|
Code Flow
BR
|
Branch somewhere?
|
|
BRCOND
|
Test two operands and conditionally branch to a label
|
if (arg1 <condition> arg2) goto label
|
CALL
|
Call a helper function
|
|
GOTO_TB
|
Goto translation block
|
|
EXIT_TB
|
Exit translation block
|
|
SETCOND
|
Compare two operands
|
ret = arg1 <condition> arg2
|
SET_LABEL
|
Mark the current location with a label
|
label:
|
Misc
DISCARD
|
Discard a register
|
NOP
|
Generate a No Operation insn
|