TCG to LLVM
-
Upload
eliana-odom -
Category
Documents
-
view
15 -
download
1
description
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