procedures: code generation

21
Procedures: Code Generation COP 3402 Software Systems Summer 2014

Upload: joy

Post on 22-Feb-2016

42 views

Category:

Documents


0 download

DESCRIPTION

Procedures: Code Generation. COP 3402 Software Systems Summer 2014. Procedures: PM/0 code look. In general, when a procedure is compiled, the machine code looks like this:. 00 jmp 0 0 6 01 jmp 0 0 2 02 inc 0 0 5 03 lit 0 0 2 04 sto 0 0 5 05 opr 0 0 0 06 inc 0 0 4 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Procedures: Code Generation

Procedures: Code Generation

COP 3402 Software SystemsSummer 2014

Page 2: Procedures: Code Generation

Procedures: PM/0 code look• In general, when a procedure is compiled, the

machine code looks like this:

procedure A; var y;begin y:= 2;end;call A.

00 jmp 0 0 6 01 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 006 inc 0 0 407 cal 0 0 208 rtn 0 0 0

This code corresponds to the “program” block.

Page 3: Procedures: Code Generation

Procedures: PM/0 code look

00 jmp 0 0 6 01 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 006 inc 0 0 407 cal 0 0 208 rtn 0 0 0

First comes a ‘jump’ to the actual procedure code.

Later comes the code for the procedure.

Finally, we return from the call.

Then we reserve space for the AR and variables.

Page 4: Procedures: Code Generation

Procedures: PM/0 code look

First comes a ‘jump’ to the actual procedure code.

Later comes the code for the procedure.

Finally, we return from the call.

Then we reserve space for the AR and variables.

• How do I know the address for the first jump?

00 jmp 0 0 6 01 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 006 inc 0 0 407 cal 0 0 208 rtn 0 0 0

Page 5: Procedures: Code Generation

Step 1: The “jump” operation• When we have nested

procedures, we don’t know where to jump at the time we have to generate the jump operation.

• We must remember where the jump is in order to replace the correct address later.

00 jmp 0 0 ??

jmpCodeAddr = 00

Page 6: Procedures: Code Generation

Step 1: The “jump” operation• When we have nested

procedures, we don’t know where to jump at the time we have to generate the jump operation.

• We must remember where the jump is in order to replace the correct address later.

00 jmp 0 0 ??01 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 0

jmpCodeAddr = 00

Page 7: Procedures: Code Generation

Step 1: The “jump” operation• When we have nested

procedures, we don’t know where to jump at the time we have to generate the jump operation.

• We must remember where the jump is in order to replace the correct address later.

00 jmp 0 0 601 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 0…

jmpCodeAddr = 00

Page 8: Procedures: Code Generation

Step 1: The “jump” operation• When we have nested

procedures, we don’t know where to jump at the time we have to generate the jump operation.

• We must remember where the jump is in order to replace the correct address later.

00 jmp 0 0 601 jmp 0 0 202 inc 0 0 503 lit 0 0 204 sto 0 0 5 05 opr 0 0 0 06 inc 0 0 4…

jmpCodeAddr = 00

Page 9: Procedures: Code Generation

Step 1: The “jump” operation• When we parse the procedure declaration, we

inserted it’s name into the Symbol Table, but we didn’t know it’s address.– procedure MyProc;

• Once we know the address where the procedure code starts, we must:– Update the jump operation.– Update the procedure address in the symbol table.

Page 10: Procedures: Code Generation

Step 2: Reserve space• A procedure must reserve space for it’s activation

record and variables, before its actual code starts.• We must keep track of how much space we should

reserve. It should be 4 at least (for the AR), and must increase for each declared variable.

• Be careful: each procedure must keep track of their own space, don’t use a global variable.

• To reserve space, we generate a “inc” operation.– gen(INC, 0, 0, SPACE);

Page 11: Procedures: Code Generation

Step 3: Procedure code generation• Now we can generate code for the procedure.

• This will be handle by the “statement” function.

Page 12: Procedures: Code Generation

Step 4: The return call• This one is simple: just generate a return

operation (rtn 0 0 0).

Page 13: Procedures: Code Generation

Code Generation for Procedure• Step 1: Generate a jump operation.

– Store the address of this jump.– Keep parsing/generating code.– Update the jump address.– Update the procedure address in the Symbol Table.

• Step 2: Reserve Space• Step 3: Generate the procedure code (parse the

statements).• Step 4: Generate a return operation.

Page 14: Procedures: Code Generation

Who will handle all this?• The code generation for a procedure is handle

by the block function.– <proc-decl> ::= procedure <ident> ; <block> ; | e– <program> ::= <block> .– <block> ::= <const-decl> <var-decl> <proc-decl> <statement>

Page 15: Procedures: Code Generation

<block> Parser Procedure

procedure BLOCK();begin

if TOKEN = “const” then CONST-DECL();if TOKEN = “var” then VAR-DECL();if TOKEN = “procedure” then PROC-DECL();STATEMENT();

end;

<block> ::= <const-decl> <var-decl> <proc-decl> <statement>

Page 16: Procedures: Code Generation

<block> Parser and Code Generation

procedure BLOCK();begin

space = 4;jmpaddr = gen(JMP, 0, 0, 0); // Step 1if TOKEN = “const” then CONST-DECL();if TOKEN = “var” then space += VAR-DECL();if TOKEN = “procedure” then PROC-DECL();code[jmpaddr].m = NEXT_CODE_ADDR;gen(INC, 0, 0, space); // Step 2STATEMENT(); // Step 3gen(RTN, 0, 0, 0); // Step 4

end;

Page 17: Procedures: Code Generation

call Code Generation• At this point, we already know the procedure

address, so the call code is easy to generate.

procedure STATEMENT;begin

…else if TOKEN = "call" then begin

GET_TOKEN();if TOKEN <> IDENT then ERROR (missing identifier);GET_TOKEN();

end…

Page 18: Procedures: Code Generation

call Code Generation• At this point, we already know the procedure

address, so the call code is easy to generate. procedure STATEMENT;begin

…else if TOKEN = "call" then begin

GET_TOKEN();if TOKEN <> IDENT then ERROR (missing identifier);i = find(TOKEN);if i == 0 then ERROR (Undeclared identifier);

if symboltype(i) == PROCEDURE then gen(CAL, 0, 0, symboladdr(i));else ERROR(call must be followed by a procedure identifier);GET_TOKEN();

end…

Page 19: Procedures: Code Generation

Keep track of lexicographical level• We need to set the correct lexicographical

each time we generate a LOD or STO operation.

• One way is to keep track of the current lexicographical level in a global variable.

• The lexicographical level increases when we enter the BLOCK procedure, and decreases when we exit it.

Page 20: Procedures: Code Generation

<block> Parser and Code Generation

procedure BLOCK();begin

current_level++;space = 4;jmpaddr = gen(JMP, 0, 0, 0); if TOKEN = “const” then CONST-DECL();if TOKEN = “var” then space += VAR-DECL();if TOKEN = “procedure” then PROC-DECL();code[jmpaddr].addr = NEXT_CODE_ADDR;gen(INC, 0, 0, space); STATEMENT(); gen(RTN, 0, 0, 0); current_level--;

end;

Page 21: Procedures: Code Generation

Keep track of lexicographical level• To generate a LOD or STO, the correct

lexicographical level is given by:current_level – var_level

• For example:procedure A; var y;

procedure B; var x; begin x = y; end;begin y:= 2;end;call A.

y_level = 1

x_level = 2

curr_level = 2

LOD reg curr_level-y_level y_addrSTO reg curr_level-x_level x_addr

LOD reg 2-1 5STO reg 2-2 5

LOD reg 1 5STO reg 0 5