Mercurial > repos > tabletprog
annotate modules/il.tp @ 251:2557ce4e671f
Fix a couple of compiler bugs. topenv was getting initialized in multiple places. This resulted in multiple copies of modules getting created which caused problems for macro expansion. Additionally, arguments were not being marked as declared during code generation so assigning to an argument that was not closed over generated invalid C code.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 11 Apr 2014 22:29:32 -0700 |
parents | 56b2100d9fff |
children | 2308336790d4 |
rev | line source |
---|---|
185 | 1 { |
2 //commutative ops | |
3 _add <- 0 | |
4 _and <- 1 | |
5 _or <- 2 | |
6 _xor <- 3 | |
7 //non-commutative ops | |
8 _sub <- 4 | |
9 _cmp <- 5 | |
10 _not <- 6 | |
11 _sl <- 7 | |
12 _asr <- 8 | |
13 _lsr <- 9 | |
14 _rol <- 10 | |
15 _ror <- 11 | |
16 _mov <- 12 | |
17 _call <- 13 | |
18 _ret <- 14 | |
19 _skipif <- 15 | |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
20 _save <- 16 |
185 | 21 |
22 _names <- #[ | |
23 "add" | |
24 "and" | |
25 "or" | |
26 "xor" | |
27 "sub" | |
28 "cmp" | |
29 "not" | |
30 "sl" | |
31 "asr" | |
32 "lsr" | |
33 "rol" | |
34 "ror" | |
35 "mov" | |
36 "call" | |
37 "ret" | |
38 "skipIf" | |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
39 "save" |
185 | 40 ] |
41 | |
42 op3:a:b:out:size <- :_opcode :_ina :_inb :_out :_size { | |
43 #{ | |
44 opcode <- { _opcode } | |
45 ina <- { _ina } | |
46 inb <- { _inb } | |
47 commutative? <- { _opcode < _sub } | |
48 out <- { _out } | |
49 size <- { _size } | |
50 numops <- { 3 } | |
51 name <- { _names get: _opcode } | |
52 string <- { name . " " . (string: _ina) . " " . (string: _inb) . " " . (string: _out) . " " . (string: _size) } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
53 recordUsage:at <- :tracker :address { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
54 if: (not: (_ina isInteger?)) { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
55 _ina recordUsage: tracker at: 0 | address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
56 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
57 _inb recordUsage: tracker at: 0 | address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
58 _out recordUsage: tracker at: 1 | address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
59 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
60 assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
61 newa <- if: (not: (_ina isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
62 _ina assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
63 } else: { _ina } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
64 newb <- _inb assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
65 newout <- _out assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
66 op3: _opcode a: newa b: newb out: newout size: _size |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
67 } |
185 | 68 } |
69 } | |
70 op2:in:out:size <- :_opcode :_in :_out :_size { | |
71 #{ | |
72 opcode <- { _opcode } | |
73 in <- { _in } | |
74 out <- { _out } | |
75 size <- { _size } | |
76 numops <- { 2 } | |
77 name <- { _names get: _opcode } | |
78 string <- { name . " " . (string: _in) . " " . (string: _out) . " " . (string: _size) } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
79 recordUsage:at <- :tracker :address { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
80 if: (not: (_in isInteger?)) { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
81 _in recordUsage: tracker at: 0 | address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
82 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
83 _out recordUsage: tracker at: 1 | address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
84 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
85 assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
86 newin <- if: (not: (_in isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
87 _in assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
88 } else: { _in } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
89 newout <- _out assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
90 op2: _opcode in: newin out: newout size: _size |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
91 } |
185 | 92 } |
93 } | |
94 op1:arg:size <- :_opcode :_arg :_size { | |
95 #{ | |
96 opcode <- { _opcode } | |
97 arg <- { _arg } | |
98 size <- { _size } | |
99 numops <- { 1 } | |
100 name <- { _names get: _opcode } | |
101 string <- { name . " " . (string: _arg) . " " . (string: _size) } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
102 recordUsage:at <- :tracker :address { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
103 if: (not: (_arg isInteger?)) { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
104 _arg recordUsage: tracker at: address withSize: _size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
105 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
106 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
107 assignRegs:at:withSource:andUsage <- :assignments :at :regSrc :usage { |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
108 newarg <- if: (not: (_arg isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
109 _arg assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
110 } else: { _arg } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
111 op1: _opcode arg: newarg size: _size |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
112 } |
185 | 113 } |
114 } | |
115 | |
116 _sizenames <- #["b" "w" "l" "q"] | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
117 _size <- :_bytes { |
185 | 118 #{ |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
119 bytes <- { _bytes } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
120 string <- { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
121 idx <- if: _bytes = 8 { 3 } else: { _bytes / 2} |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
122 _sizenames get: idx |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
123 } |
185 | 124 = <- :other { |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
125 _bytes = (other bytes) |
185 | 126 } |
127 <= <- :other { | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
128 _bytes <= (other bytes) |
185 | 129 } |
130 >= <- :other { | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
131 _bytes >= (other bytes) |
185 | 132 } |
133 > <- :other { | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
134 _bytes > (other bytes) |
185 | 135 } |
136 < <- :other { | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
137 _bytes < (other bytes) |
185 | 138 } |
139 } | |
140 } | |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
141 byte <- _size: 1 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
142 word <- _size: 2 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
143 long <- _size: 4 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
144 quad <- _size: 8 |
185 | 145 |
146 _retr <- #{ | |
147 isInteger? <- { false } | |
148 register? <- { true } | |
149 argument? <- { false } | |
150 return? <- { true } | |
151 string <- { "retr" } | |
152 = <- :other { | |
153 (not: (other isInteger?)) && (other register?) && (other return?) | |
154 } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
155 != <- :other { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
156 not: self = other |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
157 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
158 recordUsage:at:withSize <- :tracker :address :size { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
159 //TODO: Figure out what tracking is necessary here |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
160 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
161 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
162 regSrc allocRet |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
163 } |
185 | 164 } |
165 | |
166 _condnames <- #[ | |
167 "eq" | |
168 "neq" | |
169 "ge" | |
170 "le" | |
171 "gr" | |
172 "ls" | |
173 "uge" | |
174 "ule" | |
175 "ugr" | |
176 "uls" | |
177 ] | |
178 condition <- :num { | |
179 #{ | |
180 cc <- { num } | |
181 string <- { _condnames get: num } | |
182 = <- :other { num = (other cc) } | |
183 } | |
184 } | |
185 _eq <- condition: 0 | |
186 _neq <- condition: 1 | |
187 _ge <- condition: 2 | |
188 _le <- condition: 3 | |
189 _gr <- condition: 4 | |
190 _ls <- condition: 5 | |
191 _uge <- condition: 6 | |
192 _ule <- condition: 7 | |
193 _ugr <- condition: 8 | |
194 _uls <- condition: 9 | |
195 | |
196 #{ | |
197 b <- { byte } | |
198 w <- { word } | |
199 l <- { long } | |
200 q <- { quad } | |
201 | |
202 eq <- { _eq } | |
203 neq <- { _neq } | |
204 | |
205 //signed conditions | |
206 ge <- { _ge } | |
207 le <- { _le } | |
208 gr <- { _gr } | |
209 ls <- { _ls } | |
210 | |
211 //unsigned conditions | |
212 uge <- { _uge } | |
213 ule <- { _ule } | |
214 ugr <- { _ugr } | |
215 uls <- { _uls } | |
216 | |
217 | |
218 reg <- :num { | |
219 #{ | |
220 isInteger? <- { false } | |
221 register? <- { true } | |
222 argument? <- { false } | |
223 return? <- { false } | |
224 regnum <- { num } | |
225 string <- { "r" . (string: num) } | |
226 = <- :other { | |
227 (not: (other isInteger?)) && (other register?) && (not: (other argument?)) && (not: (other return?)) && num = (other regnum) | |
228 } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
229 != <- :other { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
230 not: self = other |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
231 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
232 recordUsage:at:withSize <- :tracker :address :size { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
233 tracker reg: self usedAt: address withSize: size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
234 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
235 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
236 assignments get: self |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
237 } |
185 | 238 } |
239 } | |
240 arg <- :num { | |
241 #{ | |
242 isInteger? <- { false } | |
243 register? <- { true } | |
244 argument? <- { true } | |
245 return? <- { false } | |
246 argnum <- { num } | |
247 string <- { "a" . (string: num) } | |
248 = <- :other { | |
249 (not: (other isInteger?)) && (other register?) && (other argument?) && num = (other regnum) | |
250 } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
251 != <- :other { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
252 not: self = other |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
253 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
254 recordUsage:at:withSize <- :tracker :address :size { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
255 tracker arg: self usedAt: address withSize: size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
256 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
257 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
258 regSrc allocArg: num |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
259 } |
185 | 260 } |
261 } | |
262 retr <- { _retr } | |
263 | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
264 base:offset <- :_base :_offset { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
265 #{ |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
266 base <- { _base } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
267 offset <- { _offset } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
268 string <- { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
269 start <- if: _offset = 0 { "" } else: { (string: _offset) } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
270 start . "[" . (string: _base) . "]" |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
271 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
272 recordUsage:at:withSize <- :tracker :address :size { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
273 _base recordUsage: tracker at: address withSize: size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
274 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
275 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
276 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
277 |
185 | 278 add <- :ina inb out size { |
279 op3: _add a: ina b: inb out: out size: size | |
280 } | |
281 | |
282 sub <- :ina inb out size { | |
283 op3: _sub a: ina b: inb out: out size: size | |
284 } | |
285 | |
286 cmp <- :ina inb out size { | |
287 op3: _cmp a: ina b: inb out: out size: size | |
288 } | |
289 | |
290 and <- :ina inb out size { | |
291 op3: _and a: ina b: inb out: out size: size | |
292 } | |
293 | |
294 or <- :ina inb out size { | |
295 op3: _or a: ina b: inb out: out size: size | |
296 } | |
297 | |
298 xor <- :ina inb out size { | |
299 op3: _xor a: ina b: inb out: out size: size | |
300 } | |
301 | |
302 bnot <- :in out size { | |
303 op2: _not in: in out: out size: size | |
304 } | |
305 | |
306 sl <- :shift in out size { | |
307 op3: _sl a: shift b: in out: out size: size | |
308 } | |
309 | |
310 asr <- :shift in out size { | |
311 op3: _asr a: shift b: in out: out size: size | |
312 } | |
313 | |
314 lsr <- :shift in out size { | |
315 op3: _lsr a: shift b: in out: out size: size | |
316 } | |
317 | |
318 rol <- :rot in out size { | |
319 op3: _rol a: rot b: in out: out size: size | |
320 } | |
321 | |
322 ror <- :rot in out size { | |
323 op3: _ror a: rot b: in out: out size: size | |
324 } | |
325 | |
326 mov <- :in out size { | |
327 op2: _mov in: in out: out size: size | |
328 } | |
329 | |
330 call:withArgs <- :_target :_args { | |
331 #{ | |
332 opcode <- { _call } | |
333 target <- { _target } | |
334 args <- { _args } | |
335 numops <- { 0 } | |
336 name <- { _names get: _call } | |
337 string <- { | |
338 argstr <- _args map: :el { | |
339 string: el | |
340 } | |
341 name . " " . (string: _target) . " " . (argstr join: " ") | |
342 } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
343 recordUsage:at <- :tracker :address { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
344 if: (not: (_target isString?)) { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
345 //TODO: use size l for 32-bit targets or an abstract pointer size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
346 _target recordUsage: tracker at: address withSize: q |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
347 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
348 foreach: _args :_ arg { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
349 //TODO: have some mechanism for properly expressing sizes of arguments |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
350 arg recordUsage: tracker at: address withSize: q |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
351 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
352 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
353 assignRegs:at:withSource:andUsage <- :assignments :address :regSrc :usage { |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
354 newtarget <- if: (_target isString?) { _target } else: { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
355 _target assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
356 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
357 newargs <- _args map: :arg { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
358 if: (arg isInteger?) { arg } else: { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
359 arg assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
360 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
361 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
362 newcall <- call: newtarget withArgs: newargs |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
363 regSrc returnAll |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
364 raddress <- address reverse |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
365 foreach: (usage liveArgsAt: raddress) :_ arg { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
366 regSrc allocArg: (arg num) |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
367 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
368 foreach: (usage liveRegsAt: raddress) :_ reg { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
369 regSrc allocSpecific: (assignments get: reg) |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
370 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
371 tosave <- regSrc needSaveForCall |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
372 if: (tosave length) > 0 { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
373 save: tosave #[newcall] |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
374 } else: { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
375 newcall |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
376 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
377 } |
185 | 378 } |
379 } | |
380 | |
381 return <- :val size { | |
382 op1: _ret arg: val size: size | |
383 } | |
384 skipIf <- :_cond _toskip { | |
385 #{ | |
386 opcode <- { _skipif } | |
387 toskip <- { _toskip } | |
388 cond <- { _cond } | |
389 numops <- { 0 } | |
390 name <- { _names get: _skipif } | |
391 string <- { | |
392 block <- (_toskip map: :el { string: el }) join: "\n\t" | |
393 if: (_toskip length) > 0 { | |
394 block <- "\n\t" . block . "\n" | |
395 } | |
396 name . " " . (string: _cond) . " {" . block . "}" | |
397 } | |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
398 recordUsage:at <- :tracker :address { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
399 foreach: _toskip :idx inst { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
400 inst recordUsage: tracker at: idx | address |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
401 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
402 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
403 assignRegs:at:withSource:andUsage <- :assignments :address :regSrc :usage { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
404 newskip <- #[] |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
405 foreach: _toskip :idx inst { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
406 newskip append: (inst assignRegs: assignments at: idx | address withSource: regSrc andUsage: usage) |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
407 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
408 skipIf: _cond newskip |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
409 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
410 to2OpInst <- { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
411 skipIf: _cond (to2Op: _toskip) |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
412 } |
185 | 413 } |
414 } | |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
415 save <- :regs :_scope{ |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
416 #{ |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
417 opcode <- { _save } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
418 numops <- { 0 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
419 name <- { _names get: _save } |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
420 tosave <- { regs } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
421 scope <- { _scope } |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
422 string <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
423 block <- _scope join: "\n\t" |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
424 if: (_scope length) > 0 { |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
425 block <- "\n\t" . block . "\n" |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
426 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
427 name . " " . (regs join: " ") . " {" . block . "}" |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
428 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
429 to2OpInst <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
430 save: regs (to2Op: _scope) |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
431 } |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
432 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
433 } |
185 | 434 |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
435 allocRegs:withSource <- :instarr:regSrc { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
436 _regMap <- dict linear |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
437 _argMap <- dict linear |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
438 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
439 _usageTracker <- :_firstUsage { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
440 #{ |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
441 firstUsage <- _firstUsage |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
442 lastUsage <- _firstUsage |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
443 useCount <- 0 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
444 maxSize <- byte |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
445 usedAt:withSize <- :address :size { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
446 useCount <- useCount + 1 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
447 lastUsage <- address |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
448 if: size > maxSize { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
449 maxSize <- size |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
450 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
451 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
452 string <- { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
453 "Uses: " . useCount . ", FirstUse: " . (firstUsage join: ":") . ", Last Use: " . (lastUsage join: ":") . ", Max Size: " . maxSize |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
454 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
455 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
456 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
457 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
458 _maxUses <- 0 |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
459 liveFrom:to <- :regs :from :to { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
460 live <- #[] |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
461 foreach: regs :reg usage { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
462 if: ((usage lastUsage) addrGreatEq: from) && ((usage firstUsage) addrLessEq: to) { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
463 live append: reg |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
464 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
465 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
466 live |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
467 } |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
468 regUsage <- #{ |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
469 reg:usedAt:withSize <- :reg :address :size { |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
470 raddress <- address reverse |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
471 usage <- _regMap get: reg elseSet: { |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
472 _usageTracker: raddress |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
473 } |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
474 usage usedAt: raddress withSize: size |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
475 if: (usage useCount) > _maxUses { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
476 _maxUses <- usage useCount |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
477 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
478 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
479 arg:usedAt:withSize <- :arg :address :size { |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
480 raddress <- address reverse |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
481 usage <- _argMap get: arg elseSet: { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
482 _usageTracker: [0 0] |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
483 } |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
484 usage usedAt: raddress withSize: size |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
485 } |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
486 |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
487 liveRegsAt <- :address { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
488 _regMap liveFrom: address to: address |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
489 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
490 liveArgsAt <- :address { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
491 _argMap liveFrom: address to: address |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
492 } |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
493 |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
494 print <- { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
495 foreach: _regMap :reg usage { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
496 print: (string: reg) . " | " . (string: usage) . "\n" |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
497 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
498 foreach: _argMap :arg usage { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
499 print: (string: arg) . " | " . (string: usage) . "\n" |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
500 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
501 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
502 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
503 foreach: instarr :idx inst { |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
504 inst recordUsage: regUsage at: [idx] |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
505 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
506 print: regUsage |
193
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
507 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
508 addrLessEq <- :left :right { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
509 lesseq <- true |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
510 while: { lesseq && (not: (left empty?)) && (not: (right empty?)) } do: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
511 if: (left value) > (right value) { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
512 lesseq <- false |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
513 } else: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
514 if: (left value) < (right value) { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
515 left <- [] |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
516 } else: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
517 left <- left tail |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
518 right <- right tail |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
519 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
520 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
521 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
522 lesseq |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
523 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
524 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
525 addrGreatEq <- :left :right { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
526 greateq <- true |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
527 while: { greateq && (not: (left empty?)) && (not: (right empty?)) } do: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
528 if: (left value) < (right value) { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
529 greateq <- false |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
530 } else: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
531 if: (left value) > (right value) { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
532 left <- [] |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
533 } else: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
534 left <- left tail |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
535 right <- right tail |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
536 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
537 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
538 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
539 greateq |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
540 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
541 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
542 _assignments <- dict linear |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
543 curuses <- _maxUses |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
544 while: { curuses > 0 && (_assignments length) < (_regMap length) } do: { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
545 foreach: _regMap :reg usage { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
546 if: (usage useCount) = curuses { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
547 liveArgs <- _argMap liveFrom: (usage firstUsage) to: (usage lastUsage) |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
548 foreach: liveArgs :_ arg { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
549 regSrc allocArg: (arg num) |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
550 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
551 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
552 liveRegs <- _regMap liveFrom: (usage firstUsage) to: (usage lastUsage) |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
553 print: (string: reg) . " | Live: " . (liveRegs join: ", ") . ", Live Args: " . (liveArgs join: ", ") . "\n" |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
554 foreach: liveRegs :_ reg { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
555 if: (_assignments contains?: reg) { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
556 regSrc allocSpecific: (_assignments get: reg) |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
557 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
558 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
559 _assignments set: reg (regSrc alloc: (usage maxSize)) |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
560 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
561 regSrc returnAll |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
562 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
563 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
564 curuses <- curuses - 1 |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
565 } |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
566 print: "\n\nAssignments:\n\n" |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
567 foreach: _assignments :reg assign { |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
568 print: (string: reg) . " = " . assign . "\n" |
4293c725394c
Mostly complete register allocation in il module with a register source in the x86 module
Mike Pavone <pavone@retrodev.com>
parents:
189
diff
changeset
|
569 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
570 |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
571 withassign <- #[] |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
572 foreach: instarr :idx inst { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
573 withassign append: (inst assignRegs: _assignments at: [idx] withSource: regSrc andUsage: regUsage) |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
574 } |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
575 psave <- regSrc needSaveProlog |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
576 if: (psave length) > 0 { |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
577 withassign <- #[save: psave withassign] |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
578 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
579 withassign |
189
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
580 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
581 |
185 | 582 //used to convert IL to a format suitable for a 2-operand architecture |
583 //should be run after register allocation (I think....) | |
584 to2Op <- :instarr { | |
585 instarr fold: #[] with: :newarr inst { | |
586 if: (inst numops) = 3 { | |
587 if: (inst inb) = (inst out) { | |
588 newarr append: (op2: (inst opcode) in: (inst ina) out: (inst out) size: (inst size)) | |
589 } else: { | |
590 if: (inst commutative?) && (inst ina) = (inst out) { | |
591 newarr append: (op2: (inst opcode) in: (inst inb) out: (inst out) size: (inst size)) | |
592 } else: { | |
593 newarr append: (mov: (inst inb) (inst out) (inst size)) | |
594 newarr append: (op2: (inst opcode) in: (inst ina) out: (inst out) size: (inst size)) | |
595 } | |
596 } | |
597 } else: { | |
598 if: (inst numops) = 2 && (inst opcode) != _mov { | |
599 if: (inst in) != (inst out) { | |
600 newarr append: (mov: (inst in) (inst out) (inst size)) | |
601 } | |
602 newarr append: (op1: (inst opcode) val: (inst out) size: (inst size)) | |
603 } else: { | |
200
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
604 if: (inst opcode) = _skipif || (inst opcode) = _save { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
605 newarr append: (inst to2OpInst) |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
606 } else: { |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
607 newarr append: inst |
49bca6487178
Add a save instruction around calls if there are caller-saved registers live at call-time. Fix to2Op for skipIf and save instructions.
Mike Pavone <pavone@retrodev.com>
parents:
195
diff
changeset
|
608 } |
185 | 609 } |
610 } | |
611 } | |
612 } | |
613 | |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
614 toBackend <- :program :backend { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
615 prepped <- program map: :fun { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
616 backend adjustIL: fun |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
617 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
618 labels <- prepped map: :_ { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
619 backend label |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
620 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
621 outprog <- #[] |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
622 foreach: prepped :name instarr { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
623 outprog append: (labels get: name) |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
624 foreach: instarr :_ inst { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
625 backend convertIL: inst to: outprog withLabels: labels |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
626 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
627 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
628 outprog |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
629 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
630 |
185 | 631 main <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
632 prog <- dict linear |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
633 |
185 | 634 fib <- #[ |
635 sub: 2 (arg: 0) (reg: 0) q | |
636 skipIf: ge #[ | |
637 return: 1 q | |
638 ] | |
639 call: "fib" withArgs: #[reg: 0] | |
640 mov: retr (reg: 1) q | |
641 add: 1 (reg: 0) (reg: 2) q | |
642 call: "fib" withArgs: #[reg: 2] | |
643 add: retr (reg: 1) (reg: 3) q | |
644 return: (reg: 3) q | |
645 ] | |
646 print: "Original:\n\n" | |
647 foreach: fib :idx inst { | |
648 print: (string: inst) . "\n" | |
649 } | |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
650 prog set: "fib" fib |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
651 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
652 mprog <- prog toBackend: x86 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
653 ba <- bytearray executableFromBytes: mprog |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
654 res <- ba runWithArg: 30u64 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
655 print: (string: res) . "\n" |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
656 0 |
185 | 657 } |
658 } | |
659 } |