Add template parameter for suffix to BinopXmm BUG= R=jpp@chromium.org, stichnot@chromium.org Review URL: https://codereview.chromium.org/1530423002 .
diff --git a/src/IceInstX86Base.h b/src/IceInstX86Base.h index b536208..40be5a7 100644 --- a/src/IceInstX86Base.h +++ b/src/IceInstX86Base.h
@@ -149,6 +149,8 @@ IacaEnd }; + enum SseSuffix { None, Packed, Scalar, Integral }; + static const char *getWidthString(Type Ty); static const char *getFldString(Type Ty); static typename Traits::Cond::BrCond @@ -156,8 +158,8 @@ void dump(const Cfg *Func) const override; // Shared emit routines for common forms of instructions. - static void emitTwoAddress(const char *Opcode, const Inst *Inst, - const Cfg *Func); + void emitTwoAddress(const Cfg *Func, const char *Opcode, + const char *Suffix = "") const; static void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, @@ -628,7 +630,7 @@ void emit(const Cfg *Func) const override { if (!BuildDefs::dump()) return; - this->emitTwoAddress(Opcode, this, Func); + this->emitTwoAddress(Func, Opcode); } void emitIAS(const Cfg *Func) const override { Type Ty = this->getDest()->getType(); @@ -671,7 +673,7 @@ void emit(const Cfg *Func) const override { if (!BuildDefs::dump()) return; - this->emitTwoAddress(Opcode, this, Func); + this->emitTwoAddress(Func, Opcode); } void emitIAS(const Cfg *Func) const override { Type Ty = this->getDest()->getType(); @@ -715,7 +717,7 @@ void emit(const Cfg *Func) const override { if (!BuildDefs::dump()) return; - this->emitTwoAddress(Opcode, this, Func); + this->emitTwoAddress(Func, Opcode); } void emitIAS(const Cfg *Func) const override { Type Ty = this->getSrc(0)->getType(); @@ -749,20 +751,43 @@ }; template <class Machine, typename InstX86Base<Machine>::InstKindX86 K, - bool NeedsElementType> + bool NeedsElementType, + typename InstX86Base<Machine>::SseSuffix Suffix> class InstX86BaseBinopXmm : public InstX86Base<Machine> { InstX86BaseBinopXmm() = delete; InstX86BaseBinopXmm(const InstX86BaseBinopXmm &) = delete; InstX86BaseBinopXmm &operator=(const InstX86BaseBinopXmm &) = delete; public: - using Base = InstX86BaseBinopXmm<Machine, K, NeedsElementType>; + using Base = InstX86BaseBinopXmm<Machine, K, NeedsElementType, Suffix>; void emit(const Cfg *Func) const override { if (!BuildDefs::dump()) return; this->validateVectorAddrMode(); - this->emitTwoAddress(Opcode, this, Func); + switch (Suffix) { + case InstX86Base<Machine>::SseSuffix::None: + this->emitTwoAddress(Func, Opcode); + break; + case InstX86Base<Machine>::SseSuffix::Packed: { + const Type DestTy = this->getDest()->getType(); + this->emitTwoAddress( + Func, this->Opcode, + InstX86Base<Machine>::Traits::TypeAttributes[DestTy].PdPsString); + } break; + case InstX86Base<Machine>::SseSuffix::Scalar: { + const Type DestTy = this->getDest()->getType(); + this->emitTwoAddress( + Func, this->Opcode, + InstX86Base<Machine>::Traits::TypeAttributes[DestTy].SdSsString); + } break; + case InstX86Base<Machine>::SseSuffix::Integral: { + const Type DestTy = this->getDest()->getType(); + this->emitTwoAddress( + Func, this->Opcode, + InstX86Base<Machine>::Traits::TypeAttributes[DestTy].PackString); + } break; + } } void emitIAS(const Cfg *Func) const override { this->validateVectorAddrMode(); @@ -818,7 +843,11 @@ if (!BuildDefs::dump()) return; this->validateVectorAddrMode(); - this->emitTwoAddress(Opcode, this, Func); + // Shift operations are always integral, and hence always need a suffix. + const Type DestTy = this->getDest()->getType(); + this->emitTwoAddress( + Func, this->Opcode, + InstX86Base<Machine>::Traits::TypeAttributes[DestTy].PackString); } void emitIAS(const Cfg *Func) const override { this->validateVectorAddrMode(); @@ -1254,7 +1283,8 @@ template <class Machine> class InstX86Addps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Addps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Addps>()) @@ -1263,8 +1293,9 @@ private: InstX86Addps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> @@ -1303,34 +1334,34 @@ template <class Machine> class InstX86Addss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Addss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Addss>()) InstX86Addss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Addss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Addss, false, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Padd - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true, + InstX86Base<Machine>::SseSuffix::Integral> { public: static InstX86Padd *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Padd>()) InstX86Padd(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Padd(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true>( + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Padd, true, + InstX86Base<Machine>::SseSuffix::Integral>( Func, Dest, Source) {} }; @@ -1370,7 +1401,8 @@ template <class Machine> class InstX86Subps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Subps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Subps>()) @@ -1379,25 +1411,26 @@ private: InstX86Subps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Subss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Subss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Subss>()) InstX86Subss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Subss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Subss, false, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> @@ -1436,17 +1469,17 @@ template <class Machine> class InstX86Psub - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true, + InstX86Base<Machine>::SseSuffix::Integral> { public: static InstX86Psub *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Psub>()) InstX86Psub(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Psub(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true>( + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Psub, true, + InstX86Base<Machine>::SseSuffix::Integral>( Func, Dest, Source) {} }; @@ -1466,36 +1499,36 @@ template <class Machine> class InstX86Andnps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andnps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andnps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Andnps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Andnps>()) InstX86Andnps(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Andnps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andnps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andnps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Andps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Andps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Andps>()) InstX86Andps(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Andps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Andps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> @@ -1520,7 +1553,8 @@ template <class Machine> class InstX86Pand - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false, + InstX86Base<Machine>::SseSuffix::None> { public: static InstX86Pand *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Pand>()) InstX86Pand(Func, Dest, Source); @@ -1528,13 +1562,15 @@ private: InstX86Pand(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pand, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Pandn - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false, + InstX86Base<Machine>::SseSuffix::None> { public: static InstX86Pandn *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Pandn>()) @@ -1543,42 +1579,43 @@ private: InstX86Pandn(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pandn, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Maxss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Maxss, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Maxss, true, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Maxss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Maxss>()) InstX86Maxss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Maxss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Maxss, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Maxss, true, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Minss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Minss, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Minss, true, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Minss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Minss>()) InstX86Minss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Minss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Minss, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Minss, true, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> @@ -1597,18 +1634,18 @@ template <class Machine> class InstX86Orps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Orps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Orps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Orps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Orps>()) InstX86Orps(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Orps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Orps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Orps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> @@ -1633,7 +1670,8 @@ template <class Machine> class InstX86Por - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false, + InstX86Base<Machine>::SseSuffix::None> { public: static InstX86Por *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Por>()) InstX86Por(Func, Dest, Source); @@ -1641,8 +1679,9 @@ private: InstX86Por(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Por, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> @@ -1661,19 +1700,19 @@ template <class Machine> class InstX86Xorps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Xorps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Xorps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Xorps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Xorps>()) InstX86Xorps(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Xorps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Xorps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Xorps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> @@ -1698,7 +1737,8 @@ template <class Machine> class InstX86Pxor - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false, + InstX86Base<Machine>::SseSuffix::None> { public: static InstX86Pxor *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Pxor>()) InstX86Pxor(Func, Dest, Source); @@ -1706,8 +1746,9 @@ private: InstX86Pxor(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pxor, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> @@ -1748,7 +1789,8 @@ template <class Machine> class InstX86Mulps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Mulps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Mulps>()) @@ -1757,66 +1799,78 @@ private: InstX86Mulps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Mulss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Mulss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Mulss>()) InstX86Mulss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Mulss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Mulss, false, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Pmull - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true, + InstX86Base<Machine>::SseSuffix::Integral> { public: static InstX86Pmull *create(Cfg *Func, Variable *Dest, Operand *Source) { + bool TypesAreValid = + Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v8i16; + auto *Target = InstX86Base<Machine>::getTarget(Func); + bool InstructionSetIsValid = + Dest->getType() == IceType_v8i16 || + Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1; + (void)TypesAreValid; + (void)InstructionSetIsValid; + assert(TypesAreValid); + assert(InstructionSetIsValid); return new (Func->allocate<InstX86Pmull>()) InstX86Pmull(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - void emitIAS(const Cfg *Func) const override; - private: InstX86Pmull(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true>( + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmull, true, + InstX86Base<Machine>::SseSuffix::Integral>( Func, Dest, Source) {} }; template <class Machine> class InstX86Pmuludq - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, - false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, false, + InstX86Base<Machine>::SseSuffix::None> { public: static InstX86Pmuludq *create(Cfg *Func, Variable *Dest, Operand *Source) { + assert(Dest->getType() == IceType_v4i32 && + Source->getType() == IceType_v4i32); return new (Func->allocate<InstX86Pmuludq>()) InstX86Pmuludq(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Pmuludq(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pmuludq, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Divps - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true, + InstX86Base<Machine>::SseSuffix::Packed> { public: static InstX86Divps *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Divps>()) @@ -1825,25 +1879,26 @@ private: InstX86Divps(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divps, true, + InstX86Base<Machine>::SseSuffix::Packed>(Func, Dest, + Source) {} }; template <class Machine> class InstX86Divss - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false, + InstX86Base<Machine>::SseSuffix::Scalar> { public: static InstX86Divss *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Divss>()) InstX86Divss(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Divss(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Divss, false, + InstX86Base<Machine>::SseSuffix::Scalar>(Func, Dest, + Source) {} }; template <class Machine> @@ -1879,11 +1934,12 @@ : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll> { public: static InstX86Psll *create(Cfg *Func, Variable *Dest, Operand *Source) { + assert(Dest->getType() == IceType_v8i16 || + Dest->getType() == IceType_v8i1 || + Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1); return new (Func->allocate<InstX86Psll>()) InstX86Psll(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Psll(Cfg *Func, Variable *Dest, Operand *Source) : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psll>( @@ -1899,8 +1955,6 @@ return new (Func->allocate<InstX86Psrl>()) InstX86Psrl(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Psrl(Cfg *Func, Variable *Dest, Operand *Source) : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psrl, true>( @@ -1940,11 +1994,12 @@ : public InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra> { public: static InstX86Psra *create(Cfg *Func, Variable *Dest, Operand *Source) { + assert(Dest->getType() == IceType_v8i16 || + Dest->getType() == IceType_v8i1 || + Dest->getType() == IceType_v4i32 || Dest->getType() == IceType_v4i1); return new (Func->allocate<InstX86Psra>()) InstX86Psra(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Psra(Cfg *Func, Variable *Dest, Operand *Source) : InstX86BaseBinopXmmShift<Machine, InstX86Base<Machine>::Psra>( @@ -1953,35 +2008,35 @@ template <class Machine> class InstX86Pcmpeq - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true, + InstX86Base<Machine>::SseSuffix::Integral> { public: static InstX86Pcmpeq *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Pcmpeq>()) InstX86Pcmpeq(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Pcmpeq(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true>( + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpeq, true, + InstX86Base<Machine>::SseSuffix::Integral>( Func, Dest, Source) {} }; template <class Machine> class InstX86Pcmpgt - : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true> { + : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true, + InstX86Base<Machine>::SseSuffix::Integral> { public: static InstX86Pcmpgt *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86Pcmpgt>()) InstX86Pcmpgt(Func, Dest, Source); } - void emit(const Cfg *Func) const override; - private: InstX86Pcmpgt(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true>( + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::Pcmpgt, true, + InstX86Base<Machine>::SseSuffix::Integral>( Func, Dest, Source) {} }; @@ -1994,7 +2049,7 @@ template <class Machine> class InstX86MovssRegs : public InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, - false> { + false, InstX86Base<Machine>::SseSuffix::None> { public: static InstX86MovssRegs *create(Cfg *Func, Variable *Dest, Operand *Source) { return new (Func->allocate<InstX86MovssRegs>()) @@ -2005,8 +2060,9 @@ private: InstX86MovssRegs(Cfg *Func, Variable *Dest, Operand *Source) - : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, false>( - Func, Dest, Source) {} + : InstX86BaseBinopXmm<Machine, InstX86Base<Machine>::MovssRegs, false, + InstX86Base<Machine>::SseSuffix::None>(Func, Dest, + Source) {} }; template <class Machine> @@ -2071,6 +2127,11 @@ public: static InstX86Pinsr *create(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) { + // pinsrb and pinsrd are SSE4.1 instructions. + assert(Dest->getType() == IceType_v8i16 || + Dest->getType() == IceType_v8i1 || + InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= + InstX86Base<Machine>::Traits::SSE4_1); return new (Func->allocate<InstX86Pinsr>()) InstX86Pinsr(Func, Dest, Source1, Source2); } @@ -2108,6 +2169,8 @@ public: static InstX86Blendvps *create(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) { + assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= + InstX86Base<Machine>::Traits::SSE4_1); return new (Func->allocate<InstX86Blendvps>()) InstX86Blendvps(Func, Dest, Source1, Source2); } @@ -2127,6 +2190,8 @@ public: static InstX86Pblendvb *create(Cfg *Func, Variable *Dest, Operand *Source1, Operand *Source2) { + assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= + InstX86Base<Machine>::Traits::SSE4_1); return new (Func->allocate<InstX86Pblendvb>()) InstX86Pblendvb(Func, Dest, Source1, Source2); } @@ -2146,6 +2211,10 @@ public: static InstX86Pextr *create(Cfg *Func, Variable *Dest, Operand *Source0, Operand *Source1) { + assert(Source0->getType() == IceType_v8i16 || + Source0->getType() == IceType_v8i1 || + InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= + InstX86Base<Machine>::Traits::SSE4_1); return new (Func->allocate<InstX86Pextr>()) InstX86Pextr(Func, Dest, Source0, Source1); }
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h index c943560..3b62001 100644 --- a/src/IceInstX86BaseImpl.h +++ b/src/IceInstX86BaseImpl.h
@@ -622,19 +622,19 @@ // The this->Opcode parameter needs to be char* and not IceString because of // template issues. template <class Machine> -void InstX86Base<Machine>::emitTwoAddress(const char *Opcode, const Inst *Inst, - const Cfg *Func) { +void InstX86Base<Machine>::emitTwoAddress(const Cfg *Func, const char *Opcode, + const char *Suffix) const { if (!BuildDefs::dump()) return; Ostream &Str = Func->getContext()->getStrEmit(); - assert(Inst->getSrcSize() == 2); - Operand *Dest = Inst->getDest(); + assert(getSrcSize() == 2); + Operand *Dest = getDest(); if (Dest == nullptr) - Dest = Inst->getSrc(0); - assert(Dest == Inst->getSrc(0)); - Operand *Src1 = Inst->getSrc(1); - Str << "\t" << Opcode << InstX86Base<Machine>::getWidthString(Dest->getType()) - << "\t"; + Dest = getSrc(0); + assert(Dest == getSrc(0)); + Operand *Src1 = getSrc(1); + Str << "\t" << Opcode << Suffix + << InstX86Base<Machine>::getWidthString(Dest->getType()) << "\t"; Src1->emit(Func); Str << ", "; Dest->emit(Func); @@ -1008,205 +1008,6 @@ this->getDest()->emit(Func); } -template <class Machine> -void InstX86Addss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "add%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Padd<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "padd%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Pmull<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - bool TypesAreValid = this->getDest()->getType() == IceType_v4i32 || - this->getDest()->getType() == IceType_v8i16; - auto *Target = InstX86Base<Machine>::getTarget(Func); - bool InstructionSetIsValid = - this->getDest()->getType() == IceType_v8i16 || - Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1; - (void)TypesAreValid; - (void)InstructionSetIsValid; - assert(TypesAreValid); - assert(InstructionSetIsValid); - snprintf( - buf, llvm::array_lengthof(buf), "pmull%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Pmull<Machine>::emitIAS(const Cfg *Func) const { - Type Ty = this->getDest()->getType(); - bool TypesAreValid = Ty == IceType_v4i32 || Ty == IceType_v8i16; - auto *Target = InstX86Base<Machine>::getTarget(Func); - bool InstructionSetIsValid = - Ty == IceType_v8i16 || - Target->getInstructionSet() >= InstX86Base<Machine>::Traits::SSE4_1; - (void)TypesAreValid; - (void)InstructionSetIsValid; - assert(TypesAreValid); - assert(InstructionSetIsValid); - assert(this->getSrcSize() == 2); - Type ElementTy = typeElementType(Ty); - emitIASRegOpTyXMM<Machine>(Func, ElementTy, this->getDest(), this->getSrc(1), - this->Emitter); -} - -template <class Machine> -void InstX86Subss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "sub%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Psub<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "psub%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Mulss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "mul%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Andnps<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PdPsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Andps<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PdPsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Maxss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Minss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Orps<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PdPsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Xorps<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "%s%s", this->Opcode, - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PdPsString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Pmuludq<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - assert(this->getSrc(0)->getType() == IceType_v4i32 && - this->getSrc(1)->getType() == IceType_v4i32); - this->emitTwoAddress(this->Opcode, this, Func); -} - -template <class Machine> -void InstX86Divss<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "div%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .SdSsString); - this->emitTwoAddress(buf, this, Func); -} - template <class Machine> void InstX86Div<Machine>::emit(const Cfg *Func) const { if (!BuildDefs::dump()) return; @@ -1283,15 +1084,11 @@ void InstX86Blendvps<Machine>::emit(const Cfg *Func) const { if (!BuildDefs::dump()) return; - assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); emitVariableBlendInst<Machine>(this->Opcode, this, Func); } template <class Machine> void InstX86Blendvps<Machine>::emitIAS(const Cfg *Func) const { - assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {&InstX86Base<Machine>::Traits::Assembler::blendvps, &InstX86Base<Machine>::Traits::Assembler::blendvps}; @@ -1302,15 +1099,11 @@ void InstX86Pblendvb<Machine>::emit(const Cfg *Func) const { if (!BuildDefs::dump()) return; - assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); emitVariableBlendInst<Machine>(this->Opcode, this, Func); } template <class Machine> void InstX86Pblendvb<Machine>::emitIAS(const Cfg *Func) const { - assert(InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); static const typename InstX86Base<Machine>::Traits::Assembler::XmmEmitterRegOp Emitter = {&InstX86Base<Machine>::Traits::Assembler::pblendvb, &InstX86Base<Machine>::Traits::Assembler::pblendvb}; @@ -1342,7 +1135,7 @@ Str << ", "; Dest->emit(Func); } else { - this->emitTwoAddress("imul", this, Func); + this->emitTwoAddress(Func, this->Opcode); } } @@ -2791,40 +2584,12 @@ } template <class Machine> -void InstX86Pcmpeq<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "pcmpeq%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Pcmpgt<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "pcmpgt%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> void InstX86Pextr<Machine>::emit(const Cfg *Func) const { if (!BuildDefs::dump()) return; Ostream &Str = Func->getContext()->getStrEmit(); assert(this->getSrcSize() == 2); // pextrb and pextrd are SSE4.1 instructions. - assert(this->getSrc(0)->getType() == IceType_v8i16 || - this->getSrc(0)->getType() == IceType_v8i1 || - InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); Str << "\t" << this->Opcode << InstX86Base<Machine>::Traits::TypeAttributes[this->getSrc(0) ->getType()] @@ -2848,9 +2613,6 @@ const Variable *Dest = this->getDest(); Type DispatchTy = InstX86Base<Machine>::Traits::getInVectorElementType( this->getSrc(0)->getType()); - assert(DispatchTy == IceType_i16 || - InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); // pextrw must take a register dest. There is an SSE4.1 version that takes a // memory dest, but we aren't using it. For uniformity, just restrict them // all to have a register dest for now. @@ -2876,11 +2638,6 @@ return; Ostream &Str = Func->getContext()->getStrEmit(); assert(this->getSrcSize() == 3); - // pinsrb and pinsrd are SSE4.1 instructions. - assert(this->getDest()->getType() == IceType_v8i16 || - this->getDest()->getType() == IceType_v8i1 || - InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); Str << "\t" << this->Opcode << InstX86Base< Machine>::Traits::TypeAttributes[this->getDest()->getType()] @@ -2912,9 +2669,6 @@ // pinsrb and pinsrd are SSE4.1 instructions. const Operand *Src0 = this->getSrc(1); Type DispatchTy = Src0->getType(); - assert(DispatchTy == IceType_i16 || - InstX86Base<Machine>::getTarget(Func)->getInstructionSet() >= - InstX86Base<Machine>::Traits::SSE4_1); // If src1 is a register, it should always be r32 (this should fall out from // the encodings for ByteRegs overlapping the encodings for r32), but we have // to make sure the register allocator didn't choose an 8-bit high register @@ -3049,50 +2803,6 @@ this->dumpSources(Func); } -template <class Machine> -void InstX86Psll<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - assert(this->getDest()->getType() == IceType_v8i16 || - this->getDest()->getType() == IceType_v8i1 || - this->getDest()->getType() == IceType_v4i32 || - this->getDest()->getType() == IceType_v4i1); - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "psll%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Psra<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - assert(this->getDest()->getType() == IceType_v8i16 || - this->getDest()->getType() == IceType_v8i1 || - this->getDest()->getType() == IceType_v4i32 || - this->getDest()->getType() == IceType_v4i1); - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "psra%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - -template <class Machine> -void InstX86Psrl<Machine>::emit(const Cfg *Func) const { - if (!BuildDefs::dump()) - return; - char buf[30]; - snprintf( - buf, llvm::array_lengthof(buf), "psrl%s", - InstX86Base<Machine>::Traits::TypeAttributes[this->getDest()->getType()] - .PackString); - this->emitTwoAddress(buf, this, Func); -} - template <class Machine> void InstX86Ret<Machine>::emit(const Cfg *Func) const { if (!BuildDefs::dump()) return;