Mercurial > repos > tabletprog
annotate modules/il.tp @ 243:5b830147c1cd
Use a lightweight substring object in a few places in the parser to improve performance for large files.
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 05 Jan 2014 23:07:26 -0800 |
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 } |