Index: src/IceInstX8632.h |
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h |
index 8bac6c7ef9058787c7aca074a2909743f1bf33aa..5449c78521b98026ed60e2654ad6eba120f01cbb 100644 |
--- a/src/IceInstX8632.h |
+++ b/src/IceInstX8632.h |
@@ -200,7 +200,7 @@ public: |
Movd, |
Movp, |
Movq, |
- Movss, |
+ MovssRegs, |
Movsx, |
Movzx, |
Mul, |
@@ -521,9 +521,9 @@ private: |
static const x86::AssemblerX86::GPREmitterRegOp Emitter; |
}; |
-void emitIASVarOperandTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
- const Operand *Src, |
- const x86::AssemblerX86::XmmEmitterTwoOps &Emitter); |
+void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, |
+ const Operand *Src, |
+ const x86::AssemblerX86::XmmEmitterRegOp &Emitter); |
template <InstX8632::InstKindX8632 K> |
class InstX8632UnaryopXmm : public InstX8632 { |
@@ -544,7 +544,7 @@ public: |
void emitIAS(const Cfg *Func) const override { |
Type Ty = getDest()->getType(); |
assert(getSrcSize() == 1); |
- emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); |
+ emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(0), Emitter); |
} |
void dump(const Cfg *Func) const override { |
Ostream &Str = Func->getContext()->getStrDump(); |
@@ -563,7 +563,7 @@ private: |
InstX8632UnaryopXmm &operator=(const InstX8632UnaryopXmm &) = delete; |
~InstX8632UnaryopXmm() override {} |
static const char *Opcode; |
- static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
+ static const x86::AssemblerX86::XmmEmitterRegOp Emitter; |
}; |
// See the definition of emitTwoAddress() for a description of |
@@ -571,37 +571,6 @@ private: |
void emitTwoAddress(const char *Opcode, const Inst *Inst, const Cfg *Func, |
bool ShiftHack = false); |
-template <InstX8632::InstKindX8632 K> class InstX8632Binop : public InstX8632 { |
-public: |
- // Create a binary-op instruction (not yet migrated to integrated assembler) |
- static InstX8632Binop *create(Cfg *Func, Variable *Dest, Operand *Source) { |
- return new (Func->allocate<InstX8632Binop>()) |
- InstX8632Binop(Func, Dest, Source); |
- } |
- void emit(const Cfg *Func) const override { |
- const bool ShiftHack = false; |
- emitTwoAddress(Opcode, this, Func, ShiftHack); |
- } |
- void dump(const Cfg *Func) const override { |
- Ostream &Str = Func->getContext()->getStrDump(); |
- dumpDest(Func); |
- Str << " = " << Opcode << "." << getDest()->getType() << " "; |
- dumpSources(Func); |
- } |
- static bool classof(const Inst *Inst) { return isClassof(Inst, K); } |
- |
-private: |
- InstX8632Binop(Cfg *Func, Variable *Dest, Operand *Source) |
- : InstX8632(Func, K, 2, Dest) { |
- addSource(Dest); |
- addSource(Source); |
- } |
- InstX8632Binop(const InstX8632Binop &) = delete; |
- InstX8632Binop &operator=(const InstX8632Binop &) = delete; |
- ~InstX8632Binop() override {} |
- static const char *Opcode; |
-}; |
- |
void emitIASGPRShift(const Cfg *Func, Type Ty, const Variable *Var, |
const Operand *Src, |
const x86::AssemblerX86::GPREmitterShiftOp &Emitter); |
@@ -700,7 +669,7 @@ public: |
if (NeedsElementType) |
Ty = typeElementType(Ty); |
assert(getSrcSize() == 2); |
- emitIASVarOperandTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); |
+ emitIASRegOpTyXMM(Func, Ty, getDest(), getSrc(1), Emitter); |
} |
void dump(const Cfg *Func) const override { |
Ostream &Str = Func->getContext()->getStrDump(); |
@@ -720,7 +689,7 @@ private: |
InstX8632BinopXmm &operator=(const InstX8632BinopXmm &) = delete; |
~InstX8632BinopXmm() override {} |
static const char *Opcode; |
- static const x86::AssemblerX86::XmmEmitterTwoOps Emitter; |
+ static const x86::AssemblerX86::XmmEmitterRegOp Emitter; |
}; |
void emitIASXmmShift(const Cfg *Func, Type Ty, const Variable *Var, |
@@ -866,6 +835,7 @@ public: |
} |
bool isSimpleAssign() const override { return true; } |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override { emit(Func); } |
void dump(const Cfg *Func) const override { |
Ostream &Str = Func->getContext()->getStrDump(); |
Str << Opcode << "." << getDest()->getType() << " "; |
@@ -935,13 +905,14 @@ typedef InstX8632BinopGPRShift<InstX8632::Sar> InstX8632Sar; |
typedef InstX8632BinopXmmShift<InstX8632::Psra> InstX8632Psra; |
typedef InstX8632BinopXmm<InstX8632::Pcmpeq, true> InstX8632Pcmpeq; |
typedef InstX8632BinopXmm<InstX8632::Pcmpgt, true> InstX8632Pcmpgt; |
-// TODO: movss is only a binary operation when the source and dest |
-// operands are both registers. In other cases, it behaves like a copy |
-// (mov-like) operation. Eventually, InstX8632Movss should assert that |
-// both its source and dest operands are registers, and the lowering |
-// code should use _mov instead of _movss in cases where a copy |
-// operation is intended. |
-typedef InstX8632Binop<InstX8632::Movss> InstX8632Movss; |
+// movss is only a binary operation when the source and dest |
+// operands are both registers (the high bits of dest are left untouched). |
+// In other cases, it behaves like a copy (mov-like) operation (and the |
+// high bits of dest are cleared). |
+// InstX8632Movss will assert that both its source and dest operands are |
+// registers, so the lowering code should use _mov instead of _movss |
+// in cases where a copy operation is intended. |
+typedef InstX8632BinopXmm<InstX8632::MovssRegs, false> InstX8632MovssRegs; |
typedef InstX8632Ternop<InstX8632::Idiv> InstX8632Idiv; |
typedef InstX8632Ternop<InstX8632::Div> InstX8632Div; |
typedef InstX8632Ternop<InstX8632::Insertps> InstX8632Insertps; |
@@ -1163,6 +1134,7 @@ public: |
InstX8632Icmp(Func, Src1, Src2); |
} |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override; |
void dump(const Cfg *Func) const override; |
static bool classof(const Inst *Inst) { return isClassof(Inst, Icmp); } |
@@ -1199,6 +1171,7 @@ public: |
return new (Func->allocate<InstX8632UD2>()) InstX8632UD2(Func); |
} |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override; |
void dump(const Cfg *Func) const override; |
static bool classof(const Inst *Inst) { return isClassof(Inst, UD2); } |
@@ -1217,6 +1190,7 @@ public: |
InstX8632Test(Func, Source1, Source2); |
} |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override; |
void dump(const Cfg *Func) const override; |
static bool classof(const Inst *Inst) { return isClassof(Inst, Test); } |
@@ -1265,38 +1239,43 @@ private: |
~InstX8632Store() override {} |
}; |
+// This is essentially a vector "mov" instruction with an OperandX8632Mem |
+// operand instead of Variable as the destination. It's important |
+// for liveness that there is no Dest operand. The source must be an |
+// Xmm register, since Dest is mem. |
class InstX8632StoreP : public InstX8632 { |
public: |
- static InstX8632StoreP *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
+ static InstX8632StoreP *create(Cfg *Func, Variable *Value, |
+ OperandX8632Mem *Mem) { |
return new (Func->allocate<InstX8632StoreP>()) |
InstX8632StoreP(Func, Value, Mem); |
} |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override; |
void dump(const Cfg *Func) const override; |
static bool classof(const Inst *Inst) { return isClassof(Inst, StoreP); } |
private: |
- InstX8632StoreP(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
+ InstX8632StoreP(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); |
InstX8632StoreP(const InstX8632StoreP &) = delete; |
InstX8632StoreP &operator=(const InstX8632StoreP &) = delete; |
~InstX8632StoreP() override {} |
}; |
-// This is essentially a "movq" instruction with an OperandX8632Mem |
-// operand instead of Variable as the destination. It's important |
-// for liveness that there is no Dest operand. |
class InstX8632StoreQ : public InstX8632 { |
public: |
- static InstX8632StoreQ *create(Cfg *Func, Operand *Value, OperandX8632 *Mem) { |
+ static InstX8632StoreQ *create(Cfg *Func, Variable *Value, |
+ OperandX8632Mem *Mem) { |
return new (Func->allocate<InstX8632StoreQ>()) |
InstX8632StoreQ(Func, Value, Mem); |
} |
void emit(const Cfg *Func) const override; |
+ void emitIAS(const Cfg *Func) const override; |
void dump(const Cfg *Func) const override; |
static bool classof(const Inst *Inst) { return isClassof(Inst, StoreQ); } |
private: |
- InstX8632StoreQ(Cfg *Func, Operand *Value, OperandX8632 *Mem); |
+ InstX8632StoreQ(Cfg *Func, Variable *Value, OperandX8632Mem *Mem); |
InstX8632StoreQ(const InstX8632StoreQ &) = delete; |
InstX8632StoreQ &operator=(const InstX8632StoreQ &) = delete; |
~InstX8632StoreQ() override {} |
@@ -1535,6 +1514,9 @@ template <> void InstX8632Idiv::emitIAS(const Cfg *Func) const; |
template <> void InstX8632Imul::emitIAS(const Cfg *Func) const; |
template <> void InstX8632Cbwdq::emitIAS(const Cfg *Func) const; |
template <> void InstX8632Movd::emitIAS(const Cfg *Func) const; |
+template <> void InstX8632Movp::emitIAS(const Cfg *Func) const; |
+template <> void InstX8632Movq::emitIAS(const Cfg *Func) const; |
+template <> void InstX8632MovssRegs::emitIAS(const Cfg *Func) const; |
template <> void InstX8632Pmull::emitIAS(const Cfg *Func) const; |
} // end of namespace Ice |