1 / 27

Code Generation II

Code Generation II. x86 executable. exe. IC Program. ic. IC compiler. Compiler. Lexical Analysis. Syntax Analysis Parsing. AST. Symbol Table etc. Inter. Rep. (IR). Code Generation. x86 assembly. AT&T syntax and Intel syntax We’ll be using AT&T syntax

anitra
Download Presentation

Code Generation II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Code Generation II

  2. x86 executable exe ICProgram ic IC compiler Compiler LexicalAnalysis Syntax Analysis Parsing AST SymbolTableetc. Inter.Rep.(IR) CodeGeneration

  3. x86 assembly • AT&T syntax and Intel syntax • We’ll be using AT&T syntax • Work with GNU Assembler (GAS)

  4. Immediate and register operands • Immediate • Value specified in the instruction itself • Preceded by $ • Example: add $4,%esp • Register • Register name is used • Preceded by % • Example: mov %esp,%ebp

  5. Memory Access • Memory operands • Obtain value at given address • Example: mov (%eax), %ebx • Base displacement • Obtain value at computed address • Syntax: disp(base,index,scale) • address = base + (index * scale) + displacement • Example: mov $42, 2(%eax) • Example: mov $42, (%eax,%ecx,4)

  6. Accessing Variables • Use offset from frame pointer • Examples • %ebp + 8 = first parameter • %eax = %ebp + 8 • (%eax) = the value 572 • 8(%ebp) = the value 572 … … param n … 572 %eax,%ebp+8 Return address Previous ebp ebp local 1 … local n ebp-4 SP

  7. LIR to assembly • Need to know how to translate: • Function bodies • Translation for each kind of LIR instruction • Calling sequences • Correctly access parameters and variables • Compute offsets for parameter and variables • Dispatch tables • String literals • Runtime checks & error handlers

  8. Translating LIR instructions • Translate function bodies: • Compute offsets for: • Local variables & LIR registers (-4,-8,-12,…) • Function parameters (+8,+12,+16,…) • take this parameter into account • Translate instruction list for each function • Local translation for each LIR instruction • local (machine) register allocation

  9. Memory offsets implementation // MethodLayout instance per function declarationclass MethodLayout { // Maps variables/parameters/LIR registers to // offsets relative to frame pointer (EBP) Map<Memory,Integer> memoryToOffset;} PA5 1 virtual function takesone extra parameter: this MethodLayout for foo (manual) LIR translation _A_foo: Move x,R0 Add y,R0 Move R0,z Move this,R1 MoveField R0,R1.1 Library __printi(R0),Rdummy void foo(int x, int y) { int z = x + y; g = z; // g is a field Library.printi(z); } PA4

  10. Memory offsets example 2 Translation to x86 assembly LIR translation _A_foo: push %ebp # prologue mov %esp,%ebp sub $12, %esp mov 12(%ebp),%eax # Move x,R0 mov %eax,-8(%ebp) mov 16(%ebp),%eax # Add y,R0 add -8(%ebp),%eax mov %eax,-8(%ebp) mov -8(%ebp),%eax # Move R0,z mov %eax,-4(%ebp) mov 8(%ebp),%eax # Move this,R1 mov %eax,-12(%ebp) mov -8(%ebp),%eax # MoveField R0,R1.1 mov -12(%ebp),%ebx mov %eax,4(%ebx) mov -8(%ebp),%eax # Library __printi(R0) push %eax call __printi add $4,%esp_A_foo_epilogoue: mov %ebp,%esp # epilogoue pop %ebp ret _A_foo: Move x,R0 Add y,R0 Move R0,z Move this,R1 MoveField R0,R1.1 Library __printi(R0),Rdummy MethodLayout for foo

  11. Translating instructions

  12. Translating instructions

  13. Call sequences FP Push caller-save registers Push actual parameters (in reverse order) … … caller Caller push code SP Reg 1 … Reg n push return address Jump to call address call SP Push current base-pointer bp = sp Push local variables Push callee-save registers Param n … param1 Callee push code (prologue) callee SP Return address Callee pop code (epilogue) Pop callee-save registers Pop callee activation record Pop old base-pointer SP Previous fp SP Local 1 Local 2 … … Local n return FP pop return address Jump to address Copy returned value Caller pop code SP caller Pop parametersPop caller-save registers

  14. Translating static calls StaticCall _A_foo(a=R1,b=5,c=x),R3 LIR code: # push caller-saved registerspush %eaxpush %ecxpush %edx Only if return register is notRdummy # push parametersmov -4(%ebp),%eax # push xpush %eaxpush $5 # push 5mov -8(%ebp),%eax # push R1push %eax only if the value stored in these registers is needed by the callerh only if the value stored in these registers is needed by the caller call _A_foo mov %eax,-16(%ebp) # store returned value in R3 # pop parameters (3 params*4 bytes = 12)add $12,%esp # pop caller-saved registerspop %edxpop %ecxpop %eax

  15. Virtual functions • Indirect call: call *(Reg) • Example: call *(%eax) • Used for virtual function calls • Dispatch table lookup • Passing/receiving the this variable

  16. Translating virtual calls VirtualCall R1.2(b=5,c=x),R3 LIR code: # push caller-saved registerspush %eaxpush %ecxpush %edx R1 DVPtr # push parametersmov -4(%ebp),%eax # push xpush %eaxpush $5 # push 5 x y # Find address of virtual method and call itmov -8(%ebp),%eax # load thispush %eax # push thismov 0(%eax),%eax # Load dispatch table addresscall *8(%eax) # Call table entry 2 (2*4=8) mov %eax,-12(%ebp) # store returned value in R3 _DV_A # pop parameters (2 params+this * 4 bytes = 12)add $12,%esp # pop caller-saved registerspop %edxpop %ecxpop %eax

  17. Function prologue/epilogue _A_foo:# prologuepush %ebpmov %esp,%ebp # push local variables of foosub $12,%esp # 3 local vars+regs * 4 = 12 # push local variables of foosub $12,%esp # 3 local vars+regs * 4 = 12 # push callee-saved registerspush %ebxpush %esipush %edi Optional: only ifregister allocation optimization is used (in PA5) only if the these registers will be modified by the collee function body _A_foo_epilogoue: # extra label for each function # pop callee-saved registerspop %edipop %esipop %ebx mov %ebp,%esppop %ebpret

  18. Representing dispatch tables file.lir PA4 _DV_A: [_A_sleep,_A_rise,_A_shine]_DV_B: [_A_sleep,_B_rise,_B_shine,_B_twinkle] file.ic PA5 class A { void sleep() {…} void rise() {…} void shine() {…} static void foo() {…}}class B extends A { void rise() {…} void shine() {…} void twinkle() {…}} file.s # data section.data .align 4_DV_A: .long _A_sleep .long _A_rise .long _A_shine_DV_B: .long _A_sleep .long _B_rise .long _B_shine .long _B_twinkle

  19. Runtime checks • Insert code to check attempt to perform illegal operations • Null pointer check • MoveField, MoveArray, ArrayLength, VirtualCall • Reference arguments to library functions should not be null • Array bounds check • Array allocation size check • Division by zero • If check fails jump to error handler code that prints a message and gracefully exists program

  20. Null pointer check # null pointer check cmp $0,%eax je labelNPE Single generated handler for entire program labelNPE: push $strNPE # error message call __println push $1 # error code call __exit

  21. Array bounds check # array bounds check mov -4(%eax),%ebx # ebx = length mov $0,%ecx # ecx = index cmp %ecx,%ebx jle labelABE # ebx <= ecx ? cmp $0,%ecx jl labelABE # ecx < 0 ? Single generated handler for entire program labelABE: push $strABE # error message call __println push $1 # error code call __exit

  22. Array allocation size check # array size check cmp $0,%eax # eax == array size jle labelASE # eax <= 0 ? Single generated handler for entire program labelASE: push $strASE # error message call __println push $1 # error code call __exit

  23. Division by zero check # division by zero check cmp $0,%eax # eax is divisor je labelDBE # eax == 0 ? Single generated handler for entire program labelDBE: push $strDBE # error message call __println push $1 # error code call __exit

  24. Hello world example class Library { void println(string s); } class Hello { static void main(string[] args) { Library.println("Hello world!"); } }

  25. Assembly file structure .title "hello.ic“# global declarations.global __ic_main # data section.data.align 4.int 13str1: .string "Hello world\n“# text (code) section.text#----------------------------------------------------.align 4__ic_main: push %ebp # prologue mov %esp,%ebp push $str1 # print(...) call __print add $4, %esp mov $0,%eax # return 0 mov %ebp,%esp # epilogue pop %ebp ret header symbol exported to linker statically-allocateddata: string literalsand dispatch tables string lengthin bytes comment Method bodiesand error handlers

  26. Assembly file structure .title "hello.ic“# global declarations.global __ic_main # data section.data.align 4.int 13str1: .string "Hello world\n“# text (code) section.text#----------------------------------------------------.align 4__ic_main: push %ebp # prologue mov %esp,%ebp push $str1 # print(...) call __print add $4, %esp mov $0,%eax # return 0 mov %ebp,%esp # epilogue pop %ebp ret prologue – save ebp and set to be esp push print parameter pop parameter call print store return value of main in eax epilogue – restore esp and ebp (pop)

  27. ICProgram prog.ic x86 assembly x86 assembly prog.s prog.s From assembly to executable LexicalAnalysis Syntax Analysis Parsing AST SymbolTableetc. Inter.Rep.(IR) CodeGeneration GNU assembler prog.o GNUlinker prog.exe libic.a(libic + gc)

More Related