Mercurial > repos > tabletprog
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 } |