Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / v8 / src / x64 / assembler-x64.cc
index d18dd71..9f3428f 100644 (file)
@@ -1,29 +1,6 @@
 // Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 
 #include "v8.h"
 
@@ -52,13 +29,13 @@ ExternalReference ExternalReference::cpu_features() {
 }
 
 
-void CpuFeatures::Probe() {
+void CpuFeatures::Probe(bool serializer_enabled) {
   ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
 #ifdef DEBUG
   initialized_ = true;
 #endif
   supported_ = kDefaultCpuFeatures;
-  if (Serializer::enabled()) {
+  if (serializer_enabled) {
     supported_ |= OS::CpuFeaturesImpliedByPlatform();
     return;  // No features if we might serialize.
   }
@@ -110,7 +87,8 @@ void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
 #endif
 
   // Patch the code.
-  patcher.masm()->movp(kScratchRegister, target, Assembler::RelocInfoNone());
+  patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target),
+                       Assembler::RelocInfoNone());
   patcher.masm()->call(kScratchRegister);
 
   // Check that the size of the code generated is as expected.
@@ -466,24 +444,30 @@ void Assembler::emit_operand(int code, const Operand& adr) {
 
 // Assembler Instruction implementations.
 
-void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
+void Assembler::arithmetic_op(byte opcode,
+                              Register reg,
+                              const Operand& op,
+                              int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(reg, op);
+  emit_rex(reg, op, size);
   emit(opcode);
   emit_operand(reg, op);
 }
 
 
-void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op(byte opcode,
+                              Register reg,
+                              Register rm_reg,
+                              int size) {
   EnsureSpace ensure_space(this);
   ASSERT((opcode & 0xC6) == 2);
   if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
     // Swap reg and rm_reg and change opcode operand order.
-    emit_rex_64(rm_reg, reg);
+    emit_rex(rm_reg, reg, size);
     emit(opcode ^ 0x02);
     emit_modrm(rm_reg, reg);
   } else {
-    emit_rex_64(reg, rm_reg);
+    emit_rex(reg, rm_reg, size);
     emit(opcode);
     emit_modrm(reg, rm_reg);
   }
@@ -519,37 +503,45 @@ void Assembler::arithmetic_op_16(byte opcode,
 }
 
 
-void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
+  EnsureSpace ensure_space(this);
+  if (!reg.is_byte_register()) {
+    // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+    emit_rex_32(reg);
+  }
+  emit(opcode);
+  emit_operand(reg, op);
+}
+
+
+void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
   ASSERT((opcode & 0xC6) == 2);
-  if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
+  if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
     // Swap reg and rm_reg and change opcode operand order.
-    emit_optional_rex_32(rm_reg, reg);
-    emit(opcode ^ 0x02);  // E.g. 0x03 -> 0x01 for ADD.
+    if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
+      // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+      emit_rex_32(rm_reg, reg);
+    }
+    emit(opcode ^ 0x02);
     emit_modrm(rm_reg, reg);
   } else {
-    emit_optional_rex_32(reg, rm_reg);
+    if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
+      // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+      emit_rex_32(reg, rm_reg);
+    }
     emit(opcode);
     emit_modrm(reg, rm_reg);
   }
 }
 
 
-void Assembler::arithmetic_op_32(byte opcode,
-                                 Register reg,
-                                 const Operand& rm_reg) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(reg, rm_reg);
-  emit(opcode);
-  emit_operand(reg, rm_reg);
-}
-
-
 void Assembler::immediate_arithmetic_op(byte subcode,
                                         Register dst,
-                                        Immediate src) {
+                                        Immediate src,
+                                        int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
+  emit_rex(dst, size);
   if (is_int8(src.value_)) {
     emit(0x83);
     emit_modrm(subcode, dst);
@@ -566,9 +558,10 @@ void Assembler::immediate_arithmetic_op(byte subcode,
 
 void Assembler::immediate_arithmetic_op(byte subcode,
                                         const Operand& dst,
-                                        Immediate src) {
+                                        Immediate src,
+                                        int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
+  emit_rex(dst, size);
   if (is_int8(src.value_)) {
     emit(0x83);
     emit_operand(subcode, dst);
@@ -620,43 +613,6 @@ void Assembler::immediate_arithmetic_op_16(byte subcode,
 }
 
 
-void Assembler::immediate_arithmetic_op_32(byte subcode,
-                                           Register dst,
-                                           Immediate src) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
-  if (is_int8(src.value_)) {
-    emit(0x83);
-    emit_modrm(subcode, dst);
-    emit(src.value_);
-  } else if (dst.is(rax)) {
-    emit(0x05 | (subcode << 3));
-    emitl(src.value_);
-  } else {
-    emit(0x81);
-    emit_modrm(subcode, dst);
-    emitl(src.value_);
-  }
-}
-
-
-void Assembler::immediate_arithmetic_op_32(byte subcode,
-                                           const Operand& dst,
-                                           Immediate src) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
-  if (is_int8(src.value_)) {
-    emit(0x83);
-    emit_operand(subcode, dst);
-    emit(src.value_);
-  } else {
-    emit(0x81);
-    emit_operand(subcode, dst);
-    emitl(src.value_);
-  }
-}
-
-
 void Assembler::immediate_arithmetic_op_8(byte subcode,
                                           const Operand& dst,
                                           Immediate src) {
@@ -674,8 +630,8 @@ void Assembler::immediate_arithmetic_op_8(byte subcode,
                                           Immediate src) {
   EnsureSpace ensure_space(this);
   if (!dst.is_byte_register()) {
-    // Use 64-bit mode byte registers.
-    emit_rex_64(dst);
+    // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+    emit_rex_32(dst);
   }
   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
   emit(0x80);
@@ -684,15 +640,19 @@ void Assembler::immediate_arithmetic_op_8(byte subcode,
 }
 
 
-void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
+void Assembler::shift(Register dst,
+                      Immediate shift_amount,
+                      int subcode,
+                      int size) {
   EnsureSpace ensure_space(this);
-  ASSERT(is_uint6(shift_amount.value_));  // illegal shift count
+  ASSERT(size == kInt64Size ? is_uint6(shift_amount.value_)
+                            : is_uint5(shift_amount.value_));
   if (shift_amount.value_ == 1) {
-    emit_rex_64(dst);
+    emit_rex(dst, size);
     emit(0xD1);
     emit_modrm(subcode, dst);
   } else {
-    emit_rex_64(dst);
+    emit_rex(dst, size);
     emit(0xC1);
     emit_modrm(subcode, dst);
     emit(shift_amount.value_);
@@ -700,38 +660,14 @@ void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
 }
 
 
-void Assembler::shift(Register dst, int subcode) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
-  emit(0xD3);
-  emit_modrm(subcode, dst);
-}
-
-
-void Assembler::shift_32(Register dst, int subcode) {
+void Assembler::shift(Register dst, int subcode, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
+  emit_rex(dst, size);
   emit(0xD3);
   emit_modrm(subcode, dst);
 }
 
 
-void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
-  EnsureSpace ensure_space(this);
-  ASSERT(is_uint5(shift_amount.value_));  // illegal shift count
-  if (shift_amount.value_ == 1) {
-    emit_optional_rex_32(dst);
-    emit(0xD1);
-    emit_modrm(subcode, dst);
-  } else {
-    emit_optional_rex_32(dst);
-    emit(0xC1);
-    emit_modrm(subcode, dst);
-    emit(shift_amount.value_);
-  }
-}
-
-
 void Assembler::bt(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(src, dst);
@@ -750,6 +686,15 @@ void Assembler::bts(const Operand& dst, Register src) {
 }
 
 
+void Assembler::bsrl(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBD);
+  emit_modrm(dst, src);
+}
+
+
 void Assembler::call(Label* L) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
@@ -934,33 +879,17 @@ void Assembler::cqo() {
 }
 
 
-void Assembler::decq(Register dst) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
-  emit(0xFF);
-  emit_modrm(0x1, dst);
-}
-
-
-void Assembler::decq(const Operand& dst) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
-  emit(0xFF);
-  emit_operand(1, dst);
-}
-
-
-void Assembler::decl(Register dst) {
+void Assembler::emit_dec(Register dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
+  emit_rex(dst, size);
   emit(0xFF);
   emit_modrm(0x1, dst);
 }
 
 
-void Assembler::decl(const Operand& dst) {
+void Assembler::emit_dec(const Operand& dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
+  emit_rex(dst, size);
   emit(0xFF);
   emit_operand(1, dst);
 }
@@ -999,84 +928,43 @@ void Assembler::hlt() {
 }
 
 
-void Assembler::idivq(Register src) {
+void Assembler::emit_idiv(Register src, int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(src);
+  emit_rex(src, size);
   emit(0xF7);
   emit_modrm(0x7, src);
 }
 
 
-void Assembler::idivl(Register src) {
+void Assembler::emit_imul(Register src, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(src);
-  emit(0xF7);
-  emit_modrm(0x7, src);
-}
-
-
-void Assembler::imul(Register src) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(src);
+  emit_rex(src, size);
   emit(0xF7);
   emit_modrm(0x5, src);
 }
 
 
-void Assembler::imul(Register dst, Register src) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst, src);
-  emit(0x0F);
-  emit(0xAF);
-  emit_modrm(dst, src);
-}
-
-
-void Assembler::imul(Register dst, const Operand& src) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst, src);
-  emit(0x0F);
-  emit(0xAF);
-  emit_operand(dst, src);
-}
-
-
-void Assembler::imul(Register dst, Register src, Immediate imm) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst, src);
-  if (is_int8(imm.value_)) {
-    emit(0x6B);
-    emit_modrm(dst, src);
-    emit(imm.value_);
-  } else {
-    emit(0x69);
-    emit_modrm(dst, src);
-    emitl(imm.value_);
-  }
-}
-
-
-void Assembler::imull(Register dst, Register src) {
+void Assembler::emit_imul(Register dst, Register src, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
+  emit_rex(dst, src, size);
   emit(0x0F);
   emit(0xAF);
   emit_modrm(dst, src);
 }
 
 
-void Assembler::imull(Register dst, const Operand& src) {
+void Assembler::emit_imul(Register dst, const Operand& src, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
+  emit_rex(dst, src, size);
   emit(0x0F);
   emit(0xAF);
   emit_operand(dst, src);
 }
 
 
-void Assembler::imull(Register dst, Register src, Immediate imm) {
+void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
+  emit_rex(dst, src, size);
   if (is_int8(imm.value_)) {
     emit(0x6B);
     emit_modrm(dst, src);
@@ -1089,38 +977,22 @@ void Assembler::imull(Register dst, Register src, Immediate imm) {
 }
 
 
-void Assembler::incq(Register dst) {
+void Assembler::emit_inc(Register dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
+  emit_rex(dst, size);
   emit(0xFF);
   emit_modrm(0x0, dst);
 }
 
 
-void Assembler::incq(const Operand& dst) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
-  emit(0xFF);
-  emit_operand(0, dst);
-}
-
-
-void Assembler::incl(const Operand& dst) {
+void Assembler::emit_inc(const Operand& dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
+  emit_rex(dst, size);
   emit(0xFF);
   emit_operand(0, dst);
 }
 
 
-void Assembler::incl(Register dst) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
-  emit(0xFF);
-  emit_modrm(0, dst);
-}
-
-
 void Assembler::int3() {
   EnsureSpace ensure_space(this);
   emit(0xCC);
@@ -1287,17 +1159,9 @@ void Assembler::jmp(const Operand& src) {
 }
 
 
-void Assembler::lea(Register dst, const Operand& src) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(dst, src);
-  emit(0x8D);
-  emit_operand(dst, src);
-}
-
-
-void Assembler::leal(Register dst, const Operand& src) {
+void Assembler::emit_lea(Register dst, const Operand& src, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
+  emit_rex(dst, src, size);
   emit(0x8D);
   emit_operand(dst, src);
 }
@@ -1502,6 +1366,15 @@ void Assembler::movl(const Operand& dst, Label* src) {
 }
 
 
+void Assembler::movsxbl(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBE);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::movsxbq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(dst, src);
@@ -1511,6 +1384,15 @@ void Assembler::movsxbq(Register dst, const Operand& src) {
 }
 
 
+void Assembler::movsxwl(Register dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBF);
+  emit_operand(dst, src);
+}
+
+
 void Assembler::movsxwq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(dst, src);
@@ -1536,7 +1418,7 @@ void Assembler::movsxlq(Register dst, const Operand& src) {
 }
 
 
-void Assembler::movzxbq(Register dst, const Operand& src) {
+void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
   EnsureSpace ensure_space(this);
   // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
   // there is no need to make this a 64 bit operation.
@@ -1547,26 +1429,10 @@ void Assembler::movzxbq(Register dst, const Operand& src) {
 }
 
 
-void Assembler::movzxbl(Register dst, const Operand& src) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
-  emit(0x0F);
-  emit(0xB6);
-  emit_operand(dst, src);
-}
-
-
-void Assembler::movzxwq(Register dst, const Operand& src) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst, src);
-  emit(0x0F);
-  emit(0xB7);
-  emit_operand(dst, src);
-}
-
-
-void Assembler::movzxwl(Register dst, const Operand& src) {
+void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
   EnsureSpace ensure_space(this);
+  // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
+  // there is no need to make this a 64 bit operation.
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB7);
@@ -1574,8 +1440,10 @@ void Assembler::movzxwl(Register dst, const Operand& src) {
 }
 
 
-void Assembler::movzxwl(Register dst, Register src) {
+void Assembler::emit_movzxw(Register dst, Register src, int size) {
   EnsureSpace ensure_space(this);
+  // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
+  // there is no need to make this a 64 bit operation.
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB7);
@@ -1598,17 +1466,10 @@ void Assembler::repmovsw() {
 }
 
 
-void Assembler::repmovsl() {
-  EnsureSpace ensure_space(this);
-  emit(0xF3);
-  emit(0xA5);
-}
-
-
-void Assembler::repmovsq() {
+void Assembler::emit_repmovs(int size) {
   EnsureSpace ensure_space(this);
   emit(0xF3);
-  emit_rex_64();
+  emit_rex(size);
   emit(0xA5);
 }
 
@@ -1621,23 +1482,15 @@ void Assembler::mul(Register src) {
 }
 
 
-void Assembler::neg(Register dst) {
+void Assembler::emit_neg(Register dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
-  emit(0xF7);
-  emit_modrm(0x3, dst);
-}
-
-
-void Assembler::negl(Register dst) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
+  emit_rex(dst, size);
   emit(0xF7);
   emit_modrm(0x3, dst);
 }
 
 
-void Assembler::neg(const Operand& dst) {
+void Assembler::emit_neg(const Operand& dst, int size) {
   EnsureSpace ensure_space(this);
   emit_rex_64(dst);
   emit(0xF7);
@@ -1651,30 +1504,22 @@ void Assembler::nop() {
 }
 
 
-void Assembler::not_(Register dst) {
+void Assembler::emit_not(Register dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
+  emit_rex(dst, size);
   emit(0xF7);
   emit_modrm(0x2, dst);
 }
 
 
-void Assembler::not_(const Operand& dst) {
+void Assembler::emit_not(const Operand& dst, int size) {
   EnsureSpace ensure_space(this);
-  emit_rex_64(dst);
+  emit_rex(dst, size);
   emit(0xF7);
   emit_operand(2, dst);
 }
 
 
-void Assembler::notl(Register dst) {
-  EnsureSpace ensure_space(this);
-  emit_optional_rex_32(dst);
-  emit(0xF7);
-  emit_modrm(0x2, dst);
-}
-
-
 void Assembler::Nop(int n) {
   // The recommended muti-byte sequences of NOP instructions from the Intel 64
   // and IA-32 Architectures Software Developer's Manual.
@@ -1752,14 +1597,14 @@ void Assembler::Nop(int n) {
 }
 
 
-void Assembler::pop(Register dst) {
+void Assembler::popq(Register dst) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst);
   emit(0x58 | dst.low_bits());
 }
 
 
-void Assembler::pop(const Operand& dst) {
+void Assembler::popq(const Operand& dst) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst);
   emit(0x8F);
@@ -1773,14 +1618,14 @@ void Assembler::popfq() {
 }
 
 
-void Assembler::push(Register src) {
+void Assembler::pushq(Register src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(src);
   emit(0x50 | src.low_bits());
 }
 
 
-void Assembler::push(const Operand& src) {
+void Assembler::pushq(const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(src);
   emit(0xFF);
@@ -1788,7 +1633,7 @@ void Assembler::push(const Operand& src) {
 }
 
 
-void Assembler::push(Immediate value) {
+void Assembler::pushq(Immediate value) {
   EnsureSpace ensure_space(this);
   if (is_int8(value.value_)) {
     emit(0x6A);
@@ -1800,7 +1645,7 @@ void Assembler::push(Immediate value) {
 }
 
 
-void Assembler::push_imm32(int32_t imm32) {
+void Assembler::pushq_imm32(int32_t imm32) {
   EnsureSpace ensure_space(this);
   emit(0x68);
   emitl(imm32);
@@ -1860,36 +1705,18 @@ void Assembler::shrd(Register dst, Register src) {
 }
 
 
-void Assembler::xchgq(Register dst, Register src) {
+void Assembler::emit_xchg(Register dst, Register src, int size) {
   EnsureSpace ensure_space(this);
   if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
     Register other = src.is(rax) ? dst : src;
-    emit_rex_64(other);
+    emit_rex(other, size);
     emit(0x90 | other.low_bits());
   } else if (dst.low_bits() == 4) {
-    emit_rex_64(dst, src);
-    emit(0x87);
-    emit_modrm(dst, src);
-  } else {
-    emit_rex_64(src, dst);
-    emit(0x87);
-    emit_modrm(src, dst);
-  }
-}
-
-
-void Assembler::xchgl(Register dst, Register src) {
-  EnsureSpace ensure_space(this);
-  if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
-    Register other = src.is(rax) ? dst : src;
-    emit_optional_rex_32(other);
-    emit(0x90 | other.low_bits());
-  } else if (dst.low_bits() == 4) {
-    emit_optional_rex_32(dst, src);
+    emit_rex(dst, src, size);
     emit(0x87);
     emit_modrm(dst, src);
   } else {
-    emit_optional_rex_32(src, dst);
+    emit_rex(src, dst, size);
     emit(0x87);
     emit_modrm(src, dst);
   }
@@ -1977,21 +1804,21 @@ void Assembler::testb(const Operand& op, Register reg) {
 }
 
 
-void Assembler::testl(Register dst, Register src) {
+void Assembler::emit_test(Register dst, Register src, int size) {
   EnsureSpace ensure_space(this);
   if (src.low_bits() == 4) {
-    emit_optional_rex_32(src, dst);
+    emit_rex(src, dst, size);
     emit(0x85);
     emit_modrm(src, dst);
   } else {
-    emit_optional_rex_32(dst, src);
+    emit_rex(dst, src, size);
     emit(0x85);
     emit_modrm(dst, src);
   }
 }
 
 
-void Assembler::testl(Register reg, Immediate mask) {
+void Assembler::emit_test(Register reg, Immediate mask, int size) {
   // testl with a mask that fits in the low byte is exactly testb.
   if (is_uint8(mask.value_)) {
     testb(reg, mask);
@@ -1999,10 +1826,11 @@ void Assembler::testl(Register reg, Immediate mask) {
   }
   EnsureSpace ensure_space(this);
   if (reg.is(rax)) {
+    emit_rex(rax, size);
     emit(0xA9);
     emit(mask);
   } else {
-    emit_optional_rex_32(rax, reg);
+    emit_rex(reg, size);
     emit(0xF7);
     emit_modrm(0x0, reg);
     emit(mask);
@@ -2010,69 +1838,28 @@ void Assembler::testl(Register reg, Immediate mask) {
 }
 
 
-void Assembler::testl(const Operand& op, Immediate mask) {
+void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
   // testl with a mask that fits in the low byte is exactly testb.
   if (is_uint8(mask.value_)) {
     testb(op, mask);
     return;
   }
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(rax, op);
+  emit_rex(rax, op, size);
   emit(0xF7);
   emit_operand(rax, op);  // Operation code 0
   emit(mask);
 }
 
 
-void Assembler::testl(const Operand& op, Register reg) {
+void Assembler::emit_test(const Operand& op, Register reg, int size) {
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(reg, op);
+  emit_rex(reg, op, size);
   emit(0x85);
   emit_operand(reg, op);
 }
 
 
-void Assembler::testq(const Operand& op, Register reg) {
-  EnsureSpace ensure_space(this);
-  emit_rex_64(reg, op);
-  emit(0x85);
-  emit_operand(reg, op);
-}
-
-
-void Assembler::testq(Register dst, Register src) {
-  EnsureSpace ensure_space(this);
-  if (src.low_bits() == 4) {
-    emit_rex_64(src, dst);
-    emit(0x85);
-    emit_modrm(src, dst);
-  } else {
-    emit_rex_64(dst, src);
-    emit(0x85);
-    emit_modrm(dst, src);
-  }
-}
-
-
-void Assembler::testq(Register dst, Immediate mask) {
-  if (is_uint8(mask.value_)) {
-    testb(dst, mask);
-    return;
-  }
-  EnsureSpace ensure_space(this);
-  if (dst.is(rax)) {
-    emit_rex_64();
-    emit(0xA9);
-    emit(mask);
-  } else {
-    emit_rex_64(dst);
-    emit(0xF7);
-    emit_modrm(0, dst);
-    emit(mask);
-  }
-}
-
-
 // FPU instructions.
 
 
@@ -2577,6 +2364,86 @@ void Assembler::divps(XMMRegister dst, const Operand& src) {
 }
 
 
+void Assembler::addpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x58);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::addpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x58);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x59);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::mulpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x59);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::divpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::divpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
 // SSE 2 operations.
 
 void Assembler::movd(XMMRegister dst, Register src) {
@@ -2788,7 +2655,19 @@ void Assembler::movups(const Operand& dst, XMMRegister src) {
 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
   ASSERT(is_uint8(imm8));
   EnsureSpace ensure_space(this);
-  emit_optional_rex_32(src, dst);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xC6);
+  emit_sse_operand(dst, src);
+  emit(imm8);
+}
+
+
+void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) {
+  ASSERT(is_uint8(imm8));
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xC6);
   emit_sse_operand(dst, src);
@@ -2835,6 +2714,16 @@ void Assembler::movss(const Operand& src, XMMRegister dst) {
 }
 
 
+void Assembler::psllq(XMMRegister reg, byte imm8) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit(0x0F);
+  emit(0x73);
+  emit_sse_operand(rsi, reg);  // rsi == 6
+  emit(imm8);
+}
+
+
 void Assembler::cvttss2si(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit(0xF3);
@@ -3045,6 +2934,16 @@ void Assembler::andpd(XMMRegister dst, XMMRegister src) {
 }
 
 
+void Assembler::andpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x54);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit(0x66);
@@ -3065,6 +2964,16 @@ void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
 }
 
 
+void Assembler::xorpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x57);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit(0xF2);
@@ -3299,6 +3208,46 @@ void Assembler::maxps(XMMRegister dst, const Operand& src) {
 }
 
 
+void Assembler::minpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5D);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::minpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5D);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5F);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::maxpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5F);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst, src);
@@ -3353,6 +3302,26 @@ void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
 }
 
 
+void Assembler::sqrtpd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x51);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::sqrtpd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x51);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst, src);
@@ -3559,12 +3528,7 @@ void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
   ASSERT(!RelocInfo::IsNone(rmode));
   if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
     // Don't record external references unless the heap will be serialized.
-#ifdef DEBUG
-    if (!Serializer::enabled()) {
-      Serializer::TooLateToEnableNow();
-    }
-#endif
-    if (!Serializer::enabled() && !emit_debug_code()) {
+    if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
       return;
     }
   } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
@@ -3598,6 +3562,20 @@ void Assembler::RecordComment(const char* msg, bool force) {
 }
 
 
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
+  // No out-of-line constant pool support.
+  ASSERT(!FLAG_enable_ool_constant_pool);
+  return isolate->factory()->empty_constant_pool_array();
+}
+
+
+void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
+  // No out-of-line constant pool support.
+  ASSERT(!FLAG_enable_ool_constant_pool);
+  return;
+}
+
+
 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
     1 << RelocInfo::RUNTIME_ENTRY |
     1 << RelocInfo::INTERNAL_REFERENCE |
@@ -3611,6 +3589,12 @@ bool RelocInfo::IsCodedSpecially() {
   return (1 << rmode_) & kApplyMask;
 }
 
+
+bool RelocInfo::IsInConstantPool() {
+  return false;
+}
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_TARGET_ARCH_X64