code generation continued
play

Code Generation, Continued 1 How to be a MIPS Master Its really - PowerPoint PPT Presentation

Code Generation, Continued 1 How to be a MIPS Master Its really easy to get confused with assembly Some suggestions Create super simple test cases Main procedure: print the value of some expression Start simple: main


  1. Code Generation, Continued 1

  2. How to be a MIPS Master • It’s really easy to get confused with assembly • Some suggestions Create super simple test cases • Main procedure: print the value of some expression – Start simple: main procedure with “print(1);” • Create more and more complicated expressions • Get procedure main to compile and run Regression suite • Rerun all test cases to check whether you introduced a bug – Function prologue and epilog • Trivial case of expressions: evaluating the constant 1, which pushes a 1 on the stack • Printing: print(1); – Then grow your compiler incrementally • Expressions • Control constructes • Call/return 2

  3. How to be a MIPS Master • More suggestions – Try writing the desired assembly code by hand before having the compiler generate it – Draw pictures of program flow – Have your compiler put in detailed comments in the assembly code it emits! • Get help – Post on piazza • It’s really easy to get confused with assembly (did I say that already?) 3

  4. Roadmap • Last time: Scanner Scanner – Talked about compiler Tokens Parser Parser backend design points Parse Tree – Decided to go directly from AST AST to machine code for Semantic our language Analysis • This time: Annotated AST Symbol Table – Discuss what the actual MC Codegen codegen pass should look like 4

  5. Review: Global Variables • Showed you one way to do declaration last time: .data .align 2 _name: .space 4 • Simpler form for primitives: .data _name: .word <value> 5

  6. Review: Functions – Preamble • Sort of like the function signature – Prologue • Set up the AR – Body • Do the thing – Epilogue • Tear down the AR 6

  7. Function Preambles int f(int a, int b){ .text int c = a + b; _f: int d = c – 7; #... Function body ... return c; } This label gives us something to jump to jal _f 7

  8. Function Prologue sp space for local 2 • Recall our view of the static space for local 1 sp Activation Record size ctrl link (caller $fp) sp 1. save the return address ret address (caller $ra) 2. save the frame pointer sp fp 3. make space for locals param 1 4. update the frame ptr param 2 low mem caller’s AR fp high mem 8

  9. *sp = ra; Function Prologue: MIPS sp -= 4; *sp = fp; sp -= 4; .text • Recall our view of the _f: sp -= 8; sw $ra 0($sp) #call lnk Activation Record fp = sp + 16; subu $sp $sp 4 # (push) 1. save the return address sw $fp 0($sp) #ctrl lnk subu $sp $sp 4 # (push) 2. save the frame pointer subu $sp $sp 8 #locals 3. make space for locals addu $fp $sp 16 #update fp 4. update the frame ptr 9

  10. Function Epilogue $sp space for local 2 • Restore Caller AR space for local 1 1. restore return address II ctrl link (caller $fp) 2. restore frame pointer ret address (caller $ra) $fp $sp 3. restore stack pointer I 4. return control param 1 param 2 $t0: (old fp) $ra: (old $ra) caller’s AR $fp 10

  11. Function Epilogue: MIPS .text • Restore Caller AR _f: sw $ra 0($sp) 1. restore return address ra = *fp; subu $sp $sp 4 t0 = fp; 2. restore frame pointer sw $fp 0($sp) subu $sp $sp 4 fp = *(fp-4); 3. restore stack pointer subu $sp $sp 8 sp = t0; addu $fp $sp 16 4. return control #... Function body ... lw $ra, 0($fp) move $t0, $fp lw $fp, -4($fp) move $sp, $t0 jr $ra 11

  12. Function Body • Obviously, quite different based on content – Higher-level data constructs • Loading parameters, setting return • Evaluating expressions – Higher-level control constructs • Performing a call • While loops • If-then and if-then-else statements 12

  13. Function Locals sp space for local 2 .text _f: space for local 1 # … prologue … # lw $t0, -8($fp) ctrl link (caller $fp) lw $t1, -12($fp) fp ret address (caller $ra) param 1 # … epilogue … # param 2 caller’s AR 13

  14. Function Returns sp space for local 2 .text _f: space for local 1 # … prologue … # lw $t0, -8($fp) ctrl link (caller $fp) lw $t1, -12($fp) lw $v0, -8($fp) fp ret address (caller $ra) j _f_exit _f_exit: param 1 # … epilogue … # param 2 caller’s AR 14

  15. Function Body: Expressions • Goal – Linearize (“flatten”) an expression tree • Use the same insight as SDT during parsing – Use a work stack and a post-order traversal Visit 1 Visit 2 + Visit id Visit * Visit + 1 * 2 id 15

  16. Linearized Pseudocode • Key insights – Use the stack-pointer location as “scratch space” Push the value of id! – At operands: push value onto the stack – At operators: pop source values from stack, push result $t1 = id push 2 $t0 = 2 2 * id I IV push id pop id into t1 * pop 2 into t0 id mult t0 * t1 into t0 II III 2 push t0 2 id result (2 * id) 16

  17. Linearized MIPS L1: li $t0 2 .data sw $t0 0($sp) _id: .word <value> subu $sp $sp 4 L2: lw $t0 _id .text sw $t0 0($sp) L1: push 2 subu $sp $sp 4 L2: push id L3: lw $t1 4($sp) L3: pop id into t1 addu $sp $sp 4 L4: pop 2 into t0 L4: lw $t0 4($sp) L5: mult t0 * t1 into t0 addu $sp $sp 4 L6: push t0 L5: mult $t0 $t0 $t1 L6: sw $t0 0($sp) subu $sp $sp 4 17

  18. Function Body: Expressions • Goal – Linearize (“flatten”) an expression tree • Use the same insight as SDT during parsing – Use a work stack and a post-order traversal Visit 1 push 1 Visit 2 push 2 Visit id push value of id + Visit * pop id into t1 pop 2 into t0 mult t0 * t1 into t0 push t0 1 * Visit + pop into t1 pop 1 into t0 add t0 + t1 into t0 2 id push t0 18

  19. Assignment Statements • By the end of the expression, the stack isn’t exactly as we found it – Contains the value of the expression – This organization is intentional 1) Compute address of LHS location ; leave result on stack assign 2) Compute value of RHS expr; leave result on stack 3) Pop RHS into $t1 4) Pop LHS into $t0 5) Store value $t1 at the address held in $t0 loc (exp) 19

  20. Simple Assignment, You Try sp • Generate stack-machine id2 style MIPS code for (space for id) id = 1 + 2; ctrl link (caller $fp) fp ret address (caller $ra) param 1 Algorithm 1) Compute address of LHS location ; leave result on stack 2) Compute value of RHS expr; leave result on stack param 2 3) Pop RHS into $t1 4) Pop LHS into $t0 5) Store value $t1 at the address held in $t0 caller’s AR 20

  21. Dot Access • Fortunately, we know the offset from the base of a struct to a certain field statically – The compiler can do the math for the slot address – This isn’t true for languages with pointers! struct Inner{ bool hi; int there; struct Demo inst; int c; struct Demo inst2; }; inst.b.c = inst2.b.c + 1; struct Demo{ load this value struct Inner b; load this address int val; }; 21

  22. Dot Access Example void v(){ sp struct Inner{ inst is based at $fp-8 bool hi; inst.val field b.c is -8 off the base int there; int c; inst.b.c }; struct Demo{ inst.b.there struct Inner b; int val; inst.b.hi }; struct Demo inst; ctrl link (caller $fp) … = inst.b.c; inst.b.c = …; } fp ret address (caller $ra) LHS RHS subu $t0 $fp 16 lw $t0 -16($fp) caller’s AR sw $t0 0($sp) sw $t0 0($sp) subu $sp $sp 4 subu $sp $sp 4 22

  23. Control-Flow Constructs • Function Calls • Loops • Ifs 23

  24. Function Call • Two tasks: – Put argument values on the stack (pass-by-value semantics) – Jump to the callee preamble label – Bonus 3 rd task: save live registers • (We don’t have any in a stack machine) • On return – Tear down the actual parameters – Retrieve and push the result value 24

  25. Function-Call Example int f(int arg1, int arg2){ return 2; } int main(){ int a; a = f( a, 4) ; } li $t0 4 # push arg 2 sw $t0 0($sp) # subu $sp $sp 4 # lw $t0 -8($fp) # push arg 1 sw $t0 0($sp) # subu $sp $sp 4 # jal _f # call f (via jump and link) addu $sp $sp 8 # tear down actual parameters sw $v0 0($sp) # retrieve and push the result subu $sp $sp 4 # 25

  26. Generating If-Then[-Else] Statements • First, obtain names to use for the labels of the – [false branch] – successor • Generate code for the branch condition – Can emit a jump to the (not-yet placed!) false-branch label • Generate code for the true branch – Emit the code for the body of the true branch – [Emit a jump to the (not-yet placed!) successor label] • [Generate code for the false branch (similar to the true branch) – Emit the false-branch label – Emit the code for the body of the false branch] • Emit the successor label 26

  27. If-Then Statement Example … lw $t0 _val # evaluate condition LHS sw $t0 0($sp) # push onto stack if (val == 1){ subu $sp $sp 4 # val = 2; li $t0 1 # evaluate condition RHS } sw $t0 0($sp) # push onto stack … subu $sp $sp 4 # lw $t1 4($sp) # pop RHS into $t1 addu $sp $sp 4 # lw $t0 4($sp) # pop LHS into $t0 addu $sp $sp 4 # bne $t0 $t1 L_0 # branch if condition false li $t0 2 # true branch sw $t0 _val j L_0 # end true branch L_0: # successor label … 27

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend