Mercurial > repos > tabletprog
diff 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 |
line wrap: on
line diff
--- a/modules/x86.tp Mon Aug 26 19:50:17 2013 -0700 +++ b/modules/x86.tp Mon Aug 26 19:53:16 2013 -0700 @@ -128,8 +128,8 @@ } mod_rm:withTail <- :register regmem :end { - l <- regmem rm: end - (l value) or ( lshift: (register reg) by: 3u8) | (l tail) + list <- regmem rm: end + (list value) or ( lshift: (register reg) by: 3u8) | (list tail) } mod_rm <- :reg rm { @@ -190,6 +190,30 @@ _dh <- upper: 6u8 _bh <- upper: 7u8 + //AMD64 convention + _argregs <- #[ + _rdi + _rsi + _rdx + _rcx + _r8 + _r9 + ] + _calleesave <- #[ + _rbx + _rbp + _r12 + _r13 + _r14 + _r15 + ] + _tempregs <- #[ + _r10 + _r11 + _rax + ] + + inst <- :ilist { #{ length <- { ilist length } @@ -477,6 +501,108 @@ inst: (prefix: fakesrc dst d withInstruction: base) } + //TODO: support multiple calling conventions + regSource <- { + _used <- 0 + _usedAllTime <- 0 + _nextStackOff <- 0 + _findUnused <- :size reglists{ + found <- -1 + foundlist <- -1 + curlist <- 0 + ll <- reglists length + while: { found < 0 && curlist < ll } do: { + cur <- 0 + regs <- reglists get: curlist + len <- regs length + while: { found < 0 && cur < len } do: { + bit <- lshift: 1 by: cur + if: (_used and bit) = 0 { + found <- cur + foundlist <- regs + _used <- _used or bit + _usedAllTime <- _usedAllTime or bit + } + cur <- cur + 1 + } + curlist <- curlist + 1 + } + if: found >= 0 { + foundlist get: found + } else: { + myoff <- _nextStackOff + _nextStackOff <- _nextStackOff + size + il base: _rsp offset: myoff + } + } + #{ + alloc <- :size { + _findUnused: size #[ + _calleesave + _tempregs + _argregs + ] + } + //used to allocate a register + //that will be returned before a call + allocTemp <- :size { + _findUnused: size #[ + _tempregs + _argregs + _calleesave + ] + } + //allocated the return register + allocRet <- :size { + bit <- (lshift: 1 by: (_rax num)) + _used <- _used or bit + _usedAllTime <- _usedAllTime or bit + _rax + } + allocArg <- :argnum { + if: argnum < (_argregs length) { + reg <- _argregs get: argnum + bit <- (lshift: 1 by: (reg num)) + _used <- _used or bit + _usedAllTime <- _usedAllTime or bit + } else: { + il base: _rsp offset: _nextStackOff + 8 * (argnum - (_argregs length)) + } + } + allocSpecific <- :reg { + if: (reg register?) { + bit <- (lshift: 1 by: (reg num)) + _used <- _used or bit + } + } + stackSize <- { _nextStackOff } + return <- :reg { + _used <- _used and (0xF xor (lshift: 1 by: (reg num))) + } + returnAll <- { _used = 0 } + needSaveProlog <- { + retval <- #[] + foreach: _calleesave :idx reg { + if: (_usedAllTime and (lshift: 1 by: (reg num))) != 0 { + retval append: reg + } + } + retval + } + needSaveForCall <- { + retval <- #[] + foreach: #[_tempregs _argregs] :_ regs { + foreach: regs :_ reg { + if: (_used and (lshift: 1 by: (reg num))) != 0 { + retval append: reg + } + } + } + retval + } + } + } + main <- { fib <- label: notbase <- label: