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