[SubZero] Fix code generation issues occurred in Cross-test and PNaCL smoke-tests

The patch fixes various code generation issues found during testing of Cross-test and PNaCL smoke-test framework.

     1)	To keep track of branches to same label, relative position of the branch from previous branch is used.
     2)	Fixed encoding of conditional mov instructions
     3)	Added MovFP64ToI64 instruction for f64 to i64 move
     4)	Handled vector-types in Phi nodes
     5)	Fixed alignment of spilled vector arguments on stack
     6)	Save-restore FP registers
     7)	Fixed code generation for Zext and Sext operations
     8)	Fixed InsertElement for vi16x8 type

R=stichnot@chromium.org

Patch from Jaydeep Patil <jaydeep.patil@imgtec.com>.

Review-Url: https://codereview.chromium.org/2619943003 .
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h
index 96e6cb7..aaffbcf 100644
--- a/src/IceInstMIPS32.h
+++ b/src/IceInstMIPS32.h
@@ -29,6 +29,7 @@
 namespace MIPS32 {
 
 enum RelocOp { RO_No, RO_Hi, RO_Lo, RO_Jal };
+enum Int64Part { Int64_Hi, Int64_Lo };
 
 inline void emitRelocOp(Ostream &Str, RelocOp Reloc) {
   switch (Reloc) {
@@ -232,6 +233,7 @@
     Mfhi,
     Mflo,
     Mov, // actually a pseudo op for addi rd, rs, 0
+    Mov_fp,
     Mov_d,
     Mov_s,
     Movf,
@@ -1320,6 +1322,44 @@
   Variable *DestHi = nullptr;
 };
 
+/// Handle double to i64 move
+class InstMIPS32MovFP64ToI64 final : public InstMIPS32 {
+  InstMIPS32MovFP64ToI64() = delete;
+  InstMIPS32MovFP64ToI64(const InstMIPS32MovFP64ToI64 &) = delete;
+  InstMIPS32MovFP64ToI64 &operator=(const InstMIPS32MovFP64ToI64 &) = delete;
+
+public:
+  static InstMIPS32MovFP64ToI64 *create(Cfg *Func, Variable *Dest, Operand *Src,
+                                        Int64Part Int64HiLo) {
+    return new (Func->allocate<InstMIPS32MovFP64ToI64>())
+        InstMIPS32MovFP64ToI64(Func, Dest, Src, Int64HiLo);
+  }
+
+  bool isRedundantAssign() const override {
+    return checkForRedundantAssign(getDest(), getSrc(0));
+  }
+
+  void dump(const Cfg *Func) const override {
+    if (!BuildDefs::dump())
+      return;
+    Ostream &Str = Func->getContext()->getStrDump();
+    getDest()->dump(Func);
+    Str << " = ";
+    dumpOpcode(Str, "mov_fp", getDest()->getType());
+    Str << " ";
+    getSrc(0)->dump(Func);
+  }
+
+  Int64Part getInt64Part() const { return Int64HiLo; }
+
+  static bool classof(const Inst *Inst) { return isClassof(Inst, Mov_fp); }
+
+private:
+  InstMIPS32MovFP64ToI64(Cfg *Func, Variable *Dest, Operand *Src,
+                         Int64Part Int64HiLo);
+  const Int64Part Int64HiLo;
+};
+
 // Declare partial template specializations of emit() methods that already have
 // default implementations. Without this, there is the possibility of ODR
 // violations and link errors.