comparison modules/il.tp @ 194:30bed95cbb18

Apply register assignments in il module
author Mike Pavone <pavone@retrodev.com>
date Mon, 26 Aug 2013 20:42:20 -0700
parents 4293c725394c
children 7856f0916549
comparison
equal deleted inserted replaced
193:4293c725394c 194:30bed95cbb18
53 _ina recordUsage: tracker at: 0 | address withSize: _size 53 _ina recordUsage: tracker at: 0 | address withSize: _size
54 } 54 }
55 _inb recordUsage: tracker at: 0 | address withSize: _size 55 _inb recordUsage: tracker at: 0 | address withSize: _size
56 _out recordUsage: tracker at: 1 | address withSize: _size 56 _out recordUsage: tracker at: 1 | address withSize: _size
57 } 57 }
58 assignRegs:withSource <- :assignments :regSrc {
59 newa <- if: (not: (_ina isInteger?)) {
60 _ina assign: assignments withSource: regSrc
61 } else: { _ina }
62 newb <- _inb assign: assignments withSource: regSrc
63 newout <- _out assign: assignments withSource: regSrc
64 op3: _opcode a: newa b: newb out: newout size: _size
65 }
58 } 66 }
59 } 67 }
60 op2:in:out:size <- :_opcode :_in :_out :_size { 68 op2:in:out:size <- :_opcode :_in :_out :_size {
61 #{ 69 #{
62 opcode <- { _opcode } 70 opcode <- { _opcode }
70 if: (not: (_in isInteger?)) { 78 if: (not: (_in isInteger?)) {
71 _in recordUsage: tracker at: 0 | address withSize: _size 79 _in recordUsage: tracker at: 0 | address withSize: _size
72 } 80 }
73 _out recordUsage: tracker at: 1 | address withSize: _size 81 _out recordUsage: tracker at: 1 | address withSize: _size
74 } 82 }
83 assignRegs:withSource <- :assignments :regSrc {
84 newin <- if: (not: (_in isInteger?)) {
85 _in assign: assignments withSource: regSrc
86 } else: { _in }
87 newout <- _out assign: assignments withSource: regSrc
88 op2: _opcode in: newin out: newout size: _size
89 }
75 } 90 }
76 } 91 }
77 op1:arg:size <- :_opcode :_arg :_size { 92 op1:arg:size <- :_opcode :_arg :_size {
78 #{ 93 #{
79 opcode <- { _opcode } 94 opcode <- { _opcode }
85 recordUsage:at <- :tracker :address { 100 recordUsage:at <- :tracker :address {
86 if: (not: (_arg isInteger?)) { 101 if: (not: (_arg isInteger?)) {
87 _arg recordUsage: tracker at: address withSize: _size 102 _arg recordUsage: tracker at: address withSize: _size
88 } 103 }
89 } 104 }
105 assignRegs:withSource <- :assignments :regSrc {
106 newarg <- if: (not: (_arg isInteger?)) {
107 _arg assign: assignments withSource: regSrc
108 } else: { _arg }
109 op1: _opcode arg: newarg size: _size
110 }
90 } 111 }
91 } 112 }
92 113
93 _sizenames <- #["b" "w" "l" "q"] 114 _sizenames <- #["b" "w" "l" "q"]
94 _size <- :_bytes { 115 _size <- :_bytes {
132 != <- :other { 153 != <- :other {
133 not: self = other 154 not: self = other
134 } 155 }
135 recordUsage:at:withSize <- :tracker :address :size { 156 recordUsage:at:withSize <- :tracker :address :size {
136 //TODO: Figure out what tracking is necessary here 157 //TODO: Figure out what tracking is necessary here
158 }
159 assign:withSource <- :assignments :regSrc {
160 regSrc allocRet
137 } 161 }
138 } 162 }
139 163
140 _condnames <- #[ 164 _condnames <- #[
141 "eq" 165 "eq"
204 not: self = other 228 not: self = other
205 } 229 }
206 recordUsage:at:withSize <- :tracker :address :size { 230 recordUsage:at:withSize <- :tracker :address :size {
207 tracker reg: self usedAt: address withSize: size 231 tracker reg: self usedAt: address withSize: size
208 } 232 }
233 assign:withSource <- :assignments :regSrc {
234 assignments get: self
235 }
209 } 236 }
210 } 237 }
211 arg <- :num { 238 arg <- :num {
212 #{ 239 #{
213 isInteger? <- { false } 240 isInteger? <- { false }
223 not: self = other 250 not: self = other
224 } 251 }
225 recordUsage:at:withSize <- :tracker :address :size { 252 recordUsage:at:withSize <- :tracker :address :size {
226 tracker arg: self usedAt: address withSize: size 253 tracker arg: self usedAt: address withSize: size
227 } 254 }
255 assign:withSource <- :assignments :regSrc {
256 regSrc allocArg: num
257 }
228 } 258 }
229 } 259 }
230 retr <- { _retr } 260 retr <- { _retr }
231 261
232 base:offset <- :_base :_offset { 262 base:offset <- :_base :_offset {
315 } 345 }
316 foreach: _args :_ arg { 346 foreach: _args :_ arg {
317 //TODO: have some mechanism for properly expressing sizes of arguments 347 //TODO: have some mechanism for properly expressing sizes of arguments
318 arg recordUsage: tracker at: address withSize: q 348 arg recordUsage: tracker at: address withSize: q
319 } 349 }
350 }
351 assignRegs:withSource <- :assignments :regSrc {
352 newtarget <- if: (_target isString?) { _target } else: {
353 _target assign: assignments withSource: regSrc
354 }
355 newargs <- _args map: :arg {
356 if: (arg isInteger?) { arg } else: {
357 arg assign: assignments withSource: regSrc
358 }
359 }
360 //TODO: Save caller-save regs if necessary
361 //TODO: Add instructions for moving arguments to proper regs/stack locations
362 call: newtarget withArgs: newargs
320 } 363 }
321 } 364 }
322 } 365 }
323 366
324 return <- :val size { 367 return <- :val size {
341 recordUsage:at <- :tracker :address { 384 recordUsage:at <- :tracker :address {
342 foreach: _toskip :idx inst { 385 foreach: _toskip :idx inst {
343 inst recordUsage: tracker at: idx | address 386 inst recordUsage: tracker at: idx | address
344 } 387 }
345 } 388 }
389 assignRegs:withSource <- :assignments :regSrc {
390 newskip <- _toskip map: :inst {
391 inst assignRegs: assignments withSource: regSrc
392 }
393 skipIf: _cond newskip
394 }
346 } 395 }
347 } 396 }
348 397
349 allocRegs:withSource <- :instarr:regSrc { 398 allocRegs:withSource <- :instarr:regSrc {
350 _regMap <- dict linear 399 _regMap <- dict linear
471 curuses <- curuses - 1 520 curuses <- curuses - 1
472 } 521 }
473 print: "\n\nAssignments:\n\n" 522 print: "\n\nAssignments:\n\n"
474 foreach: _assignments :reg assign { 523 foreach: _assignments :reg assign {
475 print: (string: reg) . " = " . assign . "\n" 524 print: (string: reg) . " = " . assign . "\n"
525 }
526
527 //TODO: Save callee saved regs
528 map: instarr :inst {
529 inst assignRegs: _assignments withSource: regSrc
476 } 530 }
477 } 531 }
478 532
479 //used to convert IL to a format suitable for a 2-operand architecture 533 //used to convert IL to a format suitable for a 2-operand architecture
480 //should be run after register allocation (I think....) 534 //should be run after register allocation (I think....)
520 print: "Original:\n\n" 574 print: "Original:\n\n"
521 foreach: fib :idx inst { 575 foreach: fib :idx inst {
522 print: (string: inst) . "\n" 576 print: (string: inst) . "\n"
523 } 577 }
524 print: "\n\nUsage:\n\n" 578 print: "\n\nUsage:\n\n"
525 allocRegs: fib withSource: (x86 regSource) 579 fiba <- allocRegs: fib withSource: (x86 regSource)
526 fib2 <- to2Op: fib 580 print: "\n\nAFter Assignment:\n\n"
581 foreach: fiba :idx inst {
582 print: (string: inst) . "\n"
583 }
584 fib2 <- to2Op: fiba
527 print: "\n\n2-Operand:\n\n" 585 print: "\n\n2-Operand:\n\n"
528 foreach: fib2 :idx inst { 586 foreach: fib2 :idx inst {
529 print: (string: inst) . "\n" 587 print: (string: inst) . "\n"
530 } 588 }
531 } 589 }