Index: src/IceInstARM32.h |
diff --git a/src/IceInstARM32.h b/src/IceInstARM32.h |
index 56bf8cd8481d6e576a3881785c748f668f9742f6..8c2ea6f7ff524e79e0ede57703ad3c666d26f457 100644 |
--- a/src/IceInstARM32.h |
+++ b/src/IceInstARM32.h |
@@ -785,7 +785,6 @@ using InstARM32Ldr = InstARM32Movlike<InstARM32::Ldr>; |
using InstARM32Mov = InstARM32Movlike<InstARM32::Mov>; |
/// Represents various vector mov instruction forms (simple single source, |
/// single dest forms only, not the 2 GPR <-> 1 D reg forms, etc.). |
-using InstARM32Vmov = InstARM32Movlike<InstARM32::Vmov>; |
using InstARM32Vldr = InstARM32Movlike<InstARM32::Vldr>; |
/// MovT leaves the bottom bits alone so dest is also a source. |
/// This helps indicate that a previous MovW setting dest is not dead code. |
@@ -1119,6 +1118,93 @@ private: |
const VcvtVariant Variant; |
}; |
+/// Handles (some of) vmov's various formats. |
+class InstARM32Vmov final : public InstARM32Pred { |
+ InstARM32Vmov() = delete; |
+ InstARM32Vmov(const InstARM32Vmov &) = delete; |
+ InstARM32Vmov &operator=(const InstARM32Vmov &) = delete; |
+ |
+public: |
+ /// RegisterPair is used to group registers in |
+ /// |
+ /// vmov D, (R, R) |
+ /// |
+ /// and |
+ /// |
+ /// vmov (R, R), D |
+ struct RegisterPair { |
+ explicit RegisterPair(Variable *V0, Variable *V1) : _0(V0), _1(V1) { |
+ assert(V0->getType() == IceType_i32); |
+ assert(V1->getType() == IceType_i32); |
+ } |
+ Variable *_0; |
+ Variable *_1; |
+ }; |
+ |
+ static InstARM32Vmov *create(Cfg *Func, Variable *Dest, Operand *Src, |
+ CondARM32::Cond Predicate) { |
+ return new (Func->allocate<InstARM32Vmov>()) |
+ InstARM32Vmov(Func, Dest, Src, Predicate); |
+ } |
+ static InstARM32Vmov *create(Cfg *Func, const RegisterPair &Dests, |
+ Variable *Src, CondARM32::Cond Predicate) { |
+ return new (Func->allocate<InstARM32Vmov>()) |
+ InstARM32Vmov(Func, Dests, Src, Predicate); |
+ } |
+ static InstARM32Vmov *create(Cfg *Func, Variable *Dest, |
+ const RegisterPair &Srcs, |
+ CondARM32::Cond Predicate) { |
+ return new (Func->allocate<InstARM32Vmov>()) |
+ InstARM32Vmov(Func, Dest, Srcs, Predicate); |
+ } |
+ bool isRedundantAssign() const override { |
+ return Dest1 == nullptr && getSrcSize() == 1 && |
+ checkForRedundantAssign(getDest(), getSrc(0)); |
+ } |
+ bool isSimpleAssign() const override { return true; } |
+ 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, Vmov); } |
+ |
+private: |
+ InstARM32Vmov(Cfg *Func, Variable *Dest, Operand *Src, |
+ CondARM32::Cond Predicate) |
+ : InstARM32Pred(Func, InstARM32::Vmov, 1, Dest, Predicate) { |
+ addSource(Src); |
+ } |
+ |
+ InstARM32Vmov(Cfg *Func, const RegisterPair &Dests, Variable *Src, |
+ CondARM32::Cond Predicate) |
+ : InstARM32Pred(Func, InstARM32::Vmov, 1, Dests._0, Predicate), |
+ Dest1(Dests._1) { |
+ addSource(Src); |
+ } |
+ |
+ InstARM32Vmov(Cfg *Func, Variable *Dest, const RegisterPair &Srcs, |
+ CondARM32::Cond Predicate) |
+ : InstARM32Pred(Func, InstARM32::Vmov, 2, Dest, Predicate) { |
+ addSource(Srcs._0); |
+ addSource(Srcs._1); |
+ } |
+ |
+ bool isMultiDest() const { |
+ assert(getDest() != nullptr); |
+ return Dest1 != nullptr; |
+ } |
+ |
+ bool isMultiSource() const { |
+ assert(getSrcSize() >= 1); |
+ return getSrcSize() > 1; |
+ } |
+ |
+ void emitMultiDestSingleSource(const Cfg *Func) const; |
+ void emitSingleDestMultiSource(const Cfg *Func) const; |
+ void emitSingleDestSingleSource(const Cfg *Func) const; |
+ |
+ Variable *Dest1 = nullptr; |
+}; |
+ |
// Declare partial template specializations of emit() methods that |
// already have default implementations. Without this, there is the |
// possibility of ODR violations and link errors. |
@@ -1128,7 +1214,6 @@ template <> void InstARM32Mov::emit(const Cfg *Func) const; |
template <> void InstARM32Movw::emit(const Cfg *Func) const; |
template <> void InstARM32Movt::emit(const Cfg *Func) const; |
template <> void InstARM32Vldr::emit(const Cfg *Func) const; |
-template <> void InstARM32Vmov::emit(const Cfg *Func) const; |
} // end of namespace Ice |