Documentation/TCG/backend-ops

From QEMU

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