source: liacs/coco/assignment4/DOCUMENTATION.txt@ 49

Last change on this file since 49 was 2, checked in by Rick van der Zwet, 15 years ago

Initial import of data of old repository ('data') worth keeping (e.g. tracking
means of URL access statistics)

File size: 8.7 KB
RevLine 
[2]1= INTRODUCTION =
2
3Welcome reader,
4
5You will find our solution on assignment 4 of Compiler Constructions 2008
6given at LIACS University. First we will give you a grand overview of the files
7altered, next we will bullet point the most important design decisions. After that
8an example is shown.
9
10And the grand finale will show the usage of the program.
11
12Enjoy!
13Johan and Rick <hvdzwet@liacs.nl>
14
15= FILES EDITED/ADDED =
16A globals.h = Some global definitions
17A MOperand.cc = Represents a operand for a MIPS statement
18A MOperator.cc = Represents a MIPS operator/opcode
19A MStatement.cc = Represents MIPS statements
20E StackFrameManager.cc = Manages the stack frame
21A RegisterManager.cc
22E CodeGenerator.cc
23E main.cc = Main program function, argument parsing
24
25= DESIGN DECISIONS =
26* Added a register manager to keep track of what symbols are associated with what
27 registers. The register manager also loads the register if it's new and writes
28 it back to memory.
29
30* The current implementation for spilling a register is to select a random one. Also
31 all registers are written back before a function call, before the end of a
32 function and before jumps and branches. This can be optimized in the next assignment.
33
34* We prefix all the symbol names with "__" to prevent name clashes with MIPS
35 assembly instructions.
36
37* Register $V0 is used for integer function return values and $f0 for real
38 return values.
39
40* Register $V1 is used for expressions
41
42* Registers $A0, $A1, $A2 and $A3 do not have to be gotten through the RegisterManager
43 and can thus be used as temporaries inside a known code block while generating code.
44
45* The stack pointer $sp points to the last used word on the stack. We generate code
46 that assumes it's pointing to the first free word. Therefore the stack is increased
47 by one word in main before calling the program body.
48
49* The stack frame layout is as follows:
50 ^ ^
51 | |
52 $fp + 8 second parameter
53 $fp + 4 first parameter
54 $fp + 0 return address
55 $fp - 4 previous frame pointer
56 $fp - 8 return value
57 $fp - 12 first local variable
58 $fp - 16 second local variable
59 | |
60 v v
61
62* We created a framework for Assembly code, model-ed after the intermediate code
63 framework. This was done to separate the generation of the output file from
64 generation of the code. It can also later be used to implement further
65 optimizations on the MIPS assembly code.
66
67= SAMPLE GENERATED CODE =
68C01) program example;
69C02)
70C03) var x, y, z: integer;
71C04) function foo(a,b: integer): integer;
72C05) begin
73C06) foo := 1
74C07) end;
75C08)
76C09) begin
77C10) x := readinteger;
78C11) y := 20;
79C12) z := x + 20;
80C13) z := z + foo(0,0)
81C14) end.
82
83 1 ## Output generated by ./comp @ kubuntu-desktop
84 2 ## Thu Nov 20 14:30:48 2008
85 3
86 4 ## Compiler Construction Course - Leiden University - LIACS
87 5 ## Johan IJsveld - Rick van der Zwet
88 6 ## BSD Licenced
89 7
90 8 .data # Global data section
91 9 .align 4
92 10 __x:
93 11 .word 0
94 12 __y:
95 13 .word 0
96 14 __z:
97 15 .word 0
98 16
99 17 .text # Code section
100 18 .align 4
101 19 .globl main
102 20
103 21 .ent main
104 22 main:
105 23 addi $sp, $sp, -4
106 24 jal __example # Jump to program body
107 25 addi $sp, $sp, 4
108 26 addi $v0, $0, 10 # Exit system call
109 27 syscall
110 28 .end main
111 29
112 30 .ent __example
113 31 __example:
114 32 sw $ra, 0($sp) # Set up stack frame
115 33 sw $fp, -4($sp)
116 34 move $fp, $sp
117 35 addi $sp, $sp, -28
118 36 jal __readinteger
119 37 lw $t0, -12($fp) # Load integer Register
120 38 move $t0, $v0 # Store integer function result
121 39 lw $t1, __x # Load integer Register
122 40 move $t1, $t0 # Assign integer
123 41 lw $t2, __y # Load integer Register
124 42 addi $t2, $0, 20 # Assign constant integer
125 43 lw $t3, -16($fp) # Load integer Register
126 44 addi $a0, $0, 20
127 45 add $t3, $t1, $a0 # Add integers
128 46 lw $t4, __z # Load integer Register
129 47 move $t4, $t3 # Assign integer
130 48 addi $v1, $0, 0 # Push constant integer parameter
131 49 sw $v1, 0($sp)
132 50 addi $sp, $sp, -4
133 51 addi $v1, $0, 0 # Push constant integer parameter
134 52 sw $v1, 0($sp)
135 53 addi $sp, $sp, -4
136 54 sw $t0, -12($fp) # Write back integer register
137 55 sw $t1, __x # Write back integer register
138 56 sw $t2, __y # Write back integer register
139 57 sw $t3, -16($fp) # Write back integer register
140 58 sw $t4, __z # Write back integer register
141 59 jal __foo
142 60 lw $t0, -20($fp) # Load integer Register
143 61 move $t0, $v0 # Store integer function result
144 62 lw $t1, -24($fp) # Load integer Register
145 63 lw $t2, __z # Load integer Register
146 64 add $t1, $t2, $t0 # Add integers
147 65 move $t2, $t1 # Assign integer
148 66 sw $t0, -20($fp) # Write back integer register
149 67 sw $t1, -24($fp) # Write back integer register
150 68 sw $t2, __z # Write back integer register
151 69 lw $ra, 0($fp) # Return from call
152 70 lw $fp, -4($fp)
153 71 addi $sp, $sp, 28
154 72 jr $ra
155 73 .end __example
156 74
157 75 .ent __foo
158 76 __foo:
159 77 sw $ra, 0($sp) # Set up stack frame
160 78 sw $fp, -4($sp)
161 79 move $fp, $sp
162 80 addi $sp, $sp, -12
163 81 lw $t0, -8($fp) # Load integer Register
164 82 addi $t0, $0, 1 # Assign constant integer
165 83 sw $t0, -8($fp) # Write back integer register
166 84 lw $t0, -8($fp) # Load integer Register
167 85 move $v0, $t0 # Store integer return value
168 86 lw $ra, 0($fp) # Return from call
169 87 lw $fp, -4($fp)
170 88 addi $sp, $sp, 20
171 89 jr $ra
172 90 .end __foo
173 91
174 92 .ent __readinteger # Start of builtin functions and procedures
175 93 __readinteger:
176 94 addi $v0, $0, 5
177 95 syscall
178 96 jr $ra
179 97 .end __readinteger
180 98
181 99 .ent __writeinteger
182 100 __writeinteger:
183 101 lw $a0, 4($sp)
184 102 addi $v0, $0, 1
185 103 syscall
186 104 addi $sp, $sp, 4
187 105 jr $ra
188 106 .end __writeinteger
189 107
190 108 .ent __readreal
191 109 __readreal:
192 110 addi $v0, $0, 6
193 111 syscall
194 112 jr $ra
195 113 .end __readreal
196 114
197 115 .ent __writereal
198 116 __writereal:
199 117 l.s $f12, 4($sp)
200 118 addi $v0, $0, 2
201 119 syscall
202 120 addi $sp, $sp, 4
203 121 jr $ra
204 122 .end __writereal
205 123
206
207Lines 8 through 16 shows the space for globals being reserved.
208Lines 21 through 28 is the main function calling the program body and doing a syscall to exit.
209Lines 30 through 73 is the program body code.
210Lines 75 through 90 is the function foo, where on lines 77 through 80 the stack
211frame is set up. In lines 81 through 85 the return value 1 is stored on the stack
212and then put in the return register $v0.
213On line 86 and line 87, $ra and the old $fp are restored. The stack is shrunk back again,
214including parameters, on line 88 and on line 89 is the jump back from where the call was made.
215After line 92 are the builtin functions.
216
217= USAGE =
218# Compile
219$ make first
220$ make
221# Call without optimalisation
222$ ./comp -w -00 <testfile
223# Call with optimalisation
224$ ./comp -w -01 <testfile
225The resultant MIPS assembly is stored in the file "out.s".
Note: See TracBrowser for help on using the repository browser.