| 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 24 matching lines...) Expand all Loading... |
| 35 }; | 35 }; |
| 36 const size_t InstX8632BrAttributesSize = | 36 const size_t InstX8632BrAttributesSize = |
| 37 llvm::array_lengthof(InstX8632BrAttributes); | 37 llvm::array_lengthof(InstX8632BrAttributes); |
| 38 | 38 |
| 39 const struct TypeX8632Attributes_ { | 39 const struct TypeX8632Attributes_ { |
| 40 const char *CvtString; // i (integer), s (single FP), d (double FP) | 40 const char *CvtString; // i (integer), s (single FP), d (double FP) |
| 41 const char *SdSsString; // ss, sd, or <blank> | 41 const char *SdSsString; // ss, sd, or <blank> |
| 42 const char *PackString; // b, w, d, or <blank> | 42 const char *PackString; // b, w, d, or <blank> |
| 43 const char *WidthString; // {byte,word,dword,qword} ptr | 43 const char *WidthString; // {byte,word,dword,qword} ptr |
| 44 } TypeX8632Attributes[] = { | 44 } TypeX8632Attributes[] = { |
| 45 #define X(tag, cvt, sdss, pack, width) \ | 45 #define X(tag, elementty, cvt, sdss, pack, width) \ |
| 46 { cvt, "" sdss, pack, width } \ | 46 { cvt, "" sdss, pack, width } \ |
| 47 , | 47 , |
| 48 ICETYPEX8632_TABLE | 48 ICETYPEX8632_TABLE |
| 49 #undef X | 49 #undef X |
| 50 }; | 50 }; |
| 51 const size_t TypeX8632AttributesSize = | 51 const size_t TypeX8632AttributesSize = |
| 52 llvm::array_lengthof(TypeX8632Attributes); | 52 llvm::array_lengthof(TypeX8632Attributes); |
| 53 | 53 |
| 54 const char *InstX8632SegmentRegNames[] = { | 54 const char *InstX8632SegmentRegNames[] = { |
| 55 #define X(val, name) name, | 55 #define X(val, name) name, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 return false; | 305 return false; |
| 306 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { | 306 if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) { |
| 307 return true; | 307 return true; |
| 308 } | 308 } |
| 309 if (!getDest()->hasReg() && !Src->hasReg() && | 309 if (!getDest()->hasReg() && !Src->hasReg() && |
| 310 Dest->getStackOffset() == Src->getStackOffset()) | 310 Dest->getStackOffset() == Src->getStackOffset()) |
| 311 return true; | 311 return true; |
| 312 return false; | 312 return false; |
| 313 } | 313 } |
| 314 | 314 |
| 315 InstX8632Pshufd::InstX8632Pshufd(Cfg *Func, Variable *Dest, Operand *Source1, | |
| 316 Operand *Source2) | |
| 317 : InstX8632(Func, InstX8632::Pshufd, 2, Dest) { | |
| 318 addSource(Source1); | |
| 319 addSource(Source2); | |
| 320 } | |
| 321 | |
| 322 InstX8632Shufps::InstX8632Shufps(Cfg *Func, Variable *Dest, Operand *Source1, | |
| 323 Operand *Source2) | |
| 324 : InstX8632(Func, InstX8632::Shufps, 3, Dest) { | |
| 325 addSource(Dest); | |
| 326 addSource(Source1); | |
| 327 addSource(Source2); | |
| 328 } | |
| 329 | |
| 330 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) | 315 InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source) |
| 331 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { | 316 : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) { |
| 332 if (Source) | 317 if (Source) |
| 333 addSource(Source); | 318 addSource(Source); |
| 334 } | 319 } |
| 335 | 320 |
| 336 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, | 321 InstX8632Xadd::InstX8632Xadd(Cfg *Func, Operand *Dest, Variable *Source, |
| 337 bool Locked) | 322 bool Locked) |
| 338 : InstX8632Lockable(Func, InstX8632::Xadd, 2, | 323 : InstX8632Lockable(Func, InstX8632::Xadd, 2, |
| 339 llvm::dyn_cast<Variable>(Dest), Locked) { | 324 llvm::dyn_cast<Variable>(Dest), Locked) { |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { | 432 if (ShiftReg && ShiftReg->getRegNum() == TargetX8632::Reg_ecx) { |
| 448 Str << "cl"; | 433 Str << "cl"; |
| 449 EmittedSrc1 = true; | 434 EmittedSrc1 = true; |
| 450 } | 435 } |
| 451 } | 436 } |
| 452 if (!EmittedSrc1) | 437 if (!EmittedSrc1) |
| 453 Inst->getSrc(1)->emit(Func); | 438 Inst->getSrc(1)->emit(Func); |
| 454 Str << "\n"; | 439 Str << "\n"; |
| 455 } | 440 } |
| 456 | 441 |
| 442 |
| 443 // Unary ops |
| 457 template <> const char *InstX8632Bsf::Opcode = "bsf"; | 444 template <> const char *InstX8632Bsf::Opcode = "bsf"; |
| 458 template <> const char *InstX8632Bsr::Opcode = "bsr"; | 445 template <> const char *InstX8632Bsr::Opcode = "bsr"; |
| 446 template <> const char *InstX8632Lea::Opcode = "lea"; |
| 447 template <> const char *InstX8632Movd::Opcode = "movd"; |
| 448 template <> const char *InstX8632Movss::Opcode = "movss"; |
| 459 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; | 449 template <> const char *InstX8632Sqrtss::Opcode = "sqrtss"; |
| 450 // Binary ops |
| 460 template <> const char *InstX8632Add::Opcode = "add"; | 451 template <> const char *InstX8632Add::Opcode = "add"; |
| 461 template <> const char *InstX8632Addps::Opcode = "addps"; | 452 template <> const char *InstX8632Addps::Opcode = "addps"; |
| 462 template <> const char *InstX8632Adc::Opcode = "adc"; | 453 template <> const char *InstX8632Adc::Opcode = "adc"; |
| 463 template <> const char *InstX8632Addss::Opcode = "addss"; | 454 template <> const char *InstX8632Addss::Opcode = "addss"; |
| 464 template <> const char *InstX8632Padd::Opcode = "padd"; | 455 template <> const char *InstX8632Padd::Opcode = "padd"; |
| 465 template <> const char *InstX8632Sub::Opcode = "sub"; | 456 template <> const char *InstX8632Sub::Opcode = "sub"; |
| 466 template <> const char *InstX8632Subps::Opcode = "subps"; | 457 template <> const char *InstX8632Subps::Opcode = "subps"; |
| 467 template <> const char *InstX8632Subss::Opcode = "subss"; | 458 template <> const char *InstX8632Subss::Opcode = "subss"; |
| 468 template <> const char *InstX8632Sbb::Opcode = "sbb"; | 459 template <> const char *InstX8632Sbb::Opcode = "sbb"; |
| 469 template <> const char *InstX8632Psub::Opcode = "psub"; | 460 template <> const char *InstX8632Psub::Opcode = "psub"; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 482 template <> const char *InstX8632Divps::Opcode = "divps"; | 473 template <> const char *InstX8632Divps::Opcode = "divps"; |
| 483 template <> const char *InstX8632Idiv::Opcode = "idiv"; | 474 template <> const char *InstX8632Idiv::Opcode = "idiv"; |
| 484 template <> const char *InstX8632Divss::Opcode = "divss"; | 475 template <> const char *InstX8632Divss::Opcode = "divss"; |
| 485 template <> const char *InstX8632Shl::Opcode = "shl"; | 476 template <> const char *InstX8632Shl::Opcode = "shl"; |
| 486 template <> const char *InstX8632Psll::Opcode = "psll"; | 477 template <> const char *InstX8632Psll::Opcode = "psll"; |
| 487 template <> const char *InstX8632Shr::Opcode = "shr"; | 478 template <> const char *InstX8632Shr::Opcode = "shr"; |
| 488 template <> const char *InstX8632Sar::Opcode = "sar"; | 479 template <> const char *InstX8632Sar::Opcode = "sar"; |
| 489 template <> const char *InstX8632Psra::Opcode = "psra"; | 480 template <> const char *InstX8632Psra::Opcode = "psra"; |
| 490 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; | 481 template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq"; |
| 491 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; | 482 template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt"; |
| 483 // Ternary ops |
| 484 template <> const char *InstX8632Shufps::Opcode = "shufps"; |
| 485 template <> const char *InstX8632Pinsrw::Opcode = "pinsrw"; |
| 486 // Three address ops |
| 487 template <> const char *InstX8632Pextrw::Opcode = "pextrw"; |
| 488 template <> const char *InstX8632Pshufd::Opcode = "pshufd"; |
| 492 | 489 |
| 493 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { | 490 template <> void InstX8632Sqrtss::emit(const Cfg *Func) const { |
| 494 Ostream &Str = Func->getContext()->getStrEmit(); | 491 Ostream &Str = Func->getContext()->getStrEmit(); |
| 495 assert(getSrcSize() == 1); | 492 assert(getSrcSize() == 1); |
| 496 Type Ty = getSrc(0)->getType(); | 493 Type Ty = getSrc(0)->getType(); |
| 497 assert(Ty == IceType_f32 || Ty == IceType_f64); | 494 assert(Ty == IceType_f32 || Ty == IceType_f64); |
| 498 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; | 495 Str << "\tsqrt" << TypeX8632Attributes[Ty].SdSsString << "\t"; |
| 499 getDest()->emit(Func); | 496 getDest()->emit(Func); |
| 500 Str << ", "; | 497 Str << ", "; |
| 501 getSrc(0)->emit(Func); | 498 getSrc(0)->emit(Func); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 emitTwoAddress(Opcode, this, Func); | 546 emitTwoAddress(Opcode, this, Func); |
| 550 } | 547 } |
| 551 | 548 |
| 552 template <> void InstX8632Divss::emit(const Cfg *Func) const { | 549 template <> void InstX8632Divss::emit(const Cfg *Func) const { |
| 553 char buf[30]; | 550 char buf[30]; |
| 554 snprintf(buf, llvm::array_lengthof(buf), "div%s", | 551 snprintf(buf, llvm::array_lengthof(buf), "div%s", |
| 555 TypeX8632Attributes[getDest()->getType()].SdSsString); | 552 TypeX8632Attributes[getDest()->getType()].SdSsString); |
| 556 emitTwoAddress(buf, this, Func); | 553 emitTwoAddress(buf, this, Func); |
| 557 } | 554 } |
| 558 | 555 |
| 556 template <> void InstX8632Div::emit(const Cfg *Func) const { |
| 557 Ostream &Str = Func->getContext()->getStrEmit(); |
| 558 assert(getSrcSize() == 3); |
| 559 Str << "\t" << Opcode << "\t"; |
| 560 getSrc(1)->emit(Func); |
| 561 Str << "\n"; |
| 562 } |
| 563 |
| 564 template <> void InstX8632Idiv::emit(const Cfg *Func) const { |
| 565 Ostream &Str = Func->getContext()->getStrEmit(); |
| 566 assert(getSrcSize() == 3); |
| 567 Str << "\t" << Opcode << "\t"; |
| 568 getSrc(1)->emit(Func); |
| 569 Str << "\n"; |
| 570 } |
| 571 |
| 559 template <> void InstX8632Imul::emit(const Cfg *Func) const { | 572 template <> void InstX8632Imul::emit(const Cfg *Func) const { |
| 560 Ostream &Str = Func->getContext()->getStrEmit(); | 573 Ostream &Str = Func->getContext()->getStrEmit(); |
| 561 assert(getSrcSize() == 2); | 574 assert(getSrcSize() == 2); |
| 562 if (getDest()->getType() == IceType_i8) { | 575 if (getDest()->getType() == IceType_i8) { |
| 563 // The 8-bit version of imul only allows the form "imul r/m8". | 576 // The 8-bit version of imul only allows the form "imul r/m8". |
| 564 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); | 577 Variable *Src0 = llvm::dyn_cast<Variable>(getSrc(0)); |
| 565 assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax); | 578 assert(Src0 && Src0->getRegNum() == TargetX8632::Reg_eax); |
| 566 Str << "\timul\t"; | 579 Str << "\timul\t"; |
| 567 getSrc(1)->emit(Func); | 580 getSrc(1)->emit(Func); |
| 568 Str << "\n"; | 581 Str << "\n"; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 861 } | 874 } |
| 862 | 875 |
| 863 void InstX8632StoreQ::dump(const Cfg *Func) const { | 876 void InstX8632StoreQ::dump(const Cfg *Func) const { |
| 864 Ostream &Str = Func->getContext()->getStrDump(); | 877 Ostream &Str = Func->getContext()->getStrDump(); |
| 865 Str << "storeq." << getSrc(0)->getType() << " "; | 878 Str << "storeq." << getSrc(0)->getType() << " "; |
| 866 getSrc(1)->dump(Func); | 879 getSrc(1)->dump(Func); |
| 867 Str << ", "; | 880 Str << ", "; |
| 868 getSrc(0)->dump(Func); | 881 getSrc(0)->dump(Func); |
| 869 } | 882 } |
| 870 | 883 |
| 884 template <> void InstX8632Lea::emit(const Cfg *Func) const { |
| 885 Ostream &Str = Func->getContext()->getStrEmit(); |
| 886 assert(getSrcSize() == 1); |
| 887 assert(getDest()->hasReg()); |
| 888 Str << "\tlea\t"; |
| 889 getDest()->emit(Func); |
| 890 Str << ", "; |
| 891 Operand *Src0 = getSrc(0); |
| 892 if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) { |
| 893 Type Ty = VSrc0->getType(); |
| 894 // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an |
| 895 // acceptable type. |
| 896 VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func); |
| 897 } else { |
| 898 Src0->emit(Func); |
| 899 } |
| 900 Str << "\n"; |
| 901 } |
| 902 |
| 871 void InstX8632Mov::emit(const Cfg *Func) const { | 903 void InstX8632Mov::emit(const Cfg *Func) const { |
| 872 Ostream &Str = Func->getContext()->getStrEmit(); | 904 Ostream &Str = Func->getContext()->getStrEmit(); |
| 873 assert(getSrcSize() == 1); | 905 assert(getSrcSize() == 1); |
| 874 Operand *Src = getSrc(0); | 906 Operand *Src = getSrc(0); |
| 875 // The llvm-mc assembler using Intel syntax has a bug in which "mov | 907 // The llvm-mc assembler using Intel syntax has a bug in which "mov |
| 876 // reg, RelocatableConstant" does not generate the right instruction | 908 // reg, RelocatableConstant" does not generate the right instruction |
| 877 // with a relocation. To work around, we emit "lea reg, | 909 // with a relocation. To work around, we emit "lea reg, |
| 878 // [RelocatableConstant]". Also, the lowering and legalization is | 910 // [RelocatableConstant]". Also, the lowering and legalization is |
| 879 // changed to allow relocatable constants only in Assign and Call | 911 // changed to allow relocatable constants only in Assign and Call |
| 880 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK | 912 // instructions or in Mem operands. TODO(stichnot): remove LEAHACK |
| 881 // once a proper emitter is used. | 913 // once a proper emitter is used. |
| 882 bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src); | 914 bool UseLeaHack = llvm::isa<ConstantRelocatable>(Src); |
| 883 Str << "\t"; | 915 Str << "\t"; |
| 884 if (UseLeaHack) | 916 if (UseLeaHack) |
| 885 Str << "lea"; | 917 Str << "lea"; |
| 886 else | 918 else |
| 887 Str << "mov" << TypeX8632Attributes[getDest()->getType()].SdSsString; | 919 Str << "mov" << TypeX8632Attributes[getDest()->getType()].SdSsString; |
| 888 Str << "\t"; | 920 Str << "\t"; |
| 889 // For an integer truncation operation, src is wider than dest. | 921 // For an integer truncation operation, src is wider than dest. |
| 890 // Ideally, we use a mov instruction whose data width matches the | 922 // Ideally, we use a mov instruction whose data width matches the |
| 891 // narrower dest. This is a problem if e.g. src is a register like | 923 // narrower dest. This is a problem if e.g. src is a register like |
| 892 // esi or si where there is no 8-bit version of the register. To be | 924 // esi or si where there is no 8-bit version of the register. To be |
| 893 // safe, we instead widen the dest to match src. This works even | 925 // safe, we instead widen the dest to match src. This works even |
| 894 // for stack-allocated dest variables because typeWidthOnStack() | 926 // for stack-allocated dest variables because typeWidthOnStack() |
| 895 // pads to a 4-byte boundary even if only a lower portion is used. | 927 // pads to a 4-byte boundary even if only a lower portion is used. |
| 928 // TODO: This assert disallows usages such as copying a floating point |
| 929 // value between a vector and a scalar (which movss is used for). |
| 930 // Clean this up. |
| 896 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == | 931 assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) == |
| 897 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); | 932 Func->getTarget()->typeWidthInBytesOnStack(Src->getType())); |
| 898 getDest()->asType(Src->getType()).emit(Func); | 933 getDest()->asType(Src->getType()).emit(Func); |
| 899 Str << ", "; | 934 Str << ", "; |
| 900 Src->emit(Func); | 935 Src->emit(Func); |
| 901 Str << "\n"; | 936 Str << "\n"; |
| 902 } | 937 } |
| 903 | 938 |
| 904 void InstX8632Mov::dump(const Cfg *Func) const { | 939 void InstX8632Mov::dump(const Cfg *Func) const { |
| 905 Ostream &Str = Func->getContext()->getStrDump(); | 940 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1059 emitTwoAddress(buf, this, Func); | 1094 emitTwoAddress(buf, this, Func); |
| 1060 } | 1095 } |
| 1061 | 1096 |
| 1062 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { | 1097 template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const { |
| 1063 char buf[30]; | 1098 char buf[30]; |
| 1064 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", | 1099 snprintf(buf, llvm::array_lengthof(buf), "pcmpgt%s", |
| 1065 TypeX8632Attributes[getDest()->getType()].PackString); | 1100 TypeX8632Attributes[getDest()->getType()].PackString); |
| 1066 emitTwoAddress(buf, this, Func); | 1101 emitTwoAddress(buf, this, Func); |
| 1067 } | 1102 } |
| 1068 | 1103 |
| 1104 template <> void InstX8632Pextrw::emit(const Cfg *Func) const { |
| 1105 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1106 assert(getSrcSize() == 2); |
| 1107 Str << "\t" << Opcode << "\t"; |
| 1108 Variable *Dest = getDest(); |
| 1109 assert(Dest->hasReg() && Dest->getType() == IceType_i16); |
| 1110 // pextrw takes r32 dest. |
| 1111 Dest->asType(IceType_i32).emit(Func); |
| 1112 Str << ", "; |
| 1113 getSrc(0)->emit(Func); |
| 1114 Str << ", "; |
| 1115 getSrc(1)->emit(Func); |
| 1116 Str << "\n"; |
| 1117 } |
| 1118 |
| 1119 template <> void InstX8632Pinsrw::emit(const Cfg *Func) const { |
| 1120 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1121 assert(getSrcSize() == 3); |
| 1122 Str << "\t" << Opcode << "\t"; |
| 1123 getDest()->emit(Func); |
| 1124 Str << ", "; |
| 1125 Operand *Src1 = getSrc(1); |
| 1126 if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) { |
| 1127 // If src1 is a register, it should be r32. |
| 1128 VSrc1->asType(VSrc1->hasReg() ? IceType_i32 : IceType_i16).emit(Func); |
| 1129 } else { |
| 1130 Src1->emit(Func); |
| 1131 } |
| 1132 Str << ", "; |
| 1133 getSrc(2)->emit(Func); |
| 1134 Str << "\n"; |
| 1135 } |
| 1136 |
| 1069 void InstX8632Pop::emit(const Cfg *Func) const { | 1137 void InstX8632Pop::emit(const Cfg *Func) const { |
| 1070 Ostream &Str = Func->getContext()->getStrEmit(); | 1138 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1071 assert(getSrcSize() == 0); | 1139 assert(getSrcSize() == 0); |
| 1072 Str << "\tpop\t"; | 1140 Str << "\tpop\t"; |
| 1073 getDest()->emit(Func); | 1141 getDest()->emit(Func); |
| 1074 Str << "\n"; | 1142 Str << "\n"; |
| 1075 } | 1143 } |
| 1076 | 1144 |
| 1077 void InstX8632Pop::dump(const Cfg *Func) const { | 1145 void InstX8632Pop::dump(const Cfg *Func) const { |
| 1078 Ostream &Str = Func->getContext()->getStrDump(); | 1146 Ostream &Str = Func->getContext()->getStrDump(); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1131 | 1199 |
| 1132 template <> void InstX8632Psra::emit(const Cfg *Func) const { | 1200 template <> void InstX8632Psra::emit(const Cfg *Func) const { |
| 1133 assert(getDest()->getType() == IceType_v8i16 || | 1201 assert(getDest()->getType() == IceType_v8i16 || |
| 1134 getDest()->getType() == IceType_v4i32); | 1202 getDest()->getType() == IceType_v4i32); |
| 1135 char buf[30]; | 1203 char buf[30]; |
| 1136 snprintf(buf, llvm::array_lengthof(buf), "psra%s", | 1204 snprintf(buf, llvm::array_lengthof(buf), "psra%s", |
| 1137 TypeX8632Attributes[getDest()->getType()].PackString); | 1205 TypeX8632Attributes[getDest()->getType()].PackString); |
| 1138 emitTwoAddress(buf, this, Func); | 1206 emitTwoAddress(buf, this, Func); |
| 1139 } | 1207 } |
| 1140 | 1208 |
| 1141 void InstX8632Pshufd::emit(const Cfg *Func) const { | |
| 1142 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1143 assert(getSrcSize() == 2); | |
| 1144 Str << "\tpshufd\t"; | |
| 1145 getDest()->emit(Func); | |
| 1146 Str << ", "; | |
| 1147 getSrc(0)->emit(Func); | |
| 1148 Str << ", "; | |
| 1149 getSrc(1)->emit(Func); | |
| 1150 Str << "\n"; | |
| 1151 } | |
| 1152 | |
| 1153 void InstX8632Pshufd::dump(const Cfg *Func) const { | |
| 1154 Ostream &Str = Func->getContext()->getStrDump(); | |
| 1155 dumpDest(Func); | |
| 1156 Str << " = pshufd." << getDest()->getType() << " "; | |
| 1157 dumpSources(Func); | |
| 1158 } | |
| 1159 | |
| 1160 void InstX8632Ret::emit(const Cfg *Func) const { | 1209 void InstX8632Ret::emit(const Cfg *Func) const { |
| 1161 Ostream &Str = Func->getContext()->getStrEmit(); | 1210 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1162 Str << "\tret\n"; | 1211 Str << "\tret\n"; |
| 1163 } | 1212 } |
| 1164 | 1213 |
| 1165 void InstX8632Ret::dump(const Cfg *Func) const { | 1214 void InstX8632Ret::dump(const Cfg *Func) const { |
| 1166 Ostream &Str = Func->getContext()->getStrDump(); | 1215 Ostream &Str = Func->getContext()->getStrDump(); |
| 1167 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); | 1216 Type Ty = (getSrcSize() == 0 ? IceType_void : getSrc(0)->getType()); |
| 1168 Str << "ret." << Ty << " "; | 1217 Str << "ret." << Ty << " "; |
| 1169 dumpSources(Func); | 1218 dumpSources(Func); |
| 1170 } | 1219 } |
| 1171 | 1220 |
| 1172 void InstX8632Shufps::emit(const Cfg *Func) const { | |
| 1173 Ostream &Str = Func->getContext()->getStrEmit(); | |
| 1174 assert(getSrcSize() == 3); | |
| 1175 Str << "\tshufps\t"; | |
| 1176 getDest()->emit(Func); | |
| 1177 Str << ", "; | |
| 1178 getSrc(1)->emit(Func); | |
| 1179 Str << ", "; | |
| 1180 getSrc(2)->emit(Func); | |
| 1181 Str << "\n"; | |
| 1182 } | |
| 1183 | |
| 1184 void InstX8632Shufps::dump(const Cfg *Func) const { | |
| 1185 Ostream &Str = Func->getContext()->getStrDump(); | |
| 1186 dumpDest(Func); | |
| 1187 Str << " = shufps." << getDest()->getType() << " "; | |
| 1188 dumpSources(Func); | |
| 1189 } | |
| 1190 | |
| 1191 void InstX8632Xadd::emit(const Cfg *Func) const { | 1221 void InstX8632Xadd::emit(const Cfg *Func) const { |
| 1192 Ostream &Str = Func->getContext()->getStrEmit(); | 1222 Ostream &Str = Func->getContext()->getStrEmit(); |
| 1193 if (Locked) { | 1223 if (Locked) { |
| 1194 Str << "\tlock"; | 1224 Str << "\tlock"; |
| 1195 } | 1225 } |
| 1196 Str << "\txadd\t"; | 1226 Str << "\txadd\t"; |
| 1197 getSrc(0)->emit(Func); | 1227 getSrc(0)->emit(Func); |
| 1198 Str << ", "; | 1228 Str << ", "; |
| 1199 getSrc(1)->emit(Func); | 1229 getSrc(1)->emit(Func); |
| 1200 Str << "\n"; | 1230 Str << "\n"; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1352 default: | 1382 default: |
| 1353 Str << "???"; | 1383 Str << "???"; |
| 1354 break; | 1384 break; |
| 1355 } | 1385 } |
| 1356 Str << "("; | 1386 Str << "("; |
| 1357 Var->dump(Func); | 1387 Var->dump(Func); |
| 1358 Str << ")"; | 1388 Str << ")"; |
| 1359 } | 1389 } |
| 1360 | 1390 |
| 1361 } // end of namespace Ice | 1391 } // end of namespace Ice |
| OLD | NEW |