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.


2 0