Merge V8 at r7668: Initial merge by Git.

Change-Id: I1703c8b4f5c63052451a22cf3fb878abc9a0ec75
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 0744b8a..c06bc0c 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -38,22 +38,38 @@
 // -----------------------------------------------------------------------------
 // Implementation of CpuFeatures
 
-CpuFeatures::CpuFeatures()
-    : supported_(kDefaultCpuFeatures),
-      enabled_(0),
-      found_by_runtime_probing_(0) {
-}
+
+#ifdef DEBUG
+bool CpuFeatures::initialized_ = false;
+#endif
+uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
+uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
 
 
-void CpuFeatures::Probe(bool portable)  {
-  ASSERT(HEAP->HasBeenSetup());
+void CpuFeatures::Probe() {
+  ASSERT(!initialized_);
+#ifdef DEBUG
+  initialized_ = true;
+#endif
   supported_ = kDefaultCpuFeatures;
-  if (portable && Serializer::enabled()) {
+  if (Serializer::enabled()) {
     supported_ |= OS::CpuFeaturesImpliedByPlatform();
     return;  // No features if we might serialize.
   }
 
-  Assembler assm(NULL, 0);
+  const int kBufferSize = 4 * KB;
+  VirtualMemory* memory = new VirtualMemory(kBufferSize);
+  if (!memory->IsReserved()) {
+    delete memory;
+    return;
+  }
+  ASSERT(memory->size() >= static_cast<size_t>(kBufferSize));
+  if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) {
+    delete memory;
+    return;
+  }
+
+  Assembler assm(NULL, memory->address(), kBufferSize);
   Label cpuid, done;
 #define __ assm.
   // Save old rsp, since we are going to modify the stack.
@@ -83,7 +99,7 @@
   // ecx:edx. Temporarily enable CPUID support because we know it's
   // safe here.
   __ bind(&cpuid);
-  __ movq(rax, Immediate(1));
+  __ movl(rax, Immediate(1));
   supported_ = kDefaultCpuFeatures | (1 << CPUID);
   { Scope fscope(CPUID);
     __ cpuid();
@@ -117,31 +133,20 @@
   __ ret(0);
 #undef __
 
-  CodeDesc desc;
-  assm.GetCode(&desc);
-  Isolate* isolate = Isolate::Current();
-  MaybeObject* maybe_code =
-      isolate->heap()->CreateCode(desc,
-                                  Code::ComputeFlags(Code::STUB),
-                                  Handle<Object>());
-  Object* code;
-  if (!maybe_code->ToObject(&code)) return;
-  if (!code->IsCode()) return;
-  PROFILE(isolate,
-          CodeCreateEvent(Logger::BUILTIN_TAG,
-                          Code::cast(code), "CpuFeatures::Probe"));
   typedef uint64_t (*F0)();
-  F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
+  F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
   supported_ = probe();
   found_by_runtime_probing_ = supported_;
   found_by_runtime_probing_ &= ~kDefaultCpuFeatures;
   uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform();
   supported_ |= os_guarantees;
-  found_by_runtime_probing_ &= portable ? ~os_guarantees : 0;
+  found_by_runtime_probing_ &= ~os_guarantees;
   // SSE2 and CMOV must be available on an X64 CPU.
   ASSERT(IsSupported(CPUID));
   ASSERT(IsSupported(SSE2));
   ASSERT(IsSupported(CMOV));
+
+  delete memory;
 }
 
 
@@ -339,8 +344,8 @@
 static void InitCoverageLog();
 #endif
 
-Assembler::Assembler(void* buffer, int buffer_size)
-    : AssemblerBase(Isolate::Current()),
+Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
+    : AssemblerBase(arg_isolate),
       code_targets_(100),
       positions_recorder_(this),
       emit_debug_code_(FLAG_debug_code) {
@@ -349,7 +354,7 @@
     if (buffer_size <= kMinimalBufferSize) {
       buffer_size = kMinimalBufferSize;
 
-      if (isolate()->assembler_spare_buffer() != NULL) {
+      if (isolate() != NULL && isolate()->assembler_spare_buffer() != NULL) {
         buffer = isolate()->assembler_spare_buffer();
         isolate()->set_assembler_spare_buffer(NULL);
       }
@@ -383,7 +388,6 @@
   pc_ = buffer_;
   reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
 
-  last_pc_ = NULL;
 
 #ifdef GENERATED_CODE_COVERAGE
   InitCoverageLog();
@@ -393,7 +397,8 @@
 
 Assembler::~Assembler() {
   if (own_buffer_) {
-    if (isolate()->assembler_spare_buffer() == NULL &&
+    if (isolate() != NULL &&
+        isolate()->assembler_spare_buffer() == NULL &&
         buffer_size_ == kMinimalBufferSize) {
       isolate()->set_assembler_spare_buffer(buffer_);
     } else {
@@ -438,7 +443,6 @@
 
 void Assembler::bind_to(Label* L, int pos) {
   ASSERT(!L->is_bound());  // Label may only be bound once.
-  last_pc_ = NULL;
   ASSERT(0 <= pos && pos <= pc_offset());  // Position must be valid.
   if (L->is_linked()) {
     int current = L->pos();
@@ -465,7 +469,6 @@
 
 void Assembler::bind(NearLabel* L) {
   ASSERT(!L->is_bound());
-  last_pc_ = NULL;
   while (L->unresolved_branches_ > 0) {
     int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1];
     int disp = pc_offset() - branch_pos;
@@ -516,7 +519,8 @@
           reloc_info_writer.pos(), desc.reloc_size);
 
   // Switch buffers.
-  if (isolate()->assembler_spare_buffer() == NULL &&
+  if (isolate() != NULL &&
+      isolate()->assembler_spare_buffer() == NULL &&
       buffer_size_ == kMinimalBufferSize) {
     isolate()->set_assembler_spare_buffer(buffer_);
   } else {
@@ -525,9 +529,6 @@
   buffer_ = desc.buffer;
   buffer_size_ = desc.buffer_size;
   pc_ += pc_delta;
-  if (last_pc_ != NULL) {
-    last_pc_ += pc_delta;
-  }
   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
                                reloc_info_writer.last_pc() + pc_delta);
 
@@ -565,7 +566,6 @@
 
 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(reg, op);
   emit(opcode);
   emit_operand(reg, op);
@@ -574,7 +574,6 @@
 
 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT((opcode & 0xC6) == 2);
   if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
     // Swap reg and rm_reg and change opcode operand order.
@@ -591,7 +590,6 @@
 
 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT((opcode & 0xC6) == 2);
   if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
     // Swap reg and rm_reg and change opcode operand order.
@@ -612,7 +610,6 @@
                                  Register reg,
                                  const Operand& rm_reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(reg, rm_reg);
   emit(opcode);
@@ -622,7 +619,6 @@
 
 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT((opcode & 0xC6) == 2);
   if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
     // Swap reg and rm_reg and change opcode operand order.
@@ -641,7 +637,6 @@
                                  Register reg,
                                  const Operand& rm_reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(reg, rm_reg);
   emit(opcode);
   emit_operand(reg, rm_reg);
@@ -652,7 +647,6 @@
                                         Register dst,
                                         Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   if (is_int8(src.value_)) {
     emit(0x83);
@@ -672,7 +666,6 @@
                                         const Operand& dst,
                                         Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   if (is_int8(src.value_)) {
     emit(0x83);
@@ -690,7 +683,6 @@
                                            Register dst,
                                            Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);  // Operand size override prefix.
   emit_optional_rex_32(dst);
   if (is_int8(src.value_)) {
@@ -712,7 +704,6 @@
                                            const Operand& dst,
                                            Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);  // Operand size override prefix.
   emit_optional_rex_32(dst);
   if (is_int8(src.value_)) {
@@ -731,7 +722,6 @@
                                            Register dst,
                                            Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   if (is_int8(src.value_)) {
     emit(0x83);
@@ -752,7 +742,6 @@
                                            const Operand& dst,
                                            Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   if (is_int8(src.value_)) {
     emit(0x83);
@@ -770,7 +759,6 @@
                                           const Operand& dst,
                                           Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
   emit(0x80);
@@ -783,7 +771,6 @@
                                           Register dst,
                                           Immediate src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (dst.code() > 3) {
     // Use 64-bit mode byte registers.
     emit_rex_64(dst);
@@ -797,7 +784,6 @@
 
 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint6(shift_amount.value_));  // illegal shift count
   if (shift_amount.value_ == 1) {
     emit_rex_64(dst);
@@ -814,7 +800,6 @@
 
 void Assembler::shift(Register dst, int subcode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xD3);
   emit_modrm(subcode, dst);
@@ -823,7 +808,6 @@
 
 void Assembler::shift_32(Register dst, int subcode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xD3);
   emit_modrm(subcode, dst);
@@ -832,7 +816,6 @@
 
 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint5(shift_amount.value_));  // illegal shift count
   if (shift_amount.value_ == 1) {
     emit_optional_rex_32(dst);
@@ -849,7 +832,6 @@
 
 void Assembler::bt(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src, dst);
   emit(0x0F);
   emit(0xA3);
@@ -859,7 +841,6 @@
 
 void Assembler::bts(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src, dst);
   emit(0x0F);
   emit(0xAB);
@@ -870,7 +851,6 @@
 void Assembler::call(Label* L) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // 1110 1000 #32-bit disp.
   emit(0xE8);
   if (L->is_bound()) {
@@ -892,7 +872,6 @@
 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // 1110 1000 #32-bit disp.
   emit(0xE8);
   emit_code_target(target, rmode);
@@ -902,7 +881,6 @@
 void Assembler::call(Register adr) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: FF /2 r64.
   emit_optional_rex_32(adr);
   emit(0xFF);
@@ -913,7 +891,6 @@
 void Assembler::call(const Operand& op) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: FF /2 m64.
   emit_optional_rex_32(op);
   emit(0xFF);
@@ -928,7 +905,6 @@
 void Assembler::call(Address target) {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // 1110 1000 #32-bit disp.
   emit(0xE8);
   Address source = pc_ + 4;
@@ -940,19 +916,16 @@
 
 void Assembler::clc() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF8);
 }
 
 void Assembler::cld() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xFC);
 }
 
 void Assembler::cdq() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x99);
 }
 
@@ -967,7 +940,6 @@
   // 64-bit architecture.
   ASSERT(cc >= 0);  // Use mov for unconditional moves.
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: REX.W 0f 40 + cc /r.
   emit_rex_64(dst, src);
   emit(0x0f);
@@ -984,7 +956,6 @@
   }
   ASSERT(cc >= 0);
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: REX.W 0f 40 + cc /r.
   emit_rex_64(dst, src);
   emit(0x0f);
@@ -1001,7 +972,6 @@
   }
   ASSERT(cc >= 0);
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: 0f 40 + cc /r.
   emit_optional_rex_32(dst, src);
   emit(0x0f);
@@ -1018,7 +988,6 @@
   }
   ASSERT(cc >= 0);
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode: 0f 40 + cc /r.
   emit_optional_rex_32(dst, src);
   emit(0x0f);
@@ -1030,16 +999,14 @@
 void Assembler::cmpb_al(Immediate imm8) {
   ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x3c);
   emit(imm8.value_);
 }
 
 
 void Assembler::cpuid() {
-  ASSERT(isolate()->cpu_features()->IsEnabled(CPUID));
+  ASSERT(CpuFeatures::IsEnabled(CPUID));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x0F);
   emit(0xA2);
 }
@@ -1047,7 +1014,6 @@
 
 void Assembler::cqo() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64();
   emit(0x99);
 }
@@ -1055,7 +1021,6 @@
 
 void Assembler::decq(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xFF);
   emit_modrm(0x1, dst);
@@ -1064,7 +1029,6 @@
 
 void Assembler::decq(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xFF);
   emit_operand(1, dst);
@@ -1073,7 +1037,6 @@
 
 void Assembler::decl(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xFF);
   emit_modrm(0x1, dst);
@@ -1082,7 +1045,6 @@
 
 void Assembler::decl(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xFF);
   emit_operand(1, dst);
@@ -1091,7 +1053,6 @@
 
 void Assembler::decb(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (dst.code() > 3) {
     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
     emit_rex_32(dst);
@@ -1103,7 +1064,6 @@
 
 void Assembler::decb(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xFE);
   emit_operand(1, dst);
@@ -1112,7 +1072,6 @@
 
 void Assembler::enter(Immediate size) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xC8);
   emitw(size.value_);  // 16 bit operand, always.
   emit(0);
@@ -1121,14 +1080,12 @@
 
 void Assembler::hlt() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF4);
 }
 
 
 void Assembler::idivq(Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src);
   emit(0xF7);
   emit_modrm(0x7, src);
@@ -1137,7 +1094,6 @@
 
 void Assembler::idivl(Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(src);
   emit(0xF7);
   emit_modrm(0x7, src);
@@ -1146,7 +1102,6 @@
 
 void Assembler::imul(Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src);
   emit(0xF7);
   emit_modrm(0x5, src);
@@ -1155,7 +1110,6 @@
 
 void Assembler::imul(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x0F);
   emit(0xAF);
@@ -1165,7 +1119,6 @@
 
 void Assembler::imul(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x0F);
   emit(0xAF);
@@ -1175,7 +1128,6 @@
 
 void Assembler::imul(Register dst, Register src, Immediate imm) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   if (is_int8(imm.value_)) {
     emit(0x6B);
@@ -1191,7 +1143,6 @@
 
 void Assembler::imull(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xAF);
@@ -1201,7 +1152,6 @@
 
 void Assembler::imull(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xAF);
@@ -1211,7 +1161,6 @@
 
 void Assembler::imull(Register dst, Register src, Immediate imm) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   if (is_int8(imm.value_)) {
     emit(0x6B);
@@ -1227,7 +1176,6 @@
 
 void Assembler::incq(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xFF);
   emit_modrm(0x0, dst);
@@ -1236,7 +1184,6 @@
 
 void Assembler::incq(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xFF);
   emit_operand(0, dst);
@@ -1245,7 +1192,6 @@
 
 void Assembler::incl(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xFF);
   emit_operand(0, dst);
@@ -1254,7 +1200,6 @@
 
 void Assembler::incl(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xFF);
   emit_modrm(0, dst);
@@ -1263,7 +1208,6 @@
 
 void Assembler::int3() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xCC);
 }
 
@@ -1276,7 +1220,6 @@
     return;
   }
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint4(cc));
   if (L->is_bound()) {
     const int short_size = 2;
@@ -1314,7 +1257,6 @@
                   Handle<Code> target,
                   RelocInfo::Mode rmode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint4(cc));
   // 0000 1111 1000 tttn #32-bit disp.
   emit(0x0F);
@@ -1325,7 +1267,6 @@
 
 void Assembler::j(Condition cc, NearLabel* L, Hint hint) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(0 <= cc && cc < 16);
   if (FLAG_emit_branch_hints && hint != no_hint) emit(hint);
   if (L->is_bound()) {
@@ -1346,7 +1287,6 @@
 
 void Assembler::jmp(Label* L) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   const int short_size = sizeof(int8_t);
   const int long_size = sizeof(int32_t);
   if (L->is_bound()) {
@@ -1379,7 +1319,6 @@
 
 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // 1110 1001 #32-bit disp.
   emit(0xE9);
   emit_code_target(target, rmode);
@@ -1388,7 +1327,6 @@
 
 void Assembler::jmp(NearLabel* L) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (L->is_bound()) {
     const int short_size = sizeof(int8_t);
     int offs = L->pos() - pc_offset();
@@ -1407,7 +1345,6 @@
 
 void Assembler::jmp(Register target) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode FF/4 r64.
   emit_optional_rex_32(target);
   emit(0xFF);
@@ -1417,7 +1354,6 @@
 
 void Assembler::jmp(const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   // Opcode FF/4 m64.
   emit_optional_rex_32(src);
   emit(0xFF);
@@ -1427,7 +1363,6 @@
 
 void Assembler::lea(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x8D);
   emit_operand(dst, src);
@@ -1436,7 +1371,6 @@
 
 void Assembler::leal(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x8D);
   emit_operand(dst, src);
@@ -1445,7 +1379,6 @@
 
 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x48);  // REX.W
   emit(0xA1);
   emitq(reinterpret_cast<uintptr_t>(value), mode);
@@ -1459,15 +1392,18 @@
 
 void Assembler::leave() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xC9);
 }
 
 
 void Assembler::movb(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
-  emit_rex_32(dst, src);
+  if (dst.code() > 3) {
+    // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+    emit_rex_32(dst, src);
+  } else {
+    emit_optional_rex_32(dst, src);
+  }
   emit(0x8A);
   emit_operand(dst, src);
 }
@@ -1475,18 +1411,21 @@
 
 void Assembler::movb(Register dst, Immediate imm) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
-  emit_rex_32(dst);
-  emit(0xC6);
-  emit_modrm(0x0, dst);
+  if (dst.code() > 3) {
+    emit_rex_32(dst);
+  }
+  emit(0xB0 + dst.low_bits());
   emit(imm.value_);
 }
 
 
 void Assembler::movb(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
-  emit_rex_32(src, dst);
+  if (src.code() > 3) {
+    emit_rex_32(src, dst);
+  } else {
+    emit_optional_rex_32(src, dst);
+  }
   emit(0x88);
   emit_operand(src, dst);
 }
@@ -1494,7 +1433,6 @@
 
 void Assembler::movw(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(src, dst);
   emit(0x89);
@@ -1504,7 +1442,6 @@
 
 void Assembler::movl(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x8B);
   emit_operand(dst, src);
@@ -1513,7 +1450,6 @@
 
 void Assembler::movl(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.low_bits() == 4) {
     emit_optional_rex_32(src, dst);
     emit(0x89);
@@ -1528,7 +1464,6 @@
 
 void Assembler::movl(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(src, dst);
   emit(0x89);
   emit_operand(src, dst);
@@ -1537,27 +1472,23 @@
 
 void Assembler::movl(const Operand& dst, Immediate value) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xC7);
   emit_operand(0x0, dst);
-  emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
+  emit(value);
 }
 
 
 void Assembler::movl(Register dst, Immediate value) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
-  emit(0xC7);
-  emit_modrm(0x0, dst);
-  emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
+  emit(0xB8 + dst.low_bits());
+  emit(value);
 }
 
 
 void Assembler::movq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x8B);
   emit_operand(dst, src);
@@ -1566,7 +1497,6 @@
 
 void Assembler::movq(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.low_bits() == 4) {
     emit_rex_64(src, dst);
     emit(0x89);
@@ -1581,7 +1511,6 @@
 
 void Assembler::movq(Register dst, Immediate value) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xC7);
   emit_modrm(0x0, dst);
@@ -1591,7 +1520,6 @@
 
 void Assembler::movq(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src, dst);
   emit(0x89);
   emit_operand(src, dst);
@@ -1603,7 +1531,6 @@
   // address is not GC safe. Use the handle version instead.
   ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xB8 | dst.low_bits());
   emitq(reinterpret_cast<uintptr_t>(value), rmode);
@@ -1625,7 +1552,6 @@
     // value.
   }
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xB8 | dst.low_bits());
   emitq(value, rmode);
@@ -1640,7 +1566,6 @@
 
 void Assembler::movq(const Operand& dst, Immediate value) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xC7);
   emit_operand(0, dst);
@@ -1652,7 +1577,6 @@
 // (as a 32-bit offset sign extended to 64-bit).
 void Assembler::movl(const Operand& dst, Label* src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xC7);
   emit_operand(0, dst);
@@ -1682,7 +1606,6 @@
     movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE);
   } else {
     EnsureSpace ensure_space(this);
-    last_pc_ = pc_;
     ASSERT(value->IsHeapObject());
     ASSERT(!HEAP->InNewSpace(*value));
     emit_rex_64(dst);
@@ -1694,7 +1617,6 @@
 
 void Assembler::movsxbq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x0F);
   emit(0xBE);
@@ -1704,7 +1626,6 @@
 
 void Assembler::movsxwq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x0F);
   emit(0xBF);
@@ -1714,7 +1635,6 @@
 
 void Assembler::movsxlq(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x63);
   emit_modrm(dst, src);
@@ -1723,7 +1643,6 @@
 
 void Assembler::movsxlq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst, src);
   emit(0x63);
   emit_operand(dst, src);
@@ -1732,7 +1651,6 @@
 
 void Assembler::movzxbq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB6);
@@ -1742,7 +1660,6 @@
 
 void Assembler::movzxbl(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB6);
@@ -1752,7 +1669,6 @@
 
 void Assembler::movzxwq(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB7);
@@ -1762,7 +1678,6 @@
 
 void Assembler::movzxwl(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst, src);
   emit(0x0F);
   emit(0xB7);
@@ -1772,7 +1687,6 @@
 
 void Assembler::repmovsb() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit(0xA4);
 }
@@ -1780,7 +1694,6 @@
 
 void Assembler::repmovsw() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);  // Operand size override.
   emit(0xF3);
   emit(0xA4);
@@ -1789,7 +1702,6 @@
 
 void Assembler::repmovsl() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit(0xA5);
 }
@@ -1797,7 +1709,6 @@
 
 void Assembler::repmovsq() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_rex_64();
   emit(0xA5);
@@ -1806,7 +1717,6 @@
 
 void Assembler::mul(Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src);
   emit(0xF7);
   emit_modrm(0x4, src);
@@ -1815,7 +1725,6 @@
 
 void Assembler::neg(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xF7);
   emit_modrm(0x3, dst);
@@ -1824,7 +1733,6 @@
 
 void Assembler::negl(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xF7);
   emit_modrm(0x3, dst);
@@ -1833,7 +1741,6 @@
 
 void Assembler::neg(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xF7);
   emit_operand(3, dst);
@@ -1842,14 +1749,12 @@
 
 void Assembler::nop() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x90);
 }
 
 
 void Assembler::not_(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xF7);
   emit_modrm(0x2, dst);
@@ -1858,7 +1763,6 @@
 
 void Assembler::not_(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(dst);
   emit(0xF7);
   emit_operand(2, dst);
@@ -1867,7 +1771,6 @@
 
 void Assembler::notl(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0xF7);
   emit_modrm(0x2, dst);
@@ -1892,7 +1795,6 @@
   ASSERT(1 <= n);
   ASSERT(n <= 9);
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   switch (n) {
   case 1:
     emit(0x90);
@@ -1963,7 +1865,6 @@
 
 void Assembler::pop(Register dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0x58 | dst.low_bits());
 }
@@ -1971,7 +1872,6 @@
 
 void Assembler::pop(const Operand& dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(dst);
   emit(0x8F);
   emit_operand(0, dst);
@@ -1980,14 +1880,12 @@
 
 void Assembler::popfq() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x9D);
 }
 
 
 void Assembler::push(Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(src);
   emit(0x50 | src.low_bits());
 }
@@ -1995,7 +1893,6 @@
 
 void Assembler::push(const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(src);
   emit(0xFF);
   emit_operand(6, src);
@@ -2004,7 +1901,6 @@
 
 void Assembler::push(Immediate value) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (is_int8(value.value_)) {
     emit(0x6A);
     emit(value.value_);  // Emit low byte of value.
@@ -2017,7 +1913,6 @@
 
 void Assembler::push_imm32(int32_t imm32) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x68);
   emitl(imm32);
 }
@@ -2025,14 +1920,12 @@
 
 void Assembler::pushfq() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x9C);
 }
 
 
 void Assembler::rdtsc() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x0F);
   emit(0x31);
 }
@@ -2040,7 +1933,6 @@
 
 void Assembler::ret(int imm16) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint16(imm16));
   if (imm16 == 0) {
     emit(0xC3);
@@ -2058,7 +1950,6 @@
     return;
   }
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   ASSERT(is_uint4(cc));
   if (reg.code() > 3) {  // Use x64 byte registers, where different.
     emit_rex_32(reg);
@@ -2071,7 +1962,6 @@
 
 void Assembler::shld(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src, dst);
   emit(0x0F);
   emit(0xA5);
@@ -2081,7 +1971,6 @@
 
 void Assembler::shrd(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(src, dst);
   emit(0x0F);
   emit(0xAD);
@@ -2091,7 +1980,6 @@
 
 void Assembler::xchg(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
     Register other = src.is(rax) ? dst : src;
     emit_rex_64(other);
@@ -2110,7 +1998,6 @@
 
 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x48);  // REX.W
   emit(0xA3);
   emitq(reinterpret_cast<uintptr_t>(dst), mode);
@@ -2124,7 +2011,6 @@
 
 void Assembler::testb(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.low_bits() == 4) {
     emit_rex_32(src, dst);
     emit(0x84);
@@ -2143,7 +2029,6 @@
 void Assembler::testb(Register reg, Immediate mask) {
   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (reg.is(rax)) {
     emit(0xA8);
     emit(mask.value_);  // Low byte emitted.
@@ -2162,7 +2047,6 @@
 void Assembler::testb(const Operand& op, Immediate mask) {
   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(rax, op);
   emit(0xF6);
   emit_operand(rax, op);  // Operation code 0
@@ -2172,7 +2056,6 @@
 
 void Assembler::testb(const Operand& op, Register reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (reg.code() > 3) {
     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
     emit_rex_32(reg, op);
@@ -2186,7 +2069,6 @@
 
 void Assembler::testl(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.low_bits() == 4) {
     emit_optional_rex_32(src, dst);
     emit(0x85);
@@ -2206,7 +2088,6 @@
     return;
   }
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (reg.is(rax)) {
     emit(0xA9);
     emit(mask);
@@ -2226,7 +2107,6 @@
     return;
   }
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(rax, op);
   emit(0xF7);
   emit_operand(rax, op);  // Operation code 0
@@ -2236,7 +2116,6 @@
 
 void Assembler::testq(const Operand& op, Register reg) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_rex_64(reg, op);
   emit(0x85);
   emit_operand(reg, op);
@@ -2245,7 +2124,6 @@
 
 void Assembler::testq(Register dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (src.low_bits() == 4) {
     emit_rex_64(src, dst);
     emit(0x85);
@@ -2260,7 +2138,6 @@
 
 void Assembler::testq(Register dst, Immediate mask) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   if (dst.is(rax)) {
     emit_rex_64();
     emit(0xA9);
@@ -2279,14 +2156,12 @@
 
 void Assembler::fld(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xD9, 0xC0, i);
 }
 
 
 void Assembler::fld1() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xE8);
 }
@@ -2294,7 +2169,6 @@
 
 void Assembler::fldz() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xEE);
 }
@@ -2302,7 +2176,6 @@
 
 void Assembler::fldpi() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xEB);
 }
@@ -2310,7 +2183,6 @@
 
 void Assembler::fldln2() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xED);
 }
@@ -2318,7 +2190,6 @@
 
 void Assembler::fld_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xD9);
   emit_operand(0, adr);
@@ -2327,7 +2198,6 @@
 
 void Assembler::fld_d(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDD);
   emit_operand(0, adr);
@@ -2336,7 +2206,6 @@
 
 void Assembler::fstp_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xD9);
   emit_operand(3, adr);
@@ -2345,7 +2214,6 @@
 
 void Assembler::fstp_d(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDD);
   emit_operand(3, adr);
@@ -2355,14 +2223,12 @@
 void Assembler::fstp(int index) {
   ASSERT(is_uint3(index));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDD, 0xD8, index);
 }
 
 
 void Assembler::fild_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDB);
   emit_operand(0, adr);
@@ -2371,7 +2237,6 @@
 
 void Assembler::fild_d(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDF);
   emit_operand(5, adr);
@@ -2380,7 +2245,6 @@
 
 void Assembler::fistp_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDB);
   emit_operand(3, adr);
@@ -2388,9 +2252,8 @@
 
 
 void Assembler::fisttp_s(const Operand& adr) {
-  ASSERT(isolate()->cpu_features()->IsEnabled(SSE3));
+  ASSERT(CpuFeatures::IsEnabled(SSE3));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDB);
   emit_operand(1, adr);
@@ -2398,9 +2261,8 @@
 
 
 void Assembler::fisttp_d(const Operand& adr) {
-  ASSERT(isolate()->cpu_features()->IsEnabled(SSE3));
+  ASSERT(CpuFeatures::IsEnabled(SSE3));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDD);
   emit_operand(1, adr);
@@ -2409,7 +2271,6 @@
 
 void Assembler::fist_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDB);
   emit_operand(2, adr);
@@ -2418,7 +2279,6 @@
 
 void Assembler::fistp_d(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDF);
   emit_operand(7, adr);
@@ -2427,7 +2287,6 @@
 
 void Assembler::fabs() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xE1);
 }
@@ -2435,7 +2294,6 @@
 
 void Assembler::fchs() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xE0);
 }
@@ -2443,7 +2301,6 @@
 
 void Assembler::fcos() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xFF);
 }
@@ -2451,7 +2308,6 @@
 
 void Assembler::fsin() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xFE);
 }
@@ -2459,7 +2315,6 @@
 
 void Assembler::fyl2x() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xF1);
 }
@@ -2467,21 +2322,18 @@
 
 void Assembler::fadd(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDC, 0xC0, i);
 }
 
 
 void Assembler::fsub(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDC, 0xE8, i);
 }
 
 
 void Assembler::fisub_s(const Operand& adr) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_optional_rex_32(adr);
   emit(0xDA);
   emit_operand(4, adr);
@@ -2490,56 +2342,48 @@
 
 void Assembler::fmul(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDC, 0xC8, i);
 }
 
 
 void Assembler::fdiv(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDC, 0xF8, i);
 }
 
 
 void Assembler::faddp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDE, 0xC0, i);
 }
 
 
 void Assembler::fsubp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDE, 0xE8, i);
 }
 
 
 void Assembler::fsubrp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDE, 0xE0, i);
 }
 
 
 void Assembler::fmulp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDE, 0xC8, i);
 }
 
 
 void Assembler::fdivp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDE, 0xF8, i);
 }
 
 
 void Assembler::fprem() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xF8);
 }
@@ -2547,7 +2391,6 @@
 
 void Assembler::fprem1() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xF5);
 }
@@ -2555,14 +2398,12 @@
 
 void Assembler::fxch(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xD9, 0xC8, i);
 }
 
 
 void Assembler::fincstp() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xF7);
 }
@@ -2570,14 +2411,12 @@
 
 void Assembler::ffree(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDD, 0xC0, i);
 }
 
 
 void Assembler::ftst() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xE4);
 }
@@ -2585,14 +2424,12 @@
 
 void Assembler::fucomp(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit_farith(0xDD, 0xE8, i);
 }
 
 
 void Assembler::fucompp() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDA);
   emit(0xE9);
 }
@@ -2600,7 +2437,6 @@
 
 void Assembler::fucomi(int i) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDB);
   emit(0xE8 + i);
 }
@@ -2608,7 +2444,6 @@
 
 void Assembler::fucomip() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDF);
   emit(0xE9);
 }
@@ -2616,7 +2451,6 @@
 
 void Assembler::fcompp() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDE);
   emit(0xD9);
 }
@@ -2624,7 +2458,6 @@
 
 void Assembler::fnstsw_ax() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDF);
   emit(0xE0);
 }
@@ -2632,14 +2465,12 @@
 
 void Assembler::fwait() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x9B);
 }
 
 
 void Assembler::frndint() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xD9);
   emit(0xFC);
 }
@@ -2647,7 +2478,6 @@
 
 void Assembler::fnclex() {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xDB);
   emit(0xE2);
 }
@@ -2657,7 +2487,6 @@
   // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
   // in 64-bit mode. Test CpuID.
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x9E);
 }
 
@@ -2673,7 +2502,6 @@
 
 void Assembler::movd(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2684,7 +2512,6 @@
 
 void Assembler::movd(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(src, dst);
   emit(0x0F);
@@ -2695,7 +2522,6 @@
 
 void Assembler::movq(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_rex_64(dst, src);
   emit(0x0F);
@@ -2706,7 +2532,6 @@
 
 void Assembler::movq(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_rex_64(src, dst);
   emit(0x0F);
@@ -2715,10 +2540,26 @@
 }
 
 
-void Assembler::movdqa(const Operand& dst, XMMRegister src) {
-  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
+void Assembler::movq(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
+  if (dst.low_bits() == 4) {
+    // Avoid unnecessary SIB byte.
+    emit(0xf3);
+    emit_optional_rex_32(dst, src);
+    emit(0x0F);
+    emit(0x7e);
+    emit_sse_operand(dst, src);
+  } else {
+    emit(0x66);
+    emit_optional_rex_32(src, dst);
+    emit(0x0F);
+    emit(0xD6);
+    emit_sse_operand(src, dst);
+  }
+}
+
+void Assembler::movdqa(const Operand& dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
   emit(0x66);
   emit_rex_64(src, dst);
   emit(0x0F);
@@ -2728,9 +2569,7 @@
 
 
 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
-  ASSERT(isolate()->cpu_features()->IsEnabled(SSE2));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_rex_64(dst, src);
   emit(0x0F);
@@ -2742,7 +2581,6 @@
 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
   ASSERT(is_uint2(imm8));
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2755,7 +2593,6 @@
 
 void Assembler::movsd(const Operand& dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);  // double
   emit_optional_rex_32(src, dst);
   emit(0x0F);
@@ -2766,7 +2603,6 @@
 
 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);  // double
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2777,7 +2613,6 @@
 
 void Assembler::movsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);  // double
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2786,9 +2621,44 @@
 }
 
 
+void Assembler::movaps(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  if (src.low_bits() == 4) {
+    // Try to avoid an unnecessary SIB byte.
+    emit_optional_rex_32(src, dst);
+    emit(0x0F);
+    emit(0x29);
+    emit_sse_operand(src, dst);
+  } else {
+    emit_optional_rex_32(dst, src);
+    emit(0x0F);
+    emit(0x28);
+    emit_sse_operand(dst, src);
+  }
+}
+
+
+void Assembler::movapd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  if (src.low_bits() == 4) {
+    // Try to avoid an unnecessary SIB byte.
+    emit(0x66);
+    emit_optional_rex_32(src, dst);
+    emit(0x0F);
+    emit(0x29);
+    emit_sse_operand(src, dst);
+  } else {
+    emit(0x66);
+    emit_optional_rex_32(dst, src);
+    emit(0x0F);
+    emit(0x28);
+    emit_sse_operand(dst, src);
+  }
+}
+
+
 void Assembler::movss(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);  // single
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2799,7 +2669,6 @@
 
 void Assembler::movss(const Operand& src, XMMRegister dst) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);  // single
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2810,7 +2679,6 @@
 
 void Assembler::cvttss2si(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2821,7 +2689,6 @@
 
 void Assembler::cvttss2si(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2832,7 +2699,6 @@
 
 void Assembler::cvttsd2si(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2843,7 +2709,6 @@
 
 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2854,7 +2719,6 @@
 
 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_rex_64(dst, src);
   emit(0x0F);
@@ -2865,7 +2729,6 @@
 
 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2876,7 +2739,6 @@
 
 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2887,7 +2749,6 @@
 
 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2898,7 +2759,6 @@
 
 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_rex_64(dst, src);
   emit(0x0F);
@@ -2909,7 +2769,6 @@
 
 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2920,7 +2779,6 @@
 
 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF3);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2931,7 +2789,6 @@
 
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2942,7 +2799,6 @@
 
 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2953,7 +2809,6 @@
 
 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_rex_64(dst, src);
   emit(0x0F);
@@ -2964,7 +2819,6 @@
 
 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2975,7 +2829,6 @@
 
 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2986,7 +2839,6 @@
 
 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -2997,7 +2849,6 @@
 
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -3008,7 +2859,6 @@
 
 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -3019,7 +2869,6 @@
 
 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -3030,7 +2879,6 @@
 
 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -3039,9 +2887,17 @@
 }
 
 
+void Assembler::xorps(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  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);
-  last_pc_ = pc_;
   emit(0xF2);
   emit_optional_rex_32(dst, src);
   emit(0x0F);
@@ -3052,7 +2908,6 @@
 
 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0f);
@@ -3063,7 +2918,6 @@
 
 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0f);
@@ -3072,9 +2926,23 @@
 }
 
 
+void Assembler::roundsd(XMMRegister dst, XMMRegister src,
+                        Assembler::RoundingMode mode) {
+  ASSERT(CpuFeatures::IsEnabled(SSE4_1));
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x3a);
+  emit(0x0b);
+  emit_sse_operand(dst, src);
+  // Mask precision exeption.
+  emit(static_cast<byte>(mode) | 0x8);
+}
+
+
 void Assembler::movmskpd(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
-  last_pc_ = pc_;
   emit(0x66);
   emit_optional_rex_32(dst, src);
   emit(0x0f);