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