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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 | 159 |
160 InstX8632UD2::InstX8632UD2(Cfg *Func) | 160 InstX8632UD2::InstX8632UD2(Cfg *Func) |
161 : InstX8632(Func, InstX8632::UD2, 0, NULL) {} | 161 : InstX8632(Func, InstX8632::UD2, 0, NULL) {} |
162 | 162 |
163 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) | 163 InstX8632Test::InstX8632Test(Cfg *Func, Operand *Src1, Operand *Src2) |
164 : InstX8632(Func, InstX8632::Test, 2, NULL) { | 164 : InstX8632(Func, InstX8632::Test, 2, NULL) { |
165 addSource(Src1); | 165 addSource(Src1); |
166 addSource(Src2); | 166 addSource(Src2); |
167 } | 167 } |
168 | 168 |
| 169 InstX8632Mfence::InstX8632Mfence(Cfg *Func) |
| 170 : InstX8632(Func, InstX8632::Mfence, 0, NULL) {} |
| 171 |
169 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) | 172 InstX8632Store::InstX8632Store(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
170 : InstX8632(Func, InstX8632::Store, 2, NULL) { | 173 : InstX8632(Func, InstX8632::Store, 2, NULL) { |
171 addSource(Value); | 174 addSource(Value); |
172 addSource(Mem); | 175 addSource(Mem); |
173 } | 176 } |
174 | 177 |
175 InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source) | 178 InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source) |
176 : InstX8632(Func, InstX8632::Mov, 1, Dest) { | 179 : InstX8632(Func, InstX8632::Mov, 1, Dest) { |
177 addSource(Source); | 180 addSource(Source); |
178 } | 181 } |
179 | 182 |
| 183 InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem) |
| 184 : InstX8632(Func, InstX8632::StoreQ, 2, NULL) { |
| 185 addSource(Value); |
| 186 addSource(Mem); |
| 187 } |
| 188 |
| 189 InstX8632Movq::InstX8632Movq(Cfg *Func, Variable *Dest, Operand *Source) |
| 190 : InstX8632(Func, InstX8632::Movq, 1, Dest) { |
| 191 addSource(Source); |
| 192 } |
| 193 |
180 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) | 194 InstX8632Movsx::InstX8632Movsx(Cfg *Func, Variable *Dest, Operand *Source) |
181 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { | 195 : InstX8632(Func, InstX8632::Movsx, 1, Dest) { |
182 addSource(Source); | 196 addSource(Source); |
183 } | 197 } |
184 | 198 |
185 InstX8632Movzx::InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source) | 199 InstX8632Movzx::InstX8632Movzx(Cfg *Func, Variable *Dest, Operand *Source) |
186 : InstX8632(Func, InstX8632::Movzx, 1, Dest) { | 200 : InstX8632(Func, InstX8632::Movzx, 1, Dest) { |
187 addSource(Source); | 201 addSource(Source); |
188 } | 202 } |
189 | 203 |
(...skipping 24 matching lines...) Expand all Loading... |
214 // clear the upper 32 bits of rax. We need to recognize and | 228 // clear the upper 32 bits of rax. We need to recognize and |
215 // preserve these. | 229 // preserve these. |
216 return true; | 230 return true; |
217 } | 231 } |
218 if (!getDest()->hasReg() && !Src->hasReg() && | 232 if (!getDest()->hasReg() && !Src->hasReg() && |
219 Dest->getStackOffset() == Src->getStackOffset()) | 233 Dest->getStackOffset() == Src->getStackOffset()) |
220 return true; | 234 return true; |
221 return false; | 235 return false; |
222 } | 236 } |
223 | 237 |
| 238 bool InstX8632Movq::isRedundantAssign() const { |
| 239 Variable *Src = llvm::dyn_cast<Variable>(getSrc(0)); |
| 240 if (Src == NULL) |
| 241 return false; |
| 242 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
| 243 return true; |
| 244 } |
| 245 if (!getDest()->hasReg() && !Src->hasReg() && |
| 246 Dest->getStackOffset() == Src->getStackOffset()) |
| 247 return true; |
| 248 return false; |
| 249 } |
| 250 |
224 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) | 251 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) |
225 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { | 252 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { |
226 if (Source) | 253 if (Source) |
227 addSource(Source); | 254 addSource(Source); |
228 } | 255 } |
229 | 256 |
| 257 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, |
| 258 bool Locked) |
| 259 : InstX8632(Func, InstX8632::Xadd, 2, llvm::dyn_cast<Variable>(Dest)), |
| 260 Locked(Locked) { |
| 261 addSource(Dest); |
| 262 addSource(Source); |
| 263 } |
| 264 |
230 // ======================== Dump routines ======================== // | 265 // ======================== Dump routines ======================== // |
231 | 266 |
232 void InstX8632::dump(const Cfg *Func) const { | 267 void InstX8632::dump(const Cfg *Func) const { |
233 Ostream &Str = Func->getContext()->getStrDump(); | 268 Ostream &Str = Func->getContext()->getStrDump(); |
234 Str << "[X8632] "; | 269 Str << "[X8632] "; |
235 Inst::dump(Func); | 270 Inst::dump(Func); |
236 } | 271 } |
237 | 272 |
238 void InstX8632Label::emit(const Cfg *Func) const { | 273 void InstX8632Label::emit(const Cfg *Func) const { |
239 Ostream &Str = Func->getContext()->getStrEmit(); | 274 Ostream &Str = Func->getContext()->getStrEmit(); |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 getSrc(1)->emit(Func); | 592 getSrc(1)->emit(Func); |
558 Str << "\n"; | 593 Str << "\n"; |
559 } | 594 } |
560 | 595 |
561 void InstX8632Test::dump(const Cfg *Func) const { | 596 void InstX8632Test::dump(const Cfg *Func) const { |
562 Ostream &Str = Func->getContext()->getStrDump(); | 597 Ostream &Str = Func->getContext()->getStrDump(); |
563 Str << "test." << getSrc(0)->getType() << " "; | 598 Str << "test." << getSrc(0)->getType() << " "; |
564 dumpSources(Func); | 599 dumpSources(Func); |
565 } | 600 } |
566 | 601 |
| 602 void InstX8632Mfence::emit(const Cfg *Func) const { |
| 603 Ostream &Str = Func->getContext()->getStrEmit(); |
| 604 assert(getSrcSize() == 0); |
| 605 Str << "\tmfence\n"; |
| 606 } |
| 607 |
| 608 void InstX8632Mfence::dump(const Cfg *Func) const { |
| 609 Ostream &Str = Func->getContext()->getStrDump(); |
| 610 Str << "mfence\n"; |
| 611 } |
| 612 |
567 void InstX8632Store::emit(const Cfg *Func) const { | 613 void InstX8632Store::emit(const Cfg *Func) const { |
568 Ostream &Str = Func->getContext()->getStrEmit(); | 614 Ostream &Str = Func->getContext()->getStrEmit(); |
569 assert(getSrcSize() == 2); | 615 assert(getSrcSize() == 2); |
570 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString | 616 Str << "\tmov" << TypeX8632Attributes[getSrc(0)->getType()].SdSsString |
571 << "\t"; | 617 << "\t"; |
572 getSrc(1)->emit(Func); | 618 getSrc(1)->emit(Func); |
573 Str << ", "; | 619 Str << ", "; |
574 getSrc(0)->emit(Func); | 620 getSrc(0)->emit(Func); |
575 Str << "\n"; | 621 Str << "\n"; |
576 } | 622 } |
577 | 623 |
578 void InstX8632Store::dump(const Cfg *Func) const { | 624 void InstX8632Store::dump(const Cfg *Func) const { |
579 Ostream &Str = Func->getContext()->getStrDump(); | 625 Ostream &Str = Func->getContext()->getStrDump(); |
580 Str << "mov." << getSrc(0)->getType() << " "; | 626 Str << "mov." << getSrc(0)->getType() << " "; |
581 getSrc(1)->dump(Func); | 627 getSrc(1)->dump(Func); |
582 Str << ", "; | 628 Str << ", "; |
583 getSrc(0)->dump(Func); | 629 getSrc(0)->dump(Func); |
584 } | 630 } |
585 | 631 |
| 632 void InstX8632StoreQ::emit(const Cfg *Func) const { |
| 633 Ostream &Str = Func->getContext()->getStrEmit(); |
| 634 assert(getSrcSize() == 2); |
| 635 assert(getSrc(1)->getType() == IceType_i64 || |
| 636 getSrc(1)->getType() == IceType_f64); |
| 637 Str << "\tmovq\t"; |
| 638 getSrc(1)->emit(Func); |
| 639 Str << ", "; |
| 640 getSrc(0)->emit(Func); |
| 641 Str << "\n"; |
| 642 } |
| 643 |
| 644 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 645 Ostream &Str = Func->getContext()->getStrDump(); |
| 646 Str << "storeq." << getSrc(0)->getType() << " "; |
| 647 getSrc(1)->dump(Func); |
| 648 Str << ", "; |
| 649 getSrc(0)->dump(Func); |
| 650 } |
| 651 |
586 void InstX8632Mov::emit(const Cfg *Func) const { | 652 void InstX8632Mov::emit(const Cfg *Func) const { |
587 Ostream &Str = Func->getContext()->getStrEmit(); | 653 Ostream &Str = Func->getContext()->getStrEmit(); |
588 assert(getSrcSize() == 1); | 654 assert(getSrcSize() == 1); |
589 Str << "\tmov" << TypeX8632Attributes[getDest()->getType()].SdSsString | 655 Str << "\tmov" << TypeX8632Attributes[getDest()->getType()].SdSsString |
590 << "\t"; | 656 << "\t"; |
591 // For an integer truncation operation, src is wider than dest. | 657 // For an integer truncation operation, src is wider than dest. |
592 // Ideally, we use a mov instruction whose data width matches the | 658 // Ideally, we use a mov instruction whose data width matches the |
593 // narrower dest. This is a problem if e.g. src is a register like | 659 // narrower dest. This is a problem if e.g. src is a register like |
594 // esi or si where there is no 8-bit version of the register. To be | 660 // esi or si where there is no 8-bit version of the register. To be |
595 // safe, we instead widen the dest to match src. This works even | 661 // safe, we instead widen the dest to match src. This works even |
596 // for stack-allocated dest variables because typeWidthOnStack() | 662 // for stack-allocated dest variables because typeWidthOnStack() |
597 // pads to a 4-byte boundary even if only a lower portion is used. | 663 // pads to a 4-byte boundary even if only a lower portion is used. |
598 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 664 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
599 Func->getTarget()->typeWidthInBytesOnStack(getSrc(0)->getType())); | 665 Func->getTarget()->typeWidthInBytesOnStack(getSrc(0)->getType())); |
600 getDest()->asType(getSrc(0)->getType()).emit(Func); | 666 getDest()->asType(getSrc(0)->getType()).emit(Func); |
601 Str << ", "; | 667 Str << ", "; |
602 getSrc(0)->emit(Func); | 668 getSrc(0)->emit(Func); |
603 Str << "\n"; | 669 Str << "\n"; |
604 } | 670 } |
605 | 671 |
606 void InstX8632Mov::dump(const Cfg *Func) const { | 672 void InstX8632Mov::dump(const Cfg *Func) const { |
607 Ostream &Str = Func->getContext()->getStrDump(); | 673 Ostream &Str = Func->getContext()->getStrDump(); |
608 Str << "mov." << getDest()->getType() << " "; | 674 Str << "mov." << getDest()->getType() << " "; |
609 dumpDest(Func); | 675 dumpDest(Func); |
610 Str << ", "; | 676 Str << ", "; |
611 dumpSources(Func); | 677 dumpSources(Func); |
612 } | 678 } |
613 | 679 |
| 680 void InstX8632Movq::emit(const Cfg *Func) const { |
| 681 Ostream &Str = Func->getContext()->getStrEmit(); |
| 682 assert(getSrcSize() == 1); |
| 683 assert(getDest()->getType() == IceType_i64 || |
| 684 getDest()->getType() == IceType_f64); |
| 685 Str << "\tmovq\t"; |
| 686 getDest()->emit(Func); |
| 687 Str << ", "; |
| 688 getSrc(0)->emit(Func); |
| 689 Str << "\n"; |
| 690 } |
| 691 |
| 692 void InstX8632Movq::dump(const Cfg *Func) const { |
| 693 Ostream &Str = Func->getContext()->getStrDump(); |
| 694 Str << "movq." << getDest()->getType() << " "; |
| 695 dumpDest(Func); |
| 696 Str << ", "; |
| 697 dumpSources(Func); |
| 698 } |
| 699 |
614 void InstX8632Movsx::emit(const Cfg *Func) const { | 700 void InstX8632Movsx::emit(const Cfg *Func) const { |
615 Ostream &Str = Func->getContext()->getStrEmit(); | 701 Ostream &Str = Func->getContext()->getStrEmit(); |
616 assert(getSrcSize() == 1); | 702 assert(getSrcSize() == 1); |
617 Str << "\tmovsx\t"; | 703 Str << "\tmovsx\t"; |
618 getDest()->emit(Func); | 704 getDest()->emit(Func); |
619 Str << ", "; | 705 Str << ", "; |
620 getSrc(0)->emit(Func); | 706 getSrc(0)->emit(Func); |
621 Str << "\n"; | 707 Str << "\n"; |
622 } | 708 } |
623 | 709 |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
766 Str << "\tret\n"; | 852 Str << "\tret\n"; |
767 } | 853 } |
768 | 854 |
769 void InstX8632Ret::dump(const Cfg *Func) const { | 855 void InstX8632Ret::dump(const Cfg *Func) const { |
770 Ostream &Str = Func->getContext()->getStrDump(); | 856 Ostream &Str = Func->getContext()->getStrDump(); |
771 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 857 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
772 Str << "ret." << Ty << " "; | 858 Str << "ret." << Ty << " "; |
773 dumpSources(Func); | 859 dumpSources(Func); |
774 } | 860 } |
775 | 861 |
| 862 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 863 Ostream &Str = Func->getContext()->getStrEmit(); |
| 864 if (Locked) { |
| 865 Str << "\tlock xadd "; |
| 866 } else { |
| 867 Str << "\txadd\t"; |
| 868 } |
| 869 getSrc(0)->emit(Func); |
| 870 Str << ", "; |
| 871 getSrc(1)->emit(Func); |
| 872 Str << "\n"; |
| 873 } |
| 874 |
| 875 void InstX8632Xadd::dump(const Cfg *Func) const { |
| 876 Ostream &Str = Func->getContext()->getStrDump(); |
| 877 if (Locked) { |
| 878 Str << "lock "; |
| 879 } |
| 880 Type Ty = getSrc(0)->getType(); |
| 881 Str << "xadd." << Ty << " "; |
| 882 dumpSources(Func); |
| 883 } |
| 884 |
776 void OperandX8632::dump(const Cfg *Func) const { | 885 void OperandX8632::dump(const Cfg *Func) const { |
777 Ostream &Str = Func->getContext()->getStrDump(); | 886 Ostream &Str = Func->getContext()->getStrDump(); |
778 Str << "<OperandX8632>"; | 887 Str << "<OperandX8632>"; |
779 } | 888 } |
780 | 889 |
781 void OperandX8632Mem::emit(const Cfg *Func) const { | 890 void OperandX8632Mem::emit(const Cfg *Func) const { |
782 Ostream &Str = Func->getContext()->getStrEmit(); | 891 Ostream &Str = Func->getContext()->getStrEmit(); |
783 Str << TypeX8632Attributes[getType()].WidthString << " "; | 892 Str << TypeX8632Attributes[getType()].WidthString << " "; |
784 if (SegmentReg != DefaultSegment) { | 893 if (SegmentReg != DefaultSegment) { |
785 assert(SegmentReg >= 0 && | 894 assert(SegmentReg >= 0 && |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
899 default: | 1008 default: |
900 Str << "???"; | 1009 Str << "???"; |
901 break; | 1010 break; |
902 } | 1011 } |
903 Str << "("; | 1012 Str << "("; |
904 Var->dump(Func); | 1013 Var->dump(Func); |
905 Str << ")"; | 1014 Str << ")"; |
906 } | 1015 } |
907 | 1016 |
908 } // end of namespace Ice | 1017 } // end of namespace Ice |
OLD | NEW |