Chromium Code Reviews| 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 } | |
| 163 | |
| 151 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) | 164 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) |
| 152 : InstX8632(Func, InstX8632::Test, 2, NULL) { | 165 : InstX8632(Func, InstX8632::Test, 2, NULL) { |
| 153 addSource(Src1); | 166 addSource(Src1); |
| 154 addSource(Src2); | 167 addSource(Src2); |
| 155 } | 168 } |
| 156 | 169 |
| 157 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 170 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
| 158 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 171 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
| 159 addSource(Value); | 172 addSource(Value); |
| 160 addSource(Mem); | 173 addSource(Mem); |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 518 getSrc(1)->emit(Func); | 531 getSrc(1)->emit(Func); |
| 519 Str << "\n"; | 532 Str << "\n"; |
| 520 } | 533 } |
| 521 | 534 |
| 522 void InstX8632Ucomiss::dump(const Cfg *Func) const { | 535 void InstX8632Ucomiss::dump(const Cfg *Func) const { |
| 523 Ostream &Str = Func->getContext()->getStrDump(); | 536 Ostream &Str = Func->getContext()->getStrDump(); |
| 524 Str << "ucomiss." << getSrc(0)->getType() << " "; | 537 Str << "ucomiss." << getSrc(0)->getType() << " "; |
| 525 dumpSources(Func); | 538 dumpSources(Func); |
| 526 } | 539 } |
| 527 | 540 |
| 541 void InstX8632UD2::emit(const Cfg *Func) const { | |
| 542 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 543 assert(getSrcSize() == 0); | |
| 544 Str << "\tud2\n"; | |
| 545 } | |
| 546 | |
| 547 void InstX8632UD2::dump(const Cfg *Func) const { | |
| 548 Ostream &Str = Func->getContext()->getStrDump(); | |
| 549 Str << "ud2\n"; | |
| 550 } | |
| 551 | |
| 528 void InstX8632Test::emit(const Cfg *Func) const { | 552 void InstX8632Test::emit(const Cfg *Func) const { |
| 529 Ostream &Str = Func->getContext()->getStrEmit(); | 553 Ostream &Str = Func->getContext()->getStrEmit(); |
| 530 assert(getSrcSize() == 2); | 554 assert(getSrcSize() == 2); |
| 531 Str << "\ttest\t"; | 555 Str << "\ttest\t"; |
| 532 getSrc(0)->emit(Func); | 556 getSrc(0)->emit(Func); |
| 533 Str << ", "; | 557 Str << ", "; |
| 534 getSrc(1)->emit(Func); | 558 getSrc(1)->emit(Func); |
| 535 Str << "\n"; | 559 Str << "\n"; |
| 536 } | 560 } |
| 537 | 561 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 } | 774 } |
| 751 | 775 |
| 752 void OperandX8632::dump(const Cfg *Func) const { | 776 void OperandX8632::dump(const Cfg *Func) const { |
| 753 Ostream &Str = Func->getContext()->getStrDump(); | 777 Ostream &Str = Func->getContext()->getStrDump(); |
| 754 Str << "<OperandX8632>"; | 778 Str << "<OperandX8632>"; |
| 755 } | 779 } |
| 756 | 780 |
| 757 void OperandX8632Mem::emit(const Cfg *Func) const { | 781 void OperandX8632Mem::emit(const Cfg *Func) const { |
| 758 Ostream &Str = Func->getContext()->getStrEmit(); | 782 Ostream &Str = Func->getContext()->getStrEmit(); |
| 759 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 } | |
| 760 // TODO: The following is an almost verbatim paste of dump(). | 789 // TODO: The following is an almost verbatim paste of dump(). |
| 761 bool Dumped = false; | 790 bool Dumped = false; |
| 762 Str << "["; | 791 Str << "["; |
| 763 if (Base) { | 792 if (Base) { |
| 764 Base->emit(Func); | 793 Base->emit(Func); |
| 765 Dumped = true; | 794 Dumped = true; |
| 766 } | 795 } |
| 767 if (Index) { | 796 if (Index) { |
| 768 assert(Base); | 797 assert(Base); |
| 769 Str << "+"; | 798 Str << "+"; |
| 770 if (Shift > 0) | 799 if (Shift > 0) |
| 771 Str << (1u << Shift) << "*"; | 800 Str << (1u << Shift) << "*"; |
| 772 Index->emit(Func); | 801 Index->emit(Func); |
| 773 Dumped = true; | 802 Dumped = true; |
| 774 } | 803 } |
| 775 // Pretty-print the Offset. | 804 // Pretty-print the Offset. |
| 776 bool OffsetIsZero = false; | 805 bool OffsetIsZero = false; |
| 777 bool OffsetIsNegative = false; | 806 bool OffsetIsNegative = false; |
| 778 if (Offset == NULL) { | 807 if (Offset == NULL) { |
| 779 OffsetIsZero = true; | 808 OffsetIsZero = true; |
| 780 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { | 809 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { |
| 781 OffsetIsZero = (CI->getValue() == 0); | 810 OffsetIsZero = (CI->getValue() == 0); |
| 782 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); | 811 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); |
| 783 } | 812 } |
| 784 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 813 if (Dumped) { |
| 785 if (Dumped) { | 814 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
| 786 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 815 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
| 787 Str << "+"; | 816 Str << "+"; |
| 817 Offset->emit(Func); | |
| 788 } | 818 } |
| 819 } else { | |
| 820 // There is only the offset. | |
| 789 Offset->emit(Func); | 821 Offset->emit(Func); |
| 790 } | 822 } |
| 791 Str << "]"; | 823 Str << "]"; |
| 792 } | 824 } |
| 793 | 825 |
| 794 void OperandX8632Mem::dump(const Cfg *Func) const { | 826 void OperandX8632Mem::dump(const Cfg *Func) const { |
| 795 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 } | |
| 796 bool Dumped = false; | 833 bool Dumped = false; |
| 797 Str << "["; | 834 Str << "["; |
| 798 if (Base) { | 835 if (Base) { |
| 799 Base->dump(Func); | 836 Base->dump(Func); |
| 800 Dumped = true; | 837 Dumped = true; |
| 801 } | 838 } |
| 802 if (Index) { | 839 if (Index) { |
| 803 assert(Base); | 840 assert(Base); |
| 804 Str << "+"; | 841 Str << "+"; |
| 805 if (Shift > 0) | 842 if (Shift > 0) |
| 806 Str << (1u << Shift) << "*"; | 843 Str << (1u << Shift) << "*"; |
| 807 Index->dump(Func); | 844 Index->dump(Func); |
| 808 Dumped = true; | 845 Dumped = true; |
| 809 } | 846 } |
| 810 // Pretty-print the Offset. | 847 // Pretty-print the Offset. |
| 811 bool OffsetIsZero = false; | 848 bool OffsetIsZero = false; |
| 812 bool OffsetIsNegative = false; | 849 bool OffsetIsNegative = false; |
| 813 if (Offset == NULL) { | 850 if (Offset == NULL) { |
| 814 OffsetIsZero = true; | 851 OffsetIsZero = true; |
| 815 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { | 852 } else if (ConstantInteger *CI = llvm::dyn_cast<ConstantInteger>(Offset)) { |
| 816 OffsetIsZero = (CI->getValue() == 0); | 853 OffsetIsZero = (CI->getValue() == 0); |
| 817 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); | 854 OffsetIsNegative = (static_cast<int64_t>(CI->getValue()) < 0); |
| 818 } | 855 } |
| 819 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 | 856 if (Dumped) { |
| 820 if (Dumped) { | 857 if (!OffsetIsZero) { // Suppress if Offset is known to be 0 |
| 821 if (!OffsetIsNegative) // Suppress if Offset is known to be negative | 858 if (!OffsetIsNegative) // Suppress if Offset is known to be negative |
| 822 Str << "+"; | 859 Str << "+"; |
| 860 Offset->emit(Func); | |
|
Jim Stichnoth
2014/06/12 20:52:07
emit --> dump
jvoung (off chromium)
2014/06/16 20:51:59
Oops the dangers of copy paste. Done.
| |
| 823 } | 861 } |
| 824 Offset->dump(Func); | 862 } else { |
| 863 // There is only the offset. | |
| 864 Offset->emit(Func); | |
|
Jim Stichnoth
2014/06/12 20:52:07
emit --> dump
jvoung (off chromium)
2014/06/16 20:51:59
Done.
| |
| 825 } | 865 } |
| 826 Str << "]"; | 866 Str << "]"; |
| 827 } | 867 } |
| 828 | 868 |
| 829 void VariableSplit::emit(const Cfg *Func) const { | 869 void VariableSplit::emit(const Cfg *Func) const { |
| 830 Ostream &Str = Func->getContext()->getStrEmit(); | 870 Ostream &Str = Func->getContext()->getStrEmit(); |
| 831 assert(Var->getLocalUseNode() == NULL || | 871 assert(Var->getLocalUseNode() == NULL || |
| 832 Var->getLocalUseNode() == Func->getCurrentNode()); | 872 Var->getLocalUseNode() == Func->getCurrentNode()); |
| 833 assert(!Var->hasReg()); | 873 assert(!Var->hasReg()); |
| 834 // The following is copied/adapted from TargetX8632::emitVariable(). | 874 // The following is copied/adapted from TargetX8632::emitVariable(). |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 859 default: | 899 default: |
| 860 Str << "???"; | 900 Str << "???"; |
| 861 break; | 901 break; |
| 862 } | 902 } |
| 863 Str << "("; | 903 Str << "("; |
| 864 Var->dump(Func); | 904 Var->dump(Func); |
| 865 Str << ")"; | 905 Str << ")"; |
| 866 } | 906 } |
| 867 | 907 |
| 868 } // end of namespace Ice | 908 } // end of namespace Ice |
| OLD | NEW |