Mercurial > repos > tabletprog
diff modules/x86.tp @ 203:56b2100d9fff
Add code for converting IL into x86 machine code
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 28 Aug 2013 01:05:45 -0700 |
parents | 3b13ced3b562 |
children | a8dffa4d4b54 |
line wrap: on
line diff
--- a/modules/x86.tp Wed Aug 28 01:05:29 2013 -0700 +++ b/modules/x86.tp Wed Aug 28 01:05:45 2013 -0700 @@ -9,6 +9,7 @@ rm <- :tail { reg or 0xC0u8 | tail } validforSize? <- :size { true } isInteger? <- { false } + isString? <- { false } register? <- { true } label? <- { false } upper? <- { false } @@ -57,7 +58,7 @@ rexBitReg <- { 0u8 } rexBitRM <- { 0u8 } } - size <- :s { + _size <- :s { #{ num <- { s } = <- :other { @@ -85,10 +86,10 @@ } } } - byte <- size: 0 - word <- size: 1 - dword <- size: 2 - qword <- size: 3 + byte <- _size: 0 + word <- _size: 1 + dword <- _size: 2 + qword <- _size: 3 condition <- :num { #{ @@ -607,6 +608,118 @@ } } + adjustIL <- :ilfun { + il to2Op: (il allocRegs: ilfun withSource: regSource) + } + + convertIL:to:withLabels:withSaved <- :inst :outarr :labels :saved { + mapSize <- :ilsize { + if: (ilsize bytes) > 2 { + if: (ilsize bytes) = 8 { q } else: { d } + } else: { + if: (ilsize bytes) = 1 { b } else: { w } + } + } + mapcond <- :ilcond { + ccmap <- #[ + e + ne + ge + le + g + l + ae + be + a + c + ] + ccmap get: (ilcond cc) + } + opmap <- #[ + { outarr append: (add: (inst in) (inst out) (mapSize: (inst size))) } + { } //and + { } //or + { } //xor + { outarr append: (sub: (inst in) (inst out) (mapSize: (inst size))) } + { } //cmp + { } //not + { } //sl + { } //asr + { } //lsr + { } //rol + { } //ror + { outarr append: (mov: (inst in) (inst out) (mapSize: (inst size))) } + { + //call + arguments <- inst args + cur <- (arguments length) - 1 + while: { cur >= 0 } do: { + src <- (arguments get: cur) + if: cur < (_argregs length) { + dst <- _argregs get: cur + if: (not: dst = src) { + //TODO: Handle edge case in which src is a caller saved + //reg that has been pusehd onto the stack to preserve + //it across this call + outarr append: (mov: src dst q) + } + } else: { + outarr append: (push: src) + } + cur <- cur - 1 + } + toCall <- inst target + if: (toCall isString?) { + //TODO: Handle call to undefined label + toCall <- labels get: toCall + } + outarr append: (call: toCall) + } + { + //return + if: (not: _rax = (inst arg)) { + outarr append: (mov: (inst arg) _rax q) + } + foreach: saved :_ reg { + outarr append: (pop: reg) + } + outarr append: (ret: ) + } + { + //skipIf + endlab <- label: + outarr append: (jcc: (mapcond: (inst cond)) endlab) + foreach: (inst toskip) :_ inst { + convertIL: inst to: outarr withLabels: labels withSaved: saved + } + outarr append: endlab + } + { + //save + newsave <- [] + foreach: (inst tosave) :_ reg { + outarr append: (push: reg) + newsave <- reg | newsave + } + foreach: (inst scope) :_ inst { + convertIL: inst to: outarr withLabels: labels withSaved: newsave + } + if: ((inst scope) length) = 0 || (((inst scope) get: ((inst scope) length) - 1) opcode) != 14 { + foreach: newsave :_ reg { + outarr append: (pop: reg) + } + } + } + ] + fun <- opmap get: (inst opcode) + fun: + outarr + } + + convertIL:to:withLabels <- :inst :outarr :labels { + convertIL: inst to: outarr withLabels: labels withSaved: [] + } + main <- { fib <- label: notbase <- label: