Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(478)

Side by Side Diff: src/IceInstX8632.cpp

Issue 321993002: Add a few Subzero intrinsics (not the atomic ones yet). (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: bitwise sideeffects Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t" 739 Str << "\tmov" << TypeX8632Attributes[Ty].SdSsString << "\t"
717 << TypeX8632Attributes[Ty].WidthString << " [esp], "; 740 << TypeX8632Attributes[Ty].WidthString << " [esp], ";
718 getSrc(0)->emit(Func); 741 getSrc(0)->emit(Func);
719 Str << "\n"; 742 Str << "\n";
720 } else if (Ty == IceType_f64 && (!Var || !Var->hasReg())) { 743 } else if (Ty == IceType_f64 && (!Var || !Var->hasReg())) {
721 // A double on the stack has to be pushed as two halves. Push the 744 // A double on the stack has to be pushed as two halves. Push the
722 // upper half followed by the lower half for little-endian. TODO: 745 // upper half followed by the lower half for little-endian. TODO:
723 // implement. 746 // implement.
724 llvm_unreachable("Missing support for pushing doubles from memory"); 747 llvm_unreachable("Missing support for pushing doubles from memory");
725 } else { 748 } else {
749 // TODO: we may want to assert that the operand type/size is legal.
726 Str << "\tpush\t"; 750 Str << "\tpush\t";
727 getSrc(0)->emit(Func); 751 getSrc(0)->emit(Func);
728 Str << "\n"; 752 Str << "\n";
729 if (!SuppressStackAdjustment) 753 if (!SuppressStackAdjustment)
730 Func->getTarget()->updateStackAdjustment(4); 754 Func->getTarget()->updateStackAdjustment(4);
731 } 755 }
732 } 756 }
733 757
734 void InstX8632Push::dump(const Cfg *Func) const { 758 void InstX8632Push::dump(const Cfg *Func) const {
735 Ostream &Str = Func->getContext()->getStrDump(); 759 Ostream &Str = Func->getContext()->getStrDump();
(...skipping 14 matching lines...) Expand all
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->dump(Func);
823 } 861 }
862 } else {
863 // There is only the offset.
824 Offset->dump(Func); 864 Offset->dump(Func);
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());
(...skipping 25 matching lines...) Expand all
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698