Mercurial > repos > tabletprog
annotate modules/il.tp @ 331:61f5b794d939
Breaking change: method call syntax now always uses the syntactic receiver as the actual receiver. This makes its behavior different from function call syntax, but solves some problems with methods being shadowed by local variables and the like.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Mar 2015 14:21:04 -0700 |
parents | f987bb2a1911 |
children | a840e9a068a2 |
rev | line source |
---|---|
185 | 1 { |
2 //commutative ops | |
3 _add <- 0 | |
4 _and <- 1 | |
5 _or <- 2 | |
6 _xor <- 3 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
7 _muls <- 4 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
8 _mulu <- 5 |
185 | 9 //non-commutative ops |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
10 _divs <- 6 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
11 _divu <- 7 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
12 _sub <- 8 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
13 _cmp <- 9 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
14 _not <- 10 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
15 _sl <- 11 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
16 _asr <- 12 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
17 _lsr <- 13 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
18 _rol <- 14 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
19 _ror <- 15 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
20 _mov <- 16 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
21 _call <- 17 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
22 _ret <- 18 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
23 _skipif <- 19 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
24 _skipifelse <- 20 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
25 _save <- 21 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
26 _bool <- 22 |
185 | 27 |
28 _names <- #[ | |
29 "add" | |
30 "and" | |
31 "or" | |
32 "xor" | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
33 "muls" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
34 "mulu" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
35 "divs" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
36 "divu" |
185 | 37 "sub" |
38 "cmp" | |
39 "not" | |
40 "sl" | |
41 "asr" | |
42 "lsr" | |
43 "rol" | |
44 "ror" | |
45 "mov" | |
46 "call" | |
47 "ret" | |
48 "skipIf" | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
49 "skipIf:else" |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
50 "save" |
310
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
51 "bool" |
185 | 52 ] |
53 | |
54 op3:a:b:out:size <- :_opcode :_ina :_inb :_out :_size { | |
55 #{ | |
56 opcode <- { _opcode } | |
57 ina <- { _ina } | |
58 inb <- { _inb } | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
59 commutative? <- { _opcode < _divs } |
185 | 60 out <- { _out } |
61 size <- { _size } | |
62 numops <- { 3 } | |
63 name <- { _names get: _opcode } | |
64 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
|
65 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
|
66 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
|
67 _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
|
68 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
69 _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
|
70 _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
|
71 } |
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
|
72 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
|
73 newa <- if: (not: (_ina isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
74 _ina assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
75 } else: { _ina } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
76 newb <- _inb assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
77 newout <- _out assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
78 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
|
79 } |
185 | 80 } |
81 } | |
82 op2:in:out:size <- :_opcode :_in :_out :_size { | |
83 #{ | |
84 opcode <- { _opcode } | |
85 in <- { _in } | |
86 out <- { _out } | |
87 size <- { _size } | |
88 numops <- { 2 } | |
89 name <- { _names get: _opcode } | |
90 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
|
91 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
|
92 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
|
93 _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
|
94 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
95 _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
|
96 } |
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
|
97 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
|
98 newin <- if: (not: (_in isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
99 _in assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
100 } else: { _in } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
101 newout <- _out assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
102 op2: _opcode in: newin out: newout size: _size |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
103 } |
185 | 104 } |
105 } | |
106 op1:arg:size <- :_opcode :_arg :_size { | |
107 #{ | |
108 opcode <- { _opcode } | |
109 arg <- { _arg } | |
110 size <- { _size } | |
111 numops <- { 1 } | |
112 name <- { _names get: _opcode } | |
113 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
|
114 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
|
115 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
|
116 _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
|
117 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
118 } |
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
|
119 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
|
120 newarg <- if: (not: (_arg isInteger?)) { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
121 _arg assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
122 } else: { _arg } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
123 op1: _opcode arg: newarg size: _size |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
124 } |
185 | 125 } |
126 } | |
127 | |
128 _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
|
129 _size <- :_bytes { |
185 | 130 #{ |
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 <- { _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
|
132 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
|
133 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
|
134 _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
|
135 } |
185 | 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 <= <- :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
|
140 _bytes <= (other bytes) |
185 | 141 } |
142 >= <- :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
|
143 _bytes >= (other bytes) |
185 | 144 } |
145 > <- :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
|
146 _bytes > (other bytes) |
185 | 147 } |
148 < <- :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
|
149 _bytes < (other bytes) |
185 | 150 } |
151 } | |
152 } | |
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
|
153 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
|
154 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
|
155 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
|
156 quad <- _size: 8 |
185 | 157 |
158 _retr <- #{ | |
159 isInteger? <- { false } | |
160 register? <- { true } | |
161 argument? <- { false } | |
162 return? <- { true } | |
163 string <- { "retr" } | |
164 = <- :other { | |
165 (not: (other isInteger?)) && (other register?) && (other return?) | |
166 } | |
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
|
167 != <- :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
|
168 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
|
169 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
170 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
|
171 //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
|
172 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
173 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
174 regSrc allocRet |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
175 } |
185 | 176 } |
177 | |
178 _condnames <- #[ | |
179 "eq" | |
180 "neq" | |
181 "ge" | |
182 "le" | |
183 "gr" | |
184 "ls" | |
185 "uge" | |
186 "ule" | |
187 "ugr" | |
188 "uls" | |
189 ] | |
190 condition <- :num { | |
191 #{ | |
192 cc <- { num } | |
193 string <- { _condnames get: num } | |
194 = <- :other { num = (other cc) } | |
195 } | |
196 } | |
197 _eq <- condition: 0 | |
198 _neq <- condition: 1 | |
199 _ge <- condition: 2 | |
200 _le <- condition: 3 | |
201 _gr <- condition: 4 | |
202 _ls <- condition: 5 | |
203 _uge <- condition: 6 | |
204 _ule <- condition: 7 | |
205 _ugr <- condition: 8 | |
206 _uls <- condition: 9 | |
207 | |
208 #{ | |
209 b <- { byte } | |
210 w <- { word } | |
211 l <- { long } | |
212 q <- { quad } | |
213 | |
214 eq <- { _eq } | |
215 neq <- { _neq } | |
216 | |
217 //signed conditions | |
218 ge <- { _ge } | |
219 le <- { _le } | |
220 gr <- { _gr } | |
221 ls <- { _ls } | |
222 | |
223 //unsigned conditions | |
224 uge <- { _uge } | |
225 ule <- { _ule } | |
226 ugr <- { _ugr } | |
227 uls <- { _uls } | |
228 | |
229 | |
230 reg <- :num { | |
231 #{ | |
232 isInteger? <- { false } | |
233 register? <- { true } | |
234 argument? <- { false } | |
235 return? <- { false } | |
236 regnum <- { num } | |
237 string <- { "r" . (string: num) } | |
238 = <- :other { | |
239 (not: (other isInteger?)) && (other register?) && (not: (other argument?)) && (not: (other return?)) && num = (other regnum) | |
240 } | |
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
|
241 != <- :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
|
242 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
|
243 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
244 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
|
245 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
|
246 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
247 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
248 assignments get: self |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
249 } |
185 | 250 } |
251 } | |
252 arg <- :num { | |
253 #{ | |
254 isInteger? <- { false } | |
255 register? <- { true } | |
256 argument? <- { true } | |
257 return? <- { false } | |
258 argnum <- { num } | |
259 string <- { "a" . (string: num) } | |
260 = <- :other { | |
261 (not: (other isInteger?)) && (other register?) && (other argument?) && num = (other regnum) | |
262 } | |
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
|
263 != <- :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
|
264 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
|
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 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
|
267 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
|
268 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
269 assign:withSource <- :assignments :regSrc { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
270 regSrc allocArg: num |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
271 } |
185 | 272 } |
273 } | |
274 retr <- { _retr } | |
275 | |
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
|
276 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
|
277 #{ |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
278 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
|
279 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
|
280 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
|
281 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
|
282 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
|
283 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
284 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
|
285 _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
|
286 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
287 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
288 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
289 |
185 | 290 add <- :ina inb out size { |
291 op3: _add a: ina b: inb out: out size: size | |
292 } | |
293 | |
294 sub <- :ina inb out size { | |
295 op3: _sub a: ina b: inb out: out size: size | |
296 } | |
297 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
298 cmp <- :ina inb size { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
299 op2: _cmp a: ina out: inb size: size |
185 | 300 } |
301 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
302 band <- :ina inb out size { |
185 | 303 op3: _and a: ina b: inb out: out size: size |
304 } | |
305 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
306 bor <- :ina inb out size { |
185 | 307 op3: _or a: ina b: inb out: out size: size |
308 } | |
309 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
310 bxor <- :ina inb out size { |
185 | 311 op3: _xor a: ina b: inb out: out size: size |
312 } | |
313 | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
314 muls <- :ina inb out size { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
315 op3: _muls a: ina b: inb out: out size: size |
310
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
316 } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
317 |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
318 mulu <- :ina inb out size { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
319 op3: _mulu a: ina b: inb out: out size: size |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
320 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
321 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
322 divs <- :ina inb out size { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
323 op3: _divs a: ina b: inb out: out size: size |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
324 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
325 |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
326 divu <- :ina inb out size { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
327 op3: _divu a: ina b: inb out: out size: size |
310
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
328 } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
329 |
185 | 330 bnot <- :in out size { |
331 op2: _not in: in out: out size: size | |
332 } | |
333 | |
334 sl <- :shift in out size { | |
335 op3: _sl a: shift b: in out: out size: size | |
336 } | |
337 | |
338 asr <- :shift in out size { | |
339 op3: _asr a: shift b: in out: out size: size | |
340 } | |
341 | |
342 lsr <- :shift in out size { | |
343 op3: _lsr a: shift b: in out: out size: size | |
344 } | |
345 | |
346 rol <- :rot in out size { | |
347 op3: _rol a: rot b: in out: out size: size | |
348 } | |
349 | |
350 ror <- :rot in out size { | |
351 op3: _ror a: rot b: in out: out size: size | |
352 } | |
353 | |
354 mov <- :in out size { | |
355 op2: _mov in: in out: out size: size | |
356 } | |
357 | |
358 call:withArgs <- :_target :_args { | |
359 #{ | |
360 opcode <- { _call } | |
361 target <- { _target } | |
362 args <- { _args } | |
363 numops <- { 0 } | |
364 name <- { _names get: _call } | |
365 string <- { | |
366 argstr <- _args map: :el { | |
367 string: el | |
368 } | |
369 name . " " . (string: _target) . " " . (argstr join: " ") | |
370 } | |
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
|
371 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
|
372 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
|
373 //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
|
374 _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
|
375 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
376 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
|
377 //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
|
378 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
|
379 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
380 } |
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
|
381 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
|
382 newtarget <- if: (_target isString?) { _target } else: { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
383 _target assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
384 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
385 newargs <- _args map: :arg { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
386 if: (arg isInteger?) { arg } else: { |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
387 arg assign: assignments withSource: regSrc |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
388 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
389 } |
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
|
390 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
|
391 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
|
392 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
|
393 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
|
394 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
|
395 } |
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
|
396 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
|
397 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
|
398 } |
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
|
399 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
|
400 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
|
401 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
|
402 } 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
|
403 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
|
404 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
405 } |
185 | 406 } |
407 } | |
408 | |
409 return <- :val size { | |
410 op1: _ret arg: val size: size | |
411 } | |
412 skipIf <- :_cond _toskip { | |
413 #{ | |
414 opcode <- { _skipif } | |
415 toskip <- { _toskip } | |
416 cond <- { _cond } | |
417 numops <- { 0 } | |
418 name <- { _names get: _skipif } | |
419 string <- { | |
420 block <- (_toskip map: :el { string: el }) join: "\n\t" | |
421 if: (_toskip length) > 0 { | |
422 block <- "\n\t" . block . "\n" | |
423 } | |
424 name . " " . (string: _cond) . " {" . block . "}" | |
425 } | |
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
|
426 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
|
427 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
|
428 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
|
429 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
430 } |
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 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
|
432 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
|
433 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
|
434 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
|
435 } |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
436 skipIf: _cond newskip |
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
437 } |
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
|
438 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
|
439 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
|
440 } |
185 | 441 } |
442 } | |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
443 skipIf:else <- :_cond _toskip :_else { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
444 #{ |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
445 opcode <- { _skipif } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
446 toskip <- { _toskip } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
447 else <- { _else } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
448 cond <- { _cond } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
449 numops <- { 0 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
450 name <- { _names get: _skipifelse } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
451 string <- { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
452 block <- (_toskip map: :el { string: el }) join: "\n\t" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
453 if: (_toskip length) > 0 { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
454 block <- "\n\t" . block . "\n" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
455 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
456 elseblock <- (_else map: :el { string: el }) join: "\n\t" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
457 if: (_else length) > 0 { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
458 elseblock <- "\n\t" . elseblock . "\n" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
459 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
460 name . " " . (string: _cond) . " {" . block . "} {" . elseblock . "}" |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
461 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
462 recordUsage:at <- :tracker :address { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
463 foreach: _toskip :idx inst { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
464 inst recordUsage: tracker at: idx | address |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
465 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
466 foreach: _else :idx inst { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
467 inst recordUsage: tracker at: idx | address |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
468 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
469 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
470 assignRegs:at:withSource:andUsage <- :assignments :address :regSrc :usage { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
471 newskip <- #[] |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
472 foreach: _toskip :idx inst { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
473 newskip append: (inst assignRegs: assignments at: idx | address withSource: regSrc andUsage: usage) |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
474 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
475 newelse <- #[] |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
476 foreach: _else :idx inst { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
477 newelse append: (inst assignRegs: assignments at: idx | address withSource: regSrc andUsage: usage) |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
478 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
479 skipIf: _cond newskip else: newelse |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
480 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
481 to2OpInst <- { |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
482 skipIf: _cond (to2Op: _toskip) (to2Op: _else) |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
483 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
484 } |
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
485 } |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
486 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
|
487 #{ |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
488 opcode <- { _save } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
489 numops <- { 0 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
490 name <- { _names get: _save } |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
491 tosave <- { regs } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
492 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
|
493 string <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
494 block <- _scope join: "\n\t" |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
495 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
|
496 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
|
497 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
498 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
|
499 } |
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
|
500 to2OpInst <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
501 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
|
502 } |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
503 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
504 } |
185 | 505 |
310
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
506 //produces a non-zero value or zero based on condition code flags |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
507 bool <- :_cond _out { |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
508 #{ |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
509 opcode <- { _bool } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
510 cond <- { _cond } |
315
f987bb2a1911
WIP native compiler work
Michael Pavone <pavone@retrodev.com>
parents:
310
diff
changeset
|
511 out <- { _out } |
310
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
512 name <- { _names get: _save } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
513 numops <- { 0 } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
514 |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
515 } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
516 } |
2308336790d4
WIP compiler module for low-level dialect
Michael Pavone <pavone@retrodev.com>
parents:
203
diff
changeset
|
517 |
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
|
518 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
|
519 _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
|
520 _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
|
521 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
522 _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
|
523 #{ |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
524 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
|
525 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
|
526 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
|
527 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
|
528 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
|
529 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
|
530 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
|
531 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
|
532 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
|
533 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
534 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
535 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
|
536 "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
|
537 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
538 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
539 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
540 |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
541 _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
|
542 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
|
543 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
|
544 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
|
545 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
|
546 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
|
547 } |
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
|
548 } |
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
|
549 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
|
550 } |
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
|
551 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
|
552 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
|
553 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
|
554 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
|
555 _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
|
556 } |
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
|
557 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
|
558 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
|
559 _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
|
560 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
561 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
562 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
|
563 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
|
564 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
|
565 _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
|
566 } |
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
|
567 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
|
568 } |
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
|
569 |
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
|
570 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
|
571 _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
|
572 } |
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 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
|
574 _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
|
575 } |
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
|
576 |
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
|
577 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
|
578 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
|
579 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
|
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 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
|
582 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
|
583 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
584 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
585 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
586 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
|
587 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
|
588 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
589 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
|
590 |
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
|
591 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
|
592 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
|
593 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
|
594 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
|
595 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
|
596 } 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
|
597 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
|
598 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
|
599 } 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
|
600 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
|
601 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
|
602 } |
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
|
603 } |
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
|
604 } |
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
|
605 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
|
606 } |
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
|
607 |
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
|
608 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
|
609 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
|
610 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
|
611 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
|
612 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
|
613 } 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
|
614 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
|
615 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
|
616 } 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
|
617 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
|
618 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
|
619 } |
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
|
620 } |
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
|
621 } |
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
|
622 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
|
623 } |
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
|
624 |
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
|
625 _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
|
626 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
|
627 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
|
628 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
|
629 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
|
630 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
|
631 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
|
632 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
|
633 } |
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
|
634 |
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
|
635 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
|
636 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
|
637 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
|
638 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
|
639 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
|
640 } |
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
|
641 } |
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
|
642 _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
|
643 |
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
|
644 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
|
645 } |
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
|
646 } |
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
|
647 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
|
648 } |
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
|
649 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
|
650 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
|
651 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
|
652 } |
194
30bed95cbb18
Apply register assignments in il module
Mike Pavone <pavone@retrodev.com>
parents:
193
diff
changeset
|
653 |
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
|
654 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
|
655 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
|
656 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
|
657 } |
195
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
658 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
|
659 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
|
660 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
|
661 } |
7856f0916549
Add save il instruction to save callee saved registers in function prolog
Mike Pavone <pavone@retrodev.com>
parents:
194
diff
changeset
|
662 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
|
663 } |
a45e535f7742
Determine live ranges for logical registers as part of initial work on register allocator
Mike Pavone <pavone@retrodev.com>
parents:
185
diff
changeset
|
664 |
185 | 665 //used to convert IL to a format suitable for a 2-operand architecture |
666 //should be run after register allocation (I think....) | |
667 to2Op <- :instarr { | |
668 instarr fold: #[] with: :newarr inst { | |
669 if: (inst numops) = 3 { | |
670 if: (inst inb) = (inst out) { | |
671 newarr append: (op2: (inst opcode) in: (inst ina) out: (inst out) size: (inst size)) | |
672 } else: { | |
673 if: (inst commutative?) && (inst ina) = (inst out) { | |
674 newarr append: (op2: (inst opcode) in: (inst inb) out: (inst out) size: (inst size)) | |
675 } else: { | |
676 newarr append: (mov: (inst inb) (inst out) (inst size)) | |
677 newarr append: (op2: (inst opcode) in: (inst ina) out: (inst out) size: (inst size)) | |
678 } | |
679 } | |
680 } else: { | |
681 if: (inst numops) = 2 && (inst opcode) != _mov { | |
682 if: (inst in) != (inst out) { | |
683 newarr append: (mov: (inst in) (inst out) (inst size)) | |
684 } | |
685 newarr append: (op1: (inst opcode) val: (inst out) size: (inst size)) | |
686 } 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
|
687 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
|
688 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
|
689 } 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
|
690 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
|
691 } |
185 | 692 } |
693 } | |
694 } | |
695 } | |
696 | |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
697 toBackend <- :program :backend { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
698 prepped <- program map: :fun { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
699 backend adjustIL: fun |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
700 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
701 labels <- prepped map: :_ { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
702 backend label |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
703 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
704 outprog <- #[] |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
705 foreach: prepped :name instarr { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
706 outprog append: (labels get: name) |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
707 foreach: instarr :_ inst { |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
708 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
|
709 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
710 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
711 outprog |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
712 } |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
713 |
185 | 714 main <- { |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
715 prog <- dict linear |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
716 |
185 | 717 fib <- #[ |
718 sub: 2 (arg: 0) (reg: 0) q | |
719 skipIf: ge #[ | |
720 return: 1 q | |
721 ] | |
722 call: "fib" withArgs: #[reg: 0] | |
723 mov: retr (reg: 1) q | |
724 add: 1 (reg: 0) (reg: 2) q | |
725 call: "fib" withArgs: #[reg: 2] | |
726 add: retr (reg: 1) (reg: 3) q | |
727 return: (reg: 3) q | |
728 ] | |
729 print: "Original:\n\n" | |
730 foreach: fib :idx inst { | |
731 print: (string: inst) . "\n" | |
732 } | |
203
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
733 prog set: "fib" fib |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
734 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
735 mprog <- prog toBackend: x86 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
736 ba <- bytearray executableFromBytes: mprog |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
737 res <- ba runWithArg: 30u64 |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
738 print: (string: res) . "\n" |
56b2100d9fff
Add code for converting IL into x86 machine code
Mike Pavone <pavone@retrodev.com>
parents:
200
diff
changeset
|
739 0 |
185 | 740 } |
741 } | |
742 } |