TCG to LLVM

Post on 01-Jan-2016

15 views 1 download

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

TCG to LLVM

Ding-Yong Hong

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

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

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;}

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

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;};

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

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

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

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

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

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