CSC448: Phases: Code Generation [8/8] |
For programs, suppose that all the global variable declarations precede the function declarations, then we have:
code (T1 x1) = asmd1 ... code (Tn xn) = asmdn context((decl1 ... decln fundef1 ... fundefm)) |- code (fundef1) = asmf1 ... context((decl1 ... decln fundef1 ... fundefm)) |- code (fundefm) = asmfm ------------------------------------------------------------------------ code ((decl1 ... decln fundef1 ... fundefm)) = .text asmf1 ... asmfm .data asmd1 ... asmdm
For global variable declarations:
-------------------------------------------- code ((T x;)) = .align 4 .global x x: .long 0
For function declarations:
G,x1:S1,...,xn:Sn |- code (compoundStat) = asm ------------------------------------------------- G |- code ((T f(S1 x1,...,Sn xn) compoundStat)) = .align 4 .global f f: pushl %ebp movl %esp, %ebp asm
Recall the three-address syntax for statements:
stat ::= { decl1 ... decln stat1 ... statm } (StatCompound) | exp; (StatExp) | goto l; (StatGoto) | if (exp) goto l1; else goto l2; (StatIf) | return; (StatReturn) | return exp; (StatReturn) | skip; (StatSkip)
case StatCompound
:
G,x1:T1,...,xn:Tn |- code (stat1) = asm1 ... G,x1:T1,...,xn:Tn |- code (statm) = asmm --------------------------------------------------- G |- code ({ T1 x1; ... Tn xn; stat1 ... statm }) = subl $(n*intSize), %esp asm1 ... asmm addl $(n*intSize), %esp
case StatExp
:
G |- code (exp) = asm --------------------------------------------------- G |- code ((exp;)) = asm
case StatGoto
:
--------------------------------------------------- G |- code ((goto l;)) = jmp l
case StatIf
:
G |- location (v) = v'' --------------------------------------------- G |- code ((if (v) goto l1; else goto l2;)) = movl v'', %eax testl %eax, %eax jne %l1 jmp %l2
case StatReturn
:
--------------------------------------------- G |- code ((return;)) = movl %ebp, %esp popl %ebp ret G |- location (v) = v'' --------------------------------------------- G |- code ((return v;)) = movl v'', %eax movl %ebp, %esp popl %ebp ret
case StatSkip
:
--------------------------------------------- G |- code ((skip;)) = nop
Recall the three-address syntax for expressions:
exp ::= rhs | lhs = rhs (ExpAssign) lhs ::= x (ExpVar) | x[v] (ExpArrayAccess) rhs ::= n (ExpInt) | x (ExpVar) | "value" (ExpString) | new T[v] (ExpNew) | x[v] (ExpArrayAccess) | unop v (ExpUnOp) | vL binop vR (ExpBinOp) | f(v1,...,vn) (ExpFunCall)
First generate code for the RHS, and put the result in %eax
case ExpInt
:
--------------------------------------------- G |- code (n) = movl $n, %eax
case ExpVar
:
G |- location (x) = x'' --------------------------------------------- G |- code (x) = movl x'', %eax
case ExpString
:
--------------------------------------------- G |- code (("value")) = movl lab_string, %eax lab_string: .int 'v' .int 'a' .int 'l' .int 'u' .int 'e' .int 0
case ExpNew
:
G |- location (v) = v'' --------------------------------------------- G |- code ((new T[v])) = movl v'', %eax sall $(log_2(intSize)), %eax push %eax call _malloc addl $(1*intSize), %esp
case ExpArrayAccess
:
G |- location (x) = x'' G |- location (v) = v'' --------------------------------------------- G |- code (x[v]) = movl x'', %edx movl v'', %ecx sall $(log_2(intSize)), %ecx addl %ecx, %edx movl 0(%edx), %eax
case ExpUnOp
:
G |- location (v) = v'' --------------------------------------------- G |- code ((- v)) = movl v1'', %eax negl %eax
case ExpBinOp
:
G |- location (v1) = v1'' G |- location (v2) = v2'' --------------------------------------------- G |- code ((v1 + v2)) = movl v1'', %eax movl v2'', %ecx addl %ecx, %eax
case ExpFunCall
:
G |- location (v1) = v1'' ... G |- location (vn) = vn'' --------------------------------------------- G |- code ((f(v1,...,vn))) = pushl vn'' ... pushl v1'' call f addl $(n*intSize), %esp
Then generate code for the LHS, if any, getting the result
from %eax
case ExpVar
:
G |- location (x) = x'' --------------------------------------------- G |- code (x) = movl %eax, x''
case ExpArrayAccess
:
G |- location (x) = x'' G |- location (v) = v'' --------------------------------------------- G |- code (x[v]) = movl x'', %edx movl v'', %ecx sall $(log_2(intSize)), %ecx addl %ecx, %edx movl %eax, 0(%edx)