Mercurial > repos > tabletprog
comparison modules/x86.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 | 97f107b9e8d3 |
children | 30bed95cbb18 |
comparison
equal
deleted
inserted
replaced
192:a868a2aec930 | 193:4293c725394c |
---|---|
126 string <- { "opex " . val} | 126 string <- { "opex " . val} |
127 } | 127 } |
128 } | 128 } |
129 | 129 |
130 mod_rm:withTail <- :register regmem :end { | 130 mod_rm:withTail <- :register regmem :end { |
131 l <- regmem rm: end | 131 list <- regmem rm: end |
132 (l value) or ( lshift: (register reg) by: 3u8) | (l tail) | 132 (list value) or ( lshift: (register reg) by: 3u8) | (list tail) |
133 } | 133 } |
134 | 134 |
135 mod_rm <- :reg rm { | 135 mod_rm <- :reg rm { |
136 mod_rm: reg rm withTail: [] | 136 mod_rm: reg rm withTail: [] |
137 } | 137 } |
187 _r15 <- ireg: 15u8 | 187 _r15 <- ireg: 15u8 |
188 _ah <- upper: 4u8 | 188 _ah <- upper: 4u8 |
189 _ch <- upper: 5u8 | 189 _ch <- upper: 5u8 |
190 _dh <- upper: 6u8 | 190 _dh <- upper: 6u8 |
191 _bh <- upper: 7u8 | 191 _bh <- upper: 7u8 |
192 | |
193 //AMD64 convention | |
194 _argregs <- #[ | |
195 _rdi | |
196 _rsi | |
197 _rdx | |
198 _rcx | |
199 _r8 | |
200 _r9 | |
201 ] | |
202 _calleesave <- #[ | |
203 _rbx | |
204 _rbp | |
205 _r12 | |
206 _r13 | |
207 _r14 | |
208 _r15 | |
209 ] | |
210 _tempregs <- #[ | |
211 _r10 | |
212 _r11 | |
213 _rax | |
214 ] | |
215 | |
192 | 216 |
193 inst <- :ilist { | 217 inst <- :ilist { |
194 #{ | 218 #{ |
195 length <- { ilist length } | 219 length <- { ilist length } |
196 flattenTo:at <- :dest :idx { | 220 flattenTo:at <- :dest :idx { |
475 0x8Fu8 | (mod_rm: (opex: 0u8) dst) | 499 0x8Fu8 | (mod_rm: (opex: 0u8) dst) |
476 } | 500 } |
477 inst: (prefix: fakesrc dst d withInstruction: base) | 501 inst: (prefix: fakesrc dst d withInstruction: base) |
478 } | 502 } |
479 | 503 |
504 //TODO: support multiple calling conventions | |
505 regSource <- { | |
506 _used <- 0 | |
507 _usedAllTime <- 0 | |
508 _nextStackOff <- 0 | |
509 _findUnused <- :size reglists{ | |
510 found <- -1 | |
511 foundlist <- -1 | |
512 curlist <- 0 | |
513 ll <- reglists length | |
514 while: { found < 0 && curlist < ll } do: { | |
515 cur <- 0 | |
516 regs <- reglists get: curlist | |
517 len <- regs length | |
518 while: { found < 0 && cur < len } do: { | |
519 bit <- lshift: 1 by: cur | |
520 if: (_used and bit) = 0 { | |
521 found <- cur | |
522 foundlist <- regs | |
523 _used <- _used or bit | |
524 _usedAllTime <- _usedAllTime or bit | |
525 } | |
526 cur <- cur + 1 | |
527 } | |
528 curlist <- curlist + 1 | |
529 } | |
530 if: found >= 0 { | |
531 foundlist get: found | |
532 } else: { | |
533 myoff <- _nextStackOff | |
534 _nextStackOff <- _nextStackOff + size | |
535 il base: _rsp offset: myoff | |
536 } | |
537 } | |
538 #{ | |
539 alloc <- :size { | |
540 _findUnused: size #[ | |
541 _calleesave | |
542 _tempregs | |
543 _argregs | |
544 ] | |
545 } | |
546 //used to allocate a register | |
547 //that will be returned before a call | |
548 allocTemp <- :size { | |
549 _findUnused: size #[ | |
550 _tempregs | |
551 _argregs | |
552 _calleesave | |
553 ] | |
554 } | |
555 //allocated the return register | |
556 allocRet <- :size { | |
557 bit <- (lshift: 1 by: (_rax num)) | |
558 _used <- _used or bit | |
559 _usedAllTime <- _usedAllTime or bit | |
560 _rax | |
561 } | |
562 allocArg <- :argnum { | |
563 if: argnum < (_argregs length) { | |
564 reg <- _argregs get: argnum | |
565 bit <- (lshift: 1 by: (reg num)) | |
566 _used <- _used or bit | |
567 _usedAllTime <- _usedAllTime or bit | |
568 } else: { | |
569 il base: _rsp offset: _nextStackOff + 8 * (argnum - (_argregs length)) | |
570 } | |
571 } | |
572 allocSpecific <- :reg { | |
573 if: (reg register?) { | |
574 bit <- (lshift: 1 by: (reg num)) | |
575 _used <- _used or bit | |
576 } | |
577 } | |
578 stackSize <- { _nextStackOff } | |
579 return <- :reg { | |
580 _used <- _used and (0xF xor (lshift: 1 by: (reg num))) | |
581 } | |
582 returnAll <- { _used = 0 } | |
583 needSaveProlog <- { | |
584 retval <- #[] | |
585 foreach: _calleesave :idx reg { | |
586 if: (_usedAllTime and (lshift: 1 by: (reg num))) != 0 { | |
587 retval append: reg | |
588 } | |
589 } | |
590 retval | |
591 } | |
592 needSaveForCall <- { | |
593 retval <- #[] | |
594 foreach: #[_tempregs _argregs] :_ regs { | |
595 foreach: regs :_ reg { | |
596 if: (_used and (lshift: 1 by: (reg num))) != 0 { | |
597 retval append: reg | |
598 } | |
599 } | |
600 } | |
601 retval | |
602 } | |
603 } | |
604 } | |
605 | |
480 main <- { | 606 main <- { |
481 fib <- label: | 607 fib <- label: |
482 notbase <- label: | 608 notbase <- label: |
483 prog <- #[ | 609 prog <- #[ |
484 fib | 610 fib |