README revision cec22f4b94382f5ebee9d2f6b6df672689681e07
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncTiny Code Generator - Fabrice Bellard.
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync1) Introduction
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncTCG (Tiny Code Generator) began as a generic backend for a C
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsynccompiler. It was simplified to be used in QEMU. It also has its roots
cae3b8810c39392e70dfb12b951431018a80fcbavboxsyncin the QOP code generator written by Paul Brook.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync2) Definitions
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncThe TCG "target" is the architecture for which we generate the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsynccode. It is of course not the same as the "target" of QEMU which is
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncthe emulated architecture. As TCG started as a generic C backend used
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncfor cross compiling, it is assumed that the TCG target is different
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncfrom the host, although it is never the case for QEMU.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncA TCG "function" corresponds to a QEMU Translated Block (TB).
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncA TCG "temporary" is a variable only live in a basic
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncblock. Temporaries are allocated explicitly in each function.
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsyncA TCG "local temporary" is a variable only live in a function. Local
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsynctemporaries are allocated explicitly in each function.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncA TCG "global" is a variable which is live in all the functions
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync(equivalent of a C global variable). They are defined before the
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncfunctions defined. A TCG global can be a memory location (e.g. a QEMU
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncCPU register), a fixed host register (e.g. the QEMU CPU state pointer)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncor a memory location which is stored in a register outside QEMU TBs
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync(not implemented yet).
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncA TCG "basic block" corresponds to a list of instructions terminated
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncby a branch instruction.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync3) Intermediate representation
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync3.1) Introduction
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncTCG instructions operate on variables which are temporaries, local
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsynctemporaries or globals. TCG instructions and variables are strongly
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsynctyped. Two types are supported: 32 bit integers and 64 bit
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncintegers. Pointers are defined as an alias to 32 bit or 64 bit
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncintegers depending on the TCG target word size.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncEach instruction has a fixed number of output variable operands, input
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncvariable operands and always constant operands.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncThe notable exception is the call instruction which has a variable
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncnumber of outputs and inputs.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncIn the textual form, output operands usually come first, followed by
cae3b8810c39392e70dfb12b951431018a80fcbavboxsyncinput operands, followed by constant operands. The output type is
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncincluded in the instruction name. Constants are prefixed with a '$'.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncadd_i32 t0, t1, t2 (t0 <- t1 + t2)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync3.2) Assumptions
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* Basic blocks
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync- Basic blocks end after branches (e.g. brcond_i32 instruction),
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync goto_tb and exit_tb instructions.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync- Basic blocks start after the end of a previous basic block, or at a
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync set_label instruction.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncAfter the end of a basic block, the content of temporaries is
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncdestroyed, but local temporaries and globals are preserved.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* Floating point types are not supported yet
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* Pointers: depending on the TCG target, pointer size is 32 bit or 64
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync bit. The type TCG_TYPE_PTR is an alias to TCG_TYPE_I32 or
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_TYPE_I64.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncUsing the tcg_gen_helper_x_y it is possible to call any function
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsynctaking i32, i64 or pointer types. By default, before calling an helper,
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncall globals are stored at their canonical location and it is assumed
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncthat the function can modify them. This can be overriden by the
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncTCG_CALL_CONST function modifier. By default, the helper is allowed to
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncmodify the CPU state or raise an exception. This can be overriden by
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncthe TCG_CALL_PURE function modifier, in which case the call to the
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncfunction is removed if the return value is not used.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncOn some TCG targets (e.g. x86), several calling conventions are
611992ec6994e6050e4970a973d2f549f823a3eavboxsyncUse the instruction 'br' to jump to a label. Use 'jmp' to jump to an
611992ec6994e6050e4970a973d2f549f823a3eavboxsyncexplicit address. Conditional branches can only jump to labels.
611992ec6994e6050e4970a973d2f549f823a3eavboxsync3.3) Code Optimizations
611992ec6994e6050e4970a973d2f549f823a3eavboxsyncWhen generating instructions, you can count on at least the following
611992ec6994e6050e4970a973d2f549f823a3eavboxsyncoptimizations:
611992ec6994e6050e4970a973d2f549f823a3eavboxsync- Single instructions are simplified, e.g.
611992ec6994e6050e4970a973d2f549f823a3eavboxsync and_i32 t0, t0, $0xffffffff
611992ec6994e6050e4970a973d2f549f823a3eavboxsync is suppressed.
611992ec6994e6050e4970a973d2f549f823a3eavboxsync- A liveness analysis is done at the basic block level. The
611992ec6994e6050e4970a973d2f549f823a3eavboxsync information is used to suppress moves from a dead variable to
611992ec6994e6050e4970a973d2f549f823a3eavboxsync another one. It is also used to remove instructions which compute
611992ec6994e6050e4970a973d2f549f823a3eavboxsync dead results. The later is especially useful for condition code
611992ec6994e6050e4970a973d2f549f823a3eavboxsync optimization in QEMU.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync In the following example:
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync add_i32 t0, t1, t2
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync add_i32 t0, t0, $1
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync mov_i32 t0, $1
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync only the last instruction is kept.
cae3b8810c39392e70dfb12b951431018a80fcbavboxsync3.4) Instruction Reference
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync********* Function call
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* call <ret> <params> ptr
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsynccall function 'ptr' (pointer type)
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync<ret> optional 32 bit or 64 bit return value
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync<params> optional 32 bit or 64 bit parameters
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncAbsolute jump to address t0 (pointer type).
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* set_label $label
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncDefine label 'label' at the current program point.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncJump to label.
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync* brcond_i32/i64 cond, t0, t1, label
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsyncConditional jump if t0 cond t1 is true. cond can be:
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_EQ
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_NE
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_LT /* signed */
cae3b8810c39392e70dfb12b951431018a80fcbavboxsync TCG_COND_GE /* signed */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_LE /* signed */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_GT /* signed */
c7945191b700920f0ab9b951ce92cc69cb48ffb4vboxsync TCG_COND_LTU /* unsigned */
611992ec6994e6050e4970a973d2f549f823a3eavboxsync TCG_COND_GEU /* unsigned */
611992ec6994e6050e4970a973d2f549f823a3eavboxsync TCG_COND_LEU /* unsigned */
611992ec6994e6050e4970a973d2f549f823a3eavboxsync TCG_COND_GTU /* unsigned */
611992ec6994e6050e4970a973d2f549f823a3eavboxsync********* Arithmetic
* mul_i32/i64 t0, t1, t2
* div_i32/i64 t0, t1, t2
t0=t1/t2 (signed). Undefined behavior if division by zero or overflow.
* divu_i32/i64 t0, t1, t2
t0=t1/t2 (unsigned). Undefined behavior if division by zero.
* rem_i32/i64 t0, t1, t2
* remu_i32/i64 t0, t1, t2
* and_i32/i64 t0, t1, t2
* or_i32/i64 t0, t1, t2
* xor_i32/i64 t0, t1, t2
* not_i32/i64 t0, t1
* andc_i32/i64 t0, t1, t2
* eqv_i32/i64 t0, t1, t2
* nand_i32/i64 t0, t1, t2
* nor_i32/i64 t0, t1, t2
* orc_i32/i64 t0, t1, t2
********* Shifts/Rotates
* shl_i32/i64 t0, t1, t2
* shr_i32/i64 t0, t1, t2
* sar_i32/i64 t0, t1, t2
* rotl_i32/i64 t0, t1, t2
* rotr_i32/i64 t0, t1, t2
* mov_i32/i64 t0, t1
* ext8s_i32/i64 t0, t1
ext8u_i32/i64 t0, t1
ext16s_i32/i64 t0, t1
ext16u_i32/i64 t0, t1
8, 16 or 32 bit sign/zero extension (both operands must have the same type)
* bswap16_i32/i64 t0, t1
16 bit byte swap on a 32/64 bit value. It assumes that the two/six high order
* bswap32_i32/i64 t0, t1
* discard_i32/i64 t0
* setcond_i32/i64 cond, dest, t1, t2
********* Load/Store
* ld_i32/i64 t0, t1, offset
ld8s_i32/i64 t0, t1, offset
ld8u_i32/i64 t0, t1, offset
ld16s_i32/i64 t0, t1, offset
ld16u_i32/i64 t0, t1, offset
* st_i32/i64 t0, t1, offset
st8_i32/i64 t0, t1, offset
st16_i32/i64 t0, t1, offset
They are emitted as needed by inline functions within "tcg-op.h".
Similar to add/sub, except that the 64-bit inputs T1 and T2 are
a constant (e.g. addi for add, movi for mov).
The ld/st instructions must accept signed 32 bit constant offsets. It
The ld/st instructions must accept any destination (ld) or source (st)
often modified, e.g. the integer registers and the condition
e.g. when you need to use a value after a jump. Local temporaries