comparison modules/il.tp @ 193:4293c725394c

Mostly complete register allocation in il module with a register source in the x86 module
author Mike Pavone <pavone@retrodev.com>
date Mon, 26 Aug 2013 19:53:16 -0700
parents a45e535f7742
children 30bed95cbb18
comparison
equal deleted inserted replaced
192:a868a2aec930 193:4293c725394c
89 } 89 }
90 } 90 }
91 } 91 }
92 92
93 _sizenames <- #["b" "w" "l" "q"] 93 _sizenames <- #["b" "w" "l" "q"]
94 _size <- :_num { 94 _size <- :_bytes {
95 #{ 95 #{
96 num <- { _num } 96 bytes <- { _bytes }
97 string <- { _sizenames get: _num } 97 string <- {
98 idx <- if: _bytes = 8 { 3 } else: { _bytes / 2}
99 _sizenames get: idx
100 }
98 = <- :other { 101 = <- :other {
99 _num = (other num) 102 _bytes = (other bytes)
100 } 103 }
101 <= <- :other { 104 <= <- :other {
102 _num <= (other num) 105 _bytes <= (other bytes)
103 } 106 }
104 >= <- :other { 107 >= <- :other {
105 _num >= (other num) 108 _bytes >= (other bytes)
106 } 109 }
107 > <- :other { 110 > <- :other {
108 _num > (other num) 111 _bytes > (other bytes)
109 } 112 }
110 < <- :other { 113 < <- :other {
111 _num < (other num) 114 _bytes < (other bytes)
112 } 115 }
113 } 116 }
114 } 117 }
115 byte <- _size: 0 118 byte <- _size: 1
116 word <- _size: 1 119 word <- _size: 2
117 long <- _size: 2 120 long <- _size: 4
118 quad <- _size: 3 121 quad <- _size: 8
119 122
120 _retr <- #{ 123 _retr <- #{
121 isInteger? <- { false } 124 isInteger? <- { false }
122 register? <- { true } 125 register? <- { true }
123 argument? <- { false } 126 argument? <- { false }
365 } 368 }
366 } 369 }
367 } 370 }
368 371
369 _maxUses <- 0 372 _maxUses <- 0
370 _maxUseReg <- false
371 regUsage <- #{ 373 regUsage <- #{
372 reg:usedAt:withSize <- :reg :address :size { 374 reg:usedAt:withSize <- :reg :address :size {
375 raddress <- address reverse
373 usage <- _regMap get: reg elseSet: { 376 usage <- _regMap get: reg elseSet: {
374 _usageTracker: address 377 _usageTracker: raddress
375 } 378 }
376 usage usedAt: address withSize: size 379 usage usedAt: raddress withSize: size
377 if: (usage useCount) > _maxUses { 380 if: (usage useCount) > _maxUses {
378 _maxUses <- usage useCount 381 _maxUses <- usage useCount
379 _maxUseReg <- reg
380 } 382 }
381 } 383 }
382 arg:usedAt:withSize <- :arg :address :size { 384 arg:usedAt:withSize <- :arg :address :size {
385 raddress <- address reverse
383 usage <- _argMap get: arg elseSet: { 386 usage <- _argMap get: arg elseSet: {
384 _usageTracker: [0 0] 387 _usageTracker: [0 0]
385 } 388 }
386 usage usedAt: address withSize: size 389 usage usedAt: raddress withSize: size
387 } 390 }
388 print <- { 391 print <- {
389 foreach: _regMap :reg usage { 392 foreach: _regMap :reg usage {
390 print: (string: reg) . " | " . (string: usage) . "\n" 393 print: (string: reg) . " | " . (string: usage) . "\n"
391 } 394 }
396 } 399 }
397 foreach: instarr :idx inst { 400 foreach: instarr :idx inst {
398 inst recordUsage: regUsage at: [idx] 401 inst recordUsage: regUsage at: [idx]
399 } 402 }
400 print: regUsage 403 print: regUsage
404
405 addrLessEq <- :left :right {
406 lesseq <- true
407 while: { lesseq && (not: (left empty?)) && (not: (right empty?)) } do: {
408 if: (left value) > (right value) {
409 lesseq <- false
410 } else: {
411 if: (left value) < (right value) {
412 left <- []
413 } else: {
414 left <- left tail
415 right <- right tail
416 }
417 }
418 }
419 lesseq
420 }
421
422 addrGreatEq <- :left :right {
423 greateq <- true
424 while: { greateq && (not: (left empty?)) && (not: (right empty?)) } do: {
425 if: (left value) < (right value) {
426 greateq <- false
427 } else: {
428 if: (left value) > (right value) {
429 left <- []
430 } else: {
431 left <- left tail
432 right <- right tail
433 }
434 }
435 }
436 greateq
437 }
438
439 liveFrom:to <- :regs :from :to {
440 live <- #[]
441 foreach: regs :reg usage {
442 if: ((usage lastUsage) addrGreatEq: from) && ((usage firstUsage) addrLessEq: to) {
443 live append: reg
444 }
445 }
446 live
447 }
448
449 _assignments <- dict linear
450 curuses <- _maxUses
451 while: { curuses > 0 && (_assignments length) < (_regMap length) } do: {
452 foreach: _regMap :reg usage {
453 if: (usage useCount) = curuses {
454 liveArgs <- _argMap liveFrom: (usage firstUsage) to: (usage lastUsage)
455 foreach: liveArgs :_ arg {
456 regSrc allocArg: (arg num)
457 }
458
459 liveRegs <- _regMap liveFrom: (usage firstUsage) to: (usage lastUsage)
460 print: (string: reg) . " | Live: " . (liveRegs join: ", ") . ", Live Args: " . (liveArgs join: ", ") . "\n"
461 foreach: liveRegs :_ reg {
462 if: (_assignments contains?: reg) {
463 regSrc allocSpecific: (_assignments get: reg)
464 }
465 }
466 _assignments set: reg (regSrc alloc: (usage maxSize))
467
468 regSrc returnAll
469 }
470 }
471 curuses <- curuses - 1
472 }
473 print: "\n\nAssignments:\n\n"
474 foreach: _assignments :reg assign {
475 print: (string: reg) . " = " . assign . "\n"
476 }
401 } 477 }
402 478
403 //used to convert IL to a format suitable for a 2-operand architecture 479 //used to convert IL to a format suitable for a 2-operand architecture
404 //should be run after register allocation (I think....) 480 //should be run after register allocation (I think....)
405 to2Op <- :instarr { 481 to2Op <- :instarr {
444 print: "Original:\n\n" 520 print: "Original:\n\n"
445 foreach: fib :idx inst { 521 foreach: fib :idx inst {
446 print: (string: inst) . "\n" 522 print: (string: inst) . "\n"
447 } 523 }
448 print: "\n\nUsage:\n\n" 524 print: "\n\nUsage:\n\n"
449 allocRegs: fib withSource: false 525 allocRegs: fib withSource: (x86 regSource)
450 fib2 <- to2Op: fib 526 fib2 <- to2Op: fib
451 print: "\n\n2-Operand:\n\n" 527 print: "\n\n2-Operand:\n\n"
452 foreach: fib2 :idx inst { 528 foreach: fib2 :idx inst {
453 print: (string: inst) . "\n" 529 print: (string: inst) . "\n"
454 } 530 }