TCG to LLVM

12
TCG to LLVM Ding-Yong Hong

description

TCG to LLVM. Ding-Yong Hong. Category of TCG IR. Register movement : mov , movi Logical : and, or, xor , shl , shr , … Arithmetic : add, sub, mul , div, … Memory Ops : qemu_ld , qemu_st Ex: mov % eax , 0x4(% ebx ) Internal memory Ops : ld , st Used to access entry of CPUState - PowerPoint PPT Presentation

Transcript of TCG to LLVM

Page 1: TCG to LLVM

TCG to LLVM

Ding-Yong Hong

Page 2: TCG to LLVM

Register movement: mov, movi Logical: and, or, xor, shl, shr, … Arithmetic: add, sub, mul, div, … Memory Ops: qemu_ld, qemu_st

◦ Ex: mov %eax, 0x4(%ebx) Internal memory Ops: ld, st

◦ Used to access entry of CPUState◦ Ex: movi 0x8000000, 0x20(%r14) # env->eip = 0x8000000

Branch Ops: jmp, br, brcond Helper function: call Misc: exit_tb, end

Index to opcode: INDEX_op_XXX◦ Ex: INDEX_op_add

Category of TCG IR

Page 3: TCG to LLVM

gen_opc_buf: list of opcodes gen_opparam_buf: list of opcode parameters

TCG IR Structure

Ex:

mov %eax, %ebxadd %ebx, %ecxmov 0x10, %edx...jmp 0x8000000

......

......

gen_opc_buf

gen_opparam_buf

mov add movi end

exit_tb

Page 4: TCG to LLVM

TCG-to-LLVM IR functions are contained in class IRFactory◦ All functions are named op_XXX and have the same interface TCGArg

*args◦ The return value of a function is # parameters used in this op◦ All IR function pointers are stored in a mapping table

LLVM IR Function Interface

class IRFactory { int op_mov (const TCGArg *args); int op_add (const TCGArg *args); int op_call (const TCGArg *args);

map<opcode, FnPtr*> OpcFn;};

......

......

gen_opc_buf

gen_opparam_buf

mov add movi end

exit_tb

args = gen_opparam_buf;

for (i = 0; I < num_opc; i++) { TCGOpcode opc = gen_opc_buf [i]; NumParam = (IF->*OpcFn[opc])(args); args += NumParam;}

Page 5: TCG to LLVM

Information about virtual registers allocated in TCG IR

We prepare the same # of LLVM virtual registers

Information We Need from TCG

......

......

gen_opc_buf

gen_opparam_buf

mov add movi end

exit_tb

tmp1 tmp1 tmp2 tmp8

struct Register{ int Type; int Base; int Size; llvm_offset Off; char *Name; Value *Data; bool Dirty;};

Register Reg[0]{ .Type = I32; .Base = R14; .Size = 32; .Off = 0x4; .Name = “ecx”; .Data = NULL; .Dirty = false;};

tmp1

tmp2

tmp8

.....

Register

eax ebx

Page 6: TCG to LLVM

LoadInput() is to load state from CPUState to LLVM virtual register

Return value if already loaded or load from memory

Load States from CPUState

.....

RegisterRegister Reg[8]{ .Type = I32; .Base = R14; .Size = 32; .Off = 0x4; .Name = “ecx”; .Data = NULL; .Dirty = false;}; X

llvm::Value

Register Reg[8]{ .Type = I32; .Base = R14; .Size = 32; .Off = 0x4; .Name = “ecx”; .Data = pointer to Value(X); .Dirty = false;};

Page 7: TCG to LLVM

Register movement: mov, movi

Register Movement

int IRFactory::op_mov_i32(const TCGArg *args){ Register *Out = &Reg[args[0]]; Register *In = &Reg[args[1]];

Value *InData = LoadInput(In); # A = new LoadInst(addr); Out->setData(InData, true);

return 2;}

args[0]

.....

Register

args[1]

struct Register Reg[args[0]] Reg[args[1]]{ int Type; int Base; int Size; llvm_offset Off; char *Name; Value *Data; A A bool Dirty; true false};

A

llvm::Value

opc

args

mov

Page 8: TCG to LLVM

Logical: and, or, xor, shl, shr, … Arithmetic: add, sub, mul, div, …

Logical & Arithmetic Operations

int IRFactory::op_add_i32(const TCGArg *args){ Register *Out = &Reg[args[0]]; Register *In1 = &Reg[args[1]]; Register *In2 = &Reg[args[2]];

Value *InData1 = LoadInput(In1); Value *InData2 = LoadInput(In2);

Value *OutData; = ADD(InData1, InData2); Out->setData(OutData, true);

return 3;}

#define AND(a,b) BinaryOperator::Create(Instruction::And, a, b, "", InsertPos)#define OR(a,b) BinaryOperator::Create(Instruction::Or, a, b, "", InsertPos)#define ADD(a,b) BinaryOperator::Create(Instruction::Add, a, b, "", InsertPos)

opc

args

add

tmp1 tmp1 tmp2

Page 9: TCG to LLVM

Memory Ops: qemu_ld, qemu_st◦ Ex: mov 0x4(%ebx), %eax

Memory Operations

int IRFactory::op_qemu_ld32(const TCGArg *args){ Register *Out = &Reg[args[0]]; Register *In = &Reg[args[1]];

Value *InData = LoadInput(In); # load %ebx

SaveGlobals(COHERENCE_GLOBAL, LastInst);

InData = QEMULoad(InData, GUEST_BASE, 2, args[2]); Out->setData(InData, true);

return 3;}

opc

args

qemu_ld32

eax ebx 0x4

Page 10: TCG to LLVM

SaveGlobals() is to store dirty states back to memory Opcodes need to save states

◦ op_jmp◦ op_br◦ op_brcond◦ op_call◦ op_goto_tb◦ op_exit_tb◦ op_qemu_ld_XXX◦ op_qemu_st_XXX

Store Dirty States to CPUState

D

D

.....

Register

A

Register Reg[1]{ .Type = I32; .Base = R14; .Size = 32; .Off = 0x4; .Name = “ecx”; .Data = pointer to X; .Dirty = true;};

X

llvm::Value

Page 11: TCG to LLVM

QEMULoad()

Page Fault Handling in QEMU System Mode

S1: mov %eax, %ebxS2: add %eax, %ecxS3: add %eax, %edxS4: mov (%eax), eaxS5: mov %eax, %ebxS6: mov %eax, %ebx

Guest code:

S1’: …S2’: …S3’: …S4’: op_qemu_ld32 %1 = LoadInput ( %eax ) %2 = do_tlb_Lookup ( %r0 ) If %2 = HIT then mov (%eax), eax goto S5’ else # page fault call PageFaultHelper() endif

S5’: …S6’: …

Host code:

translate

Page 12: TCG to LLVM

Internal memory Ops: ld, st◦ Used to access entry of CPUState◦ Ex: movi 0x8000000, 0x20(%r14)

Branch Ops: jmp, br, brcond

Helper function: call

Misc: exit_tb, end

Category of TCG IR