Update V8 to r4588

We're using WebKit r58033, as used by
http://src.chromium.org/svn/releases/5.0.387.0/DEPS
This requires http://v8.googlecode.com/svn/trunk@4465 but this version has a
crashing bug for ARM. Instead we use http://v8.googlecode.com/svn/trunk@4588,
which is used by http://src.chromium.org/svn/releases/6.0.399.0/DEPS

Note that a trivial bug fix was required in arm/codegen-arm.cc. This is guarded
with ANDROID. See http://code.google.com/p/v8/issues/detail?id=703

Change-Id: I459647a8286c4f8c7405f0c5581ecbf051a6f1e8
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index 127c160..4ba3094 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -34,10 +34,9 @@
 //   NameConverter converter;
 //   Disassembler d(converter);
 //   for (byte* pc = begin; pc < end;) {
-//     char buffer[128];
-//     buffer[0] = '\0';
+//     v8::internal::EmbeddedVector<char, 256> buffer;
 //     byte* prev_pc = pc;
-//     pc += d.InstructionDecode(buffer, sizeof buffer, pc);
+//     pc += d.InstructionDecode(buffer, pc);
 //     printf("%p    %08x      %s\n",
 //            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
 //   }
@@ -129,6 +128,10 @@
   void DecodeTypeVFP(Instr* instr);
   void DecodeType6CoprocessorIns(Instr* instr);
 
+  void DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr);
+  void DecodeVCMP(Instr* instr);
+  void DecodeVCVTBetweenDoubleAndSingle(Instr* instr);
+  void DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr);
 
   const disasm::NameConverter& converter_;
   v8::internal::Vector<char> out_buffer_;
@@ -181,12 +184,12 @@
 
 // Print the VFP S register name according to the active name converter.
 void Decoder::PrintSRegister(int reg) {
-  Print(assembler::arm::VFPRegisters::Name(reg));
+  Print(assembler::arm::VFPRegisters::Name(reg, false));
 }
 
 // Print the  VFP D register name according to the active name converter.
 void Decoder::PrintDRegister(int reg) {
-  Print(assembler::arm::VFPRegisters::Name(reg + 32));
+  Print(assembler::arm::VFPRegisters::Name(reg, true));
 }
 
 
@@ -445,6 +448,14 @@
         out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
                                             "%d", instr->ShiftAmountField());
         return 8;
+      } else if (format[3] == '0') {
+        // 'off0to3and8to19 16-bit immediate encoded in bits 19-8 and 3-0.
+        ASSERT(STRING_STARTS_WITH(format, "off0to3and8to19"));
+        out_buffer_pos_ += v8i::OS::SNPrintF(out_buffer_ + out_buffer_pos_,
+                                            "%d",
+                                            (instr->Bits(19, 8) << 4) +
+                                                instr->Bits(3, 0));
+        return 15;
       }
       // 'off8: 8-bit offset for extra load and store instructions
       ASSERT(STRING_STARTS_WITH(format, "off8"));
@@ -646,6 +657,34 @@
       }
       return;
     }
+  } else if ((type == 0) && instr->IsMiscType0()) {
+    if (instr->Bits(22, 21) == 1) {
+      switch (instr->Bits(7, 4)) {
+        case BX:
+          Format(instr, "bx'cond 'rm");
+          break;
+        case BLX:
+          Format(instr, "blx'cond 'rm");
+          break;
+        case BKPT:
+          Format(instr, "bkpt 'off0to3and8to19");
+          break;
+        default:
+          Unknown(instr);  // not used by V8
+          break;
+      }
+    } else if (instr->Bits(22, 21) == 3) {
+      switch (instr->Bits(7, 4)) {
+        case CLZ:
+          Format(instr, "clz'cond 'rd, 'rm");
+          break;
+        default:
+          Unknown(instr);  // not used by V8
+          break;
+      }
+    } else {
+      Unknown(instr);  // not used by V8
+    }
   } else {
     switch (instr->OpcodeField()) {
       case AND: {
@@ -692,17 +731,9 @@
         if (instr->HasS()) {
           Format(instr, "teq'cond 'rn, 'shift_op");
         } else {
-          switch (instr->Bits(7, 4)) {
-            case BX:
-              Format(instr, "bx'cond 'rm");
-              break;
-            case BLX:
-              Format(instr, "blx'cond 'rm");
-              break;
-            default:
-              Unknown(instr);  // not used by V8
-              break;
-          }
+          // Other instructions matching this pattern are handled in the
+          // miscellaneous instructions part above.
+          UNREACHABLE();
         }
         break;
       }
@@ -718,14 +749,9 @@
         if (instr->HasS()) {
           Format(instr, "cmn'cond 'rn, 'shift_op");
         } else {
-          switch (instr->Bits(7, 4)) {
-            case CLZ:
-              Format(instr, "clz'cond 'rd, 'rm");
-              break;
-            default:
-              Unknown(instr);  // not used by V8
-              break;
-          }
+          // Other instructions matching this pattern are handled in the
+          // miscellaneous instructions part above.
+          UNREACHABLE();
         }
         break;
       }
@@ -930,85 +956,61 @@
 // VMRS
 void Decoder::DecodeTypeVFP(Instr* instr) {
   ASSERT((instr->TypeField() == 7) && (instr->Bit(24) == 0x0) );
+  ASSERT(instr->Bits(11, 9) == 0x5);
 
-  if (instr->Bit(23) == 1) {
-    if ((instr->Bits(21, 19) == 0x7) &&
-        (instr->Bits(18, 16) == 0x5) &&
-        (instr->Bits(11, 9) == 0x5) &&
-        (instr->Bit(8) == 1) &&
-        (instr->Bit(6) == 1) &&
-        (instr->Bit(4) == 0)) {
-      Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
-    } else if ((instr->Bits(21, 19) == 0x7) &&
-               (instr->Bits(18, 16) == 0x0) &&
-               (instr->Bits(11, 9) == 0x5) &&
-               (instr->Bit(8) == 1) &&
-               (instr->Bit(7) == 1) &&
-               (instr->Bit(6) == 1) &&
-               (instr->Bit(4) == 0)) {
-      Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
-    } else if ((instr->Bit(21) == 0x0) &&
-               (instr->Bit(20) == 0x0) &&
-               (instr->Bits(11, 9) == 0x5) &&
-               (instr->Bit(8) == 1) &&
-               (instr->Bit(6) == 0) &&
-               (instr->Bit(4) == 0)) {
+  if (instr->Bit(4) == 0) {
+    if (instr->Opc1Field() == 0x7) {
+      // Other data processing instructions
+      if ((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3)) {
+        DecodeVCVTBetweenDoubleAndSingle(instr);
+      } else if ((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) {
+        DecodeVCVTBetweenFloatingPointAndInteger(instr);
+      } else if (((instr->Opc2Field() >> 1) == 0x6) &&
+                 (instr->Opc3Field() & 0x1)) {
+        DecodeVCVTBetweenFloatingPointAndInteger(instr);
+      } else if (((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
+                 (instr->Opc3Field() & 0x1)) {
+        DecodeVCMP(instr);
+      } else {
+        Unknown(instr);  // Not used by V8.
+      }
+    } else if (instr->Opc1Field() == 0x3) {
+      if (instr->SzField() == 0x1) {
+        if (instr->Opc3Field() & 0x1) {
+          Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
+        } else {
+          Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
+        }
+      } else {
+        Unknown(instr);  // Not used by V8.
+      }
+    } else if ((instr->Opc1Field() == 0x2) && !(instr->Opc3Field() & 0x1)) {
+      if (instr->SzField() == 0x1) {
+        Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
+      } else {
+        Unknown(instr);  // Not used by V8.
+      }
+    } else if ((instr->Opc1Field() == 0x4) && !(instr->Opc3Field() & 0x1)) {
+      if (instr->SzField() == 0x1) {
         Format(instr, "vdiv.f64'cond 'Dd, 'Dn, 'Dm");
-    } else if ((instr->Bits(21, 20) == 0x3) &&
-               (instr->Bits(19, 16) == 0x4) &&
-               (instr->Bits(11, 9) == 0x5) &&
-               (instr->Bit(8) == 0x1) &&
-               (instr->Bit(6) == 0x1) &&
-               (instr->Bit(4) == 0x0)) {
-      Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
-    } else if ((instr->Bits(23, 20) == 0xF) &&
-               (instr->Bits(19, 16) == 0x1) &&
-               (instr->Bits(11, 8) == 0xA) &&
-               (instr->Bits(7, 5) == 0x0) &&
-               (instr->Bit(4) == 0x1)    &&
-               (instr->Bits(3, 0) == 0x0)) {
-        if (instr->Bits(15, 12) == 0xF)
-          Format(instr, "vmrs'cond APSR, FPSCR");
-        else
-          Unknown(instr);  // Not used by V8.
-    } else {
-      Unknown(instr);  // Not used by V8.
-    }
-  } else if (instr->Bit(21) == 1) {
-    if ((instr->Bit(20) == 0x1) &&
-        (instr->Bits(11, 9) == 0x5) &&
-        (instr->Bit(8) == 0x1) &&
-        (instr->Bit(6) == 0) &&
-        (instr->Bit(4) == 0)) {
-      Format(instr, "vadd.f64'cond 'Dd, 'Dn, 'Dm");
-    } else if ((instr->Bit(20) == 0x1) &&
-               (instr->Bits(11, 9) == 0x5) &&
-               (instr->Bit(8) == 0x1) &&
-               (instr->Bit(6) == 1) &&
-               (instr->Bit(4) == 0)) {
-      Format(instr, "vsub.f64'cond 'Dd, 'Dn, 'Dm");
-    } else if ((instr->Bit(20) == 0x0) &&
-               (instr->Bits(11, 9) == 0x5) &&
-               (instr->Bit(8) == 0x1) &&
-               (instr->Bit(6) == 0) &&
-               (instr->Bit(4) == 0)) {
-      Format(instr, "vmul.f64'cond 'Dd, 'Dn, 'Dm");
+      } else {
+        Unknown(instr);  // Not used by V8.
+      }
     } else {
       Unknown(instr);  // Not used by V8.
     }
   } else {
-    if ((instr->Bit(20) == 0x0) &&
-        (instr->Bits(11, 8) == 0xA) &&
-        (instr->Bits(6, 5) == 0x0) &&
-        (instr->Bit(4) == 1) &&
-        (instr->Bits(3, 0) == 0x0)) {
-      Format(instr, "vmov'cond 'Sn, 'rt");
-    } else if ((instr->Bit(20) == 0x1) &&
-               (instr->Bits(11, 8) == 0xA) &&
-               (instr->Bits(6, 5) == 0x0) &&
-               (instr->Bit(4) == 1) &&
-               (instr->Bits(3, 0) == 0x0)) {
-      Format(instr, "vmov'cond 'rt, 'Sn");
+    if ((instr->VCField() == 0x0) &&
+        (instr->VAField() == 0x0)) {
+      DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
+    } else if ((instr->VLField() == 0x1) &&
+               (instr->VCField() == 0x0) &&
+               (instr->VAField() == 0x7) &&
+               (instr->Bits(19, 16) == 0x1)) {
+      if (instr->Bits(15, 12) == 0xF)
+        Format(instr, "vmrs'cond APSR, FPSCR");
+      else
+        Unknown(instr);  // Not used by V8.
     } else {
       Unknown(instr);  // Not used by V8.
     }
@@ -1016,6 +1018,94 @@
 }
 
 
+void Decoder::DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(Instr* instr) {
+  ASSERT((instr->Bit(4) == 1) && (instr->VCField() == 0x0) &&
+         (instr->VAField() == 0x0));
+
+  bool to_arm_register = (instr->VLField() == 0x1);
+
+  if (to_arm_register) {
+    Format(instr, "vmov'cond 'rt, 'Sn");
+  } else {
+    Format(instr, "vmov'cond 'Sn, 'rt");
+  }
+}
+
+
+void Decoder::DecodeVCMP(Instr* instr) {
+  ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
+  ASSERT(((instr->Opc2Field() == 0x4) || (instr->Opc2Field() == 0x5)) &&
+         (instr->Opc3Field() & 0x1));
+
+  // Comparison.
+  bool dp_operation = (instr->SzField() == 1);
+  bool raise_exception_for_qnan = (instr->Bit(7) == 0x1);
+
+  if (dp_operation && !raise_exception_for_qnan) {
+    Format(instr, "vcmp.f64'cond 'Dd, 'Dm");
+  } else {
+    Unknown(instr);  // Not used by V8.
+  }
+}
+
+
+void Decoder::DecodeVCVTBetweenDoubleAndSingle(Instr* instr) {
+  ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
+  ASSERT((instr->Opc2Field() == 0x7) && (instr->Opc3Field() == 0x3));
+
+  bool double_to_single = (instr->SzField() == 1);
+
+  if (double_to_single) {
+    Format(instr, "vcvt.f32.f64'cond 'Sd, 'Dm");
+  } else {
+    Format(instr, "vcvt.f64.f32'cond 'Dd, 'Sm");
+  }
+}
+
+
+void Decoder::DecodeVCVTBetweenFloatingPointAndInteger(Instr* instr) {
+  ASSERT((instr->Bit(4) == 0) && (instr->Opc1Field() == 0x7));
+  ASSERT(((instr->Opc2Field() == 0x8) && (instr->Opc3Field() & 0x1)) ||
+         (((instr->Opc2Field() >> 1) == 0x6) && (instr->Opc3Field() & 0x1)));
+
+  bool to_integer = (instr->Bit(18) == 1);
+  bool dp_operation = (instr->SzField() == 1);
+  if (to_integer) {
+    bool unsigned_integer = (instr->Bit(16) == 0);
+
+    if (dp_operation) {
+      if (unsigned_integer) {
+        Format(instr, "vcvt.u32.f64'cond 'Sd, 'Dm");
+      } else {
+        Format(instr, "vcvt.s32.f64'cond 'Sd, 'Dm");
+      }
+    } else {
+      if (unsigned_integer) {
+        Format(instr, "vcvt.u32.f32'cond 'Sd, 'Sm");
+      } else {
+        Format(instr, "vcvt.s32.f32'cond 'Sd, 'Sm");
+      }
+    }
+  } else {
+    bool unsigned_integer = (instr->Bit(7) == 0);
+
+    if (dp_operation) {
+      if (unsigned_integer) {
+        Format(instr, "vcvt.f64.u32'cond 'Dd, 'Sm");
+      } else {
+        Format(instr, "vcvt.f64.s32'cond 'Dd, 'Sm");
+      }
+    } else {
+      if (unsigned_integer) {
+        Format(instr, "vcvt.f32.u32'cond 'Sd, 'Sm");
+      } else {
+        Format(instr, "vcvt.f32.s32'cond 'Sd, 'Sm");
+      }
+    }
+  }
+}
+
+
 // Decode Type 6 coprocessor instructions.
 // Dm = vmov(Rt, Rt2)
 // <Rt, Rt2> = vmov(Dm)
@@ -1024,9 +1114,27 @@
 void Decoder::DecodeType6CoprocessorIns(Instr* instr) {
   ASSERT((instr->TypeField() == 6));
 
-  if (instr->CoprocessorField() != 0xB) {
-    Unknown(instr);  // Not used by V8.
-  } else {
+  if (instr->CoprocessorField() == 0xA) {
+    switch (instr->OpcodeField()) {
+      case 0x8:
+        if (instr->HasL()) {
+          Format(instr, "vldr'cond 'Sd, ['rn - 4*'off8]");
+        } else {
+          Format(instr, "vstr'cond 'Sd, ['rn - 4*'off8]");
+        }
+        break;
+      case 0xC:
+        if (instr->HasL()) {
+          Format(instr, "vldr'cond 'Sd, ['rn + 4*'off8]");
+        } else {
+          Format(instr, "vstr'cond 'Sd, ['rn + 4*'off8]");
+        }
+        break;
+      default:
+        Unknown(instr);  // Not used by V8.
+        break;
+    }
+  } else if (instr->CoprocessorField() == 0xB) {
     switch (instr->OpcodeField()) {
       case 0x2:
         // Load and store double to two GP registers
@@ -1056,6 +1164,8 @@
         Unknown(instr);  // Not used by V8.
         break;
     }
+  } else {
+    UNIMPLEMENTED();  // Not used by V8.
   }
 }