| Index: src/IceInstX8632.cpp
|
| diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
|
| index b983c3e7d6d4737615d412099e3728e3745b505c..79ec127ffd36e358966b8998c3bd76dfba978029 100644
|
| --- a/src/IceInstX8632.cpp
|
| +++ b/src/IceInstX8632.cpp
|
| @@ -182,6 +182,11 @@ InstX8632Mov::InstX8632Mov(Cfg *Func, Variable *Dest, Operand *Source)
|
| addSource(Source);
|
| }
|
|
|
| +InstX8632Movp::InstX8632Movp(Cfg *Func, Variable *Dest, Operand *Source)
|
| + : InstX8632(Func, InstX8632::Movp, 1, Dest) {
|
| + addSource(Source);
|
| +}
|
| +
|
| InstX8632StoreQ::InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem)
|
| : InstX8632(Func, InstX8632::StoreQ, 2, NULL) {
|
| addSource(Value);
|
| @@ -222,6 +227,9 @@ InstX8632Push::InstX8632Push(Cfg *Func, Operand *Source,
|
| }
|
|
|
| bool InstX8632Mov::isRedundantAssign() const {
|
| + // TODO(stichnot): The isRedundantAssign() implementations for
|
| + // InstX8632Mov, InstX8632Movp, and InstX8632Movq are
|
| + // identical. Consolidate them.
|
| Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
|
| if (Src == NULL)
|
| return false;
|
| @@ -237,6 +245,19 @@ bool InstX8632Mov::isRedundantAssign() const {
|
| return false;
|
| }
|
|
|
| +bool InstX8632Movp::isRedundantAssign() const {
|
| + Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
|
| + if (Src == NULL)
|
| + return false;
|
| + if (getDest()->hasReg() && getDest()->getRegNum() == Src->getRegNum()) {
|
| + return true;
|
| + }
|
| + if (!getDest()->hasReg() && !Src->hasReg() &&
|
| + Dest->getStackOffset() == Src->getStackOffset())
|
| + return true;
|
| + return false;
|
| +}
|
| +
|
| bool InstX8632Movq::isRedundantAssign() const {
|
| Variable *Src = llvm::dyn_cast<Variable>(getSrc(0));
|
| if (Src == NULL)
|
| @@ -381,6 +402,7 @@ template <> const char *InstX8632Sbb::Opcode = "sbb";
|
| template <> const char *InstX8632And::Opcode = "and";
|
| template <> const char *InstX8632Or::Opcode = "or";
|
| template <> const char *InstX8632Xor::Opcode = "xor";
|
| +template <> const char *InstX8632Pxor::Opcode = "pxor";
|
| template <> const char *InstX8632Imul::Opcode = "imul";
|
| template <> const char *InstX8632Mulss::Opcode = "mulss";
|
| template <> const char *InstX8632Div::Opcode = "div";
|
| @@ -693,6 +715,20 @@ void InstX8632Mov::dump(const Cfg *Func) const {
|
| dumpSources(Func);
|
| }
|
|
|
| +void InstX8632Movp::emit(const Cfg *Func) const {
|
| + // TODO(wala,stichnot): movups works with all vector operands, but
|
| + // there exist other instructions (movaps, movdqa, movdqu) that may
|
| + // perform better, depending on the data type and alignment of the
|
| + // operands.
|
| + Ostream &Str = Func->getContext()->getStrEmit();
|
| + assert(getSrcSize() == 1);
|
| + Str << "\tmovups\t";
|
| + getDest()->emit(Func);
|
| + Str << ", ";
|
| + getSrc(0)->emit(Func);
|
| + Str << "\n";
|
| +}
|
| +
|
| void InstX8632Movq::emit(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrEmit();
|
| assert(getSrcSize() == 1);
|
| @@ -705,6 +741,14 @@ void InstX8632Movq::emit(const Cfg *Func) const {
|
| Str << "\n";
|
| }
|
|
|
| +void InstX8632Movp::dump(const Cfg *Func) const {
|
| + Ostream &Str = Func->getContext()->getStrDump();
|
| + Str << "movups." << getDest()->getType() << " ";
|
| + dumpDest(Func);
|
| + Str << ", ";
|
| + dumpSources(Func);
|
| +}
|
| +
|
| void InstX8632Movq::dump(const Cfg *Func) const {
|
| Ostream &Str = Func->getContext()->getStrDump();
|
| Str << "movq." << getDest()->getType() << " ";
|
|
|