Implement intrinsics for loading/storing subvectors.

This enables emulating 64-bit and 32-bit vectors using 128-bit
vectors internally (x86 only for now). Note that these Intrinsics
are not part of the PNaCL specification.

BUG=swiftshader:15

Change-Id: I61a666243832c2856e60eb477d42a72dec07d01d
Reviewed-on: https://chromium-review.googlesource.com/392246
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
index 26fa2c4..1bc2a0c 100644
--- a/src/IceInstX86BaseImpl.h
+++ b/src/IceInstX86BaseImpl.h
@@ -297,7 +297,7 @@
 }
 
 template <typename TraitsType>
-InstImpl<TraitsType>::InstX86StoreQ::InstX86StoreQ(Cfg *Func, Variable *Value,
+InstImpl<TraitsType>::InstX86StoreQ::InstX86StoreQ(Cfg *Func, Operand *Value,
                                                    X86OperandMem *Mem)
     : InstX86Base(Func, InstX86Base::StoreQ, 2, nullptr) {
   this->addSource(Value);
@@ -305,6 +305,14 @@
 }
 
 template <typename TraitsType>
+InstImpl<TraitsType>::InstX86StoreD::InstX86StoreD(Cfg *Func, Operand *Value,
+                                                   X86OperandMem *Mem)
+    : InstX86Base(Func, InstX86Base::StoreD, 2, nullptr) {
+  this->addSource(Value);
+  this->addSource(Mem);
+}
+
+template <typename TraitsType>
 InstImpl<TraitsType>::InstX86Nop::InstX86Nop(Cfg *Func, NopVariant Variant)
     : InstX86Base(Func, InstX86Base::Nop, 0, nullptr), Variant(Variant) {}
 
@@ -2021,6 +2029,46 @@
 }
 
 template <typename TraitsType>
+void InstImpl<TraitsType>::InstX86StoreD::emit(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrEmit();
+  assert(this->getSrcSize() == 2);
+  assert(this->getSrc(1)->getType() == IceType_i64 ||
+         this->getSrc(1)->getType() == IceType_f64 ||
+         isVectorType(this->getSrc(1)->getType()));
+  Str << "\t"
+         "movd\t";
+  this->getSrc(0)->emit(Func);
+  Str << ", ";
+  this->getSrc(1)->emit(Func);
+}
+
+template <typename TraitsType>
+void InstImpl<TraitsType>::InstX86StoreD::emitIAS(const Cfg *Func) const {
+  Assembler *Asm = Func->getAssembler<Assembler>();
+  assert(this->getSrcSize() == 2);
+  const auto *SrcVar = llvm::cast<Variable>(this->getSrc(0));
+  const auto DestMem = llvm::cast<X86OperandMem>(this->getSrc(1));
+  assert(DestMem->getSegmentRegister() == X86OperandMem::DefaultSegment);
+  assert(SrcVar->hasReg());
+  auto *Target = InstX86Base::getTarget(Func);
+  Asm->movd(SrcVar->getType(), DestMem->toAsmAddress(Asm, Target),
+            Traits::getEncodedXmm(SrcVar->getRegNum()));
+}
+
+template <typename TraitsType>
+void InstImpl<TraitsType>::InstX86StoreD::dump(const Cfg *Func) const {
+  if (!BuildDefs::dump())
+    return;
+  Ostream &Str = Func->getContext()->getStrDump();
+  Str << "stored." << this->getSrc(0)->getType() << " ";
+  this->getSrc(1)->dump(Func);
+  Str << ", ";
+  this->getSrc(0)->dump(Func);
+}
+
+template <typename TraitsType>
 void InstImpl<TraitsType>::InstX86Lea::emit(const Cfg *Func) const {
   if (!BuildDefs::dump())
     return;
@@ -2279,7 +2327,8 @@
 void InstImpl<TraitsType>::InstX86Movq::emitIAS(const Cfg *Func) const {
   assert(this->getSrcSize() == 1);
   assert(this->getDest()->getType() == IceType_i64 ||
-         this->getDest()->getType() == IceType_f64);
+         this->getDest()->getType() == IceType_f64 ||
+         isVectorType(this->getDest()->getType()));
   const Variable *Dest = this->getDest();
   const Operand *Src = this->getSrc(0);
   static const XmmEmitterMovOps Emitter = {&Assembler::movq, &Assembler::movq,