| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index bb994409ce4c21077d97d3ca22d1cbfb71a82717..baa145f311dc6128c8f302705c4a2a4e0c3ce774 100644
|
| --- a/src/IceInstX8632.cpp
|
| +++ b/src/IceInstX8632.cpp
|
| @@ -42,7 +42,7 @@ const struct TypeX8632Attributes_ {
|
| const char *PackString; // b, w, d, or <blank>
|
| const char *WidthString; // {byte,word,dword,qword} ptr
|
| } TypeX8632Attributes[] = {
|
| -#define X(tag, cvt, sdss, pack, width) \
|
| +#define X(tag, elementty, cvt, sdss, pack, width) \
|
| { cvt, "" sdss, pack, width } \
|
| ,
|
| ICETYPEX8632_TABLE
|
| @@ -312,21 +312,6 @@ bool InstX8632Movq::isRedundantAssign() const {
|
| return false;
|
| }
|
|
|
| -InstX8632Pshufd::InstX8632Pshufd(Cfg *Func, Variable *Dest, Operand *Source1,
|
| - Operand *Source2)
|
| - : InstX8632(Func, InstX8632::Pshufd, 2, Dest) {
|
| - addSource(Source1);
|
| - addSource(Source2);
|
| -}
|
| -
|
| -InstX8632Shufps::InstX8632Shufps(Cfg *Func, Variable *Dest, Operand *Source1,
|
| - Operand *Source2)
|
| - : InstX8632(Func, InstX8632::Shufps, 3, Dest) {
|
| - addSource(Dest);
|
| - addSource(Source1);
|
| - addSource(Source2);
|
| -}
|
| -
|
| InstX8632Ret::InstX8632Ret(Cfg *Func, Variable *Source)
|
| : InstX8632(Func, InstX8632::Ret, Source ? 1 : 0, NULL) {
|
| if (Source)
|
| @@ -454,9 +439,15 @@ void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func,
|
| Str << "\n";
|
| }
|
|
|
| +
|
| +// Unary ops
|
| template <> const char *InstX8632Bsf::Opcode = "bsf";
|
| template <> const char *InstX8632Bsr::Opcode = "bsr";
|
| +template <> const char *InstX8632Lea::Opcode = "lea";
|
| +template <> const char *InstX8632Movd::Opcode = "movd";
|
| +template <> const char *InstX8632Movss::Opcode = "movss";
|
| template <> const char *InstX8632Sqrtss::Opcode = "sqrtss";
|
| +// Binary ops
|
| template <> const char *InstX8632Add::Opcode = "add";
|
| template <> const char *InstX8632Addps::Opcode = "addps";
|
| template <> const char *InstX8632Adc::Opcode = "adc";
|
| @@ -489,6 +480,12 @@ template <> const char *InstX8632Sar::Opcode = "sar";
|
| template <> const char *InstX8632Psra::Opcode = "psra";
|
| template <> const char *InstX8632Pcmpeq::Opcode = "pcmpeq";
|
| template <> const char *InstX8632Pcmpgt::Opcode = "pcmpgt";
|
| +// Ternary ops
|
| +template <> const char *InstX8632Shufps::Opcode = "shufps";
|
| +template <> const char *InstX8632Pinsrw::Opcode = "pinsrw";
|
| +// Three address ops
|
| +template <> const char *InstX8632Pextrw::Opcode = "pextrw";
|
| +template <> const char *InstX8632Pshufd::Opcode = "pshufd";
|
|
|
| template <> void InstX8632Sqrtss::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| @@ -556,6 +553,22 @@ template <> void InstX8632Divss::emit(const Cfg *Func) const {
|
| emitTwoAddress(buf, this, Func);
|
| }
|
|
|
| +template <> void InstX8632Div::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 3);
|
| + Str << "\t" << Opcode << "\t";
|
| + getSrc(1)->emit(Func);
|
| + Str << "\n";
|
| +}
|
| +
|
| +template <> void InstX8632Idiv::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 3);
|
| + Str << "\t" << Opcode << "\t";
|
| + getSrc(1)->emit(Func);
|
| + Str << "\n";
|
| +}
|
| +
|
| template <> void InstX8632Imul::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| assert(getSrcSize() == 2);
|
| @@ -868,6 +881,25 @@ void InstX8632StoreQ::dump(const Cfg *Func) const {
|
| getSrc(0)->dump(Func);
|
| }
|
|
|
| +template <> void InstX8632Lea::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 1);
|
| + assert(getDest()->hasReg());
|
| + Str << "\tlea\t";
|
| + getDest()->emit(Func);
|
| + Str << ", ";
|
| + Operand *Src0 = getSrc(0);
|
| + if (Variable *VSrc0 = llvm::dyn_cast<Variable>(Src0)) {
|
| + Type Ty = VSrc0->getType();
|
| + // lea on x86-32 doesn't accept mem128 operands, so cast VSrc0 to an
|
| + // acceptable type.
|
| + VSrc0->asType(isVectorType(Ty) ? IceType_i32 : Ty).emit(Func);
|
| + } else {
|
| + Src0->emit(Func);
|
| + }
|
| + Str << "\n";
|
| +}
|
| +
|
| void InstX8632Mov::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| assert(getSrcSize() == 1);
|
| @@ -893,6 +925,9 @@ void InstX8632Mov::emit(const Cfg *Func) const {
|
| // safe, we instead widen the dest to match src. This works even
|
| // for stack-allocated dest variables because typeWidthOnStack()
|
| // pads to a 4-byte boundary even if only a lower portion is used.
|
| + // TODO: This assert disallows usages such as copying a floating point
|
| + // value between a vector and a scalar (which movss is used for).
|
| + // Clean this up.
|
| assert(Func->getTarget()->typeWidthInBytesOnStack(getDest()->getType()) ==
|
| Func->getTarget()->typeWidthInBytesOnStack(Src->getType()));
|
| getDest()->asType(Src->getType()).emit(Func);
|
| @@ -1066,6 +1101,39 @@ template <> void InstX8632Pcmpgt::emit(const Cfg *Func) const {
|
| emitTwoAddress(buf, this, Func);
|
| }
|
|
|
| +template <> void InstX8632Pextrw::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 2);
|
| + Str << "\t" << Opcode << "\t";
|
| + Variable *Dest = getDest();
|
| + assert(Dest->hasReg() && Dest->getType() == IceType_i16);
|
| + // pextrw takes r32 dest.
|
| + Dest->asType(IceType_i32).emit(Func);
|
| + Str << ", ";
|
| + getSrc(0)->emit(Func);
|
| + Str << ", ";
|
| + getSrc(1)->emit(Func);
|
| + Str << "\n";
|
| +}
|
| +
|
| +template <> void InstX8632Pinsrw::emit(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 3);
|
| + Str << "\t" << Opcode << "\t";
|
| + getDest()->emit(Func);
|
| + Str << ", ";
|
| + Operand *Src1 = getSrc(1);
|
| + if (Variable *VSrc1 = llvm::dyn_cast<Variable>(Src1)) {
|
| + // If src1 is a register, it should be r32.
|
| + VSrc1->asType(VSrc1->hasReg() ? IceType_i32 : IceType_i16).emit(Func);
|
| + } else {
|
| + Src1->emit(Func);
|
| + }
|
| + Str << ", ";
|
| + getSrc(2)->emit(Func);
|
| + Str << "\n";
|
| +}
|
| +
|
| void InstX8632Pop::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| assert(getSrcSize() == 0);
|
| @@ -1138,25 +1206,6 @@ template <> void InstX8632Psra::emit(const Cfg *Func) const {
|
| emitTwoAddress(buf, this, Func);
|
| }
|
|
|
| -void InstX8632Pshufd::emit(const Cfg *Func) const {
|
| - Ostream &Str = Func->getContext()->getStrEmit();
|
| - assert(getSrcSize() == 2);
|
| - Str << "\tpshufd\t";
|
| - getDest()->emit(Func);
|
| - Str << ", ";
|
| - getSrc(0)->emit(Func);
|
| - Str << ", ";
|
| - getSrc(1)->emit(Func);
|
| - Str << "\n";
|
| -}
|
| -
|
| -void InstX8632Pshufd::dump(const Cfg *Func) const {
|
| - Ostream &Str = Func->getContext()->getStrDump();
|
| - dumpDest(Func);
|
| - Str << " = pshufd." << getDest()->getType() << " ";
|
| - dumpSources(Func);
|
| -}
|
| -
|
| void InstX8632Ret::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| Str << "\tret\n";
|
| @@ -1169,25 +1218,6 @@ void InstX8632Ret::dump(const Cfg *Func) const {
|
| dumpSources(Func);
|
| }
|
|
|
| -void InstX8632Shufps::emit(const Cfg *Func) const {
|
| - Ostream &Str = Func->getContext()->getStrEmit();
|
| - assert(getSrcSize() == 3);
|
| - Str << "\tshufps\t";
|
| - getDest()->emit(Func);
|
| - Str << ", ";
|
| - getSrc(1)->emit(Func);
|
| - Str << ", ";
|
| - getSrc(2)->emit(Func);
|
| - Str << "\n";
|
| -}
|
| -
|
| -void InstX8632Shufps::dump(const Cfg *Func) const {
|
| - Ostream &Str = Func->getContext()->getStrDump();
|
| - dumpDest(Func);
|
| - Str << " = shufps." << getDest()->getType() << " ";
|
| - dumpSources(Func);
|
| -}
|
| -
|
| void InstX8632Xadd::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| if (Locked) {
|
|
|