Mercurial > repos > tabletprog
comparison 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 |
comparison
equal
deleted
inserted
replaced
202:cea671c4056c | 203:56b2100d9fff |
---|---|
7 reg <- { regnum and 7u8} | 7 reg <- { regnum and 7u8} |
8 string <- { regnames get: regnum } | 8 string <- { regnames get: regnum } |
9 rm <- :tail { reg or 0xC0u8 | tail } | 9 rm <- :tail { reg or 0xC0u8 | tail } |
10 validforSize? <- :size { true } | 10 validforSize? <- :size { true } |
11 isInteger? <- { false } | 11 isInteger? <- { false } |
12 isString? <- { false } | |
12 register? <- { true } | 13 register? <- { true } |
13 label? <- { false } | 14 label? <- { false } |
14 upper? <- { false } | 15 upper? <- { false } |
15 needsRex? <- { regnum >= 8u8 } | 16 needsRex? <- { regnum >= 8u8 } |
16 rexBitReg <- { | 17 rexBitReg <- { |
55 fakesrc <- #{ | 56 fakesrc <- #{ |
56 needsRex? <- { false } | 57 needsRex? <- { false } |
57 rexBitReg <- { 0u8 } | 58 rexBitReg <- { 0u8 } |
58 rexBitRM <- { 0u8 } | 59 rexBitRM <- { 0u8 } |
59 } | 60 } |
60 size <- :s { | 61 _size <- :s { |
61 #{ | 62 #{ |
62 num <- { s } | 63 num <- { s } |
63 = <- :other { | 64 = <- :other { |
64 s = (other num) | 65 s = (other num) |
65 } | 66 } |
83 0u8 | 84 0u8 |
84 } | 85 } |
85 } | 86 } |
86 } | 87 } |
87 } | 88 } |
88 byte <- size: 0 | 89 byte <- _size: 0 |
89 word <- size: 1 | 90 word <- _size: 1 |
90 dword <- size: 2 | 91 dword <- _size: 2 |
91 qword <- size: 3 | 92 qword <- _size: 3 |
92 | 93 |
93 condition <- :num { | 94 condition <- :num { |
94 #{ | 95 #{ |
95 cc <- { num } | 96 cc <- { num } |
96 } | 97 } |
605 retval | 606 retval |
606 } | 607 } |
607 } | 608 } |
608 } | 609 } |
609 | 610 |
611 adjustIL <- :ilfun { | |
612 il to2Op: (il allocRegs: ilfun withSource: regSource) | |
613 } | |
614 | |
615 convertIL:to:withLabels:withSaved <- :inst :outarr :labels :saved { | |
616 mapSize <- :ilsize { | |
617 if: (ilsize bytes) > 2 { | |
618 if: (ilsize bytes) = 8 { q } else: { d } | |
619 } else: { | |
620 if: (ilsize bytes) = 1 { b } else: { w } | |
621 } | |
622 } | |
623 mapcond <- :ilcond { | |
624 ccmap <- #[ | |
625 e | |
626 ne | |
627 ge | |
628 le | |
629 g | |
630 l | |
631 ae | |
632 be | |
633 a | |
634 c | |
635 ] | |
636 ccmap get: (ilcond cc) | |
637 } | |
638 opmap <- #[ | |
639 { outarr append: (add: (inst in) (inst out) (mapSize: (inst size))) } | |
640 { } //and | |
641 { } //or | |
642 { } //xor | |
643 { outarr append: (sub: (inst in) (inst out) (mapSize: (inst size))) } | |
644 { } //cmp | |
645 { } //not | |
646 { } //sl | |
647 { } //asr | |
648 { } //lsr | |
649 { } //rol | |
650 { } //ror | |
651 { outarr append: (mov: (inst in) (inst out) (mapSize: (inst size))) } | |
652 { | |
653 //call | |
654 arguments <- inst args | |
655 cur <- (arguments length) - 1 | |
656 while: { cur >= 0 } do: { | |
657 src <- (arguments get: cur) | |
658 if: cur < (_argregs length) { | |
659 dst <- _argregs get: cur | |
660 if: (not: dst = src) { | |
661 //TODO: Handle edge case in which src is a caller saved | |
662 //reg that has been pusehd onto the stack to preserve | |
663 //it across this call | |
664 outarr append: (mov: src dst q) | |
665 } | |
666 } else: { | |
667 outarr append: (push: src) | |
668 } | |
669 cur <- cur - 1 | |
670 } | |
671 toCall <- inst target | |
672 if: (toCall isString?) { | |
673 //TODO: Handle call to undefined label | |
674 toCall <- labels get: toCall | |
675 } | |
676 outarr append: (call: toCall) | |
677 } | |
678 { | |
679 //return | |
680 if: (not: _rax = (inst arg)) { | |
681 outarr append: (mov: (inst arg) _rax q) | |
682 } | |
683 foreach: saved :_ reg { | |
684 outarr append: (pop: reg) | |
685 } | |
686 outarr append: (ret: ) | |
687 } | |
688 { | |
689 //skipIf | |
690 endlab <- label: | |
691 outarr append: (jcc: (mapcond: (inst cond)) endlab) | |
692 foreach: (inst toskip) :_ inst { | |
693 convertIL: inst to: outarr withLabels: labels withSaved: saved | |
694 } | |
695 outarr append: endlab | |
696 } | |
697 { | |
698 //save | |
699 newsave <- [] | |
700 foreach: (inst tosave) :_ reg { | |
701 outarr append: (push: reg) | |
702 newsave <- reg | newsave | |
703 } | |
704 foreach: (inst scope) :_ inst { | |
705 convertIL: inst to: outarr withLabels: labels withSaved: newsave | |
706 } | |
707 if: ((inst scope) length) = 0 || (((inst scope) get: ((inst scope) length) - 1) opcode) != 14 { | |
708 foreach: newsave :_ reg { | |
709 outarr append: (pop: reg) | |
710 } | |
711 } | |
712 } | |
713 ] | |
714 fun <- opmap get: (inst opcode) | |
715 fun: | |
716 outarr | |
717 } | |
718 | |
719 convertIL:to:withLabels <- :inst :outarr :labels { | |
720 convertIL: inst to: outarr withLabels: labels withSaved: [] | |
721 } | |
722 | |
610 main <- { | 723 main <- { |
611 fib <- label: | 724 fib <- label: |
612 notbase <- label: | 725 notbase <- label: |
613 prog <- #[ | 726 prog <- #[ |
614 fib | 727 fib |