Qemu中间代码微指令类型总结
来源:互联网 发布:豫广网络宽带怎么样 编辑:程序博客网 时间:2024/05/21 19:28
Qemu采用TCG(Tiny code generator)翻译引擎,TCG的作用也和一个真正的编译器后端一样,主要负责分析、优化Target代码以及生成Host代码。所谓“微指令”,是qemu用于指令翻译的中间表示,进行指令翻译时,qemu首先将每条target的指令分解为多条类似RISC指令的微指令,这个阶段可以进行一些优化,如微指令的生命周期分析(liveness analysis)等,之后微指令在后端由host机的指令实现。
CPU指令一般都是很规则的,每条指令的长度、操作码、操作数都有固定格式,根据前面就可推导出后面,微指令的设计也采用了类似的规则,每条微指令都有固定的输入、输出与常数操作数(除了call指令有不定数目的输入输出操作数)。另外,与cpu指令对应,微指令也设计了数据传送、算术运算、逻辑运算、程序控制几大类指令。
下面对Qemu提供的微指令类型进行分析归纳:
1. 微指令基本格式
微指令在tcg/tcg-opc.h中定义。定义格式为
DEF(name, oargs,iargs, cargs, flags)
其中name为微指令名,oargs为输出操作数个数,iargs为输入操作数个数,cargs为常数操作数个数,flags表示为特殊指令的一些标志,如flags取值为TCG_OPF_SIDE_EFFECTS表示该指令会影响内存中内容。
例如,一条add指令微操作定义为:
DEF(add_i32, 1,2, 0, 0)
其含义为:
add_i32 t0, t1, t2 (t0 <- t1 + t2), i32表示target机为32位机。t0为输出操作数,t1、t2为两个输入操作数,没有常数操作数。2.qemu预定义的微指令
cpu指令对应,微指令也设计了数据传送、算术运算、逻辑运算、程序控制几大类指令。且针对32位和64位的目标机,qemu分别定义了一套微指令,即[opname]_i32、[opname]_i64,由于目前csky的cpu为32位,因此我们先只关注32位的微指令。
1) 数据传送
2) 算术运算
3) 逻辑运算
4) 程序控制
3. 微指令类型归纳
指令名
指令格式
指令含义
/* predefined ops */
end
end
end of tb
nop
nop1
nop2
nop3
nopn
discard
discard t0
mark t0 as dead variable
set_label
set_label $label
Define label 'label' at the current program point.
call
call <ret><params> ptr
call function 'ptr' (pointer type)
jmp
jmp t0
Absolute jump to address t0 (pointer type)
br
br $label
Jump to label.
mov_i32
mov_i32 t0, t1
t0 = t1
movi_i32
mov_i32 t0, $(constant)
t0 = $(constant)
setcond_i32
setcond_i32 cond, dest, t1, t2
dest = (t1 cond t2)
brcond_i32
brcond_i32 cond, t0, t1, label
Conditional jump if t0 cond t1 is true
/* load/store */
ld8u_i32
ld8u_i32 t0, t1, offset
t0 = read(t1 + offset)
Load 8, 16, 32 or 64 bits with or without sign extension from host memory.
offset must be a constant.
ld8s_i32
ld8s_i32 t0, t1, offset
ld16u_i32
ld16u_i32 t0, t1, offset
ld16s_i32
ld16s_i32 t0, t1, offset
ld_i32
ld_i32 t0, t1, offset
st8_i32
st8_i32 t0, t1, offset
write(t0, t1 + offset)
Write 8, 16, 32 or 64 bits to host memory.
st16_i32
st16_i32 t0, t1, offset
st_i32
st_i32 t0, t1, offset
/* arith */
add_i32
add_i32 t0, t1, t2
t0=t1+t2
sub_i32
sub_i32 t0, t1, t2
t0=t1-t2
mul_i32
mul_i32 t0, t1, t2
t0=t1*t2
div_i32
div_i32 t0, t1, t2
t0=t1/t2 (signed)
divu_i32
divu_i32 t0, t1, t2
t0=t1/t2 (unsigned)
rem_i32
rem_i32 t0, t1, t2
t0=t1%t2 (signed)
remu_i32
remu_i32 t0, t1, t2
t0=t1%t2 (unsigned)
and_i32
and_i32 t0, t1, t2
t0=t1&t2
or_i32
or_i32 t0, t1, t2
t0=t1|t2
xor_i32
xor_i32 t0, t1, t2
t0=t1^t2
/* shifts/rotates */
shl_i32
shl_i32 t0, t1, t2
t0=t1 << t2
shr_i32
shr_i32 t0, t1, t2
t0=t1 >> t2
sar_i32
sar_i32 t0, t1, t2
t0=t1 >> t2 (signed)
rotl_i32
rotl_i32 t0, t1, t2
Rotation of t2 bits to the left
rotr_i32
rotr_i32 t0, t1, t2
Rotation of t2 bits to the right
deposit_i32
deposit_i32 dest, t1, t2, pos, len
LEN - the length of the bitfield
POS - the position of the first bit, counting from the LSB
For example, pos=8, len=4:
dest = (t1 & ~0x0f00) | ((t2 << 8) & 0x0f00)
ext8s_i32
ext8s_i32 t0, t1
8 bit sign extension
ext8u_i32
ext8u_i32 t0, t1
8 bit zero extension
ext16s_i32
ext16s_i32 t0, t1
16 bit sign extension
ext16u_i32
ext16u_i32 t0, t1
16 bit zero extension
bswap16_i32
bswap16_i32 t0, t1
16 bit byte swap on a 32 bit value
bswap32_i32
bswap32_i32 t0, t1
32 bit byte swap on a 32 bit value
not_i32
not_i32 t0, t1
t0=~t1
neg_i32
neg_i32 t0, t1
t0=-t1
andc_i32
andc_i32 t0, t1, t2
t0=t1&~t2
orc_i32
orc_i32 t0, t1, t2
t0=t1|~t2
eqv_i32
eqv_i32 t0, t1, t2
t0=~(t1^t2), or equivalently, t0=t1^~t2
nand_i32
nand_i32 t0, t1, t2
t0=~(t1&t2)
nor_i32
nor_i32 t0, t1, t2
t0=~(t1|t2)
/* QEMU specific */
debug_insn_start
debug_insn_start $pc
write the PC of the corresponding QEMU CPU instruction
exit_tb
exit_tb t0
Exit the current TB and return the value t0 (word type)
goto_tb
goto_tb index
Exit the current TB and jump to the TB index 'index' (constant) if the
current TB was linked to this TB. Otherwise execute the next
instructions.
qemu_ld8u
qemu_ld8u t0, t1, flags
Load data at the QEMU CPU address t1 into t0. t1 has the QEMU CPU address
type. 'flags' contains the QEMU memory index (selects user or kernel access) for example.
qemu_ld8s
qemu_ld8s t0, t1, flags
qemu_ld16u
qemu_ld16u t0, t1, flags
qemu_ld16s
qemu_ld16s t0, t1, flags
qemu_ld32
qemu_ld32 t0, t1, flags
qemu_ld32u
qemu_ld32u t0, t1, flags
qemu_ld32s
qemu_ld32s t0, t1, flags
qemu_ld64
qemu_ld64 t0, t1, flags
qemu_st8
qemu_st8 t0, t1, flags
Store the data t0 at the QEMU CPU Address t1. t1 has the QEMU CPU
address type. 'flags' contains the QEMU memory index (selects user or
kernel access) for example.
- Qemu中间代码微指令类型总结
- tiny+指令流(中间代码)设计
- 栈式虚拟机中间代码编译为x86指令
- qemu指令计数
- 软考总结之总结、网络、中间代码
- qemu的网卡类型
- qemu的网卡类型
- QEMU代码结构分析
- qemu-kvm 代码分析
- QEMU代码中的QLIST
- qemu-kvm代码分析
- qemu-kvm 代码分析
- Hypervisor, KVM, QEMU总结
- C编译器剖析_6.3.1 汇编代码生成_由中间指令产生汇编代码的主要流程
- 关于QEMU中的类型算法
- QEMU中的CPU类型设计
- c++沉思录笔记(21章代码)隐藏中间类型
- 中间代码生成
- Gradle 安装和下载
- 消息传送机制
- C++中 模板Template的使用
- 图片的内存优化
- HTTP 错误 500.21 - Internal Server Error 处理程序“PageHandlerFactory-ISAPI-4.0_32bit”在其模块
- Qemu中间代码微指令类型总结
- 关于select中DISTINCT的技巧和使用
- C++中模板使用详解
- php扩展编译报错
- linnux man 手册
- 1021. 个位数统计 (15)
- 把图片从Mac本地添加到iOS Simulator中
- mysql
- /dev/input/event0 键盘输入