Code Generation Dr. Nguyen Hua Phung Faculty of CSE HCMUT CSE - HCMUT Code Generation 2 Outline • Our Compiler • Translation for a stack-based machine –Declarations – Expressions – Statements – Jasmin directives • Translation for a registered-based machine – Register allocation – Instruction selection – Code scheduling CSE - HCMUT Code Generation 3 Scanner √ Parser √ Semantic analyzer √ Code generation Sequence of tokens Parse tree/AST Parse tree /AST Jasmin code (*.j) source code Symbol table Our Compiler Java Bytecode Assembler Java Byte code (*.class) Java Virtual Machine CSE - HCMUT Code Generation 4 source code - Java mapping • A source program ⇒ Java class(es) • A global variable ⇒ a static field • A function ⇒ a static method • A parameter ⇒ a parameter • A local variable ⇒ a local variable • An expression ⇒ an expression • A statement ⇒ a statement (except an expression statement) • An invocation ⇒ a static invocation CSE - HCMUT Code Generation 5 Some issues • An array declaration ⇒ a declaration + code – global ⇒ code in the class init –local ⇒ code in the enclosing method • A main method ⇒ a main method with different signature int main() ⇒ void main(String [] args) return <integer expr> ⇒ return CSE - HCMUT Code Generation 6 Example int a,b; float c[3]; int foo(int a,int b[]) { boolean c; c = b[1] > a; if (c) return a; else return b[0]; } int main() { float d[3]; c[0] = d[0]; repeat a = a + 1; until (a > 10); return 1; } public class Cout { static int a,b; static float c[] = new float[3]; static int foo(int a,int b[]) { boolean c; c = b[1] > a; if (c) return a; else return b[0]; } public static void main(String[] arg) { float d[] = new float[3]; c[0] = d[0]; do a = a + 1; while (!(a > 10)); return ; } } CSE - HCMUT Code Generation 7 Jasmin • Java source code to Java byte code javac –g <java source code> -g: to generate debug information • Java byte code to Jasmin code java JasminVisitor <java byte code> Read JavaToJasmin script for details • Jasmin code to Java byte code java -jar jasmin.jar <Jasmin code> Read RunJasmin script for details CSE - HCMUT Code Generation 8 Example –Jasmin public class Cout { static int a,b; static float c[] = new float[3]; static int foo(int a,int b[]) { boolean c; c = b[1] > a; if (c) return a; else return b[0]; } public static void main(String[] arg) { float d[] = new float[3]; c[0] = d[0]; do a = a + 1; while (!(a > 10)); return ; } } .source Cout.java .class public Cout .super java/lang/Object .field static a I .field static b I .field static c [F .method static <clinit>()V .limit stack 1 .limit locals 0 .line 3 iconst_3 newarray float putstatic Cout.c [F return .end method CSE - HCMUT Code Generation 9 Example –Jasmin (cont’d) public class Cout { static int a,b; static float c[] = new float[3]; static int foo(int a,int b[]) { boolean c; c = b[1] > a; if (c) return a; else return b[0]; } public static void main(String[] arg) { float d[] = new float[3]; c[0] = d[0]; do a = a + 1; while (!(a > 10)); return ; } } .method public <init>()V .limit stack 1 .limit locals 1 .var 0 is this LCout; from Label0 to Label1 Label0: .line 1 aload_0 invokespecial java/lang/Object/<init>()V Label1: return .end method CSE - HCMUT Code Generation 10 Example –Jasmin (cont’d) public class Cout { static int a,b; static float c[] = new float[3]; static int foo(int a,int b[]) { boolean c; c = b[1] > a; if (c) return a; else return b[0]; } public static void main(String[] arg) { float d[] = new float[3]; c[0] = d[0]; do a = a + 1; while (!(a > 10)); return ; } } .method static foo(I[I)I .var 0 is a I from Label3 to Label4 .var 1 is b [I from Label3 to Label4 .var 2 is c Z from Label7 to Label4 Label3: .line 6 aload_1 iconst_1 iaload iload_0 if_icmple Label0 iconst_1 goto Label1 Label0: iconst_0 Label1: istore_2 Label7: .line 7 iload_2 ifeq Label2 iload_0 ireturn Label2: .line 8 aload_1 iconst_0 iaload Label4: ireturn .limit stack 2 .limit locals 3 .end method [...]... Code Generation 11 Outline • Our Compiler • Translation for a stack-based machine – – – – √ Declarations Expressions Statements Jasmin directives • Translation for a registered-based machine – Register allocation – Instruction selection – Code scheduling CSE - HCMUT Code Generation 12 Code Generation Design Independent-machine Code Generation Frame Intermediate Code Generation Dependent-machine Code Generation. .. Code Generation Frame Intermediate Code Generation Dependent-machine Code Generation CSE - HCMUT Code Generation 13 Dependent-Machine Code Generation • Generating specified machine code – E.g.: emitLDC(20) → “ldc 20” • Implemented in MachineCode.java CSE - HCMUT Code Generation 14 Intermediate Code Generation • Depend on both language and machine • Select instructions emitILOAD(index) emitREADVAR (a)... pop(): simulating a pop execution • getMaxOpStackSize(): return the max size of the operand stack CSE - HCMUT Code Generation 16 Independent-Machine Code Generation • Based on the source language • Use facilities of Frame(.java) and Intermediate Code Generation (Emitter.java) CSE - HCMUT Code Generation 17 Outline • Our Compiler • Translation for a stack-based machine – – – – √ √ Declarations Expressions... machine – Register allocation – Instruction selection – Code scheduling CSE - HCMUT Code Generation 18 Symbol Entries • Token id; • Type type; • int scope; //GLOBAL or LOCAL - the scope where the id is declared • Object object; - the index if id is a local variable - the class name if id is a method name CSE - HCMUT Code Generation 19 Variable Declarations • Global variables field static name type-desc -... /*TODO*/, or Emitter.emitLISTARRAY(), for locals CSE - HCMUT Code Generation 20 Global Procedure Declarations • User Procedures method public static class-name/method-name type-desc end method • How ? – the class name is from BKIT.CLASSNAME – Emitter.emitMETHOD(class-name/methodname, type) – Emitter.emitENDMETHOD() CSE - HCMUT Code Generation 21 Outline • Our Compiler • Translation for a stack-based... Code scheduling CSE - HCMUT Code Generation 22 Expressions • • • • • • Literals Arithmetic expressions Boolean expressions Relational expressions Variables (lvalue and rvalue) Call expressions visitIntLiteralAST,… visitBinExprAST visitVarExprAST, visitEleExpr visitCallExprAST All visit*ExprAST should print out the code and return the type of the expression CSE - HCMUT Code Generation 23 Integer Literals... visitIntLiteralAST in CodeGenerator CSE - HCMUT Code Generation 24 Arithmetic Expressions E → E1 addop T { E.code = E1.code + T.code + iadd isub fadd fsub Emitter.emitADDOP(addop.Lexeme,E.type);} | T {left for you} T → T1 mulop F { T.code = T1.code + F.code + imul idiv fmul fdiv Emitter.emitMULOP(mulop.Lexeme,T.type);} |F CSE - HCMUT {left for you} Code Generation 25 visitBinExprAST class BinExprAST {... emitADDOP(String,Type) => iadd, isub,fadd,fsub emitMULOP(String,Type) => imul,idiv,fmul,fdiv CSE - HCMUT Code Generation 26 Example bipush 8 • 8 * 10 – 12 / 4 bipush 10 BinExprAST e2 e1 iconst_4 idiv e2 e1 CSE - HCMUT bipush 12 BinExprAST – BinExprAST IntLiteralAST imul * IntLiteralAST I… Code Generation / I… isub 27 Boolean Expressions Object visitBinExprAST(ast,…) { … else if (op.kind == Token.ANDOP)... is printed out Code Generation iconst_0 invokestatic Cout/foo()Z iand 28 Short-circuit Evaluation • evaluation order is from left to right • for andop, if left operand is false, the expr is false • for orop, if left operand is true, the expr is true • boolean foo() {putString(“true”); return true;} (false && foo()); Write your own Emitter.emitANDOP( LabelF,LabelO) CSE - HCMUT Code Generation iconst_0... always leaves a value on the top of operand stack CSE - HCMUT Code Generation 31 Variables • a+8 iload_1 ; a bipush 8 class VarExprAST{ Token name; } iadd • visitVarExprAST(ast,…) { SymEntry s=sym.lookup(ast.name.Lexeme); em.printout(em.emitREADVAR(s)); Type t = s.getType(); return t; Tool: } Emitter.emitREADVAR(SymEntry) CSE - HCMUT Code Generation 32 Call Expressions iload_1 • foo(a,b*4) class CallExprAST . scheduling CSE - HCMUT Code Generation 13 Code Generation Design Independent-machine Code Generation Frame Intermediate Code Generation Dependent-machine Code Generation CSE - HCMUT Code Generation 14 Dependent-Machine. Code Generation 17 Independent-Machine Code Generation • Based on the source language • Use facilities of Frame(.java) and Intermediate Code Generation (Emitter.java) CSE - HCMUT Code Generation. 14 Dependent-Machine Code Generation • Generating specified machine code – E.g.: emitLDC(20) → “ldc 20” • Implemented in MachineCode.java CSE - HCMUT Code Generation 15 Intermediate Code Generation • Depend