OLD | NEW |
1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// | 1 //===- subzero/src/IceInstX8632.cpp - X86-32 instruction implementation ---===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // This file implements the InstX8632 and OperandX8632 classes, | 10 // This file implements the InstX8632 and OperandX8632 classes, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 } TypeX8632Attributes[] = { | 43 } TypeX8632Attributes[] = { |
44 #define X(tag, cvt, sdss, width) \ | 44 #define X(tag, cvt, sdss, width) \ |
45 { cvt, "" sdss, width } \ | 45 { cvt, "" sdss, width } \ |
46 , | 46 , |
47 ICETYPEX8632_TABLE | 47 ICETYPEX8632_TABLE |
48 #undef X | 48 #undef X |
49 }; | 49 }; |
50 const size_t TypeX8632AttributesSize = | 50 const size_t TypeX8632AttributesSize = |
51 llvm::array_lengthof(TypeX8632Attributes); | 51 llvm::array_lengthof(TypeX8632Attributes); |
52 | 52 |
| 53 const char *InstX8632SegmentRegNames[] = { |
| 54 #define X(val, name) \ |
| 55 name, |
| 56 SEG_REGX8632_TABLE |
| 57 #undef X |
| 58 }; |
| 59 const size_t InstX8632SegmentRegNamesSize = |
| 60 llvm::array_lengthof(InstX8632SegmentRegNames); |
| 61 |
53 } // end of anonymous namespace | 62 } // end of anonymous namespace |
54 | 63 |
55 const char *InstX8632::getWidthString(Type Ty) { | 64 const char *InstX8632::getWidthString(Type Ty) { |
56 return TypeX8632Attributes[Ty].WidthString; | 65 return TypeX8632Attributes[Ty].WidthString; |
57 } | 66 } |
58 | 67 |
59 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, | 68 OperandX8632Mem::OperandX8632Mem(Cfg *Func, Type Ty, Variable *Base, |
60 Constant *Offset, Variable *Index, | 69 Constant *Offset, Variable *Index, |
61 uint32_t Shift) | 70 uint16_t Shift, SegmentRegisters SegmentReg) |
62 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), | 71 : OperandX8632(kMem, Ty), Base(Base), Offset(Offset), Index(Index), |
63 Shift(Shift) { | 72 Shift(Shift), SegmentReg(SegmentReg) { |
64 assert(Shift <= 3); | 73 assert(Shift <= 3); |
65 Vars = NULL; | 74 Vars = NULL; |
66 NumVars = 0; | 75 NumVars = 0; |
67 if (Base) | 76 if (Base) |
68 ++NumVars; | 77 ++NumVars; |
69 if (Index) | 78 if (Index) |
70 ++NumVars; | 79 ++NumVars; |
71 if (NumVars) { | 80 if (NumVars) { |
72 Vars = Func->allocateArrayOf<Variable *>(NumVars); | 81 Vars = Func->allocateArrayOf<Variable *>(NumVars); |
73 SizeT I = 0; | 82 SizeT I = 0; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 addSource(Src0); | 150 addSource(Src0); |
142 addSource(Src1); | 151 addSource(Src1); |
143 } | 152 } |
144 | 153 |
145 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) | 154 InstX8632Ucomiss::InstX8632Ucomiss(Cfg *Func, Operand *Src0, Operand *Src1) |
146 : InstX8632(Func, InstX8632::Ucomiss, 2, NULL) { | 155 : InstX8632(Func, InstX8632::Ucomiss, 2, NULL) { |
147 addSource(Src0); | 156 addSource(Src0); |
148 addSource(Src1); | 157 addSource(Src1); |
149 } | 158 } |
150 | 159 |
| 160 InstX8632UD2::InstX8632UD2(Cfg *Func) |
| 161 : InstX8632(Func, InstX8632::UD2, 0, NULL) {} |
| 162 |
151 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) | 163 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) |
152 : InstX8632(Func, InstX8632::Test, 2, NULL) { | 164 : InstX8632(Func, InstX8632::Test, 2, NULL) { |
153 addSource(Src1); | 165 addSource(Src1); |
154 addSource(Src2); | 166 addSource(Src2); |
155 } | 167 } |
156 | 168 |
157 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 169 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
158 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 170 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
159 addSource(Value); | 171 addSource(Value); |
160 addSource(Mem); | 172 addSource(Mem); |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 getSrc(1)->emit(Func); | 530 getSrc(1)->emit(Func); |
519 Str << "\n"; | 531 Str << "\n"; |
520 } | 532 } |
521 | 533 |
522 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 534 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
523 Ostream &Str = Func->getContext()->getStrDump(); | 535 Ostream &Str = Func->getContext()->getStrDump(); |
524 Str << "ucomiss." << getSrc(0)->getType() << " "; | 536 Str << "ucomiss." << getSrc(0)->getType() << " "; |
525 dumpSources(Func); | 537 dumpSources(Func); |
526 } | 538 } |
527 | 539 |
| 540 void InstX8632UD2::emit(const Cfg *Func) const { |
| 541 Ostream &Str = Func->getContext()->getStrEmit(); |
| 542 assert(getSrcSize() == 0); |
| 543 Str << "\tud2\n"; |
| 544 } |
| 545 |
| 546 void InstX8632UD2::dump(const Cfg *Func) const { |
| 547 Ostream &Str = Func->getContext()->getStrDump(); |
| 548 Str << "ud2\n"; |
| 549 } |
| 550 |
528 void InstX8632Test::emit(const Cfg *Func) const { | 551 void InstX8632Test::emit(const Cfg *Func) const { |
529 Ostream &Str = Func->getContext()->getStrEmit(); | 552 Ostream &Str = Func->getContext()->getStrEmit(); |
530 assert(getSrcSize() == 2); | 553 assert(getSrcSize() == 2); |
531 Str << "\ttest\t"; | 554 Str << "\ttest\t"; |
532 getSrc(0)->emit(Func); | 555 getSrc(0)->emit(Func); |
533 Str << ", "; | 556 Str << ", "; |
534 getSrc(1)->emit(Func); | 557 getSrc(1)->emit(Func); |
535 Str << "\n"; | 558 Str << "\n"; |
536 } | 559 } |
537 | 560 |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
751 } | 774 } |
752 | 775 |
753 void OperandX8632::dump(const Cfg *Func) const { | 776 void OperandX8632::dump(const Cfg *Func) const { |
754 Ostream &Str = Func->getContext()->getStrDump(); | 777 Ostream &Str = Func->getContext()->getStrDump(); |
755 Str << "<OperandX8632>"; | 778 Str << "<OperandX8632>"; |
756 } | 779 } |
757 | 780 |
758 void OperandX8632Mem::emit(const Cfg *Func) const { | 781 void OperandX8632Mem::emit(const Cfg *Func) const { |
759 Ostream &Str = Func->getContext()->getStrEmit(); | 782 Ostream &Str = Func->getContext()->getStrEmit(); |
760 Str << TypeX8632Attributes[getType()].WidthString << " "; | 783 Str << TypeX8632Attributes[getType()].WidthString << " "; |
| 784 if (SegmentReg != DefaultSegment) { |
| 785 assert(SegmentReg >= 0 && |
| 786 static_cast<size_t>(SegmentReg) < InstX8632SegmentRegNamesSize); |
| 787 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; |
| 788 } |
761 // TODO: The following is an almost verbatim paste of dump(). | 789 // TODO: The following is an almost verbatim paste of dump(). |
762 bool Dumped = false; | 790 bool Dumped = false; |
763 Str << "["; | 791 Str << "["; |
764 if (Base) { | 792 if (Base) { |
765 Base->emit(Func); | 793 Base->emit(Func); |
766 Dumped = true; | 794 Dumped = true; |
767 } | 795 } |
768 if (Index) { | 796 if (Index) { |
769 assert(Base); | 797 assert(Base); |
770 Str << "+"; | 798 Str << "+"; |
771 if (Shift > 0) | 799 if (Shift > 0) |
772 Str << (1u << Shift) << "*"; | 800 Str << (1u << Shift) << "*"; |
773 Index->emit(Func); | 801 Index->emit(Func); |
774 Dumped = true; | 802 Dumped = true; |
775 } | 803 } |
776 // Pretty-print the Offset. | 804 // Pretty-print the Offset. |
777 bool OffsetIsZero = false; | 805 bool OffsetIsZero = false; |
778 bool OffsetIsNegative = false; | 806 bool OffsetIsNegative = false; |
779 if (Offset == NULL) { | 807 if (Offset == NULL) { |
780 OffsetIsZero = true; | 808 OffsetIsZero = true; |
781 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { | 809 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { |
782 OffsetIsZero = (CI->getValue() == 0); | 810 OffsetIsZero = (CI->getValue() == 0); |
783 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); | 811 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); |
784 } | 812 } |
785 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 813 if (Dumped) { |
786 if (Dumped) { | 814 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
787 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 815 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
788 Str << "+"; | 816 Str << "+"; |
| 817 Offset->emit(Func); |
789 } | 818 } |
| 819 } else { |
| 820 // There is only the offset. |
790 Offset->emit(Func); | 821 Offset->emit(Func); |
791 } | 822 } |
792 Str << "]"; | 823 Str << "]"; |
793 } | 824 } |
794 | 825 |
795 void OperandX8632Mem::dump(const Cfg *Func) const { | 826 void OperandX8632Mem::dump(const Cfg *Func) const { |
796 Ostream &Str = Func->getContext()->getStrDump(); | 827 Ostream &Str = Func->getContext()->getStrDump(); |
| 828 if (SegmentReg != DefaultSegment) { |
| 829 assert(SegmentReg >= 0 && |
| 830 static_cast<size_t>(SegmentReg) < InstX8632SegmentRegNamesSize); |
| 831 Str << InstX8632SegmentRegNames[SegmentReg] << ":"; |
| 832 } |
797 bool Dumped = false; | 833 bool Dumped = false; |
798 Str << "["; | 834 Str << "["; |
799 if (Base) { | 835 if (Base) { |
800 Base->dump(Func); | 836 Base->dump(Func); |
801 Dumped = true; | 837 Dumped = true; |
802 } | 838 } |
803 if (Index) { | 839 if (Index) { |
804 assert(Base); | 840 assert(Base); |
805 Str << "+"; | 841 Str << "+"; |
806 if (Shift > 0) | 842 if (Shift > 0) |
807 Str << (1u << Shift) << "*"; | 843 Str << (1u << Shift) << "*"; |
808 Index->dump(Func); | 844 Index->dump(Func); |
809 Dumped = true; | 845 Dumped = true; |
810 } | 846 } |
811 // Pretty-print the Offset. | 847 // Pretty-print the Offset. |
812 bool OffsetIsZero = false; | 848 bool OffsetIsZero = false; |
813 bool OffsetIsNegative = false; | 849 bool OffsetIsNegative = false; |
814 if (Offset == NULL) { | 850 if (Offset == NULL) { |
815 OffsetIsZero = true; | 851 OffsetIsZero = true; |
816 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { | 852 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { |
817 OffsetIsZero = (CI->getValue() == 0); | 853 OffsetIsZero = (CI->getValue() == 0); |
818 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); | 854 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); |
819 } | 855 } |
820 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 856 if (Dumped) { |
821 if (Dumped) { | 857 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
822 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 858 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
823 Str << "+"; | 859 Str << "+"; |
| 860 Offset->dump(Func); |
824 } | 861 } |
| 862 } else { |
| 863 // There is only the offset. |
825 Offset->dump(Func); | 864 Offset->dump(Func); |
826 } | 865 } |
827 Str << "]"; | 866 Str << "]"; |
828 } | 867 } |
829 | 868 |
830 void VariableSplit::emit(const Cfg *Func) const { | 869 void VariableSplit::emit(const Cfg *Func) const { |
831 Ostream &Str = Func->getContext()->getStrEmit(); | 870 Ostream &Str = Func->getContext()->getStrEmit(); |
832 assert(Var->getLocalUseNode() == NULL || | 871 assert(Var->getLocalUseNode() == NULL || |
833 Var->getLocalUseNode() == Func->getCurrentNode()); | 872 Var->getLocalUseNode() == Func->getCurrentNode()); |
834 assert(!Var->hasReg()); | 873 assert(!Var->hasReg()); |
(...skipping 25 matching lines...) Expand all Loading... |
860 default: | 899 default: |
861 Str << "???"; | 900 Str << "???"; |
862 break; | 901 break; |
863 } | 902 } |
864 Str << "("; | 903 Str << "("; |
865 Var->dump(Func); | 904 Var->dump(Func); |
866 Str << ")"; | 905 Str << ")"; |
867 } | 906 } |
868 | 907 |
869 } // end of namespace Ice | 908 } // end of namespace Ice |
OLD | NEW |