LCOV - code coverage report
Current view: top level - src/x64 - assembler-x64.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1201 1418 84.7 %
Date: 2017-10-20 Functions: 364 443 82.2 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/x64/assembler-x64.h"
       6             : 
       7             : #include <cstring>
       8             : 
       9             : #if V8_TARGET_ARCH_X64
      10             : 
      11             : #if V8_LIBC_MSVCRT
      12             : #include <intrin.h>  // _xgetbv()
      13             : #endif
      14             : #if V8_OS_MACOSX
      15             : #include <sys/sysctl.h>
      16             : #endif
      17             : 
      18             : #include "src/assembler-inl.h"
      19             : #include "src/base/bits.h"
      20             : #include "src/base/cpu.h"
      21             : #include "src/code-stubs.h"
      22             : #include "src/macro-assembler.h"
      23             : #include "src/v8.h"
      24             : 
      25             : namespace v8 {
      26             : namespace internal {
      27             : 
      28             : // -----------------------------------------------------------------------------
      29             : // Implementation of CpuFeatures
      30             : 
      31             : namespace {
      32             : 
      33             : #if !V8_LIBC_MSVCRT
      34             : 
      35             : V8_INLINE uint64_t _xgetbv(unsigned int xcr) {
      36             :   unsigned eax, edx;
      37             :   // Check xgetbv; this uses a .byte sequence instead of the instruction
      38             :   // directly because older assemblers do not include support for xgetbv and
      39             :   // there is no easy way to conditionally compile based on the assembler
      40             :   // used.
      41      107952 :   __asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
      42      107952 :   return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32);
      43             : }
      44             : 
      45             : #define _XCR_XFEATURE_ENABLED_MASK 0
      46             : 
      47             : #endif  // !V8_LIBC_MSVCRT
      48             : 
      49             : 
      50             : bool OSHasAVXSupport() {
      51             : #if V8_OS_MACOSX
      52             :   // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being
      53             :   // caused by ISRs, so we detect that here and disable AVX in that case.
      54             :   char buffer[128];
      55             :   size_t buffer_size = arraysize(buffer);
      56             :   int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
      57             :   if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
      58             :     V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
      59             :   }
      60             :   // The buffer now contains a string of the form XX.YY.ZZ, where
      61             :   // XX is the major kernel version component.
      62             :   char* period_pos = strchr(buffer, '.');
      63             :   DCHECK_NOT_NULL(period_pos);
      64             :   *period_pos = '\0';
      65             :   long kernel_version_major = strtol(buffer, nullptr, 10);  // NOLINT
      66             :   if (kernel_version_major <= 13) return false;
      67             : #endif  // V8_OS_MACOSX
      68             :   // Check whether OS claims to support AVX.
      69             :   uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
      70      107952 :   return (feature_mask & 0x6) == 0x6;
      71             : }
      72             : 
      73             : }  // namespace
      74             : 
      75             : 
      76       53977 : void CpuFeatures::ProbeImpl(bool cross_compile) {
      77       53977 :   base::CPU cpu;
      78       53977 :   CHECK(cpu.has_sse2());  // SSE2 support is mandatory.
      79       53977 :   CHECK(cpu.has_cmov());  // CMOV support is mandatory.
      80             : 
      81             :   // Only use statically determined features for cross compile (snapshot).
      82       53978 :   if (cross_compile) return;
      83             : 
      84       53976 :   if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
      85       53976 :   if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3;
      86       53976 :   if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
      87             :   // SAHF is not generally available in long mode.
      88       53976 :   if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
      89      107952 :   if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() &&
      90             :       OSHasAVXSupport()) {
      91       53976 :     supported_ |= 1u << AVX;
      92             :   }
      93      107952 :   if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() &&
      94             :       OSHasAVXSupport()) {
      95       53976 :     supported_ |= 1u << FMA3;
      96             :   }
      97       53976 :   if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1;
      98       53976 :   if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2;
      99       53976 :   if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT;
     100       53976 :   if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT;
     101       53976 :   if (strcmp(FLAG_mcpu, "auto") == 0) {
     102       53976 :     if (cpu.is_atom()) supported_ |= 1u << ATOM;
     103           0 :   } else if (strcmp(FLAG_mcpu, "atom") == 0) {
     104           0 :     supported_ |= 1u << ATOM;
     105             :   }
     106             : }
     107             : 
     108             : 
     109           6 : void CpuFeatures::PrintTarget() { }
     110           6 : void CpuFeatures::PrintFeatures() {
     111             :   printf(
     112             :       "SSE3=%d SSSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d "
     113             :       "LZCNT=%d "
     114             :       "POPCNT=%d ATOM=%d\n",
     115             :       CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3),
     116             :       CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(SAHF),
     117             :       CpuFeatures::IsSupported(AVX), CpuFeatures::IsSupported(FMA3),
     118             :       CpuFeatures::IsSupported(BMI1), CpuFeatures::IsSupported(BMI2),
     119             :       CpuFeatures::IsSupported(LZCNT), CpuFeatures::IsSupported(POPCNT),
     120          66 :       CpuFeatures::IsSupported(ATOM));
     121           6 : }
     122             : 
     123             : // -----------------------------------------------------------------------------
     124             : // Implementation of RelocInfo
     125             : 
     126        5639 : Address RelocInfo::embedded_address() const { return Memory::Address_at(pc_); }
     127             : 
     128           0 : uint32_t RelocInfo::embedded_size() const { return Memory::uint32_at(pc_); }
     129             : 
     130      192492 : void RelocInfo::set_embedded_address(Isolate* isolate, Address address,
     131             :                                      ICacheFlushMode icache_flush_mode) {
     132      192492 :   Memory::Address_at(pc_) = address;
     133      192492 :   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
     134        1406 :     Assembler::FlushICache(isolate, pc_, sizeof(Address));
     135             :   }
     136      192492 : }
     137             : 
     138        1266 : void RelocInfo::set_embedded_size(Isolate* isolate, uint32_t size,
     139             :                                   ICacheFlushMode icache_flush_mode) {
     140        1266 :   Memory::uint32_at(pc_) = size;
     141        1266 :   if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
     142         716 :     Assembler::FlushICache(isolate, pc_, sizeof(uint32_t));
     143             :   }
     144        1266 : }
     145             : 
     146             : // -----------------------------------------------------------------------------
     147             : // Implementation of Operand
     148             : 
     149    36104476 : Operand::Operand(Register base, int32_t disp) : rex_(0) {
     150    36104476 :   len_ = 1;
     151    36104476 :   if (base == rsp || base == r12) {
     152             :     // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
     153             :     set_sib(times_1, rsp, base);
     154             :   }
     155             : 
     156    36104476 :   if (disp == 0 && base != rbp && base != r13) {
     157             :     set_modrm(0, base);
     158    63554190 :   } else if (is_int8(disp)) {
     159             :     set_modrm(1, base);
     160             :     set_disp8(disp);
     161             :   } else {
     162             :     set_modrm(2, base);
     163             :     set_disp32(disp);
     164             :   }
     165    36104476 : }
     166             : 
     167             : 
     168     2095847 : Operand::Operand(Register base,
     169             :                  Register index,
     170             :                  ScaleFactor scale,
     171     2095847 :                  int32_t disp) : rex_(0) {
     172             :   DCHECK(index != rsp);
     173     2095847 :   len_ = 1;
     174             :   set_sib(scale, index, base);
     175     2095847 :   if (disp == 0 && base != rbp && base != r13) {
     176             :     // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
     177             :     // possibly set by set_sib.
     178             :     set_modrm(0, rsp);
     179     2598446 :   } else if (is_int8(disp)) {
     180             :     set_modrm(1, rsp);
     181             :     set_disp8(disp);
     182             :   } else {
     183             :     set_modrm(2, rsp);
     184             :     set_disp32(disp);
     185             :   }
     186     2095847 : }
     187             : 
     188             : 
     189       62976 : Operand::Operand(Register index,
     190             :                  ScaleFactor scale,
     191       62976 :                  int32_t disp) : rex_(0) {
     192             :   DCHECK(index != rsp);
     193       62976 :   len_ = 1;
     194             :   set_modrm(0, rsp);
     195             :   set_sib(scale, index, rbp);
     196             :   set_disp32(disp);
     197       62976 : }
     198             : 
     199             : 
     200      451162 : Operand::Operand(Label* label) : rex_(0), len_(1) {
     201             :   DCHECK_NOT_NULL(label);
     202             :   set_modrm(0, rbp);
     203      451162 :   set_disp64(reinterpret_cast<intptr_t>(label));
     204      451162 : }
     205             : 
     206             : 
     207      250614 : Operand::Operand(const Operand& operand, int32_t offset) {
     208             :   DCHECK_GE(operand.len_, 1);
     209             :   // Operand encodes REX ModR/M [SIB] [Disp].
     210      250614 :   byte modrm = operand.buf_[0];
     211             :   DCHECK_LT(modrm, 0xC0);  // Disallow mode 3 (register target).
     212      250614 :   bool has_sib = ((modrm & 0x07) == 0x04);
     213      250614 :   byte mode = modrm & 0xC0;
     214      250614 :   int disp_offset = has_sib ? 2 : 1;
     215      250614 :   int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
     216             :   // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
     217             :   // displacement.
     218      250614 :   bool is_baseless = (mode == 0) && (base_reg == 0x05);  // No base or RIP base.
     219             :   int32_t disp_value = 0;
     220      250614 :   if (mode == 0x80 || is_baseless) {
     221             :     // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
     222          36 :     disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]);
     223      250578 :   } else if (mode == 0x40) {
     224             :     // Mode 1: Byte displacement.
     225      250500 :     disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
     226             :   }
     227             : 
     228             :   // Write new operand with same registers, but with modified displacement.
     229             :   DCHECK(offset >= 0 ? disp_value + offset > disp_value
     230             :                      : disp_value + offset < disp_value);  // No overflow.
     231      250614 :   disp_value += offset;
     232      250614 :   rex_ = operand.rex_;
     233      501228 :   if (!is_int8(disp_value) || is_baseless) {
     234             :     // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
     235          60 :     buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
     236          60 :     len_ = disp_offset + 4;
     237          60 :     Memory::int32_at(&buf_[disp_offset]) = disp_value;
     238      250554 :   } else if (disp_value != 0 || (base_reg == 0x05)) {
     239             :     // Need 8 bits of displacement.
     240      250518 :     buf_[0] = (modrm & 0x3f) | 0x40;  // Mode 1.
     241      250518 :     len_ = disp_offset + 1;
     242      250518 :     buf_[disp_offset] = static_cast<byte>(disp_value);
     243             :   } else {
     244             :     // Need no displacement.
     245          36 :     buf_[0] = (modrm & 0x3f);  // Mode 0.
     246          36 :     len_ = disp_offset;
     247             :   }
     248      250614 :   if (has_sib) {
     249          54 :     buf_[1] = operand.buf_[1];
     250             :   }
     251      250614 : }
     252             : 
     253             : 
     254         696 : bool Operand::AddressUsesRegister(Register reg) const {
     255             :   int code = reg.code();
     256             :   DCHECK_NE(buf_[0] & 0xC0, 0xC0);  // Always a memory operand.
     257             :   // Start with only low three bits of base register. Initial decoding doesn't
     258             :   // distinguish on the REX.B bit.
     259         696 :   int base_code = buf_[0] & 0x07;
     260         696 :   if (base_code == rsp.code()) {
     261             :     // SIB byte present in buf_[1].
     262             :     // Check the index register from the SIB byte + REX.X prefix.
     263         552 :     int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
     264             :     // Index code (including REX.X) of 0x04 (rsp) means no index register.
     265         552 :     if (index_code != rsp.code() && index_code == code) return true;
     266             :     // Add REX.B to get the full base register code.
     267         456 :     base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
     268             :     // A base register of 0x05 (rbp) with mod = 0 means no base register.
     269         456 :     if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
     270         456 :     return code == base_code;
     271             :   } else {
     272             :     // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
     273             :     // no base register.
     274         144 :     if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
     275         144 :     base_code |= ((rex_ & 0x01) << 3);
     276         144 :     return code == base_code;
     277             :   }
     278             : }
     279             : 
     280     1707964 : void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
     281     3815887 :   for (auto& request : heap_object_requests_) {
     282      177220 :     Address pc = buffer_ + request.offset();
     283       88610 :     switch (request.kind()) {
     284             :       case HeapObjectRequest::kHeapNumber: {
     285             :         Handle<HeapNumber> object = isolate->factory()->NewHeapNumber(
     286             :             request.heap_number(), IMMUTABLE, TENURED);
     287       43091 :         Memory::Object_Handle_at(pc) = object;
     288             :         break;
     289             :       }
     290             :       case HeapObjectRequest::kCodeStub: {
     291             :         request.code_stub()->set_isolate(isolate);
     292       91038 :         code_targets_[Memory::int32_at(pc)] = request.code_stub()->GetCode();
     293       45519 :         break;
     294             :       }
     295             :     }
     296             :   }
     297     1707964 : }
     298             : 
     299             : // -----------------------------------------------------------------------------
     300             : // Implementation of Assembler.
     301             : 
     302     1708952 : Assembler::Assembler(IsolateData isolate_data, void* buffer, int buffer_size)
     303     3417947 :     : AssemblerBase(isolate_data, buffer, buffer_size) {
     304             : // Clear the buffer in debug mode unless it was provided by the
     305             : // caller in which case we can't be sure it's okay to overwrite
     306             : // existing code in it.
     307             : #ifdef DEBUG
     308             :   if (own_buffer_) {
     309             :     memset(buffer_, 0xCC, buffer_size_);  // int3
     310             :   }
     311             : #endif
     312             : 
     313     1709010 :   code_targets_.reserve(100);
     314     1709022 :   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
     315     1709022 : }
     316             : 
     317     1707964 : void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
     318             :   // At this point overflow() may be true, but the gap ensures
     319             :   // that we are still not overlapping instructions and relocation info.
     320             :   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
     321             : 
     322     1707964 :   AllocateAndInstallRequestedHeapObjects(isolate);
     323             : 
     324             :   // Set up code descriptor.
     325     1707964 :   desc->buffer = buffer_;
     326     1707964 :   desc->buffer_size = buffer_size_;
     327     5123892 :   desc->instr_size = pc_offset();
     328             :   DCHECK_GT(desc->instr_size, 0);  // Zero-size code objects upset the system.
     329             :   desc->reloc_size =
     330     1707964 :       static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
     331     1707964 :   desc->origin = this;
     332     1707964 :   desc->constant_pool_size = 0;
     333     1707964 :   desc->unwinding_info_size = 0;
     334     1707964 :   desc->unwinding_info = nullptr;
     335             : 
     336             :   // Collection stage
     337       50916 :   auto jump_opt = jump_optimization_info();
     338     1758880 :   if (jump_opt && jump_opt->is_collecting()) {
     339      379314 :     auto& bitmap = jump_opt->farjmp_bitmap();
     340       27770 :     int num = static_cast<int>(farjmp_positions_.size());
     341       50978 :     if (num && bitmap.empty()) {
     342             :       bool can_opt = false;
     343             : 
     344       23208 :       bitmap.resize((num + 31) / 32, 0);
     345      724384 :       for (int i = 0; i < num; i++) {
     346      701176 :         int disp_pos = farjmp_positions_[i];
     347      701176 :         int disp = long_at(disp_pos);
     348     1402352 :         if (is_int8(disp)) {
     349      703088 :           bitmap[i / 32] |= 1 << (i & 31);
     350             :           can_opt = true;
     351             :         }
     352             :       }
     353       23208 :       if (can_opt) {
     354             :         jump_opt->set_optimizable();
     355             :       }
     356             :     }
     357             :   }
     358     1707964 : }
     359             : 
     360             : 
     361     1356505 : void Assembler::Align(int m) {
     362             :   DCHECK(base::bits::IsPowerOfTwo(m));
     363     2713010 :   int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
     364     1356505 :   Nop(delta);
     365     1356600 : }
     366             : 
     367             : 
     368           0 : void Assembler::CodeTargetAlign() {
     369           0 :   Align(16);  // Preferred alignment of jump targets on x64.
     370           0 : }
     371             : 
     372             : 
     373           0 : bool Assembler::IsNop(Address addr) {
     374             :   Address a = addr;
     375           0 :   while (*a == 0x66) a++;
     376           0 :   if (*a == 0x90) return true;
     377           0 :   if (a[0] == 0xf && a[1] == 0x1f) return true;
     378           0 :   return false;
     379             : }
     380             : 
     381             : 
     382    25636502 : void Assembler::bind_to(Label* L, int pos) {
     383             :   DCHECK(!L->is_bound());  // Label may only be bound once.
     384             :   DCHECK(0 <= pos && pos <= pc_offset());  // Position must be valid.
     385    50252658 :   if (L->is_linked()) {
     386     8636396 :     int current = L->pos();
     387     8636335 :     int next = long_at(current);
     388   620069094 :     while (next != current) {
     389  1205592599 :       if (current >= 4 && long_at(current - 4) == 0) {
     390             :         // Absolute address.
     391           0 :         intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_ + pos);
     392           0 :         *reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
     393           0 :         internal_reference_positions_.push_back(current - 4);
     394             :       } else {
     395             :         // Relative address, relative to point after address.
     396   602796411 :         int imm32 = pos - (current + sizeof(int32_t));
     397             :         long_at_put(current, imm32);
     398             :       }
     399             :       current = next;
     400   602796424 :       next = long_at(next);
     401             :     }
     402             :     // Fix up last fixup on linked list.
     403    16735909 :     if (current >= 4 && long_at(current - 4) == 0) {
     404             :       // Absolute address.
     405        3072 :       intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_ + pos);
     406        6144 :       *reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
     407        6144 :       internal_reference_positions_.push_back(current - 4);
     408             :     } else {
     409             :       // Relative address, relative to point after address.
     410     8633382 :       int imm32 = pos - (current + sizeof(int32_t));
     411             :       long_at_put(current, imm32);
     412             :     }
     413             :   }
     414    50570030 :   while (L->is_near_linked()) {
     415             :     int fixup_pos = L->near_link_pos();
     416             :     int offset_to_next =
     417      317315 :         static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
     418             :     DCHECK_LE(offset_to_next, 0);
     419      317315 :     int disp = pos - (fixup_pos + sizeof(int8_t));
     420      634630 :     CHECK(is_int8(disp));
     421             :     set_byte_at(fixup_pos, disp);
     422      317314 :     if (offset_to_next < 0) {
     423        4038 :       L->link_to(fixup_pos + offset_to_next, Label::kNear);
     424             :     } else {
     425      313276 :       L->UnuseNear();
     426             :     }
     427             :   }
     428             : 
     429             :   // Optimization stage
     430    27975662 :   auto jump_opt = jump_optimization_info();
     431    27975662 :   if (jump_opt && jump_opt->is_optimizing()) {
     432             :     auto it = label_farjmp_maps_.find(L);
     433     1498768 :     if (it != label_farjmp_maps_.end()) {
     434             :       auto& pos_vector = it->second;
     435      912332 :       for (auto fixup_pos : pos_vector) {
     436      351544 :         int disp = pos - (fixup_pos + sizeof(int8_t));
     437      703088 :         CHECK(is_int8(disp));
     438             :         set_byte_at(fixup_pos, disp);
     439             :       }
     440             :       label_farjmp_maps_.erase(it);
     441             :     }
     442             :   }
     443    24967700 :   L->bind_to(pos);
     444    24967700 : }
     445             : 
     446             : 
     447    24967712 : void Assembler::bind(Label* L) {
     448    49935424 :   bind_to(L, pc_offset());
     449    24967783 : }
     450             : 
     451           0 : void Assembler::record_farjmp_position(Label* L, int pos) {
     452      351544 :   auto& pos_vector = label_farjmp_maps_[L];
     453      351544 :   pos_vector.push_back(pos);
     454           0 : }
     455             : 
     456      701052 : bool Assembler::is_optimizable_farjmp(int idx) {
     457      701052 :   if (predictable_code_size()) return false;
     458             : 
     459      701052 :   auto jump_opt = jump_optimization_info();
     460      701052 :   CHECK(jump_opt->is_optimizing());
     461             : 
     462      701052 :   auto& bitmap = jump_opt->farjmp_bitmap();
     463      701052 :   CHECK(idx < static_cast<int>(bitmap.size() * 32));
     464     1402104 :   return !!(bitmap[idx / 32] & (1 << (idx & 31)));
     465             : }
     466             : 
     467      204036 : void Assembler::GrowBuffer() {
     468             :   DCHECK(buffer_overflow());
     469      204036 :   if (!own_buffer_) FATAL("external code buffer is too small");
     470             : 
     471             :   // Compute new buffer size.
     472             :   CodeDesc desc;  // the new buffer
     473      204036 :   desc.buffer_size = 2 * buffer_size_;
     474             : 
     475             :   // Some internal data structures overflow for very large buffers,
     476             :   // they must ensure that kMaximalBufferSize is not too large.
     477      204036 :   if (desc.buffer_size > kMaximalBufferSize) {
     478           0 :     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
     479             :   }
     480             : 
     481             :   // Set up new buffer.
     482      204036 :   desc.buffer = NewArray<byte>(desc.buffer_size);
     483             :   desc.origin = this;
     484      204036 :   desc.instr_size = pc_offset();
     485             :   desc.reloc_size =
     486      816144 :       static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
     487             : 
     488             :   // Clear the buffer in debug mode. Use 'int3' instructions to make
     489             :   // sure to get into problems if we ever run uninitialized code.
     490             : #ifdef DEBUG
     491             :   memset(desc.buffer, 0xCC, desc.buffer_size);
     492             : #endif
     493             : 
     494             :   // Copy the data.
     495      204036 :   intptr_t pc_delta = desc.buffer - buffer_;
     496      204036 :   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
     497      204036 :       (buffer_ + buffer_size_);
     498      204036 :   MemMove(desc.buffer, buffer_, desc.instr_size);
     499      204036 :   MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
     500      408072 :           desc.reloc_size);
     501             : 
     502             :   // Switch buffers.
     503      204036 :   DeleteArray(buffer_);
     504      204036 :   buffer_ = desc.buffer;
     505      204036 :   buffer_size_ = desc.buffer_size;
     506      204036 :   pc_ += pc_delta;
     507             :   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
     508      408072 :                                reloc_info_writer.last_pc() + pc_delta);
     509             : 
     510             :   // Relocate internal references.
     511      737006 :   for (auto pos : internal_reference_positions_) {
     512      266485 :     intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos);
     513      266485 :     *p += pc_delta;
     514             :   }
     515             : 
     516             :   DCHECK(!buffer_overflow());
     517      204036 : }
     518             : 
     519             : 
     520    39052075 : void Assembler::emit_operand(int code, const Operand& adr) {
     521             :   DCHECK(is_uint3(code));
     522    39052075 :   const unsigned length = adr.len_;
     523             :   DCHECK_GT(length, 0);
     524             : 
     525             :   // Emit updated ModR/M byte containing the given register.
     526             :   DCHECK_EQ(adr.buf_[0] & 0x38, 0);
     527    39052075 :   *pc_++ = adr.buf_[0] | code << 3;
     528             : 
     529             :   // Recognize RIP relative addressing.
     530    39052075 :   if (adr.buf_[0] == 5) {
     531             :     DCHECK_EQ(9u, length);
     532      451169 :     Label* label = *bit_cast<Label* const*>(&adr.buf_[1]);
     533      451169 :     if (label->is_bound()) {
     534      451169 :       int offset = label->pos() - pc_offset() - sizeof(int32_t);
     535             :       DCHECK_GE(0, offset);
     536             :       emitl(offset);
     537      451169 :     } else if (label->is_linked()) {
     538           0 :       emitl(label->pos());
     539           0 :       label->link_to(pc_offset() - sizeof(int32_t));
     540             :     } else {
     541             :       DCHECK(label->is_unused());
     542             :       int32_t current = pc_offset();
     543      451169 :       emitl(current);
     544             :       label->link_to(current);
     545             :     }
     546             :   } else {
     547             :     // Emit the rest of the encoded operand.
     548    60199389 :     for (unsigned i = 1; i < length; i++) *pc_++ = adr.buf_[i];
     549             :   }
     550    39052075 : }
     551             : 
     552             : 
     553             : // Assembler Instruction implementations.
     554             : 
     555     2408617 : void Assembler::arithmetic_op(byte opcode,
     556             :                               Register reg,
     557             :                               const Operand& op,
     558             :                               int size) {
     559             :   EnsureSpace ensure_space(this);
     560     2408617 :   emit_rex(reg, op, size);
     561             :   emit(opcode);
     562             :   emit_operand(reg, op);
     563     2408630 : }
     564             : 
     565             : 
     566     5086751 : void Assembler::arithmetic_op(byte opcode,
     567             :                               Register reg,
     568             :                               Register rm_reg,
     569             :                               int size) {
     570             :   EnsureSpace ensure_space(this);
     571             :   DCHECK_EQ(opcode & 0xC6, 2);
     572     5086768 :   if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
     573             :     // Swap reg and rm_reg and change opcode operand order.
     574      109588 :     emit_rex(rm_reg, reg, size);
     575      109588 :     emit(opcode ^ 0x02);
     576             :     emit_modrm(rm_reg, reg);
     577             :   } else {
     578     4977180 :     emit_rex(reg, rm_reg, size);
     579             :     emit(opcode);
     580             :     emit_modrm(reg, rm_reg);
     581             :   }
     582     5086770 : }
     583             : 
     584             : 
     585           0 : void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
     586             :   EnsureSpace ensure_space(this);
     587             :   DCHECK_EQ(opcode & 0xC6, 2);
     588           0 :   if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
     589             :     // Swap reg and rm_reg and change opcode operand order.
     590             :     emit(0x66);
     591             :     emit_optional_rex_32(rm_reg, reg);
     592           0 :     emit(opcode ^ 0x02);
     593             :     emit_modrm(rm_reg, reg);
     594             :   } else {
     595             :     emit(0x66);
     596             :     emit_optional_rex_32(reg, rm_reg);
     597             :     emit(opcode);
     598             :     emit_modrm(reg, rm_reg);
     599             :   }
     600           0 : }
     601             : 
     602             : 
     603          85 : void Assembler::arithmetic_op_16(byte opcode,
     604             :                                  Register reg,
     605          85 :                                  const Operand& rm_reg) {
     606             :   EnsureSpace ensure_space(this);
     607             :   emit(0x66);
     608             :   emit_optional_rex_32(reg, rm_reg);
     609             :   emit(opcode);
     610             :   emit_operand(reg, rm_reg);
     611          85 : }
     612             : 
     613             : 
     614        2806 : void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
     615             :   EnsureSpace ensure_space(this);
     616        1403 :   if (!reg.is_byte_register()) {
     617             :     emit_rex_32(reg, op);
     618             :   } else {
     619             :     emit_optional_rex_32(reg, op);
     620             :   }
     621             :   emit(opcode);
     622             :   emit_operand(reg, op);
     623        1403 : }
     624             : 
     625             : 
     626        4188 : void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
     627             :   EnsureSpace ensure_space(this);
     628             :   DCHECK_EQ(opcode & 0xC6, 2);
     629        4188 :   if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
     630             :     // Swap reg and rm_reg and change opcode operand order.
     631           1 :     if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
     632             :       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
     633             :       emit_rex_32(rm_reg, reg);
     634             :     }
     635           1 :     emit(opcode ^ 0x02);
     636             :     emit_modrm(rm_reg, reg);
     637             :   } else {
     638        4187 :     if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
     639             :       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
     640             :       emit_rex_32(reg, rm_reg);
     641             :     }
     642             :     emit(opcode);
     643             :     emit_modrm(reg, rm_reg);
     644             :   }
     645        4188 : }
     646             : 
     647             : 
     648     8722944 : void Assembler::immediate_arithmetic_op(byte subcode,
     649             :                                         Register dst,
     650             :                                         Immediate src,
     651             :                                         int size) {
     652             :   EnsureSpace ensure_space(this);
     653             :   emit_rex(dst, size);
     654    25238705 :   if (is_int8(src.value_) && RelocInfo::IsNone(src.rmode_)) {
     655             :     emit(0x83);
     656     7790119 :     emit_modrm(subcode, dst);
     657     7790119 :     emit(src.value_);
     658      932880 :   } else if (dst == rax) {
     659      208935 :     emit(0x05 | (subcode << 3));
     660      208935 :     emit(src);
     661             :   } else {
     662             :     emit(0x81);
     663      723945 :     emit_modrm(subcode, dst);
     664      723945 :     emit(src);
     665             :   }
     666     8723000 : }
     667             : 
     668      421818 : void Assembler::immediate_arithmetic_op(byte subcode,
     669             :                                         const Operand& dst,
     670             :                                         Immediate src,
     671             :                                         int size) {
     672             :   EnsureSpace ensure_space(this);
     673      421818 :   emit_rex(dst, size);
     674     1262270 :   if (is_int8(src.value_) && RelocInfo::IsNone(src.rmode_)) {
     675             :     emit(0x83);
     676      418616 :     emit_operand(subcode, dst);
     677      418616 :     emit(src.value_);
     678             :   } else {
     679             :     emit(0x81);
     680        3202 :     emit_operand(subcode, dst);
     681        3202 :     emit(src);
     682             :   }
     683      421818 : }
     684             : 
     685             : 
     686        3488 : void Assembler::immediate_arithmetic_op_16(byte subcode,
     687             :                                            Register dst,
     688             :                                            Immediate src) {
     689             :   EnsureSpace ensure_space(this);
     690             :   emit(0x66);  // Operand size override prefix.
     691             :   emit_optional_rex_32(dst);
     692        6976 :   if (is_int8(src.value_)) {
     693             :     emit(0x83);
     694         744 :     emit_modrm(subcode, dst);
     695         744 :     emit(src.value_);
     696        2744 :   } else if (dst == rax) {
     697           0 :     emit(0x05 | (subcode << 3));
     698           0 :     emitw(src.value_);
     699             :   } else {
     700             :     emit(0x81);
     701        2744 :     emit_modrm(subcode, dst);
     702        2744 :     emitw(src.value_);
     703             :   }
     704        3488 : }
     705             : 
     706             : 
     707           8 : void Assembler::immediate_arithmetic_op_16(byte subcode,
     708           8 :                                            const Operand& dst,
     709             :                                            Immediate src) {
     710             :   EnsureSpace ensure_space(this);
     711             :   emit(0x66);  // Operand size override prefix.
     712             :   emit_optional_rex_32(dst);
     713          16 :   if (is_int8(src.value_)) {
     714             :     emit(0x83);
     715           0 :     emit_operand(subcode, dst);
     716           0 :     emit(src.value_);
     717             :   } else {
     718             :     emit(0x81);
     719           8 :     emit_operand(subcode, dst);
     720           8 :     emitw(src.value_);
     721             :   }
     722           8 : }
     723             : 
     724             : 
     725      117288 : void Assembler::immediate_arithmetic_op_8(byte subcode,
     726      117288 :                                           const Operand& dst,
     727             :                                           Immediate src) {
     728             :   EnsureSpace ensure_space(this);
     729             :   emit_optional_rex_32(dst);
     730             :   DCHECK(is_int8(src.value_) || is_uint8(src.value_));
     731             :   emit(0x80);
     732      117288 :   emit_operand(subcode, dst);
     733      117288 :   emit(src.value_);
     734      117288 : }
     735             : 
     736             : 
     737       98708 : void Assembler::immediate_arithmetic_op_8(byte subcode,
     738             :                                           Register dst,
     739             :                                           Immediate src) {
     740             :   EnsureSpace ensure_space(this);
     741       98708 :   if (!dst.is_byte_register()) {
     742             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
     743             :     emit_rex_32(dst);
     744             :   }
     745             :   DCHECK(is_int8(src.value_) || is_uint8(src.value_));
     746             :   emit(0x80);
     747       98708 :   emit_modrm(subcode, dst);
     748       98708 :   emit(src.value_);
     749       98708 : }
     750             : 
     751             : 
     752      819337 : void Assembler::shift(Register dst,
     753             :                       Immediate shift_amount,
     754             :                       int subcode,
     755             :                       int size) {
     756             :   EnsureSpace ensure_space(this);
     757             :   DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
     758             :                             : is_uint5(shift_amount.value_));
     759      819352 :   if (shift_amount.value_ == 1) {
     760             :     emit_rex(dst, size);
     761             :     emit(0xD1);
     762             :     emit_modrm(subcode, dst);
     763             :   } else {
     764             :     emit_rex(dst, size);
     765             :     emit(0xC1);
     766             :     emit_modrm(subcode, dst);
     767      660118 :     emit(shift_amount.value_);
     768             :   }
     769      819352 : }
     770             : 
     771             : 
     772          96 : void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
     773             :                       int size) {
     774             :   EnsureSpace ensure_space(this);
     775             :   DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
     776             :                             : is_uint5(shift_amount.value_));
     777          48 :   if (shift_amount.value_ == 1) {
     778             :     emit_rex(dst, size);
     779             :     emit(0xD1);
     780          24 :     emit_operand(subcode, dst);
     781             :   } else {
     782             :     emit_rex(dst, size);
     783             :     emit(0xC1);
     784          24 :     emit_operand(subcode, dst);
     785          24 :     emit(shift_amount.value_);
     786             :   }
     787          48 : }
     788             : 
     789             : 
     790       11476 : void Assembler::shift(Register dst, int subcode, int size) {
     791             :   EnsureSpace ensure_space(this);
     792             :   emit_rex(dst, size);
     793             :   emit(0xD3);
     794             :   emit_modrm(subcode, dst);
     795       11477 : }
     796             : 
     797             : 
     798          96 : void Assembler::shift(Operand dst, int subcode, int size) {
     799             :   EnsureSpace ensure_space(this);
     800             :   emit_rex(dst, size);
     801             :   emit(0xD3);
     802          48 :   emit_operand(subcode, dst);
     803          48 : }
     804             : 
     805             : 
     806           0 : void Assembler::bt(const Operand& dst, Register src) {
     807             :   EnsureSpace ensure_space(this);
     808             :   emit_rex_64(src, dst);
     809             :   emit(0x0F);
     810             :   emit(0xA3);
     811             :   emit_operand(src, dst);
     812           0 : }
     813             : 
     814             : 
     815          36 : void Assembler::bts(const Operand& dst, Register src) {
     816             :   EnsureSpace ensure_space(this);
     817             :   emit_rex_64(src, dst);
     818             :   emit(0x0F);
     819             :   emit(0xAB);
     820             :   emit_operand(src, dst);
     821          18 : }
     822             : 
     823             : 
     824           8 : void Assembler::bsrl(Register dst, Register src) {
     825             :   EnsureSpace ensure_space(this);
     826             :   emit_optional_rex_32(dst, src);
     827             :   emit(0x0F);
     828             :   emit(0xBD);
     829             :   emit_modrm(dst, src);
     830           8 : }
     831             : 
     832             : 
     833          12 : void Assembler::bsrl(Register dst, const Operand& src) {
     834             :   EnsureSpace ensure_space(this);
     835             :   emit_optional_rex_32(dst, src);
     836             :   emit(0x0F);
     837             :   emit(0xBD);
     838             :   emit_operand(dst, src);
     839           6 : }
     840             : 
     841             : 
     842           0 : void Assembler::bsrq(Register dst, Register src) {
     843             :   EnsureSpace ensure_space(this);
     844             :   emit_rex_64(dst, src);
     845             :   emit(0x0F);
     846             :   emit(0xBD);
     847             :   emit_modrm(dst, src);
     848           0 : }
     849             : 
     850             : 
     851           0 : void Assembler::bsrq(Register dst, const Operand& src) {
     852             :   EnsureSpace ensure_space(this);
     853             :   emit_rex_64(dst, src);
     854             :   emit(0x0F);
     855             :   emit(0xBD);
     856             :   emit_operand(dst, src);
     857           0 : }
     858             : 
     859             : 
     860           0 : void Assembler::bsfl(Register dst, Register src) {
     861             :   EnsureSpace ensure_space(this);
     862             :   emit_optional_rex_32(dst, src);
     863             :   emit(0x0F);
     864             :   emit(0xBC);
     865             :   emit_modrm(dst, src);
     866           0 : }
     867             : 
     868             : 
     869           0 : void Assembler::bsfl(Register dst, const Operand& src) {
     870             :   EnsureSpace ensure_space(this);
     871             :   emit_optional_rex_32(dst, src);
     872             :   emit(0x0F);
     873             :   emit(0xBC);
     874             :   emit_operand(dst, src);
     875           0 : }
     876             : 
     877             : 
     878           0 : void Assembler::bsfq(Register dst, Register src) {
     879             :   EnsureSpace ensure_space(this);
     880             :   emit_rex_64(dst, src);
     881             :   emit(0x0F);
     882             :   emit(0xBC);
     883             :   emit_modrm(dst, src);
     884           0 : }
     885             : 
     886             : 
     887           0 : void Assembler::bsfq(Register dst, const Operand& src) {
     888             :   EnsureSpace ensure_space(this);
     889             :   emit_rex_64(dst, src);
     890             :   emit(0x0F);
     891             :   emit(0xBC);
     892             :   emit_operand(dst, src);
     893           0 : }
     894             : 
     895           6 : void Assembler::pshufw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
     896             :   EnsureSpace ensure_space(this);
     897             :   emit_optional_rex_32(dst, src);
     898             :   emit(0x0F);
     899             :   emit(0x70);
     900          12 :   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
     901             :   emit(shuffle);
     902           6 : }
     903             : 
     904           0 : void Assembler::pshufw(XMMRegister dst, const Operand& src, uint8_t shuffle) {
     905             :   EnsureSpace ensure_space(this);
     906             :   emit_optional_rex_32(dst, src);
     907             :   emit(0x0F);
     908             :   emit(0x70);
     909           0 :   emit_operand(dst.code(), src);
     910             :   emit(shuffle);
     911           0 : }
     912             : 
     913     1727302 : void Assembler::call(Label* L) {
     914             :   EnsureSpace ensure_space(this);
     915             :   // 1110 1000 #32-bit disp.
     916             :   emit(0xE8);
     917      863651 :   if (L->is_bound()) {
     918      863657 :     int offset = L->pos() - pc_offset() - sizeof(int32_t);
     919             :     DCHECK_LE(offset, 0);
     920             :     emitl(offset);
     921      863645 :   } else if (L->is_linked()) {
     922      676549 :     emitl(L->pos());
     923      676549 :     L->link_to(pc_offset() - sizeof(int32_t));
     924             :   } else {
     925             :     DCHECK(L->is_unused());
     926             :     int32_t current = pc_offset();
     927      187096 :     emitl(current);
     928             :     L->link_to(current);
     929             :   }
     930      863651 : }
     931             : 
     932             : 
     933     3087699 : void Assembler::call(Address entry, RelocInfo::Mode rmode) {
     934             :   DCHECK(RelocInfo::IsRuntimeEntry(rmode));
     935             :   EnsureSpace ensure_space(this);
     936             :   // 1110 1000 #32-bit disp.
     937             :   emit(0xE8);
     938             :   emit_runtime_entry(entry, rmode);
     939     3087704 : }
     940             : 
     941       45552 : void Assembler::call(CodeStub* stub) {
     942             :   EnsureSpace ensure_space(this);
     943             :   // 1110 1000 #32-bit disp.
     944             :   emit(0xE8);
     945       45552 :   RequestHeapObject(HeapObjectRequest(stub));
     946       45563 :   emit_code_target(Handle<Code>(), RelocInfo::CODE_TARGET);
     947       45562 : }
     948             : 
     949     5024636 : void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
     950             :   EnsureSpace ensure_space(this);
     951             :   // 1110 1000 #32-bit disp.
     952             :   emit(0xE8);
     953     5024636 :   emit_code_target(target, rmode);
     954     5024733 : }
     955             : 
     956             : 
     957      628325 : void Assembler::call(Register adr) {
     958             :   EnsureSpace ensure_space(this);
     959             :   // Opcode: FF /2 r64.
     960             :   emit_optional_rex_32(adr);
     961             :   emit(0xFF);
     962             :   emit_modrm(0x2, adr);
     963      628325 : }
     964             : 
     965             : 
     966           0 : void Assembler::call(const Operand& op) {
     967             :   EnsureSpace ensure_space(this);
     968             :   // Opcode: FF /2 m64.
     969             :   emit_optional_rex_32(op);
     970             :   emit(0xFF);
     971           0 :   emit_operand(0x2, op);
     972           0 : }
     973             : 
     974             : 
     975             : // Calls directly to the given address using a relative offset.
     976             : // Should only ever be used in Code objects for calls within the
     977             : // same Code object. Should not be used when generating new code (use labels),
     978             : // but only when patching existing code.
     979           0 : void Assembler::call(Address target) {
     980             :   EnsureSpace ensure_space(this);
     981             :   // 1110 1000 #32-bit disp.
     982             :   emit(0xE8);
     983           0 :   Address source = pc_ + 4;
     984           0 :   intptr_t displacement = target - source;
     985             :   DCHECK(is_int32(displacement));
     986           0 :   emitl(static_cast<int32_t>(displacement));
     987           0 : }
     988             : 
     989             : 
     990           0 : void Assembler::clc() {
     991             :   EnsureSpace ensure_space(this);
     992             :   emit(0xF8);
     993           0 : }
     994             : 
     995             : 
     996           6 : void Assembler::cld() {
     997             :   EnsureSpace ensure_space(this);
     998             :   emit(0xFC);
     999           6 : }
    1000             : 
    1001        5492 : void Assembler::cdq() {
    1002             :   EnsureSpace ensure_space(this);
    1003             :   emit(0x99);
    1004        5492 : }
    1005             : 
    1006             : 
    1007           0 : void Assembler::cmovq(Condition cc, Register dst, Register src) {
    1008           0 :   if (cc == always) {
    1009             :     movq(dst, src);
    1010           0 :   } else if (cc == never) {
    1011           0 :     return;
    1012             :   }
    1013             :   // No need to check CpuInfo for CMOV support, it's a required part of the
    1014             :   // 64-bit architecture.
    1015             :   DCHECK_GE(cc, 0);  // Use mov for unconditional moves.
    1016             :   EnsureSpace ensure_space(this);
    1017             :   // Opcode: REX.W 0f 40 + cc /r.
    1018             :   emit_rex_64(dst, src);
    1019             :   emit(0x0f);
    1020           0 :   emit(0x40 + cc);
    1021             :   emit_modrm(dst, src);
    1022             : }
    1023             : 
    1024             : 
    1025         192 : void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
    1026          96 :   if (cc == always) {
    1027             :     movq(dst, src);
    1028          96 :   } else if (cc == never) {
    1029          96 :     return;
    1030             :   }
    1031             :   DCHECK_GE(cc, 0);
    1032             :   EnsureSpace ensure_space(this);
    1033             :   // Opcode: REX.W 0f 40 + cc /r.
    1034             :   emit_rex_64(dst, src);
    1035             :   emit(0x0f);
    1036          96 :   emit(0x40 + cc);
    1037             :   emit_operand(dst, src);
    1038             : }
    1039             : 
    1040             : 
    1041        2582 : void Assembler::cmovl(Condition cc, Register dst, Register src) {
    1042        2582 :   if (cc == always) {
    1043             :     movl(dst, src);
    1044        2582 :   } else if (cc == never) {
    1045        2582 :     return;
    1046             :   }
    1047             :   DCHECK_GE(cc, 0);
    1048             :   EnsureSpace ensure_space(this);
    1049             :   // Opcode: 0f 40 + cc /r.
    1050             :   emit_optional_rex_32(dst, src);
    1051             :   emit(0x0f);
    1052        2582 :   emit(0x40 + cc);
    1053             :   emit_modrm(dst, src);
    1054             : }
    1055             : 
    1056             : 
    1057           0 : void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
    1058           0 :   if (cc == always) {
    1059             :     movl(dst, src);
    1060           0 :   } else if (cc == never) {
    1061           0 :     return;
    1062             :   }
    1063             :   DCHECK_GE(cc, 0);
    1064             :   EnsureSpace ensure_space(this);
    1065             :   // Opcode: 0f 40 + cc /r.
    1066             :   emit_optional_rex_32(dst, src);
    1067             :   emit(0x0f);
    1068           0 :   emit(0x40 + cc);
    1069             :   emit_operand(dst, src);
    1070             : }
    1071             : 
    1072             : 
    1073           0 : void Assembler::cmpb_al(Immediate imm8) {
    1074             :   DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
    1075             :   EnsureSpace ensure_space(this);
    1076             :   emit(0x3c);
    1077           0 :   emit(imm8.value_);
    1078           0 : }
    1079             : 
    1080        2532 : void Assembler::lock() {
    1081             :   EnsureSpace ensure_space(this);
    1082             :   emit(0xf0);
    1083        2532 : }
    1084             : 
    1085        1692 : void Assembler::cmpxchgb(const Operand& dst, Register src) {
    1086             :   EnsureSpace ensure_space(this);
    1087         846 :   if (!src.is_byte_register()) {
    1088             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1089             :     emit_rex_32(src, dst);
    1090             :   } else {
    1091             :     emit_optional_rex_32(src, dst);
    1092             :   }
    1093             :   emit(0x0f);
    1094             :   emit(0xb0);
    1095             :   emit_operand(src, dst);
    1096         846 : }
    1097             : 
    1098        1692 : void Assembler::cmpxchgw(const Operand& dst, Register src) {
    1099             :   EnsureSpace ensure_space(this);
    1100             :   emit(0x66);
    1101             :   emit_optional_rex_32(src, dst);
    1102             :   emit(0x0f);
    1103             :   emit(0xb1);
    1104             :   emit_operand(src, dst);
    1105         846 : }
    1106             : 
    1107         858 : void Assembler::emit_cmpxchg(const Operand& dst, Register src, int size) {
    1108             :   EnsureSpace ensure_space(this);
    1109         858 :   emit_rex(src, dst, size);
    1110             :   emit(0x0f);
    1111             :   emit(0xb1);
    1112             :   emit_operand(src, dst);
    1113         858 : }
    1114             : 
    1115           6 : void Assembler::cpuid() {
    1116             :   EnsureSpace ensure_space(this);
    1117             :   emit(0x0F);
    1118             :   emit(0xA2);
    1119           6 : }
    1120             : 
    1121             : 
    1122        1028 : void Assembler::cqo() {
    1123             :   EnsureSpace ensure_space(this);
    1124             :   emit_rex_64();
    1125             :   emit(0x99);
    1126        1028 : }
    1127             : 
    1128             : 
    1129        4989 : void Assembler::emit_dec(Register dst, int size) {
    1130             :   EnsureSpace ensure_space(this);
    1131             :   emit_rex(dst, size);
    1132             :   emit(0xFF);
    1133             :   emit_modrm(0x1, dst);
    1134        4989 : }
    1135             : 
    1136             : 
    1137           0 : void Assembler::emit_dec(const Operand& dst, int size) {
    1138             :   EnsureSpace ensure_space(this);
    1139           0 :   emit_rex(dst, size);
    1140             :   emit(0xFF);
    1141           0 :   emit_operand(1, dst);
    1142           0 : }
    1143             : 
    1144             : 
    1145           6 : void Assembler::decb(Register dst) {
    1146             :   EnsureSpace ensure_space(this);
    1147           6 :   if (!dst.is_byte_register()) {
    1148             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1149             :     emit_rex_32(dst);
    1150             :   }
    1151             :   emit(0xFE);
    1152             :   emit_modrm(0x1, dst);
    1153           6 : }
    1154             : 
    1155             : 
    1156          24 : void Assembler::decb(const Operand& dst) {
    1157             :   EnsureSpace ensure_space(this);
    1158             :   emit_optional_rex_32(dst);
    1159             :   emit(0xFE);
    1160          12 :   emit_operand(1, dst);
    1161          12 : }
    1162             : 
    1163             : 
    1164           0 : void Assembler::enter(Immediate size) {
    1165             :   EnsureSpace ensure_space(this);
    1166             :   emit(0xC8);
    1167           0 :   emitw(size.value_);  // 16 bit operand, always.
    1168             :   emit(0);
    1169           0 : }
    1170             : 
    1171             : 
    1172           6 : void Assembler::hlt() {
    1173             :   EnsureSpace ensure_space(this);
    1174             :   emit(0xF4);
    1175           6 : }
    1176             : 
    1177             : 
    1178        6519 : void Assembler::emit_idiv(Register src, int size) {
    1179             :   EnsureSpace ensure_space(this);
    1180             :   emit_rex(src, size);
    1181             :   emit(0xF7);
    1182             :   emit_modrm(0x7, src);
    1183        6520 : }
    1184             : 
    1185             : 
    1186        2029 : void Assembler::emit_div(Register src, int size) {
    1187             :   EnsureSpace ensure_space(this);
    1188             :   emit_rex(src, size);
    1189             :   emit(0xF7);
    1190             :   emit_modrm(0x6, src);
    1191        2030 : }
    1192             : 
    1193             : 
    1194        4855 : void Assembler::emit_imul(Register src, int size) {
    1195             :   EnsureSpace ensure_space(this);
    1196             :   emit_rex(src, size);
    1197             :   emit(0xF7);
    1198             :   emit_modrm(0x5, src);
    1199        4855 : }
    1200             : 
    1201             : 
    1202           0 : void Assembler::emit_imul(const Operand& src, int size) {
    1203             :   EnsureSpace ensure_space(this);
    1204           0 :   emit_rex(src, size);
    1205             :   emit(0xF7);
    1206           0 :   emit_operand(0x5, src);
    1207           0 : }
    1208             : 
    1209             : 
    1210        4134 : void Assembler::emit_imul(Register dst, Register src, int size) {
    1211             :   EnsureSpace ensure_space(this);
    1212        4134 :   emit_rex(dst, src, size);
    1213             :   emit(0x0F);
    1214             :   emit(0xAF);
    1215             :   emit_modrm(dst, src);
    1216        4135 : }
    1217             : 
    1218             : 
    1219         147 : void Assembler::emit_imul(Register dst, const Operand& src, int size) {
    1220             :   EnsureSpace ensure_space(this);
    1221         147 :   emit_rex(dst, src, size);
    1222             :   emit(0x0F);
    1223             :   emit(0xAF);
    1224             :   emit_operand(dst, src);
    1225         147 : }
    1226             : 
    1227             : 
    1228       44550 : void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
    1229             :   EnsureSpace ensure_space(this);
    1230       44550 :   emit_rex(dst, src, size);
    1231       89100 :   if (is_int8(imm.value_)) {
    1232             :     emit(0x6B);
    1233             :     emit_modrm(dst, src);
    1234       13268 :     emit(imm.value_);
    1235             :   } else {
    1236             :     emit(0x69);
    1237             :     emit_modrm(dst, src);
    1238       31282 :     emitl(imm.value_);
    1239             :   }
    1240       44550 : }
    1241             : 
    1242             : 
    1243         168 : void Assembler::emit_imul(Register dst, const Operand& src, Immediate imm,
    1244             :                           int size) {
    1245             :   EnsureSpace ensure_space(this);
    1246         168 :   emit_rex(dst, src, size);
    1247         336 :   if (is_int8(imm.value_)) {
    1248             :     emit(0x6B);
    1249             :     emit_operand(dst, src);
    1250         147 :     emit(imm.value_);
    1251             :   } else {
    1252             :     emit(0x69);
    1253             :     emit_operand(dst, src);
    1254          21 :     emitl(imm.value_);
    1255             :   }
    1256         168 : }
    1257             : 
    1258             : 
    1259        2282 : void Assembler::emit_inc(Register dst, int size) {
    1260             :   EnsureSpace ensure_space(this);
    1261             :   emit_rex(dst, size);
    1262             :   emit(0xFF);
    1263             :   emit_modrm(0x0, dst);
    1264        2282 : }
    1265             : 
    1266             : 
    1267        7186 : void Assembler::emit_inc(const Operand& dst, int size) {
    1268             :   EnsureSpace ensure_space(this);
    1269        7186 :   emit_rex(dst, size);
    1270             :   emit(0xFF);
    1271        7186 :   emit_operand(0, dst);
    1272        7186 : }
    1273             : 
    1274             : 
    1275       28687 : void Assembler::int3() {
    1276             :   EnsureSpace ensure_space(this);
    1277             :   emit(0xCC);
    1278       28687 : }
    1279             : 
    1280             : 
    1281    27635238 : void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
    1282     9074400 :   if (cc == always) {
    1283         279 :     jmp(L);
    1284         279 :     return;
    1285     9074121 :   } else if (cc == never) {
    1286             :     return;
    1287             :   }
    1288             :   EnsureSpace ensure_space(this);
    1289             :   DCHECK(is_uint4(cc));
    1290     9074153 :   if (L->is_bound()) {
    1291             :     const int short_size = 2;
    1292             :     const int long_size  = 6;
    1293    18821401 :     int offs = L->pos() - pc_offset();
    1294             :     DCHECK_LE(offs, 0);
    1295             :     // Determine whether we can use 1-byte offsets for backwards branches,
    1296             :     // which have a max range of 128 bytes.
    1297             : 
    1298             :     // We also need to check predictable_code_size() flag here, because on x64,
    1299             :     // when the full code generator recompiles code for debugging, some places
    1300             :     // need to be padded out to a certain size. The debugger is keeping track of
    1301             :     // how often it did this so that it can adjust return addresses on the
    1302             :     // stack, but if the size of jump instructions can also change, that's not
    1303             :     // enough and the calculated offsets would be incorrect.
    1304     2508510 :     if (is_int8(offs - short_size) && !predictable_code_size()) {
    1305             :       // 0111 tttn #8-bit disp.
    1306      353404 :       emit(0x70 | cc);
    1307      353404 :       emit((offs - short_size) & 0xFF);
    1308             :     } else {
    1309             :       // 0000 1111 1000 tttn #32-bit disp.
    1310             :       emit(0x0F);
    1311      724162 :       emit(0x80 | cc);
    1312      724162 :       emitl(offs - long_size);
    1313             :     }
    1314     7996613 :   } else if (distance == Label::kNear) {
    1315             :     // 0111 tttn #8-bit disp
    1316      213891 :     emit(0x70 | cc);
    1317             :     byte disp = 0x00;
    1318      213891 :     if (L->is_near_linked()) {
    1319        3821 :       int offset = L->near_link_pos() - pc_offset();
    1320             :       DCHECK(is_int8(offset));
    1321        3821 :       disp = static_cast<byte>(offset & 0xFF);
    1322             :     }
    1323             :     L->link_to(pc_offset(), Label::kNear);
    1324             :     emit(disp);
    1325             :   } else {
    1326     1862496 :     auto jump_opt = jump_optimization_info();
    1327     7782722 :     if (V8_UNLIKELY(jump_opt)) {
    1328     1059398 :       if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
    1329             :         // 0111 tttn #8-bit disp
    1330      256300 :         emit(0x70 | cc);
    1331             :         record_farjmp_position(L, pc_offset());
    1332             :         emit(0);
    1333             :         return;
    1334             :       }
    1335      803098 :       if (jump_opt->is_collecting()) {
    1336     1059522 :         farjmp_positions_.push_back(pc_offset() + 2);
    1337             :       }
    1338             :     }
    1339     7526422 :     if (L->is_linked()) {
    1340             :       // 0000 1111 1000 tttn #32-bit disp.
    1341             :       emit(0x0F);
    1342     1746372 :       emit(0x80 | cc);
    1343     1746372 :       emitl(L->pos());
    1344     1746372 :       L->link_to(pc_offset() - sizeof(int32_t));
    1345             :     } else {
    1346             :       DCHECK(L->is_unused());
    1347             :       emit(0x0F);
    1348     5780050 :       emit(0x80 | cc);
    1349             :       int32_t current = pc_offset();
    1350     5780050 :       emitl(current);
    1351             :       L->link_to(current);
    1352             :     }
    1353             :   }
    1354             : }
    1355             : 
    1356             : 
    1357           0 : void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
    1358             :   DCHECK(RelocInfo::IsRuntimeEntry(rmode));
    1359             :   EnsureSpace ensure_space(this);
    1360             :   DCHECK(is_uint4(cc));
    1361             :   emit(0x0F);
    1362           0 :   emit(0x80 | cc);
    1363             :   emit_runtime_entry(entry, rmode);
    1364           0 : }
    1365             : 
    1366             : 
    1367      443618 : void Assembler::j(Condition cc,
    1368             :                   Handle<Code> target,
    1369             :                   RelocInfo::Mode rmode) {
    1370             :   EnsureSpace ensure_space(this);
    1371             :   DCHECK(is_uint4(cc));
    1372             :   // 0000 1111 1000 tttn #32-bit disp.
    1373             :   emit(0x0F);
    1374      443618 :   emit(0x80 | cc);
    1375      443618 :   emit_code_target(target, rmode);
    1376      443628 : }
    1377             : 
    1378             : 
    1379  2412399786 : void Assembler::jmp(Label* L, Label::Distance distance) {
    1380             :   EnsureSpace ensure_space(this);
    1381             :   const int short_size = sizeof(int8_t);
    1382             :   const int long_size = sizeof(int32_t);
    1383   604998482 :   if (L->is_bound()) {
    1384  1211034695 :     int offs = L->pos() - pc_offset() - 1;
    1385             :     DCHECK_LE(offs, 0);
    1386     6683082 :     if (is_int8(offs - short_size) && !predictable_code_size()) {
    1387             :       // 1110 1011 #8-bit disp.
    1388             :       emit(0xEB);
    1389      970520 :       emit((offs - short_size) & 0xFF);
    1390             :     } else {
    1391             :       // 1110 1001 #32-bit disp.
    1392             :       emit(0xE9);
    1393     1885923 :       emitl(offs - long_size);
    1394             :     }
    1395   602142368 :   } else if (distance == Label::kNear) {
    1396             :     emit(0xEB);
    1397             :     byte disp = 0x00;
    1398      103417 :     if (L->is_near_linked()) {
    1399         217 :       int offset = L->near_link_pos() - pc_offset();
    1400             :       DCHECK(is_int8(offset));
    1401         217 :       disp = static_cast<byte>(offset & 0xFF);
    1402             :     }
    1403             :     L->link_to(pc_offset(), Label::kNear);
    1404             :     emit(disp);
    1405             :   } else {
    1406      590416 :     auto jump_opt = jump_optimization_info();
    1407   602038951 :     if (V8_UNLIKELY(jump_opt)) {
    1408      342830 :       if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
    1409             :         emit(0xEB);
    1410             :         record_farjmp_position(L, pc_offset());
    1411             :         emit(0);
    1412   604997802 :         return;
    1413             :       }
    1414      247586 :       if (jump_opt->is_collecting()) {
    1415      342830 :         farjmp_positions_.push_back(pc_offset() + 1);
    1416             :       }
    1417             :     }
    1418   601943707 :     if (L->is_linked()) {
    1419             :       // 1110 1001 #32-bit disp.
    1420             :       emit(0xE9);
    1421   600357516 :       emitl(L->pos());
    1422             :       L->link_to(pc_offset() - long_size);
    1423             :     } else {
    1424             :       // 1110 1001 #32-bit disp.
    1425             :       DCHECK(L->is_unused());
    1426             :       emit(0xE9);
    1427             :       int32_t current = pc_offset();
    1428     1586191 :       emitl(current);
    1429             :       L->link_to(current);
    1430             :     }
    1431             :   }
    1432             : }
    1433             : 
    1434             : 
    1435      518528 : void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
    1436             :   EnsureSpace ensure_space(this);
    1437             :   // 1110 1001 #32-bit disp.
    1438             :   emit(0xE9);
    1439      518528 :   emit_code_target(target, rmode);
    1440      518528 : }
    1441             : 
    1442             : 
    1443      291191 : void Assembler::jmp(Register target) {
    1444             :   EnsureSpace ensure_space(this);
    1445             :   // Opcode FF/4 r64.
    1446             :   emit_optional_rex_32(target);
    1447             :   emit(0xFF);
    1448             :   emit_modrm(0x4, target);
    1449      291191 : }
    1450             : 
    1451             : 
    1452       15638 : void Assembler::jmp(const Operand& src) {
    1453             :   EnsureSpace ensure_space(this);
    1454             :   // Opcode FF/4 m64.
    1455             :   emit_optional_rex_32(src);
    1456             :   emit(0xFF);
    1457        7819 :   emit_operand(0x4, src);
    1458        7819 : }
    1459             : 
    1460             : 
    1461     3095880 : void Assembler::emit_lea(Register dst, const Operand& src, int size) {
    1462             :   EnsureSpace ensure_space(this);
    1463     3095880 :   emit_rex(dst, src, size);
    1464             :   emit(0x8D);
    1465             :   emit_operand(dst, src);
    1466     3095894 : }
    1467             : 
    1468             : 
    1469      863969 : void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
    1470             :   EnsureSpace ensure_space(this);
    1471             :   if (kPointerSize == kInt64Size) {
    1472             :     emit(0x48);  // REX.W
    1473             :     emit(0xA1);
    1474      863969 :     emitp(value, mode);
    1475             :   } else {
    1476             :     DCHECK_EQ(kPointerSize, kInt32Size);
    1477             :     emit(0xA1);
    1478             :     emitp(value, mode);
    1479             :     // In 64-bit mode, need to zero extend the operand to 8 bytes.
    1480             :     // See 2.2.1.4 in Intel64 and IA32 Architectures Software
    1481             :     // Developer's Manual Volume 2.
    1482             :     emitl(0);
    1483             :   }
    1484      863969 : }
    1485             : 
    1486             : 
    1487      863969 : void Assembler::load_rax(ExternalReference ref) {
    1488      863969 :   load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
    1489      863969 : }
    1490             : 
    1491             : 
    1492         155 : void Assembler::leave() {
    1493             :   EnsureSpace ensure_space(this);
    1494             :   emit(0xC9);
    1495         155 : }
    1496             : 
    1497             : 
    1498        1412 : void Assembler::movb(Register dst, const Operand& src) {
    1499             :   EnsureSpace ensure_space(this);
    1500         706 :   if (!dst.is_byte_register()) {
    1501             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1502             :     emit_rex_32(dst, src);
    1503             :   } else {
    1504             :     emit_optional_rex_32(dst, src);
    1505             :   }
    1506             :   emit(0x8A);
    1507             :   emit_operand(dst, src);
    1508         706 : }
    1509             : 
    1510             : 
    1511           6 : void Assembler::movb(Register dst, Immediate imm) {
    1512             :   EnsureSpace ensure_space(this);
    1513           6 :   if (!dst.is_byte_register()) {
    1514             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1515             :     emit_rex_32(dst);
    1516             :   }
    1517           6 :   emit(0xB0 + dst.low_bits());
    1518           6 :   emit(imm.value_);
    1519           6 : }
    1520             : 
    1521             : 
    1522       24703 : void Assembler::movb(const Operand& dst, Register src) {
    1523             :   EnsureSpace ensure_space(this);
    1524       12352 :   if (!src.is_byte_register()) {
    1525             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1526             :     emit_rex_32(src, dst);
    1527             :   } else {
    1528             :     emit_optional_rex_32(src, dst);
    1529             :   }
    1530             :   emit(0x88);
    1531             :   emit_operand(src, dst);
    1532       12352 : }
    1533             : 
    1534             : 
    1535      207094 : void Assembler::movb(const Operand& dst, Immediate imm) {
    1536             :   EnsureSpace ensure_space(this);
    1537             :   emit_optional_rex_32(dst);
    1538             :   emit(0xC6);
    1539      103547 :   emit_operand(0x0, dst);
    1540      103547 :   emit(static_cast<byte>(imm.value_));
    1541      103547 : }
    1542             : 
    1543             : 
    1544        1400 : void Assembler::movw(Register dst, const Operand& src) {
    1545             :   EnsureSpace ensure_space(this);
    1546             :   emit(0x66);
    1547             :   emit_optional_rex_32(dst, src);
    1548             :   emit(0x8B);
    1549             :   emit_operand(dst, src);
    1550         700 : }
    1551             : 
    1552             : 
    1553       17922 : void Assembler::movw(const Operand& dst, Register src) {
    1554             :   EnsureSpace ensure_space(this);
    1555             :   emit(0x66);
    1556             :   emit_optional_rex_32(src, dst);
    1557             :   emit(0x89);
    1558             :   emit_operand(src, dst);
    1559        8961 : }
    1560             : 
    1561             : 
    1562        1986 : void Assembler::movw(const Operand& dst, Immediate imm) {
    1563             :   EnsureSpace ensure_space(this);
    1564             :   emit(0x66);
    1565             :   emit_optional_rex_32(dst);
    1566             :   emit(0xC7);
    1567         993 :   emit_operand(0x0, dst);
    1568         993 :   emit(static_cast<byte>(imm.value_ & 0xff));
    1569         993 :   emit(static_cast<byte>(imm.value_ >> 8));
    1570         993 : }
    1571             : 
    1572             : 
    1573    15692853 : void Assembler::emit_mov(Register dst, const Operand& src, int size) {
    1574             :   EnsureSpace ensure_space(this);
    1575    15692853 :   emit_rex(dst, src, size);
    1576             :   emit(0x8B);
    1577             :   emit_operand(dst, src);
    1578    15692931 : }
    1579             : 
    1580             : 
    1581     7656885 : void Assembler::emit_mov(Register dst, Register src, int size) {
    1582             :   EnsureSpace ensure_space(this);
    1583     7656916 :   if (src.low_bits() == 4) {
    1584     1926653 :     emit_rex(src, dst, size);
    1585             :     emit(0x89);
    1586             :     emit_modrm(src, dst);
    1587             :   } else {
    1588     5730263 :     emit_rex(dst, src, size);
    1589             :     emit(0x8B);
    1590             :     emit_modrm(dst, src);
    1591             :   }
    1592     7656882 : }
    1593             : 
    1594             : 
    1595     7521470 : void Assembler::emit_mov(const Operand& dst, Register src, int size) {
    1596             :   EnsureSpace ensure_space(this);
    1597     7521470 :   emit_rex(src, dst, size);
    1598             :   emit(0x89);
    1599             :   emit_operand(src, dst);
    1600     7521480 : }
    1601             : 
    1602             : 
    1603     3282615 : void Assembler::emit_mov(Register dst, Immediate value, int size) {
    1604             :   EnsureSpace ensure_space(this);
    1605             :   emit_rex(dst, size);
    1606     3282610 :   if (size == kInt64Size) {
    1607             :     emit(0xC7);
    1608             :     emit_modrm(0x0, dst);
    1609             :   } else {
    1610             :     DCHECK_EQ(size, kInt32Size);
    1611     2286817 :     emit(0xB8 + dst.low_bits());
    1612             :   }
    1613     3282610 :   emit(value);
    1614     3282630 : }
    1615             : 
    1616             : 
    1617      159450 : void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
    1618             :   EnsureSpace ensure_space(this);
    1619      159454 :   emit_rex(dst, size);
    1620             :   emit(0xC7);
    1621      159454 :   emit_operand(0x0, dst);
    1622      159453 :   emit(value);
    1623      159454 : }
    1624             : 
    1625             : 
    1626    10316102 : void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
    1627             :   EnsureSpace ensure_space(this);
    1628             :   emit_rex(dst, kPointerSize);
    1629    10316102 :   emit(0xB8 | dst.low_bits());
    1630    10316102 :   emitp(value, rmode);
    1631    10316115 : }
    1632             : 
    1633       43091 : void Assembler::movp_heap_number(Register dst, double value) {
    1634             :   EnsureSpace ensure_space(this);
    1635             :   emit_rex(dst, kPointerSize);
    1636       43091 :   emit(0xB8 | dst.low_bits());
    1637       43091 :   RequestHeapObject(HeapObjectRequest(value));
    1638       43091 :   emitp(nullptr, RelocInfo::EMBEDDED_OBJECT);
    1639       43091 : }
    1640             : 
    1641     1104727 : void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
    1642             :   EnsureSpace ensure_space(this);
    1643             :   emit_rex_64(dst);
    1644     1104731 :   emit(0xB8 | dst.low_bits());
    1645     1104731 :   if (!RelocInfo::IsNone(rmode)) {
    1646      183975 :     RecordRelocInfo(rmode, value);
    1647             :   }
    1648     1104730 :   emitq(value);
    1649     1104730 : }
    1650             : 
    1651      300600 : void Assembler::movq(Register dst, uint64_t value, RelocInfo::Mode rmode) {
    1652      300600 :   movq(dst, static_cast<int64_t>(value), rmode);
    1653      300602 : }
    1654             : 
    1655             : // Loads the ip-relative location of the src label into the target location
    1656             : // (as a 32-bit offset sign extended to 64-bit).
    1657     1886295 : void Assembler::movl(const Operand& dst, Label* src) {
    1658             :   EnsureSpace ensure_space(this);
    1659             :   emit_optional_rex_32(dst);
    1660             :   emit(0xC7);
    1661      628765 :   emit_operand(0, dst);
    1662      628765 :   if (src->is_bound()) {
    1663      628771 :     int offset = src->pos() - pc_offset() - sizeof(int32_t);
    1664             :     DCHECK_LE(offset, 0);
    1665             :     emitl(offset);
    1666      628759 :   } else if (src->is_linked()) {
    1667           0 :     emitl(src->pos());
    1668           0 :     src->link_to(pc_offset() - sizeof(int32_t));
    1669             :   } else {
    1670             :     DCHECK(src->is_unused());
    1671             :     int32_t current = pc_offset();
    1672      628759 :     emitl(current);
    1673             :     src->link_to(current);
    1674             :   }
    1675      628765 : }
    1676             : 
    1677             : 
    1678        5098 : void Assembler::movsxbl(Register dst, Register src) {
    1679             :   EnsureSpace ensure_space(this);
    1680        5098 :   if (!src.is_byte_register()) {
    1681             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1682             :     emit_rex_32(dst, src);
    1683             :   } else {
    1684             :     emit_optional_rex_32(dst, src);
    1685             :   }
    1686             :   emit(0x0F);
    1687             :   emit(0xBE);
    1688             :   emit_modrm(dst, src);
    1689        5098 : }
    1690             : 
    1691             : 
    1692       19520 : void Assembler::movsxbl(Register dst, const Operand& src) {
    1693             :   EnsureSpace ensure_space(this);
    1694             :   emit_optional_rex_32(dst, src);
    1695             :   emit(0x0F);
    1696             :   emit(0xBE);
    1697             :   emit_operand(dst, src);
    1698        9760 : }
    1699             : 
    1700             : 
    1701       12760 : void Assembler::movsxbq(Register dst, const Operand& src) {
    1702             :   EnsureSpace ensure_space(this);
    1703             :   emit_rex_64(dst, src);
    1704             :   emit(0x0F);
    1705             :   emit(0xBE);
    1706             :   emit_operand(dst, src);
    1707        6380 : }
    1708             : 
    1709           0 : void Assembler::movsxbq(Register dst, Register src) {
    1710             :   EnsureSpace ensure_space(this);
    1711             :   emit_rex_64(dst, src);
    1712             :   emit(0x0F);
    1713             :   emit(0xBE);
    1714             :   emit_modrm(dst, src);
    1715           0 : }
    1716             : 
    1717        2855 : void Assembler::movsxwl(Register dst, Register src) {
    1718             :   EnsureSpace ensure_space(this);
    1719             :   emit_optional_rex_32(dst, src);
    1720             :   emit(0x0F);
    1721             :   emit(0xBF);
    1722             :   emit_modrm(dst, src);
    1723        2855 : }
    1724             : 
    1725             : 
    1726        7406 : void Assembler::movsxwl(Register dst, const Operand& src) {
    1727             :   EnsureSpace ensure_space(this);
    1728             :   emit_optional_rex_32(dst, src);
    1729             :   emit(0x0F);
    1730             :   emit(0xBF);
    1731             :   emit_operand(dst, src);
    1732        3703 : }
    1733             : 
    1734             : 
    1735        9988 : void Assembler::movsxwq(Register dst, const Operand& src) {
    1736             :   EnsureSpace ensure_space(this);
    1737             :   emit_rex_64(dst, src);
    1738             :   emit(0x0F);
    1739             :   emit(0xBF);
    1740             :   emit_operand(dst, src);
    1741        4994 : }
    1742             : 
    1743           0 : void Assembler::movsxwq(Register dst, Register src) {
    1744             :   EnsureSpace ensure_space(this);
    1745             :   emit_rex_64(dst, src);
    1746             :   emit(0x0F);
    1747             :   emit(0xBF);
    1748             :   emit_modrm(dst, src);
    1749           0 : }
    1750             : 
    1751       27545 : void Assembler::movsxlq(Register dst, Register src) {
    1752             :   EnsureSpace ensure_space(this);
    1753             :   emit_rex_64(dst, src);
    1754             :   emit(0x63);
    1755             :   emit_modrm(dst, src);
    1756       27545 : }
    1757             : 
    1758             : 
    1759     1577468 : void Assembler::movsxlq(Register dst, const Operand& src) {
    1760             :   EnsureSpace ensure_space(this);
    1761             :   emit_rex_64(dst, src);
    1762             :   emit(0x63);
    1763             :   emit_operand(dst, src);
    1764      788734 : }
    1765             : 
    1766             : 
    1767     1675252 : void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
    1768             :   EnsureSpace ensure_space(this);
    1769             :   // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
    1770             :   // there is no need to make this a 64 bit operation.
    1771             :   emit_optional_rex_32(dst, src);
    1772             :   emit(0x0F);
    1773             :   emit(0xB6);
    1774             :   emit_operand(dst, src);
    1775      837626 : }
    1776             : 
    1777             : 
    1778      202450 : void Assembler::emit_movzxb(Register dst, Register src, int size) {
    1779             :   EnsureSpace ensure_space(this);
    1780             :   // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
    1781             :   // there is no need to make this a 64 bit operation.
    1782      202454 :   if (!src.is_byte_register()) {
    1783             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    1784             :     emit_rex_32(dst, src);
    1785             :   } else {
    1786             :     emit_optional_rex_32(dst, src);
    1787             :   }
    1788             :   emit(0x0F);
    1789             :   emit(0xB6);
    1790             :   emit_modrm(dst, src);
    1791      202454 : }
    1792             : 
    1793             : 
    1794      758468 : void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
    1795             :   EnsureSpace ensure_space(this);
    1796             :   // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
    1797             :   // there is no need to make this a 64 bit operation.
    1798             :   emit_optional_rex_32(dst, src);
    1799             :   emit(0x0F);
    1800             :   emit(0xB7);
    1801             :   emit_operand(dst, src);
    1802      379234 : }
    1803             : 
    1804             : 
    1805        5186 : void Assembler::emit_movzxw(Register dst, Register src, int size) {
    1806             :   EnsureSpace ensure_space(this);
    1807             :   // 32 bit operations zero the top 32 bits of 64 bit registers.  Therefore
    1808             :   // there is no need to make this a 64 bit operation.
    1809             :   emit_optional_rex_32(dst, src);
    1810             :   emit(0x0F);
    1811             :   emit(0xB7);
    1812             :   emit_modrm(dst, src);
    1813        5187 : }
    1814             : 
    1815             : 
    1816           0 : void Assembler::repmovsb() {
    1817             :   EnsureSpace ensure_space(this);
    1818             :   emit(0xF3);
    1819             :   emit(0xA4);
    1820           0 : }
    1821             : 
    1822             : 
    1823           0 : void Assembler::repmovsw() {
    1824             :   EnsureSpace ensure_space(this);
    1825             :   emit(0x66);  // Operand size override.
    1826             :   emit(0xF3);
    1827             :   emit(0xA4);
    1828           0 : }
    1829             : 
    1830             : 
    1831           0 : void Assembler::emit_repmovs(int size) {
    1832             :   EnsureSpace ensure_space(this);
    1833             :   emit(0xF3);
    1834             :   emit_rex(size);
    1835             :   emit(0xA5);
    1836           0 : }
    1837             : 
    1838             : 
    1839         635 : void Assembler::mull(Register src) {
    1840             :   EnsureSpace ensure_space(this);
    1841             :   emit_optional_rex_32(src);
    1842             :   emit(0xF7);
    1843             :   emit_modrm(0x4, src);
    1844         635 : }
    1845             : 
    1846             : 
    1847           0 : void Assembler::mull(const Operand& src) {
    1848             :   EnsureSpace ensure_space(this);
    1849             :   emit_optional_rex_32(src);
    1850             :   emit(0xF7);
    1851           0 :   emit_operand(0x4, src);
    1852           0 : }
    1853             : 
    1854             : 
    1855           6 : void Assembler::mulq(Register src) {
    1856             :   EnsureSpace ensure_space(this);
    1857             :   emit_rex_64(src);
    1858             :   emit(0xF7);
    1859             :   emit_modrm(0x4, src);
    1860           6 : }
    1861             : 
    1862             : 
    1863      144721 : void Assembler::emit_neg(Register dst, int size) {
    1864             :   EnsureSpace ensure_space(this);
    1865             :   emit_rex(dst, size);
    1866             :   emit(0xF7);
    1867             :   emit_modrm(0x3, dst);
    1868      144722 : }
    1869             : 
    1870             : 
    1871           0 : void Assembler::emit_neg(const Operand& dst, int size) {
    1872             :   EnsureSpace ensure_space(this);
    1873             :   emit_rex_64(dst);
    1874             :   emit(0xF7);
    1875           0 :   emit_operand(3, dst);
    1876           0 : }
    1877             : 
    1878             : 
    1879     1311735 : void Assembler::nop() {
    1880             :   EnsureSpace ensure_space(this);
    1881             :   emit(0x90);
    1882     1311735 : }
    1883             : 
    1884             : 
    1885        3530 : void Assembler::emit_not(Register dst, int size) {
    1886             :   EnsureSpace ensure_space(this);
    1887             :   emit_rex(dst, size);
    1888             :   emit(0xF7);
    1889             :   emit_modrm(0x2, dst);
    1890        3530 : }
    1891             : 
    1892             : 
    1893           0 : void Assembler::emit_not(const Operand& dst, int size) {
    1894             :   EnsureSpace ensure_space(this);
    1895           0 :   emit_rex(dst, size);
    1896             :   emit(0xF7);
    1897           0 :   emit_operand(2, dst);
    1898           0 : }
    1899             : 
    1900             : 
    1901     1356696 : void Assembler::Nop(int n) {
    1902             :   // The recommended muti-byte sequences of NOP instructions from the Intel 64
    1903             :   // and IA-32 Architectures Software Developer's Manual.
    1904             :   //
    1905             :   // Length   Assembly                                Byte Sequence
    1906             :   // 2 bytes  66 NOP                                  66 90H
    1907             :   // 3 bytes  NOP DWORD ptr [EAX]                     0F 1F 00H
    1908             :   // 4 bytes  NOP DWORD ptr [EAX + 00H]               0F 1F 40 00H
    1909             :   // 5 bytes  NOP DWORD ptr [EAX + EAX*1 + 00H]       0F 1F 44 00 00H
    1910             :   // 6 bytes  66 NOP DWORD ptr [EAX + EAX*1 + 00H]    66 0F 1F 44 00 00H
    1911             :   // 7 bytes  NOP DWORD ptr [EAX + 00000000H]         0F 1F 80 00 00 00 00H
    1912             :   // 8 bytes  NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
    1913             :   // 9 bytes  66 NOP DWORD ptr [EAX + EAX*1 +         66 0F 1F 84 00 00 00 00
    1914             :   //          00000000H]                              00H
    1915             : 
    1916             :   EnsureSpace ensure_space(this);
    1917     1384007 :   while (n > 0) {
    1918      995560 :     switch (n) {
    1919             :       case 2:
    1920             :         emit(0x66);
    1921             :       case 1:
    1922             :         emit(0x90);
    1923             :         return;
    1924             :       case 3:
    1925             :         emit(0x0f);
    1926             :         emit(0x1f);
    1927             :         emit(0x00);
    1928             :         return;
    1929             :       case 4:
    1930             :         emit(0x0f);
    1931             :         emit(0x1f);
    1932             :         emit(0x40);
    1933             :         emit(0x00);
    1934             :         return;
    1935             :       case 6:
    1936             :         emit(0x66);
    1937             :       case 5:
    1938             :         emit(0x0f);
    1939             :         emit(0x1f);
    1940             :         emit(0x44);
    1941             :         emit(0x00);
    1942             :         emit(0x00);
    1943             :         return;
    1944             :       case 7:
    1945             :         emit(0x0f);
    1946             :         emit(0x1f);
    1947             :         emit(0x80);
    1948             :         emit(0x00);
    1949             :         emit(0x00);
    1950             :         emit(0x00);
    1951             :         emit(0x00);
    1952             :         return;
    1953             :       default:
    1954             :       case 11:
    1955             :         emit(0x66);
    1956       18635 :         n--;
    1957             :       case 10:
    1958             :         emit(0x66);
    1959       21490 :         n--;
    1960             :       case 9:
    1961             :         emit(0x66);
    1962       24174 :         n--;
    1963             :       case 8:
    1964             :         emit(0x0f);
    1965             :         emit(0x1f);
    1966             :         emit(0x84);
    1967             :         emit(0x00);
    1968             :         emit(0x00);
    1969             :         emit(0x00);
    1970             :         emit(0x00);
    1971             :         emit(0x00);
    1972       27217 :         n -= 8;
    1973             :     }
    1974             :   }
    1975             : }
    1976             : 
    1977             : 
    1978     6749504 : void Assembler::popq(Register dst) {
    1979             :   EnsureSpace ensure_space(this);
    1980             :   emit_optional_rex_32(dst);
    1981     6749531 :   emit(0x58 | dst.low_bits());
    1982     6749531 : }
    1983             : 
    1984             : 
    1985     2552922 : void Assembler::popq(const Operand& dst) {
    1986             :   EnsureSpace ensure_space(this);
    1987             :   emit_optional_rex_32(dst);
    1988             :   emit(0x8F);
    1989     1276461 :   emit_operand(0, dst);
    1990     1276461 : }
    1991             : 
    1992             : 
    1993         560 : void Assembler::popfq() {
    1994             :   EnsureSpace ensure_space(this);
    1995             :   emit(0x9D);
    1996         560 : }
    1997             : 
    1998             : 
    1999    12508597 : void Assembler::pushq(Register src) {
    2000             :   EnsureSpace ensure_space(this);
    2001             :   emit_optional_rex_32(src);
    2002    12508625 :   emit(0x50 | src.low_bits());
    2003    12508625 : }
    2004             : 
    2005             : 
    2006     2646348 : void Assembler::pushq(const Operand& src) {
    2007             :   EnsureSpace ensure_space(this);
    2008             :   emit_optional_rex_32(src);
    2009             :   emit(0xFF);
    2010     1323174 :   emit_operand(6, src);
    2011     1323174 : }
    2012             : 
    2013             : 
    2014      908898 : void Assembler::pushq(Immediate value) {
    2015             :   EnsureSpace ensure_space(this);
    2016     1817720 :   if (is_int8(value.value_)) {
    2017             :     emit(0x6A);
    2018      775570 :     emit(value.value_);  // Emit low byte of value.
    2019             :   } else {
    2020             :     emit(0x68);
    2021      133290 :     emitl(value.value_);
    2022             :   }
    2023      908860 : }
    2024             : 
    2025             : 
    2026   599601950 : void Assembler::pushq_imm32(int32_t imm32) {
    2027             :   EnsureSpace ensure_space(this);
    2028             :   emit(0x68);
    2029   599601950 :   emitl(imm32);
    2030   599601950 : }
    2031             : 
    2032             : 
    2033         268 : void Assembler::pushfq() {
    2034             :   EnsureSpace ensure_space(this);
    2035             :   emit(0x9C);
    2036         268 : }
    2037             : 
    2038             : 
    2039     1715228 : void Assembler::ret(int imm16) {
    2040             :   EnsureSpace ensure_space(this);
    2041             :   DCHECK(is_uint16(imm16));
    2042     1715376 :   if (imm16 == 0) {
    2043             :     emit(0xC3);
    2044             :   } else {
    2045             :     emit(0xC2);
    2046      629486 :     emit(imm16 & 0xFF);
    2047      629486 :     emit((imm16 >> 8) & 0xFF);
    2048             :   }
    2049     1715376 : }
    2050             : 
    2051             : 
    2052          12 : void Assembler::ud2() {
    2053             :   EnsureSpace ensure_space(this);
    2054             :   emit(0x0F);
    2055             :   emit(0x0B);
    2056          12 : }
    2057             : 
    2058             : 
    2059      199910 : void Assembler::setcc(Condition cc, Register reg) {
    2060      199910 :   if (cc > last_condition) {
    2061           0 :     movb(reg, Immediate(cc == always ? 1 : 0));
    2062      199910 :     return;
    2063             :   }
    2064             :   EnsureSpace ensure_space(this);
    2065             :   DCHECK(is_uint4(cc));
    2066      199910 :   if (!reg.is_byte_register()) {
    2067             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    2068             :     emit_rex_32(reg);
    2069             :   }
    2070             :   emit(0x0F);
    2071      199910 :   emit(0x90 | cc);
    2072             :   emit_modrm(0x0, reg);
    2073             : }
    2074             : 
    2075             : 
    2076          12 : void Assembler::shld(Register dst, Register src) {
    2077             :   EnsureSpace ensure_space(this);
    2078             :   emit_rex_64(src, dst);
    2079             :   emit(0x0F);
    2080             :   emit(0xA5);
    2081             :   emit_modrm(src, dst);
    2082          12 : }
    2083             : 
    2084             : 
    2085          12 : void Assembler::shrd(Register dst, Register src) {
    2086             :   EnsureSpace ensure_space(this);
    2087             :   emit_rex_64(src, dst);
    2088             :   emit(0x0F);
    2089             :   emit(0xAD);
    2090             :   emit_modrm(src, dst);
    2091          12 : }
    2092             : 
    2093         448 : void Assembler::xchgb(Register reg, const Operand& op) {
    2094             :   EnsureSpace ensure_space(this);
    2095         224 :   if (!reg.is_byte_register()) {
    2096             :     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    2097             :     emit_rex_32(reg, op);
    2098             :   } else {
    2099             :     emit_optional_rex_32(reg, op);
    2100             :   }
    2101             :   emit(0x86);
    2102             :   emit_operand(reg, op);
    2103         224 : }
    2104             : 
    2105         460 : void Assembler::xchgw(Register reg, const Operand& op) {
    2106             :   EnsureSpace ensure_space(this);
    2107             :   emit(0x66);
    2108             :   emit_optional_rex_32(reg, op);
    2109             :   emit(0x87);
    2110             :   emit_operand(reg, op);
    2111         230 : }
    2112             : 
    2113          24 : void Assembler::emit_xchg(Register dst, Register src, int size) {
    2114             :   EnsureSpace ensure_space(this);
    2115          42 :   if (src == rax || dst == rax) {  // Single-byte encoding
    2116          18 :     Register other = src == rax ? dst : src;
    2117             :     emit_rex(other, size);
    2118          18 :     emit(0x90 | other.low_bits());
    2119           6 :   } else if (dst.low_bits() == 4) {
    2120           0 :     emit_rex(dst, src, size);
    2121             :     emit(0x87);
    2122             :     emit_modrm(dst, src);
    2123             :   } else {
    2124           6 :     emit_rex(src, dst, size);
    2125             :     emit(0x87);
    2126             :     emit_modrm(src, dst);
    2127             :   }
    2128          24 : }
    2129             : 
    2130             : 
    2131         260 : void Assembler::emit_xchg(Register dst, const Operand& src, int size) {
    2132             :   EnsureSpace ensure_space(this);
    2133         260 :   emit_rex(dst, src, size);
    2134             :   emit(0x87);
    2135             :   emit_operand(dst, src);
    2136         260 : }
    2137             : 
    2138             : 
    2139         660 : void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
    2140             :   EnsureSpace ensure_space(this);
    2141             :   if (kPointerSize == kInt64Size) {
    2142             :     emit(0x48);  // REX.W
    2143             :     emit(0xA3);
    2144         660 :     emitp(dst, mode);
    2145             :   } else {
    2146             :     DCHECK_EQ(kPointerSize, kInt32Size);
    2147             :     emit(0xA3);
    2148             :     emitp(dst, mode);
    2149             :     // In 64-bit mode, need to zero extend the operand to 8 bytes.
    2150             :     // See 2.2.1.4 in Intel64 and IA32 Architectures Software
    2151             :     // Developer's Manual Volume 2.
    2152             :     emitl(0);
    2153             :   }
    2154         660 : }
    2155             : 
    2156             : 
    2157         660 : void Assembler::store_rax(ExternalReference ref) {
    2158         660 :   store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
    2159         660 : }
    2160             : 
    2161             : 
    2162         678 : void Assembler::testb(Register dst, Register src) {
    2163             :   EnsureSpace ensure_space(this);
    2164         678 :   emit_test(dst, src, sizeof(int8_t));
    2165         678 : }
    2166             : 
    2167      465336 : void Assembler::testb(Register reg, Immediate mask) {
    2168             :   DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
    2169      465336 :   emit_test(reg, mask, sizeof(int8_t));
    2170      465337 : }
    2171             : 
    2172      730381 : void Assembler::testb(const Operand& op, Immediate mask) {
    2173             :   DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
    2174      730381 :   emit_test(op, mask, sizeof(int8_t));
    2175      730381 : }
    2176             : 
    2177             : 
    2178        5662 : void Assembler::testb(const Operand& op, Register reg) {
    2179        5662 :   emit_test(op, reg, sizeof(int8_t));
    2180        5662 : }
    2181             : 
    2182         666 : void Assembler::testw(Register dst, Register src) {
    2183         666 :   emit_test(dst, src, sizeof(uint16_t));
    2184         666 : }
    2185             : 
    2186          42 : void Assembler::testw(Register reg, Immediate mask) {
    2187          42 :   emit_test(reg, mask, sizeof(int16_t));
    2188          42 : }
    2189             : 
    2190         390 : void Assembler::testw(const Operand& op, Immediate mask) {
    2191         390 :   emit_test(op, mask, sizeof(int16_t));
    2192         390 : }
    2193             : 
    2194        1200 : void Assembler::testw(const Operand& op, Register reg) {
    2195        1200 :   emit_test(op, reg, sizeof(int16_t));
    2196        1200 : }
    2197             : 
    2198      343213 : void Assembler::emit_test(Register dst, Register src, int size) {
    2199             :   EnsureSpace ensure_space(this);
    2200      343211 :   if (src.low_bits() == 4) std::swap(dst, src);
    2201      343211 :   if (size == sizeof(int16_t)) {
    2202             :     emit(0x66);
    2203             :     size = sizeof(int32_t);
    2204             :   }
    2205      343211 :   bool byte_operand = size == sizeof(int8_t);
    2206      343211 :   if (byte_operand) {
    2207             :     size = sizeof(int32_t);
    2208         678 :     if (!src.is_byte_register() || !dst.is_byte_register()) {
    2209             :       emit_rex_32(dst, src);
    2210             :     }
    2211             :   } else {
    2212      342533 :     emit_rex(dst, src, size);
    2213             :   }
    2214      343212 :   emit(byte_operand ? 0x84 : 0x85);
    2215             :   emit_modrm(dst, src);
    2216      343212 : }
    2217             : 
    2218             : 
    2219      872779 : void Assembler::emit_test(Register reg, Immediate mask, int size) {
    2220      872779 :   if (is_uint8(mask.value_)) {
    2221             :     size = sizeof(int8_t);
    2222       13475 :   } else if (is_uint16(mask.value_)) {
    2223             :     size = sizeof(int16_t);
    2224             :   }
    2225             :   EnsureSpace ensure_space(this);
    2226      872773 :   bool half_word = size == sizeof(int16_t);
    2227      872773 :   if (half_word) {
    2228             :     emit(0x66);
    2229             :     size = sizeof(int32_t);
    2230             :   }
    2231      872773 :   bool byte_operand = size == sizeof(int8_t);
    2232      872773 :   if (byte_operand) {
    2233             :     size = sizeof(int32_t);
    2234      859298 :     if (!reg.is_byte_register()) emit_rex_32(reg);
    2235             :   } else {
    2236             :     emit_rex(reg, size);
    2237             :   }
    2238      872773 :   if (reg == rax) {
    2239      403233 :     emit(byte_operand ? 0xA8 : 0xA9);
    2240             :   } else {
    2241      469540 :     emit(byte_operand ? 0xF6 : 0xF7);
    2242             :     emit_modrm(0x0, reg);
    2243             :   }
    2244      872773 :   if (byte_operand) {
    2245      859298 :     emit(mask.value_);
    2246       13475 :   } else if (half_word) {
    2247        6301 :     emitw(mask.value_);
    2248             :   } else {
    2249        7174 :     emit(mask);
    2250             :   }
    2251      872773 : }
    2252             : 
    2253     1212023 : void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
    2254     1212023 :   if (is_uint8(mask.value_)) {
    2255             :     size = sizeof(int8_t);
    2256      445936 :   } else if (is_uint16(mask.value_)) {
    2257             :     size = sizeof(int16_t);
    2258             :   }
    2259             :   EnsureSpace ensure_space(this);
    2260     1212027 :   bool half_word = size == sizeof(int16_t);
    2261     1212027 :   if (half_word) {
    2262             :     emit(0x66);
    2263             :     size = sizeof(int32_t);
    2264             :   }
    2265     1212027 :   bool byte_operand = size == sizeof(int8_t);
    2266     1212027 :   if (byte_operand) {
    2267             :     size = sizeof(int32_t);
    2268             :   }
    2269     1212027 :   emit_rex(rax, op, size);
    2270     1212031 :   emit(byte_operand ? 0xF6 : 0xF7);
    2271             :   emit_operand(rax, op);  // Operation code 0
    2272     1212034 :   if (byte_operand) {
    2273      766093 :     emit(mask.value_);
    2274      445941 :   } else if (half_word) {
    2275         413 :     emitw(mask.value_);
    2276             :   } else {
    2277      445528 :     emit(mask);
    2278             :   }
    2279     1212030 : }
    2280             : 
    2281       14456 : void Assembler::emit_test(const Operand& op, Register reg, int size) {
    2282             :   EnsureSpace ensure_space(this);
    2283        8794 :   if (size == sizeof(int16_t)) {
    2284             :     emit(0x66);
    2285             :     size = sizeof(int32_t);
    2286             :   }
    2287        8794 :   bool byte_operand = size == sizeof(int8_t);
    2288        8794 :   if (byte_operand) {
    2289             :     size = sizeof(int32_t);
    2290        5662 :     if (!reg.is_byte_register()) {
    2291             :       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
    2292             :       emit_rex_32(reg, op);
    2293             :     } else {
    2294             :       emit_optional_rex_32(reg, op);
    2295             :     }
    2296             :   } else {
    2297        3132 :     emit_rex(reg, op, size);
    2298             :   }
    2299        8794 :   emit(byte_operand ? 0x84 : 0x85);
    2300             :   emit_operand(reg, op);
    2301        8794 : }
    2302             : 
    2303             : 
    2304             : // FPU instructions.
    2305             : 
    2306             : 
    2307          37 : void Assembler::fld(int i) {
    2308             :   EnsureSpace ensure_space(this);
    2309             :   emit_farith(0xD9, 0xC0, i);
    2310          37 : }
    2311             : 
    2312             : 
    2313          37 : void Assembler::fld1() {
    2314             :   EnsureSpace ensure_space(this);
    2315             :   emit(0xD9);
    2316             :   emit(0xE8);
    2317          37 : }
    2318             : 
    2319             : 
    2320           6 : void Assembler::fldz() {
    2321             :   EnsureSpace ensure_space(this);
    2322             :   emit(0xD9);
    2323             :   emit(0xEE);
    2324           6 : }
    2325             : 
    2326             : 
    2327           6 : void Assembler::fldpi() {
    2328             :   EnsureSpace ensure_space(this);
    2329             :   emit(0xD9);
    2330             :   emit(0xEB);
    2331           6 : }
    2332             : 
    2333             : 
    2334           0 : void Assembler::fldln2() {
    2335             :   EnsureSpace ensure_space(this);
    2336             :   emit(0xD9);
    2337             :   emit(0xED);
    2338           0 : }
    2339             : 
    2340             : 
    2341          12 : void Assembler::fld_s(const Operand& adr) {
    2342             :   EnsureSpace ensure_space(this);
    2343             :   emit_optional_rex_32(adr);
    2344             :   emit(0xD9);
    2345           6 :   emit_operand(0, adr);
    2346           6 : }
    2347             : 
    2348             : 
    2349        5596 : void Assembler::fld_d(const Operand& adr) {
    2350             :   EnsureSpace ensure_space(this);
    2351             :   emit_optional_rex_32(adr);
    2352             :   emit(0xDD);
    2353        2798 :   emit_operand(0, adr);
    2354        2798 : }
    2355             : 
    2356             : 
    2357          12 : void Assembler::fstp_s(const Operand& adr) {
    2358             :   EnsureSpace ensure_space(this);
    2359             :   emit_optional_rex_32(adr);
    2360             :   emit(0xD9);
    2361           6 :   emit_operand(3, adr);
    2362           6 : }
    2363             : 
    2364             : 
    2365        2804 : void Assembler::fstp_d(const Operand& adr) {
    2366             :   EnsureSpace ensure_space(this);
    2367             :   emit_optional_rex_32(adr);
    2368             :   emit(0xDD);
    2369        1402 :   emit_operand(3, adr);
    2370        1402 : }
    2371             : 
    2372             : 
    2373        1396 : void Assembler::fstp(int index) {
    2374             :   DCHECK(is_uint3(index));
    2375             :   EnsureSpace ensure_space(this);
    2376             :   emit_farith(0xDD, 0xD8, index);
    2377        1396 : }
    2378             : 
    2379             : 
    2380          12 : void Assembler::fild_s(const Operand& adr) {
    2381             :   EnsureSpace ensure_space(this);
    2382             :   emit_optional_rex_32(adr);
    2383             :   emit(0xDB);
    2384           6 :   emit_operand(0, adr);
    2385           6 : }
    2386             : 
    2387             : 
    2388          12 : void Assembler::fild_d(const Operand& adr) {
    2389             :   EnsureSpace ensure_space(this);
    2390             :   emit_optional_rex_32(adr);
    2391             :   emit(0xDF);
    2392           6 :   emit_operand(5, adr);
    2393           6 : }
    2394             : 
    2395             : 
    2396          12 : void Assembler::fistp_s(const Operand& adr) {
    2397             :   EnsureSpace ensure_space(this);
    2398             :   emit_optional_rex_32(adr);
    2399             :   emit(0xDB);
    2400           6 :   emit_operand(3, adr);
    2401           6 : }
    2402             : 
    2403             : 
    2404           0 : void Assembler::fisttp_s(const Operand& adr) {
    2405             :   DCHECK(IsEnabled(SSE3));
    2406             :   EnsureSpace ensure_space(this);
    2407             :   emit_optional_rex_32(adr);
    2408             :   emit(0xDB);
    2409           0 :   emit_operand(1, adr);
    2410           0 : }
    2411             : 
    2412             : 
    2413           0 : void Assembler::fisttp_d(const Operand& adr) {
    2414             :   DCHECK(IsEnabled(SSE3));
    2415             :   EnsureSpace ensure_space(this);
    2416             :   emit_optional_rex_32(adr);
    2417             :   emit(0xDD);
    2418           0 :   emit_operand(1, adr);
    2419           0 : }
    2420             : 
    2421             : 
    2422           0 : void Assembler::fist_s(const Operand& adr) {
    2423             :   EnsureSpace ensure_space(this);
    2424             :   emit_optional_rex_32(adr);
    2425             :   emit(0xDB);
    2426           0 :   emit_operand(2, adr);
    2427           0 : }
    2428             : 
    2429             : 
    2430          12 : void Assembler::fistp_d(const Operand& adr) {
    2431             :   EnsureSpace ensure_space(this);
    2432             :   emit_optional_rex_32(adr);
    2433             :   emit(0xDF);
    2434           6 :   emit_operand(7, adr);
    2435           6 : }
    2436             : 
    2437             : 
    2438           6 : void Assembler::fabs() {
    2439             :   EnsureSpace ensure_space(this);
    2440             :   emit(0xD9);
    2441             :   emit(0xE1);
    2442           6 : }
    2443             : 
    2444             : 
    2445           6 : void Assembler::fchs() {
    2446             :   EnsureSpace ensure_space(this);
    2447             :   emit(0xD9);
    2448             :   emit(0xE0);
    2449           6 : }
    2450             : 
    2451             : 
    2452           0 : void Assembler::fcos() {
    2453             :   EnsureSpace ensure_space(this);
    2454             :   emit(0xD9);
    2455             :   emit(0xFF);
    2456           0 : }
    2457             : 
    2458             : 
    2459           0 : void Assembler::fsin() {
    2460             :   EnsureSpace ensure_space(this);
    2461             :   emit(0xD9);
    2462             :   emit(0xFE);
    2463           0 : }
    2464             : 
    2465             : 
    2466           0 : void Assembler::fptan() {
    2467             :   EnsureSpace ensure_space(this);
    2468             :   emit(0xD9);
    2469             :   emit(0xF2);
    2470           0 : }
    2471             : 
    2472             : 
    2473          31 : void Assembler::fyl2x() {
    2474             :   EnsureSpace ensure_space(this);
    2475             :   emit(0xD9);
    2476             :   emit(0xF1);
    2477          31 : }
    2478             : 
    2479             : 
    2480          31 : void Assembler::f2xm1() {
    2481             :   EnsureSpace ensure_space(this);
    2482             :   emit(0xD9);
    2483             :   emit(0xF0);
    2484          31 : }
    2485             : 
    2486             : 
    2487          31 : void Assembler::fscale() {
    2488             :   EnsureSpace ensure_space(this);
    2489             :   emit(0xD9);
    2490             :   emit(0xFD);
    2491          31 : }
    2492             : 
    2493             : 
    2494          37 : void Assembler::fninit() {
    2495             :   EnsureSpace ensure_space(this);
    2496             :   emit(0xDB);
    2497             :   emit(0xE3);
    2498          37 : }
    2499             : 
    2500             : 
    2501           6 : void Assembler::fadd(int i) {
    2502             :   EnsureSpace ensure_space(this);
    2503             :   emit_farith(0xDC, 0xC0, i);
    2504           6 : }
    2505             : 
    2506             : 
    2507          37 : void Assembler::fsub(int i) {
    2508             :   EnsureSpace ensure_space(this);
    2509             :   emit_farith(0xDC, 0xE8, i);
    2510          37 : }
    2511             : 
    2512             : 
    2513           0 : void Assembler::fisub_s(const Operand& adr) {
    2514             :   EnsureSpace ensure_space(this);
    2515             :   emit_optional_rex_32(adr);
    2516             :   emit(0xDA);
    2517           0 :   emit_operand(4, adr);
    2518           0 : }
    2519             : 
    2520             : 
    2521           6 : void Assembler::fmul(int i) {
    2522             :   EnsureSpace ensure_space(this);
    2523             :   emit_farith(0xDC, 0xC8, i);
    2524           6 : }
    2525             : 
    2526             : 
    2527           6 : void Assembler::fdiv(int i) {
    2528             :   EnsureSpace ensure_space(this);
    2529             :   emit_farith(0xDC, 0xF8, i);
    2530           6 : }
    2531             : 
    2532             : 
    2533          37 : void Assembler::faddp(int i) {
    2534             :   EnsureSpace ensure_space(this);
    2535             :   emit_farith(0xDE, 0xC0, i);
    2536          37 : }
    2537             : 
    2538             : 
    2539           6 : void Assembler::fsubp(int i) {
    2540             :   EnsureSpace ensure_space(this);
    2541             :   emit_farith(0xDE, 0xE8, i);
    2542           6 : }
    2543             : 
    2544             : 
    2545           0 : void Assembler::fsubrp(int i) {
    2546             :   EnsureSpace ensure_space(this);
    2547             :   emit_farith(0xDE, 0xE0, i);
    2548           0 : }
    2549             : 
    2550             : 
    2551           6 : void Assembler::fmulp(int i) {
    2552             :   EnsureSpace ensure_space(this);
    2553             :   emit_farith(0xDE, 0xC8, i);
    2554           6 : }
    2555             : 
    2556             : 
    2557           6 : void Assembler::fdivp(int i) {
    2558             :   EnsureSpace ensure_space(this);
    2559             :   emit_farith(0xDE, 0xF8, i);
    2560           6 : }
    2561             : 
    2562             : 
    2563        1371 : void Assembler::fprem() {
    2564             :   EnsureSpace ensure_space(this);
    2565             :   emit(0xD9);
    2566             :   emit(0xF8);
    2567        1371 : }
    2568             : 
    2569             : 
    2570           6 : void Assembler::fprem1() {
    2571             :   EnsureSpace ensure_space(this);
    2572             :   emit(0xD9);
    2573             :   emit(0xF5);
    2574           6 : }
    2575             : 
    2576             : 
    2577          37 : void Assembler::fxch(int i) {
    2578             :   EnsureSpace ensure_space(this);
    2579             :   emit_farith(0xD9, 0xC8, i);
    2580          37 : }
    2581             : 
    2582             : 
    2583           6 : void Assembler::fincstp() {
    2584             :   EnsureSpace ensure_space(this);
    2585             :   emit(0xD9);
    2586             :   emit(0xF7);
    2587           6 : }
    2588             : 
    2589             : 
    2590           6 : void Assembler::ffree(int i) {
    2591             :   EnsureSpace ensure_space(this);
    2592             :   emit_farith(0xDD, 0xC0, i);
    2593           6 : }
    2594             : 
    2595             : 
    2596           6 : void Assembler::ftst() {
    2597             :   EnsureSpace ensure_space(this);
    2598             :   emit(0xD9);
    2599             :   emit(0xE4);
    2600           6 : }
    2601             : 
    2602             : 
    2603           0 : void Assembler::fucomp(int i) {
    2604             :   EnsureSpace ensure_space(this);
    2605             :   emit_farith(0xDD, 0xE8, i);
    2606           0 : }
    2607             : 
    2608             : 
    2609           0 : void Assembler::fucompp() {
    2610             :   EnsureSpace ensure_space(this);
    2611             :   emit(0xDA);
    2612             :   emit(0xE9);
    2613           0 : }
    2614             : 
    2615             : 
    2616           0 : void Assembler::fucomi(int i) {
    2617             :   EnsureSpace ensure_space(this);
    2618             :   emit(0xDB);
    2619           0 :   emit(0xE8 + i);
    2620           0 : }
    2621             : 
    2622             : 
    2623           0 : void Assembler::fucomip() {
    2624             :   EnsureSpace ensure_space(this);
    2625             :   emit(0xDF);
    2626             :   emit(0xE9);
    2627           0 : }
    2628             : 
    2629             : 
    2630           6 : void Assembler::fcompp() {
    2631             :   EnsureSpace ensure_space(this);
    2632             :   emit(0xDE);
    2633             :   emit(0xD9);
    2634           6 : }
    2635             : 
    2636             : 
    2637        1402 : void Assembler::fnstsw_ax() {
    2638             :   EnsureSpace ensure_space(this);
    2639             :   emit(0xDF);
    2640             :   emit(0xE0);
    2641        1402 : }
    2642             : 
    2643             : 
    2644           6 : void Assembler::fwait() {
    2645             :   EnsureSpace ensure_space(this);
    2646             :   emit(0x9B);
    2647           6 : }
    2648             : 
    2649             : 
    2650          37 : void Assembler::frndint() {
    2651             :   EnsureSpace ensure_space(this);
    2652             :   emit(0xD9);
    2653             :   emit(0xFC);
    2654          37 : }
    2655             : 
    2656             : 
    2657          31 : void Assembler::fnclex() {
    2658             :   EnsureSpace ensure_space(this);
    2659             :   emit(0xDB);
    2660             :   emit(0xE2);
    2661          31 : }
    2662             : 
    2663             : 
    2664        1341 : void Assembler::sahf() {
    2665             :   // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
    2666             :   // in 64-bit mode. Test CpuID.
    2667             :   DCHECK(IsEnabled(SAHF));
    2668             :   EnsureSpace ensure_space(this);
    2669             :   emit(0x9E);
    2670        1341 : }
    2671             : 
    2672             : 
    2673           0 : void Assembler::emit_farith(int b1, int b2, int i) {
    2674             :   DCHECK(is_uint8(b1) && is_uint8(b2));  // wrong opcode
    2675             :   DCHECK(is_uint3(i));  // illegal stack offset
    2676           0 :   emit(b1);
    2677        1586 :   emit(b2 + i);
    2678           0 : }
    2679             : 
    2680             : 
    2681             : // SSE operations.
    2682             : 
    2683          42 : void Assembler::andps(XMMRegister dst, XMMRegister src) {
    2684             :   EnsureSpace ensure_space(this);
    2685             :   emit_optional_rex_32(dst, src);
    2686             :   emit(0x0F);
    2687             :   emit(0x54);
    2688             :   emit_sse_operand(dst, src);
    2689          42 : }
    2690             : 
    2691             : 
    2692          12 : void Assembler::andps(XMMRegister dst, const Operand& src) {
    2693             :   EnsureSpace ensure_space(this);
    2694             :   emit_optional_rex_32(dst, src);
    2695             :   emit(0x0F);
    2696             :   emit(0x54);
    2697             :   emit_sse_operand(dst, src);
    2698           6 : }
    2699             : 
    2700             : 
    2701           6 : void Assembler::orps(XMMRegister dst, XMMRegister src) {
    2702             :   EnsureSpace ensure_space(this);
    2703             :   emit_optional_rex_32(dst, src);
    2704             :   emit(0x0F);
    2705             :   emit(0x56);
    2706             :   emit_sse_operand(dst, src);
    2707           6 : }
    2708             : 
    2709             : 
    2710          12 : void Assembler::orps(XMMRegister dst, const Operand& src) {
    2711             :   EnsureSpace ensure_space(this);
    2712             :   emit_optional_rex_32(dst, src);
    2713             :   emit(0x0F);
    2714             :   emit(0x56);
    2715             :   emit_sse_operand(dst, src);
    2716           6 : }
    2717             : 
    2718             : 
    2719         392 : void Assembler::xorps(XMMRegister dst, XMMRegister src) {
    2720             :   DCHECK(!IsEnabled(AVX));
    2721             :   EnsureSpace ensure_space(this);
    2722             :   emit_optional_rex_32(dst, src);
    2723             :   emit(0x0F);
    2724             :   emit(0x57);
    2725             :   emit_sse_operand(dst, src);
    2726         392 : }
    2727             : 
    2728             : 
    2729          12 : void Assembler::xorps(XMMRegister dst, const Operand& src) {
    2730             :   DCHECK(!IsEnabled(AVX));
    2731             :   EnsureSpace ensure_space(this);
    2732             :   emit_optional_rex_32(dst, src);
    2733             :   emit(0x0F);
    2734             :   emit(0x57);
    2735             :   emit_sse_operand(dst, src);
    2736           6 : }
    2737             : 
    2738             : 
    2739          12 : void Assembler::addps(XMMRegister dst, XMMRegister src) {
    2740             :   EnsureSpace ensure_space(this);
    2741             :   emit_optional_rex_32(dst, src);
    2742             :   emit(0x0F);
    2743             :   emit(0x58);
    2744             :   emit_sse_operand(dst, src);
    2745          12 : }
    2746             : 
    2747             : 
    2748          12 : void Assembler::addps(XMMRegister dst, const Operand& src) {
    2749             :   EnsureSpace ensure_space(this);
    2750             :   emit_optional_rex_32(dst, src);
    2751             :   emit(0x0F);
    2752             :   emit(0x58);
    2753             :   emit_sse_operand(dst, src);
    2754           6 : }
    2755             : 
    2756             : 
    2757          12 : void Assembler::subps(XMMRegister dst, XMMRegister src) {
    2758             :   EnsureSpace ensure_space(this);
    2759             :   emit_optional_rex_32(dst, src);
    2760             :   emit(0x0F);
    2761             :   emit(0x5C);
    2762             :   emit_sse_operand(dst, src);
    2763          12 : }
    2764             : 
    2765             : 
    2766          12 : void Assembler::subps(XMMRegister dst, const Operand& src) {
    2767             :   EnsureSpace ensure_space(this);
    2768             :   emit_optional_rex_32(dst, src);
    2769             :   emit(0x0F);
    2770             :   emit(0x5C);
    2771             :   emit_sse_operand(dst, src);
    2772           6 : }
    2773             : 
    2774             : 
    2775          12 : void Assembler::mulps(XMMRegister dst, XMMRegister src) {
    2776             :   EnsureSpace ensure_space(this);
    2777             :   emit_optional_rex_32(dst, src);
    2778             :   emit(0x0F);
    2779             :   emit(0x59);
    2780             :   emit_sse_operand(dst, src);
    2781          12 : }
    2782             : 
    2783             : 
    2784          12 : void Assembler::mulps(XMMRegister dst, const Operand& src) {
    2785             :   EnsureSpace ensure_space(this);
    2786             :   emit_optional_rex_32(dst, src);
    2787             :   emit(0x0F);
    2788             :   emit(0x59);
    2789             :   emit_sse_operand(dst, src);
    2790           6 : }
    2791             : 
    2792             : 
    2793          12 : void Assembler::divps(XMMRegister dst, XMMRegister src) {
    2794             :   EnsureSpace ensure_space(this);
    2795             :   emit_optional_rex_32(dst, src);
    2796             :   emit(0x0F);
    2797             :   emit(0x5E);
    2798             :   emit_sse_operand(dst, src);
    2799          12 : }
    2800             : 
    2801             : 
    2802          12 : void Assembler::divps(XMMRegister dst, const Operand& src) {
    2803             :   EnsureSpace ensure_space(this);
    2804             :   emit_optional_rex_32(dst, src);
    2805             :   emit(0x0F);
    2806             :   emit(0x5E);
    2807             :   emit_sse_operand(dst, src);
    2808           6 : }
    2809             : 
    2810             : 
    2811             : // SSE 2 operations.
    2812             : 
    2813         972 : void Assembler::movd(XMMRegister dst, Register src) {
    2814             :   DCHECK(!IsEnabled(AVX));
    2815             :   EnsureSpace ensure_space(this);
    2816             :   emit(0x66);
    2817             :   emit_optional_rex_32(dst, src);
    2818             :   emit(0x0F);
    2819             :   emit(0x6E);
    2820             :   emit_sse_operand(dst, src);
    2821         972 : }
    2822             : 
    2823             : 
    2824           0 : void Assembler::movd(XMMRegister dst, const Operand& src) {
    2825             :   DCHECK(!IsEnabled(AVX));
    2826             :   EnsureSpace ensure_space(this);
    2827             :   emit(0x66);
    2828             :   emit_optional_rex_32(dst, src);
    2829             :   emit(0x0F);
    2830             :   emit(0x6E);
    2831             :   emit_sse_operand(dst, src);
    2832           0 : }
    2833             : 
    2834             : 
    2835           0 : void Assembler::movd(Register dst, XMMRegister src) {
    2836             :   DCHECK(!IsEnabled(AVX));
    2837             :   EnsureSpace ensure_space(this);
    2838             :   emit(0x66);
    2839             :   emit_optional_rex_32(src, dst);
    2840             :   emit(0x0F);
    2841             :   emit(0x7E);
    2842             :   emit_sse_operand(src, dst);
    2843           0 : }
    2844             : 
    2845             : 
    2846         628 : void Assembler::movq(XMMRegister dst, Register src) {
    2847             :   DCHECK(!IsEnabled(AVX));
    2848             :   EnsureSpace ensure_space(this);
    2849             :   emit(0x66);
    2850             :   emit_rex_64(dst, src);
    2851             :   emit(0x0F);
    2852             :   emit(0x6E);
    2853             :   emit_sse_operand(dst, src);
    2854         628 : }
    2855             : 
    2856             : 
    2857         140 : void Assembler::movq(Register dst, XMMRegister src) {
    2858             :   DCHECK(!IsEnabled(AVX));
    2859             :   EnsureSpace ensure_space(this);
    2860             :   emit(0x66);
    2861             :   emit_rex_64(src, dst);
    2862             :   emit(0x0F);
    2863             :   emit(0x7E);
    2864             :   emit_sse_operand(src, dst);
    2865         140 : }
    2866             : 
    2867             : 
    2868           0 : void Assembler::movq(XMMRegister dst, XMMRegister src) {
    2869             :   DCHECK(!IsEnabled(AVX));
    2870             :   EnsureSpace ensure_space(this);
    2871           0 :   if (dst.low_bits() == 4) {
    2872             :     // Avoid unnecessary SIB byte.
    2873             :     emit(0xf3);
    2874             :     emit_optional_rex_32(dst, src);
    2875             :     emit(0x0F);
    2876             :     emit(0x7e);
    2877             :     emit_sse_operand(dst, src);
    2878             :   } else {
    2879             :     emit(0x66);
    2880             :     emit_optional_rex_32(src, dst);
    2881             :     emit(0x0F);
    2882             :     emit(0xD6);
    2883             :     emit_sse_operand(src, dst);
    2884             :   }
    2885           0 : }
    2886             : 
    2887             : 
    2888          12 : void Assembler::movdqa(const Operand& dst, XMMRegister src) {
    2889             :   EnsureSpace ensure_space(this);
    2890             :   emit(0x66);
    2891             :   emit_rex_64(src, dst);
    2892             :   emit(0x0F);
    2893             :   emit(0x7F);
    2894             :   emit_sse_operand(src, dst);
    2895           6 : }
    2896             : 
    2897             : 
    2898          24 : void Assembler::movdqa(XMMRegister dst, const Operand& src) {
    2899             :   EnsureSpace ensure_space(this);
    2900             :   emit(0x66);
    2901             :   emit_rex_64(dst, src);
    2902             :   emit(0x0F);
    2903             :   emit(0x6F);
    2904             :   emit_sse_operand(dst, src);
    2905          12 : }
    2906             : 
    2907             : 
    2908         456 : void Assembler::movdqu(const Operand& dst, XMMRegister src) {
    2909             :   EnsureSpace ensure_space(this);
    2910             :   emit(0xF3);
    2911             :   emit_rex_64(src, dst);
    2912             :   emit(0x0F);
    2913             :   emit(0x7F);
    2914             :   emit_sse_operand(src, dst);
    2915         228 : }
    2916             : 
    2917             : 
    2918         528 : void Assembler::movdqu(XMMRegister dst, const Operand& src) {
    2919             :   EnsureSpace ensure_space(this);
    2920             :   emit(0xF3);
    2921             :   emit_rex_64(dst, src);
    2922             :   emit(0x0F);
    2923             :   emit(0x6F);
    2924             :   emit_sse_operand(dst, src);
    2925         264 : }
    2926             : 
    2927             : 
    2928          12 : void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
    2929             :   DCHECK(IsEnabled(SSE4_1));
    2930             :   DCHECK(is_uint8(imm8));
    2931             :   EnsureSpace ensure_space(this);
    2932             :   emit(0x66);
    2933             :   emit_optional_rex_32(src, dst);
    2934             :   emit(0x0F);
    2935             :   emit(0x3A);
    2936             :   emit(0x17);
    2937             :   emit_sse_operand(src, dst);
    2938             :   emit(imm8);
    2939          12 : }
    2940             : 
    2941        3648 : void Assembler::pextrb(Register dst, XMMRegister src, int8_t imm8) {
    2942             :   DCHECK(IsEnabled(SSE4_1));
    2943             :   DCHECK(is_uint8(imm8));
    2944             :   EnsureSpace ensure_space(this);
    2945             :   emit(0x66);
    2946             :   emit_optional_rex_32(src, dst);
    2947             :   emit(0x0F);
    2948             :   emit(0x3A);
    2949             :   emit(0x14);
    2950             :   emit_sse_operand(src, dst);
    2951        3648 :   emit(imm8);
    2952        3648 : }
    2953             : 
    2954           0 : void Assembler::pextrb(const Operand& dst, XMMRegister src, int8_t imm8) {
    2955             :   DCHECK(IsEnabled(SSE4_1));
    2956             :   DCHECK(is_uint8(imm8));
    2957             :   EnsureSpace ensure_space(this);
    2958             :   emit(0x66);
    2959             :   emit_optional_rex_32(src, dst);
    2960             :   emit(0x0F);
    2961             :   emit(0x3A);
    2962             :   emit(0x14);
    2963             :   emit_sse_operand(src, dst);
    2964           0 :   emit(imm8);
    2965           0 : }
    2966             : 
    2967          78 : void Assembler::pinsrw(XMMRegister dst, Register src, int8_t imm8) {
    2968             :   DCHECK(is_uint8(imm8));
    2969             :   EnsureSpace ensure_space(this);
    2970             :   emit(0x66);
    2971             :   emit_optional_rex_32(dst, src);
    2972             :   emit(0x0F);
    2973             :   emit(0xC4);
    2974             :   emit_sse_operand(dst, src);
    2975          78 :   emit(imm8);
    2976          78 : }
    2977             : 
    2978           0 : void Assembler::pinsrw(XMMRegister dst, const Operand& src, int8_t imm8) {
    2979             :   DCHECK(is_uint8(imm8));
    2980             :   EnsureSpace ensure_space(this);
    2981             :   emit(0x66);
    2982             :   emit_optional_rex_32(dst, src);
    2983             :   emit(0x0F);
    2984             :   emit(0xC4);
    2985             :   emit_sse_operand(dst, src);
    2986           0 :   emit(imm8);
    2987           0 : }
    2988             : 
    2989        1686 : void Assembler::pextrw(Register dst, XMMRegister src, int8_t imm8) {
    2990             :   DCHECK(IsEnabled(SSE4_1));
    2991             :   DCHECK(is_uint8(imm8));
    2992             :   EnsureSpace ensure_space(this);
    2993             :   emit(0x66);
    2994             :   emit_optional_rex_32(src, dst);
    2995             :   emit(0x0F);
    2996             :   emit(0x3A);
    2997             :   emit(0x15);
    2998             :   emit_sse_operand(src, dst);
    2999        1686 :   emit(imm8);
    3000        1686 : }
    3001             : 
    3002           0 : void Assembler::pextrw(const Operand& dst, XMMRegister src, int8_t imm8) {
    3003             :   DCHECK(IsEnabled(SSE4_1));
    3004             :   DCHECK(is_uint8(imm8));
    3005             :   EnsureSpace ensure_space(this);
    3006             :   emit(0x66);
    3007             :   emit_optional_rex_32(src, dst);
    3008             :   emit(0x0F);
    3009             :   emit(0x3A);
    3010             :   emit(0x15);
    3011             :   emit_sse_operand(src, dst);
    3012           0 :   emit(imm8);
    3013           0 : }
    3014             : 
    3015       30259 : void Assembler::pextrd(Register dst, XMMRegister src, int8_t imm8) {
    3016             :   DCHECK(IsEnabled(SSE4_1));
    3017             :   EnsureSpace ensure_space(this);
    3018             :   emit(0x66);
    3019             :   emit_optional_rex_32(src, dst);
    3020             :   emit(0x0F);
    3021             :   emit(0x3A);
    3022             :   emit(0x16);
    3023             :   emit_sse_operand(src, dst);
    3024       30259 :   emit(imm8);
    3025       30259 : }
    3026             : 
    3027           0 : void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t imm8) {
    3028             :   DCHECK(IsEnabled(SSE4_1));
    3029             :   EnsureSpace ensure_space(this);
    3030             :   emit(0x66);
    3031             :   emit_optional_rex_32(src, dst);
    3032             :   emit(0x0F);
    3033             :   emit(0x3A);
    3034             :   emit(0x16);
    3035             :   emit_sse_operand(src, dst);
    3036           0 :   emit(imm8);
    3037           0 : }
    3038             : 
    3039          94 : void Assembler::pinsrd(XMMRegister dst, Register src, int8_t imm8) {
    3040             :   DCHECK(IsEnabled(SSE4_1));
    3041             :   EnsureSpace ensure_space(this);
    3042             :   emit(0x66);
    3043             :   emit_optional_rex_32(dst, src);
    3044             :   emit(0x0F);
    3045             :   emit(0x3A);
    3046             :   emit(0x22);
    3047             :   emit_sse_operand(dst, src);
    3048          94 :   emit(imm8);
    3049          94 : }
    3050             : 
    3051             : 
    3052          12 : void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) {
    3053             :   DCHECK(IsEnabled(SSE4_1));
    3054             :   EnsureSpace ensure_space(this);
    3055             :   emit(0x66);
    3056             :   emit_optional_rex_32(dst, src);
    3057             :   emit(0x0F);
    3058             :   emit(0x3A);
    3059             :   emit(0x22);
    3060             :   emit_sse_operand(dst, src);
    3061           6 :   emit(imm8);
    3062           6 : }
    3063             : 
    3064         120 : void Assembler::pinsrb(XMMRegister dst, Register src, int8_t imm8) {
    3065             :   DCHECK(IsEnabled(SSE4_1));
    3066             :   EnsureSpace ensure_space(this);
    3067             :   emit(0x66);
    3068             :   emit_optional_rex_32(dst, src);
    3069             :   emit(0x0F);
    3070             :   emit(0x3A);
    3071             :   emit(0x20);
    3072             :   emit_sse_operand(dst, src);
    3073         120 :   emit(imm8);
    3074         120 : }
    3075             : 
    3076           0 : void Assembler::pinsrb(XMMRegister dst, const Operand& src, int8_t imm8) {
    3077             :   DCHECK(IsEnabled(SSE4_1));
    3078             :   EnsureSpace ensure_space(this);
    3079             :   emit(0x66);
    3080             :   emit_optional_rex_32(dst, src);
    3081             :   emit(0x0F);
    3082             :   emit(0x3A);
    3083             :   emit(0x20);
    3084             :   emit_sse_operand(dst, src);
    3085           0 :   emit(imm8);
    3086           0 : }
    3087             : 
    3088           6 : void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
    3089             :   DCHECK(CpuFeatures::IsSupported(SSE4_1));
    3090             :   DCHECK(is_uint8(imm8));
    3091             :   EnsureSpace ensure_space(this);
    3092             :   emit(0x66);
    3093             :   emit_optional_rex_32(dst, src);
    3094             :   emit(0x0F);
    3095             :   emit(0x3A);
    3096             :   emit(0x21);
    3097             :   emit_sse_operand(dst, src);
    3098             :   emit(imm8);
    3099           6 : }
    3100             : 
    3101        3430 : void Assembler::movsd(const Operand& dst, XMMRegister src) {
    3102             :   DCHECK(!IsEnabled(AVX));
    3103             :   EnsureSpace ensure_space(this);
    3104             :   emit(0xF2);  // double
    3105             :   emit_optional_rex_32(src, dst);
    3106             :   emit(0x0F);
    3107             :   emit(0x11);  // store
    3108             :   emit_sse_operand(src, dst);
    3109        1715 : }
    3110             : 
    3111             : 
    3112          14 : void Assembler::movsd(XMMRegister dst, XMMRegister src) {
    3113             :   DCHECK(!IsEnabled(AVX));
    3114             :   EnsureSpace ensure_space(this);
    3115             :   emit(0xF2);  // double
    3116             :   emit_optional_rex_32(dst, src);
    3117             :   emit(0x0F);
    3118             :   emit(0x10);  // load
    3119             :   emit_sse_operand(dst, src);
    3120          14 : }
    3121             : 
    3122             : 
    3123        4946 : void Assembler::movsd(XMMRegister dst, const Operand& src) {
    3124             :   DCHECK(!IsEnabled(AVX));
    3125             :   EnsureSpace ensure_space(this);
    3126             :   emit(0xF2);  // double
    3127             :   emit_optional_rex_32(dst, src);
    3128             :   emit(0x0F);
    3129             :   emit(0x10);  // load
    3130             :   emit_sse_operand(dst, src);
    3131        2473 : }
    3132             : 
    3133             : 
    3134         426 : void Assembler::movaps(XMMRegister dst, XMMRegister src) {
    3135             :   DCHECK(!IsEnabled(AVX));
    3136             :   EnsureSpace ensure_space(this);
    3137         426 :   if (src.low_bits() == 4) {
    3138             :     // Try to avoid an unnecessary SIB byte.
    3139             :     emit_optional_rex_32(src, dst);
    3140             :     emit(0x0F);
    3141             :     emit(0x29);
    3142             :     emit_sse_operand(src, dst);
    3143             :   } else {
    3144             :     emit_optional_rex_32(dst, src);
    3145             :     emit(0x0F);
    3146             :     emit(0x28);
    3147             :     emit_sse_operand(dst, src);
    3148             :   }
    3149         426 : }
    3150             : 
    3151             : 
    3152          36 : void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
    3153             :   DCHECK(is_uint8(imm8));
    3154             :   EnsureSpace ensure_space(this);
    3155             :   emit_optional_rex_32(dst, src);
    3156             :   emit(0x0F);
    3157             :   emit(0xC6);
    3158             :   emit_sse_operand(dst, src);
    3159             :   emit(imm8);
    3160          36 : }
    3161             : 
    3162             : 
    3163         420 : void Assembler::movapd(XMMRegister dst, XMMRegister src) {
    3164             :   DCHECK(!IsEnabled(AVX));
    3165             :   EnsureSpace ensure_space(this);
    3166         420 :   if (src.low_bits() == 4) {
    3167             :     // Try to avoid an unnecessary SIB byte.
    3168             :     emit(0x66);
    3169             :     emit_optional_rex_32(src, dst);
    3170             :     emit(0x0F);
    3171             :     emit(0x29);
    3172             :     emit_sse_operand(src, dst);
    3173             :   } else {
    3174             :     emit(0x66);
    3175             :     emit_optional_rex_32(dst, src);
    3176             :     emit(0x0F);
    3177             :     emit(0x28);
    3178             :     emit_sse_operand(dst, src);
    3179             :   }
    3180         420 : }
    3181             : 
    3182             : 
    3183          36 : void Assembler::movupd(XMMRegister dst, const Operand& src) {
    3184             :   EnsureSpace ensure_space(this);
    3185             :   emit(0x66);
    3186             :   emit_optional_rex_32(dst, src);
    3187             :   emit(0x0F);
    3188             :   emit(0x10);
    3189             :   emit_sse_operand(dst, src);
    3190          18 : }
    3191             : 
    3192          36 : void Assembler::movupd(const Operand& dst, XMMRegister src) {
    3193             :   EnsureSpace ensure_space(this);
    3194             :   emit(0x66);
    3195             :   emit_optional_rex_32(src, dst);
    3196             :   emit(0x0F);
    3197             :   emit(0x11);
    3198             :   emit_sse_operand(src, dst);
    3199          18 : }
    3200             : 
    3201         145 : void Assembler::addss(XMMRegister dst, XMMRegister src) {
    3202             :   EnsureSpace ensure_space(this);
    3203             :   emit(0xF3);
    3204             :   emit_optional_rex_32(dst, src);
    3205             :   emit(0x0F);
    3206             :   emit(0x58);
    3207             :   emit_sse_operand(dst, src);
    3208         145 : }
    3209             : 
    3210             : 
    3211          12 : void Assembler::addss(XMMRegister dst, const Operand& src) {
    3212             :   EnsureSpace ensure_space(this);
    3213             :   emit(0xF3);
    3214             :   emit_optional_rex_32(dst, src);
    3215             :   emit(0x0F);
    3216             :   emit(0x58);
    3217             :   emit_sse_operand(dst, src);
    3218           6 : }
    3219             : 
    3220             : 
    3221          24 : void Assembler::subss(XMMRegister dst, XMMRegister src) {
    3222             :   EnsureSpace ensure_space(this);
    3223             :   emit(0xF3);
    3224             :   emit_optional_rex_32(dst, src);
    3225             :   emit(0x0F);
    3226             :   emit(0x5C);
    3227             :   emit_sse_operand(dst, src);
    3228          24 : }
    3229             : 
    3230             : 
    3231          12 : void Assembler::subss(XMMRegister dst, const Operand& src) {
    3232             :   EnsureSpace ensure_space(this);
    3233             :   emit(0xF3);
    3234             :   emit_optional_rex_32(dst, src);
    3235             :   emit(0x0F);
    3236             :   emit(0x5C);
    3237             :   emit_sse_operand(dst, src);
    3238           6 : }
    3239             : 
    3240             : 
    3241          48 : void Assembler::mulss(XMMRegister dst, XMMRegister src) {
    3242             :   EnsureSpace ensure_space(this);
    3243             :   emit(0xF3);
    3244             :   emit_optional_rex_32(dst, src);
    3245             :   emit(0x0F);
    3246             :   emit(0x59);
    3247             :   emit_sse_operand(dst, src);
    3248          48 : }
    3249             : 
    3250             : 
    3251          12 : void Assembler::mulss(XMMRegister dst, const Operand& src) {
    3252             :   EnsureSpace ensure_space(this);
    3253             :   emit(0xF3);
    3254             :   emit_optional_rex_32(dst, src);
    3255             :   emit(0x0F);
    3256             :   emit(0x59);
    3257             :   emit_sse_operand(dst, src);
    3258           6 : }
    3259             : 
    3260             : 
    3261          12 : void Assembler::divss(XMMRegister dst, XMMRegister src) {
    3262             :   EnsureSpace ensure_space(this);
    3263             :   emit(0xF3);
    3264             :   emit_optional_rex_32(dst, src);
    3265             :   emit(0x0F);
    3266             :   emit(0x5E);
    3267             :   emit_sse_operand(dst, src);
    3268          12 : }
    3269             : 
    3270             : 
    3271          12 : void Assembler::divss(XMMRegister dst, const Operand& src) {
    3272             :   EnsureSpace ensure_space(this);
    3273             :   emit(0xF3);
    3274             :   emit_optional_rex_32(dst, src);
    3275             :   emit(0x0F);
    3276             :   emit(0x5E);
    3277             :   emit_sse_operand(dst, src);
    3278           6 : }
    3279             : 
    3280             : 
    3281          12 : void Assembler::maxss(XMMRegister dst, XMMRegister src) {
    3282             :   EnsureSpace ensure_space(this);
    3283             :   emit(0xF3);
    3284             :   emit_optional_rex_32(dst, src);
    3285             :   emit(0x0F);
    3286             :   emit(0x5F);
    3287             :   emit_sse_operand(dst, src);
    3288          12 : }
    3289             : 
    3290             : 
    3291          12 : void Assembler::maxss(XMMRegister dst, const Operand& src) {
    3292             :   EnsureSpace ensure_space(this);
    3293             :   emit(0xF3);
    3294             :   emit_optional_rex_32(dst, src);
    3295             :   emit(0x0F);
    3296             :   emit(0x5F);
    3297             :   emit_sse_operand(dst, src);
    3298           6 : }
    3299             : 
    3300             : 
    3301          12 : void Assembler::minss(XMMRegister dst, XMMRegister src) {
    3302             :   EnsureSpace ensure_space(this);
    3303             :   emit(0xF3);
    3304             :   emit_optional_rex_32(dst, src);
    3305             :   emit(0x0F);
    3306             :   emit(0x5D);
    3307             :   emit_sse_operand(dst, src);
    3308          12 : }
    3309             : 
    3310             : 
    3311          12 : void Assembler::minss(XMMRegister dst, const Operand& src) {
    3312             :   EnsureSpace ensure_space(this);
    3313             :   emit(0xF3);
    3314             :   emit_optional_rex_32(dst, src);
    3315             :   emit(0x0F);
    3316             :   emit(0x5D);
    3317             :   emit_sse_operand(dst, src);
    3318           6 : }
    3319             : 
    3320             : 
    3321         196 : void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
    3322             :   EnsureSpace ensure_space(this);
    3323             :   emit(0xF3);
    3324             :   emit_optional_rex_32(dst, src);
    3325             :   emit(0x0F);
    3326             :   emit(0x51);
    3327             :   emit_sse_operand(dst, src);
    3328         196 : }
    3329             : 
    3330             : 
    3331           0 : void Assembler::sqrtss(XMMRegister dst, const Operand& src) {
    3332             :   EnsureSpace ensure_space(this);
    3333             :   emit(0xF3);
    3334             :   emit_optional_rex_32(dst, src);
    3335             :   emit(0x0F);
    3336             :   emit(0x51);
    3337             :   emit_sse_operand(dst, src);
    3338           0 : }
    3339             : 
    3340             : 
    3341         186 : void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
    3342             :   DCHECK(!IsEnabled(AVX));
    3343             :   EnsureSpace ensure_space(this);
    3344             :   emit_optional_rex_32(dst, src);
    3345             :   emit(0x0f);
    3346             :   emit(0x2e);
    3347             :   emit_sse_operand(dst, src);
    3348         186 : }
    3349             : 
    3350             : 
    3351          12 : void Assembler::ucomiss(XMMRegister dst, const Operand& src) {
    3352             :   DCHECK(!IsEnabled(AVX));
    3353             :   EnsureSpace ensure_space(this);
    3354             :   emit_optional_rex_32(dst, src);
    3355             :   emit(0x0f);
    3356             :   emit(0x2e);
    3357             :   emit_sse_operand(dst, src);
    3358           6 : }
    3359             : 
    3360             : 
    3361           0 : void Assembler::movss(XMMRegister dst, XMMRegister src) {
    3362             :   DCHECK(!IsEnabled(AVX));
    3363             :   EnsureSpace ensure_space(this);
    3364             :   emit(0xF3);  // single
    3365             :   emit_optional_rex_32(dst, src);
    3366             :   emit(0x0F);
    3367             :   emit(0x10);  // load
    3368             :   emit_sse_operand(dst, src);
    3369           0 : }
    3370             : 
    3371             : 
    3372       22504 : void Assembler::movss(XMMRegister dst, const Operand& src) {
    3373             :   DCHECK(!IsEnabled(AVX));
    3374             :   EnsureSpace ensure_space(this);
    3375             :   emit(0xF3);  // single
    3376             :   emit_optional_rex_32(dst, src);
    3377             :   emit(0x0F);
    3378             :   emit(0x10);  // load
    3379             :   emit_sse_operand(dst, src);
    3380       11253 : }
    3381             : 
    3382             : 
    3383       14810 : void Assembler::movss(const Operand& src, XMMRegister dst) {
    3384             :   DCHECK(!IsEnabled(AVX));
    3385             :   EnsureSpace ensure_space(this);
    3386             :   emit(0xF3);  // single
    3387             :   emit_optional_rex_32(dst, src);
    3388             :   emit(0x0F);
    3389             :   emit(0x11);  // store
    3390             :   emit_sse_operand(dst, src);
    3391        7405 : }
    3392             : 
    3393             : 
    3394         196 : void Assembler::psllq(XMMRegister reg, byte imm8) {
    3395             :   DCHECK(!IsEnabled(AVX));
    3396             :   EnsureSpace ensure_space(this);
    3397             :   emit(0x66);
    3398             :   emit_optional_rex_32(reg);
    3399             :   emit(0x0F);
    3400             :   emit(0x73);
    3401             :   emit_sse_operand(rsi, reg);  // rsi == 6
    3402             :   emit(imm8);
    3403         196 : }
    3404             : 
    3405             : 
    3406          12 : void Assembler::psrlq(XMMRegister reg, byte imm8) {
    3407             :   DCHECK(!IsEnabled(AVX));
    3408             :   EnsureSpace ensure_space(this);
    3409             :   emit(0x66);
    3410             :   emit_optional_rex_32(reg);
    3411             :   emit(0x0F);
    3412             :   emit(0x73);
    3413             :   emit_sse_operand(rdx, reg);  // rdx == 2
    3414             :   emit(imm8);
    3415          12 : }
    3416             : 
    3417           6 : void Assembler::psllw(XMMRegister reg, byte imm8) {
    3418             :   EnsureSpace ensure_space(this);
    3419             :   emit(0x66);
    3420             :   emit_optional_rex_32(reg);
    3421             :   emit(0x0F);
    3422             :   emit(0x71);
    3423             :   emit_sse_operand(rsi, reg);  // rsi == 6
    3424             :   emit(imm8);
    3425           6 : }
    3426             : 
    3427          18 : void Assembler::pslld(XMMRegister reg, byte imm8) {
    3428             :   EnsureSpace ensure_space(this);
    3429             :   emit(0x66);
    3430             :   emit_optional_rex_32(reg);
    3431             :   emit(0x0F);
    3432             :   emit(0x72);
    3433             :   emit_sse_operand(rsi, reg);  // rsi == 6
    3434             :   emit(imm8);
    3435          18 : }
    3436             : 
    3437           6 : void Assembler::psrlw(XMMRegister reg, byte imm8) {
    3438             :   EnsureSpace ensure_space(this);
    3439             :   emit(0x66);
    3440             :   emit_optional_rex_32(reg);
    3441             :   emit(0x0F);
    3442             :   emit(0x71);
    3443             :   emit_sse_operand(rdx, reg);  // rdx == 2
    3444             :   emit(imm8);
    3445           6 : }
    3446             : 
    3447          12 : void Assembler::psrld(XMMRegister reg, byte imm8) {
    3448             :   EnsureSpace ensure_space(this);
    3449             :   emit(0x66);
    3450             :   emit_optional_rex_32(reg);
    3451             :   emit(0x0F);
    3452             :   emit(0x72);
    3453             :   emit_sse_operand(rdx, reg);  // rdx == 2
    3454             :   emit(imm8);
    3455          12 : }
    3456             : 
    3457           6 : void Assembler::psraw(XMMRegister reg, byte imm8) {
    3458             :   EnsureSpace ensure_space(this);
    3459             :   emit(0x66);
    3460             :   emit_optional_rex_32(reg);
    3461             :   emit(0x0F);
    3462             :   emit(0x71);
    3463             :   emit_sse_operand(rsp, reg);  // rsp == 4
    3464             :   emit(imm8);
    3465           6 : }
    3466             : 
    3467           6 : void Assembler::psrad(XMMRegister reg, byte imm8) {
    3468             :   EnsureSpace ensure_space(this);
    3469             :   emit(0x66);
    3470             :   emit_optional_rex_32(reg);
    3471             :   emit(0x0F);
    3472             :   emit(0x72);
    3473             :   emit_sse_operand(rsp, reg);  // rsp == 4
    3474             :   emit(imm8);
    3475           6 : }
    3476             : 
    3477          42 : void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
    3478             :   EnsureSpace ensure_space(this);
    3479             :   emit_optional_rex_32(dst, src);
    3480             :   emit(0x0F);
    3481             :   emit(0xC2);
    3482             :   emit_sse_operand(dst, src);
    3483          42 :   emit(cmp);
    3484          42 : }
    3485             : 
    3486          84 : void Assembler::cmpps(XMMRegister dst, const Operand& src, int8_t cmp) {
    3487             :   EnsureSpace ensure_space(this);
    3488             :   emit_optional_rex_32(dst, src);
    3489             :   emit(0x0F);
    3490             :   emit(0xC2);
    3491             :   emit_sse_operand(dst, src);
    3492          42 :   emit(cmp);
    3493          42 : }
    3494             : 
    3495          42 : void Assembler::cmppd(XMMRegister dst, XMMRegister src, int8_t cmp) {
    3496             :   EnsureSpace ensure_space(this);
    3497             :   emit_optional_rex_32(dst, src);
    3498             :   emit(0x66);
    3499             :   emit(0x0F);
    3500             :   emit(0xC2);
    3501             :   emit_sse_operand(dst, src);
    3502          42 :   emit(cmp);
    3503          42 : }
    3504             : 
    3505          84 : void Assembler::cmppd(XMMRegister dst, const Operand& src, int8_t cmp) {
    3506             :   EnsureSpace ensure_space(this);
    3507             :   emit_optional_rex_32(dst, src);
    3508             :   emit(0x66);
    3509             :   emit(0x0F);
    3510             :   emit(0xC2);
    3511             :   emit_sse_operand(dst, src);
    3512          42 :   emit(cmp);
    3513          42 : }
    3514             : 
    3515          12 : void Assembler::cvttss2si(Register dst, const Operand& src) {
    3516             :   DCHECK(!IsEnabled(AVX));
    3517             :   EnsureSpace ensure_space(this);
    3518             :   emit(0xF3);
    3519             :   emit_optional_rex_32(dst, src);
    3520             :   emit(0x0F);
    3521             :   emit(0x2C);
    3522             :   emit_operand(dst, src);
    3523           6 : }
    3524             : 
    3525             : 
    3526          12 : void Assembler::cvttss2si(Register dst, XMMRegister src) {
    3527             :   DCHECK(!IsEnabled(AVX));
    3528             :   EnsureSpace ensure_space(this);
    3529             :   emit(0xF3);
    3530             :   emit_optional_rex_32(dst, src);
    3531             :   emit(0x0F);
    3532             :   emit(0x2C);
    3533             :   emit_sse_operand(dst, src);
    3534          12 : }
    3535             : 
    3536             : 
    3537          12 : void Assembler::cvttsd2si(Register dst, const Operand& src) {
    3538             :   DCHECK(!IsEnabled(AVX));
    3539             :   EnsureSpace ensure_space(this);
    3540             :   emit(0xF2);
    3541             :   emit_optional_rex_32(dst, src);
    3542             :   emit(0x0F);
    3543             :   emit(0x2C);
    3544             :   emit_operand(dst, src);
    3545           6 : }
    3546             : 
    3547             : 
    3548         218 : void Assembler::cvttsd2si(Register dst, XMMRegister src) {
    3549             :   DCHECK(!IsEnabled(AVX));
    3550             :   EnsureSpace ensure_space(this);
    3551             :   emit(0xF2);
    3552             :   emit_optional_rex_32(dst, src);
    3553             :   emit(0x0F);
    3554             :   emit(0x2C);
    3555             :   emit_sse_operand(dst, src);
    3556         218 : }
    3557             : 
    3558             : 
    3559           0 : void Assembler::cvttss2siq(Register dst, XMMRegister src) {
    3560             :   DCHECK(!IsEnabled(AVX));
    3561             :   EnsureSpace ensure_space(this);
    3562             :   emit(0xF3);
    3563             :   emit_rex_64(dst, src);
    3564             :   emit(0x0F);
    3565             :   emit(0x2C);
    3566             :   emit_sse_operand(dst, src);
    3567           0 : }
    3568             : 
    3569             : 
    3570           0 : void Assembler::cvttss2siq(Register dst, const Operand& src) {
    3571             :   DCHECK(!IsEnabled(AVX));
    3572             :   EnsureSpace ensure_space(this);
    3573             :   emit(0xF3);
    3574             :   emit_rex_64(dst, src);
    3575             :   emit(0x0F);
    3576             :   emit(0x2C);
    3577             :   emit_sse_operand(dst, src);
    3578           0 : }
    3579             : 
    3580             : 
    3581         241 : void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
    3582             :   DCHECK(!IsEnabled(AVX));
    3583             :   EnsureSpace ensure_space(this);
    3584             :   emit(0xF2);
    3585             :   emit_rex_64(dst, src);
    3586             :   emit(0x0F);
    3587             :   emit(0x2C);
    3588             :   emit_sse_operand(dst, src);
    3589         241 : }
    3590             : 
    3591             : 
    3592          12 : void Assembler::cvttsd2siq(Register dst, const Operand& src) {
    3593             :   DCHECK(!IsEnabled(AVX));
    3594             :   EnsureSpace ensure_space(this);
    3595             :   emit(0xF2);
    3596             :   emit_rex_64(dst, src);
    3597             :   emit(0x0F);
    3598             :   emit(0x2C);
    3599             :   emit_sse_operand(dst, src);
    3600           6 : }
    3601             : 
    3602             : 
    3603           0 : void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
    3604             :   DCHECK(!IsEnabled(AVX));
    3605             :   EnsureSpace ensure_space(this);
    3606             :   emit(0xF2);
    3607             :   emit_optional_rex_32(dst, src);
    3608             :   emit(0x0F);
    3609             :   emit(0x2A);
    3610             :   emit_sse_operand(dst, src);
    3611           0 : }
    3612             : 
    3613             : 
    3614         849 : void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
    3615             :   DCHECK(!IsEnabled(AVX));
    3616             :   EnsureSpace ensure_space(this);
    3617             :   emit(0xF2);
    3618             :   emit_optional_rex_32(dst, src);
    3619             :   emit(0x0F);
    3620             :   emit(0x2A);
    3621             :   emit_sse_operand(dst, src);
    3622         849 : }
    3623             : 
    3624             : 
    3625           0 : void Assembler::cvtlsi2ss(XMMRegister dst, const Operand& src) {
    3626             :   DCHECK(!IsEnabled(AVX));
    3627             :   EnsureSpace ensure_space(this);
    3628             :   emit(0xF3);
    3629             :   emit_optional_rex_32(dst, src);
    3630             :   emit(0x0F);
    3631             :   emit(0x2A);
    3632             :   emit_sse_operand(dst, src);
    3633           0 : }
    3634             : 
    3635             : 
    3636           2 : void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
    3637             :   EnsureSpace ensure_space(this);
    3638             :   emit(0xF3);
    3639             :   emit_optional_rex_32(dst, src);
    3640             :   emit(0x0F);
    3641             :   emit(0x2A);
    3642             :   emit_sse_operand(dst, src);
    3643           2 : }
    3644             : 
    3645             : 
    3646           0 : void Assembler::cvtqsi2ss(XMMRegister dst, const Operand& src) {
    3647             :   DCHECK(!IsEnabled(AVX));
    3648             :   EnsureSpace ensure_space(this);
    3649             :   emit(0xF3);
    3650             :   emit_rex_64(dst, src);
    3651             :   emit(0x0F);
    3652             :   emit(0x2A);
    3653             :   emit_sse_operand(dst, src);
    3654           0 : }
    3655             : 
    3656             : 
    3657           0 : void Assembler::cvtqsi2ss(XMMRegister dst, Register src) {
    3658             :   DCHECK(!IsEnabled(AVX));
    3659             :   EnsureSpace ensure_space(this);
    3660             :   emit(0xF3);
    3661             :   emit_rex_64(dst, src);
    3662             :   emit(0x0F);
    3663             :   emit(0x2A);
    3664             :   emit_sse_operand(dst, src);
    3665           0 : }
    3666             : 
    3667             : 
    3668          12 : void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
    3669             :   DCHECK(!IsEnabled(AVX));
    3670             :   EnsureSpace ensure_space(this);
    3671             :   emit(0xF2);
    3672             :   emit_rex_64(dst, src);
    3673             :   emit(0x0F);
    3674             :   emit(0x2A);
    3675             :   emit_sse_operand(dst, src);
    3676           6 : }
    3677             : 
    3678             : 
    3679          88 : void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
    3680             :   DCHECK(!IsEnabled(AVX));
    3681             :   EnsureSpace ensure_space(this);
    3682             :   emit(0xF2);
    3683             :   emit_rex_64(dst, src);
    3684             :   emit(0x0F);
    3685             :   emit(0x2A);
    3686             :   emit_sse_operand(dst, src);
    3687          88 : }
    3688             : 
    3689             : 
    3690          20 : void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
    3691             :   DCHECK(!IsEnabled(AVX));
    3692             :   EnsureSpace ensure_space(this);
    3693             :   emit(0xF3);
    3694             :   emit_optional_rex_32(dst, src);
    3695             :   emit(0x0F);
    3696             :   emit(0x5A);
    3697             :   emit_sse_operand(dst, src);
    3698          20 : }
    3699             : 
    3700             : 
    3701           0 : void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
    3702             :   DCHECK(!IsEnabled(AVX));
    3703             :   EnsureSpace ensure_space(this);
    3704             :   emit(0xF3);
    3705             :   emit_optional_rex_32(dst, src);
    3706             :   emit(0x0F);
    3707             :   emit(0x5A);
    3708             :   emit_sse_operand(dst, src);
    3709           0 : }
    3710             : 
    3711             : 
    3712          10 : void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
    3713             :   DCHECK(!IsEnabled(AVX));
    3714             :   EnsureSpace ensure_space(this);
    3715             :   emit(0xF2);
    3716             :   emit_optional_rex_32(dst, src);
    3717             :   emit(0x0F);
    3718             :   emit(0x5A);
    3719             :   emit_sse_operand(dst, src);
    3720          10 : }
    3721             : 
    3722             : 
    3723          12 : void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
    3724             :   DCHECK(!IsEnabled(AVX));
    3725             :   EnsureSpace ensure_space(this);
    3726             :   emit(0xF2);
    3727             :   emit_optional_rex_32(dst, src);
    3728             :   emit(0x0F);
    3729             :   emit(0x5A);
    3730             :   emit_sse_operand(dst, src);
    3731           6 : }
    3732             : 
    3733             : 
    3734           0 : void Assembler::cvtsd2si(Register dst, XMMRegister src) {
    3735             :   DCHECK(!IsEnabled(AVX));
    3736             :   EnsureSpace ensure_space(this);
    3737             :   emit(0xF2);
    3738             :   emit_optional_rex_32(dst, src);
    3739             :   emit(0x0F);
    3740             :   emit(0x2D);
    3741             :   emit_sse_operand(dst, src);
    3742           0 : }
    3743             : 
    3744             : 
    3745           0 : void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
    3746             :   DCHECK(!IsEnabled(AVX));
    3747             :   EnsureSpace ensure_space(this);
    3748             :   emit(0xF2);
    3749             :   emit_rex_64(dst, src);
    3750             :   emit(0x0F);
    3751             :   emit(0x2D);
    3752             :   emit_sse_operand(dst, src);
    3753           0 : }
    3754             : 
    3755             : 
    3756         720 : void Assembler::addsd(XMMRegister dst, XMMRegister src) {
    3757             :   EnsureSpace ensure_space(this);
    3758             :   emit(0xF2);
    3759             :   emit_optional_rex_32(dst, src);
    3760             :   emit(0x0F);
    3761             :   emit(0x58);
    3762             :   emit_sse_operand(dst, src);
    3763         720 : }
    3764             : 
    3765             : 
    3766          12 : void Assembler::addsd(XMMRegister dst, const Operand& src) {
    3767             :   EnsureSpace ensure_space(this);
    3768             :   emit(0xF2);
    3769             :   emit_optional_rex_32(dst, src);
    3770             :   emit(0x0F);
    3771             :   emit(0x58);
    3772             :   emit_sse_operand(dst, src);
    3773           6 : }
    3774             : 
    3775             : 
    3776          68 : void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
    3777             :   EnsureSpace ensure_space(this);
    3778             :   emit(0xF2);
    3779             :   emit_optional_rex_32(dst, src);
    3780             :   emit(0x0F);
    3781             :   emit(0x59);
    3782             :   emit_sse_operand(dst, src);
    3783          68 : }
    3784             : 
    3785             : 
    3786          12 : void Assembler::mulsd(XMMRegister dst, const Operand& src) {
    3787             :   EnsureSpace ensure_space(this);
    3788             :   emit(0xF2);
    3789             :   emit_optional_rex_32(dst, src);
    3790             :   emit(0x0F);
    3791             :   emit(0x59);
    3792             :   emit_sse_operand(dst, src);
    3793           6 : }
    3794             : 
    3795             : 
    3796         436 : void Assembler::subsd(XMMRegister dst, XMMRegister src) {
    3797             :   EnsureSpace ensure_space(this);
    3798             :   emit(0xF2);
    3799             :   emit_optional_rex_32(dst, src);
    3800             :   emit(0x0F);
    3801             :   emit(0x5C);
    3802             :   emit_sse_operand(dst, src);
    3803         436 : }
    3804             : 
    3805             : 
    3806          12 : void Assembler::subsd(XMMRegister dst, const Operand& src) {
    3807             :   EnsureSpace ensure_space(this);
    3808             :   emit(0xF2);
    3809             :   emit_optional_rex_32(dst, src);
    3810             :   emit(0x0F);
    3811             :   emit(0x5C);
    3812             :   emit_sse_operand(dst, src);
    3813           6 : }
    3814             : 
    3815             : 
    3816          37 : void Assembler::divsd(XMMRegister dst, XMMRegister src) {
    3817             :   EnsureSpace ensure_space(this);
    3818             :   emit(0xF2);
    3819             :   emit_optional_rex_32(dst, src);
    3820             :   emit(0x0F);
    3821             :   emit(0x5E);
    3822             :   emit_sse_operand(dst, src);
    3823          37 : }
    3824             : 
    3825             : 
    3826          12 : void Assembler::divsd(XMMRegister dst, const Operand& src) {
    3827             :   EnsureSpace ensure_space(this);
    3828             :   emit(0xF2);
    3829             :   emit_optional_rex_32(dst, src);
    3830             :   emit(0x0F);
    3831             :   emit(0x5E);
    3832             :   emit_sse_operand(dst, src);
    3833           6 : }
    3834             : 
    3835             : 
    3836           6 : void Assembler::maxsd(XMMRegister dst, XMMRegister src) {
    3837             :   EnsureSpace ensure_space(this);
    3838             :   emit(0xF2);
    3839             :   emit_optional_rex_32(dst, src);
    3840             :   emit(0x0F);
    3841             :   emit(0x5F);
    3842             :   emit_sse_operand(dst, src);
    3843           6 : }
    3844             : 
    3845             : 
    3846          12 : void Assembler::maxsd(XMMRegister dst, const Operand& src) {
    3847             :   EnsureSpace ensure_space(this);
    3848             :   emit(0xF2);
    3849             :   emit_optional_rex_32(dst, src);
    3850             :   emit(0x0F);
    3851             :   emit(0x5F);
    3852             :   emit_sse_operand(dst, src);
    3853           6 : }
    3854             : 
    3855             : 
    3856           6 : void Assembler::minsd(XMMRegister dst, XMMRegister src) {
    3857             :   EnsureSpace ensure_space(this);
    3858             :   emit(0xF2);
    3859             :   emit_optional_rex_32(dst, src);
    3860             :   emit(0x0F);
    3861             :   emit(0x5D);
    3862             :   emit_sse_operand(dst, src);
    3863           6 : }
    3864             : 
    3865             : 
    3866          12 : void Assembler::minsd(XMMRegister dst, const Operand& src) {
    3867             :   EnsureSpace ensure_space(this);
    3868             :   emit(0xF2);
    3869             :   emit_optional_rex_32(dst, src);
    3870             :   emit(0x0F);
    3871             :   emit(0x5D);
    3872             :   emit_sse_operand(dst, src);
    3873           6 : }
    3874             : 
    3875             : 
    3876          12 : void Assembler::andpd(XMMRegister dst, XMMRegister src) {
    3877             :   EnsureSpace ensure_space(this);
    3878             :   emit(0x66);
    3879             :   emit_optional_rex_32(dst, src);
    3880             :   emit(0x0F);
    3881             :   emit(0x54);
    3882             :   emit_sse_operand(dst, src);
    3883          12 : }
    3884             : 
    3885             : 
    3886          12 : void Assembler::andpd(XMMRegister dst, const Operand& src) {
    3887             :   EnsureSpace ensure_space(this);
    3888             :   emit(0x66);
    3889             :   emit_optional_rex_32(dst, src);
    3890             :   emit(0x0F);
    3891             :   emit(0x54);
    3892             :   emit_sse_operand(dst, src);
    3893           6 : }
    3894             : 
    3895             : 
    3896           6 : void Assembler::orpd(XMMRegister dst, XMMRegister src) {
    3897             :   EnsureSpace ensure_space(this);
    3898             :   emit(0x66);
    3899             :   emit_optional_rex_32(dst, src);
    3900             :   emit(0x0F);
    3901             :   emit(0x56);
    3902             :   emit_sse_operand(dst, src);
    3903           6 : }
    3904             : 
    3905             : 
    3906          12 : void Assembler::orpd(XMMRegister dst, const Operand& src) {
    3907             :   EnsureSpace ensure_space(this);
    3908             :   emit(0x66);
    3909             :   emit_optional_rex_32(dst, src);
    3910             :   emit(0x0F);
    3911             :   emit(0x56);
    3912             :   emit_sse_operand(dst, src);
    3913           6 : }
    3914             : 
    3915             : 
    3916        1458 : void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
    3917             :   DCHECK(!IsEnabled(AVX));
    3918             :   EnsureSpace ensure_space(this);
    3919             :   emit(0x66);
    3920             :   emit_optional_rex_32(dst, src);
    3921             :   emit(0x0F);
    3922             :   emit(0x57);
    3923             :   emit_sse_operand(dst, src);
    3924        1458 : }
    3925             : 
    3926             : 
    3927          12 : void Assembler::xorpd(XMMRegister dst, const Operand& src) {
    3928             :   DCHECK(!IsEnabled(AVX));
    3929             :   EnsureSpace ensure_space(this);
    3930             :   emit(0x66);
    3931             :   emit_optional_rex_32(dst, src);
    3932             :   emit(0x0F);
    3933             :   emit(0x57);
    3934             :   emit_sse_operand(dst, src);
    3935           6 : }
    3936             : 
    3937             : 
    3938           2 : void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
    3939             :   DCHECK(!IsEnabled(AVX));
    3940             :   EnsureSpace ensure_space(this);
    3941             :   emit(0xF2);
    3942             :   emit_optional_rex_32(dst, src);
    3943             :   emit(0x0F);
    3944             :   emit(0x51);
    3945             :   emit_sse_operand(dst, src);
    3946           2 : }
    3947             : 
    3948             : 
    3949           0 : void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
    3950             :   DCHECK(!IsEnabled(AVX));
    3951             :   EnsureSpace ensure_space(this);
    3952             :   emit(0xF2);
    3953             :   emit_optional_rex_32(dst, src);
    3954             :   emit(0x0F);
    3955             :   emit(0x51);
    3956             :   emit_sse_operand(dst, src);
    3957           0 : }
    3958             : 
    3959             : 
    3960        1514 : void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
    3961             :   DCHECK(!IsEnabled(AVX));
    3962             :   EnsureSpace ensure_space(this);
    3963             :   emit(0x66);
    3964             :   emit_optional_rex_32(dst, src);
    3965             :   emit(0x0f);
    3966             :   emit(0x2e);
    3967             :   emit_sse_operand(dst, src);
    3968        1514 : }
    3969             : 
    3970             : 
    3971           0 : void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
    3972             :   DCHECK(!IsEnabled(AVX));
    3973             :   EnsureSpace ensure_space(this);
    3974             :   emit(0x66);
    3975             :   emit_optional_rex_32(dst, src);
    3976             :   emit(0x0f);
    3977             :   emit(0x2e);
    3978             :   emit_sse_operand(dst, src);
    3979           0 : }
    3980             : 
    3981             : 
    3982           0 : void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
    3983             :   EnsureSpace ensure_space(this);
    3984             :   emit(0xF2);
    3985             :   emit_optional_rex_32(dst, src);
    3986             :   emit(0x0F);
    3987             :   emit(0xC2);
    3988             :   emit_sse_operand(dst, src);
    3989             :   emit(0x01);  // LT == 1
    3990           0 : }
    3991             : 
    3992             : 
    3993           0 : void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
    3994             :   DCHECK(!IsEnabled(AVX));
    3995             :   DCHECK(IsEnabled(SSE4_1));
    3996             :   EnsureSpace ensure_space(this);
    3997             :   emit(0x66);
    3998             :   emit_optional_rex_32(dst, src);
    3999             :   emit(0x0f);
    4000             :   emit(0x3a);
    4001             :   emit(0x0a);
    4002             :   emit_sse_operand(dst, src);
    4003             :   // Mask precision exception.
    4004           0 :   emit(static_cast<byte>(mode) | 0x8);
    4005           0 : }
    4006             : 
    4007             : 
    4008           0 : void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
    4009             :   DCHECK(!IsEnabled(AVX));
    4010             :   DCHECK(IsEnabled(SSE4_1));
    4011             :   EnsureSpace ensure_space(this);
    4012             :   emit(0x66);
    4013             :   emit_optional_rex_32(dst, src);
    4014             :   emit(0x0f);
    4015             :   emit(0x3a);
    4016             :   emit(0x0b);
    4017             :   emit_sse_operand(dst, src);
    4018             :   // Mask precision exception.
    4019           0 :   emit(static_cast<byte>(mode) | 0x8);
    4020           0 : }
    4021             : 
    4022             : 
    4023           4 : void Assembler::movmskpd(Register dst, XMMRegister src) {
    4024             :   EnsureSpace ensure_space(this);
    4025             :   emit(0x66);
    4026             :   emit_optional_rex_32(dst, src);
    4027             :   emit(0x0f);
    4028             :   emit(0x50);
    4029             :   emit_sse_operand(dst, src);
    4030           4 : }
    4031             : 
    4032             : 
    4033           6 : void Assembler::movmskps(Register dst, XMMRegister src) {
    4034             :   EnsureSpace ensure_space(this);
    4035             :   emit_optional_rex_32(dst, src);
    4036             :   emit(0x0f);
    4037             :   emit(0x50);
    4038             :   emit_sse_operand(dst, src);
    4039           6 : }
    4040             : 
    4041             : 
    4042           6 : void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
    4043             :   EnsureSpace ensure_space(this);
    4044             :   emit(0x66);
    4045             :   emit_optional_rex_32(dst, src);
    4046             :   emit(0x0F);
    4047             :   emit(0x62);
    4048             :   emit_sse_operand(dst, src);
    4049           6 : }
    4050             : 
    4051          12 : void Assembler::punpckldq(XMMRegister dst, const Operand& src) {
    4052             :   EnsureSpace ensure_space(this);
    4053             :   emit(0x66);
    4054             :   emit_optional_rex_32(dst, src);
    4055             :   emit(0x0F);
    4056             :   emit(0x62);
    4057             :   emit_sse_operand(dst, src);
    4058           6 : }
    4059             : 
    4060           6 : void Assembler::punpckhdq(XMMRegister dst, XMMRegister src) {
    4061             :   EnsureSpace ensure_space(this);
    4062             :   emit(0x66);
    4063             :   emit_optional_rex_32(dst, src);
    4064             :   emit(0x0F);
    4065             :   emit(0x6A);
    4066             :   emit_sse_operand(dst, src);
    4067           6 : }
    4068             : 
    4069             : 
    4070             : // AVX instructions
    4071         162 : void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
    4072             :                        XMMRegister src2) {
    4073             :   DCHECK(IsEnabled(FMA3));
    4074             :   EnsureSpace ensure_space(this);
    4075         162 :   emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
    4076             :   emit(op);
    4077             :   emit_sse_operand(dst, src2);
    4078         162 : }
    4079             : 
    4080             : 
    4081         162 : void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
    4082             :                        const Operand& src2) {
    4083             :   DCHECK(IsEnabled(FMA3));
    4084             :   EnsureSpace ensure_space(this);
    4085         162 :   emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
    4086             :   emit(op);
    4087             :   emit_sse_operand(dst, src2);
    4088         162 : }
    4089             : 
    4090             : 
    4091         144 : void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
    4092             :                        XMMRegister src2) {
    4093             :   DCHECK(IsEnabled(FMA3));
    4094             :   EnsureSpace ensure_space(this);
    4095         144 :   emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
    4096             :   emit(op);
    4097             :   emit_sse_operand(dst, src2);
    4098         144 : }
    4099             : 
    4100             : 
    4101         144 : void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
    4102             :                        const Operand& src2) {
    4103             :   DCHECK(IsEnabled(FMA3));
    4104             :   EnsureSpace ensure_space(this);
    4105         144 :   emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
    4106             :   emit(op);
    4107             :   emit_sse_operand(dst, src2);
    4108         144 : }
    4109             : 
    4110             : 
    4111         242 : void Assembler::vmovd(XMMRegister dst, Register src) {
    4112             :   DCHECK(IsEnabled(AVX));
    4113             :   EnsureSpace ensure_space(this);
    4114         242 :   XMMRegister isrc = XMMRegister::from_code(src.code());
    4115         242 :   emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW0);
    4116             :   emit(0x6e);
    4117             :   emit_sse_operand(dst, src);
    4118         242 : }
    4119             : 
    4120             : 
    4121           6 : void Assembler::vmovd(XMMRegister dst, const Operand& src) {
    4122             :   DCHECK(IsEnabled(AVX));
    4123             :   EnsureSpace ensure_space(this);
    4124           6 :   emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW0);
    4125             :   emit(0x6e);
    4126             :   emit_sse_operand(dst, src);
    4127           6 : }
    4128             : 
    4129             : 
    4130       63041 : void Assembler::vmovd(Register dst, XMMRegister src) {
    4131             :   DCHECK(IsEnabled(AVX));
    4132             :   EnsureSpace ensure_space(this);
    4133       63041 :   XMMRegister idst = XMMRegister::from_code(dst.code());
    4134       63041 :   emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW0);
    4135             :   emit(0x7e);
    4136             :   emit_sse_operand(src, dst);
    4137       63041 : }
    4138             : 
    4139             : 
    4140      439821 : void Assembler::vmovq(XMMRegister dst, Register src) {
    4141             :   DCHECK(IsEnabled(AVX));
    4142             :   EnsureSpace ensure_space(this);
    4143      439821 :   XMMRegister isrc = XMMRegister::from_code(src.code());
    4144      439821 :   emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW1);
    4145             :   emit(0x6e);
    4146             :   emit_sse_operand(dst, src);
    4147      439827 : }
    4148             : 
    4149             : 
    4150          12 : void Assembler::vmovq(XMMRegister dst, const Operand& src) {
    4151             :   DCHECK(IsEnabled(AVX));
    4152             :   EnsureSpace ensure_space(this);
    4153          12 :   emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW1);
    4154             :   emit(0x6e);
    4155             :   emit_sse_operand(dst, src);
    4156          12 : }
    4157             : 
    4158             : 
    4159       62432 : void Assembler::vmovq(Register dst, XMMRegister src) {
    4160             :   DCHECK(IsEnabled(AVX));
    4161             :   EnsureSpace ensure_space(this);
    4162       62432 :   XMMRegister idst = XMMRegister::from_code(dst.code());
    4163       62432 :   emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW1);
    4164             :   emit(0x7e);
    4165             :   emit_sse_operand(src, dst);
    4166       62432 : }
    4167             : 
    4168      819337 : void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1,
    4169             :                        XMMRegister src2, SIMDPrefix pp, LeadingOpcode m,
    4170             :                        VexW w) {
    4171             :   DCHECK(IsEnabled(AVX));
    4172             :   EnsureSpace ensure_space(this);
    4173      819337 :   emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w);
    4174             :   emit(op);
    4175             :   emit_sse_operand(dst, src2);
    4176      819355 : }
    4177             : 
    4178     2388985 : void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1,
    4179             :                        const Operand& src2, SIMDPrefix pp, LeadingOpcode m,
    4180             :                        VexW w) {
    4181             :   DCHECK(IsEnabled(AVX));
    4182             :   EnsureSpace ensure_space(this);
    4183     2388985 :   emit_vex_prefix(dst, src1, src2, kLIG, pp, m, w);
    4184             :   emit(op);
    4185             :   emit_sse_operand(dst, src2);
    4186     2389005 : }
    4187             : 
    4188             : 
    4189        9562 : void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
    4190             :                     XMMRegister src2) {
    4191             :   DCHECK(IsEnabled(AVX));
    4192             :   EnsureSpace ensure_space(this);
    4193        9562 :   emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
    4194             :   emit(op);
    4195             :   emit_sse_operand(dst, src2);
    4196        9568 : }
    4197             : 
    4198             : 
    4199         126 : void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1,
    4200             :                     const Operand& src2) {
    4201             :   DCHECK(IsEnabled(AVX));
    4202             :   EnsureSpace ensure_space(this);
    4203         126 :   emit_vex_prefix(dst, src1, src2, kL128, kNone, k0F, kWIG);
    4204             :   emit(op);
    4205             :   emit_sse_operand(dst, src2);
    4206         126 : }
    4207             : 
    4208             : 
    4209      573501 : void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
    4210             :                     XMMRegister src2) {
    4211             :   DCHECK(IsEnabled(AVX));
    4212             :   EnsureSpace ensure_space(this);
    4213      573501 :   emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
    4214             :   emit(op);
    4215             :   emit_sse_operand(dst, src2);
    4216      573517 : }
    4217             : 
    4218             : 
    4219         168 : void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1,
    4220             :                     const Operand& src2) {
    4221             :   DCHECK(IsEnabled(AVX));
    4222             :   EnsureSpace ensure_space(this);
    4223         168 :   emit_vex_prefix(dst, src1, src2, kL128, k66, k0F, kWIG);
    4224             :   emit(op);
    4225             :   emit_sse_operand(dst, src2);
    4226         168 : }
    4227             : 
    4228             : 
    4229        2151 : void Assembler::vucomiss(XMMRegister dst, XMMRegister src) {
    4230             :   DCHECK(IsEnabled(AVX));
    4231             :   EnsureSpace ensure_space(this);
    4232        2151 :   emit_vex_prefix(dst, xmm0, src, kLIG, kNone, k0F, kWIG);
    4233             :   emit(0x2e);
    4234             :   emit_sse_operand(dst, src);
    4235        2157 : }
    4236             : 
    4237             : 
    4238          76 : void Assembler::vucomiss(XMMRegister dst, const Operand& src) {
    4239             :   DCHECK(IsEnabled(AVX));
    4240             :   EnsureSpace ensure_space(this);
    4241          76 :   emit_vex_prefix(dst, xmm0, src, kLIG, kNone, k0F, kWIG);
    4242             :   emit(0x2e);
    4243             :   emit_sse_operand(dst, src);
    4244          76 : }
    4245             : 
    4246             : 
    4247       11249 : void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1,
    4248             :                     XMMRegister src2) {
    4249             :   DCHECK(IsEnabled(AVX));
    4250             :   EnsureSpace ensure_space(this);
    4251       11249 :   emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
    4252             :   emit(op);
    4253             :   emit_sse_operand(dst, src2);
    4254       11250 : }
    4255             : 
    4256             : 
    4257      588941 : void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1,
    4258             :                     const Operand& src2) {
    4259             :   DCHECK(IsEnabled(AVX));
    4260             :   EnsureSpace ensure_space(this);
    4261      588941 :   emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
    4262             :   emit(op);
    4263             :   emit_sse_operand(dst, src2);
    4264      588941 : }
    4265             : 
    4266             : 
    4267          60 : void Assembler::bmi1q(byte op, Register reg, Register vreg, Register rm) {
    4268             :   DCHECK(IsEnabled(BMI1));
    4269             :   EnsureSpace ensure_space(this);
    4270             :   emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1);
    4271             :   emit(op);
    4272             :   emit_modrm(reg, rm);
    4273          60 : }
    4274             : 
    4275             : 
    4276          60 : void Assembler::bmi1q(byte op, Register reg, Register vreg, const Operand& rm) {
    4277             :   DCHECK(IsEnabled(BMI1));
    4278             :   EnsureSpace ensure_space(this);
    4279             :   emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW1);
    4280             :   emit(op);
    4281             :   emit_operand(reg, rm);
    4282          60 : }
    4283             : 
    4284             : 
    4285          60 : void Assembler::bmi1l(byte op, Register reg, Register vreg, Register rm) {
    4286             :   DCHECK(IsEnabled(BMI1));
    4287             :   EnsureSpace ensure_space(this);
    4288             :   emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0);
    4289             :   emit(op);
    4290             :   emit_modrm(reg, rm);
    4291          60 : }
    4292             : 
    4293             : 
    4294          60 : void Assembler::bmi1l(byte op, Register reg, Register vreg, const Operand& rm) {
    4295             :   DCHECK(IsEnabled(BMI1));
    4296             :   EnsureSpace ensure_space(this);
    4297             :   emit_vex_prefix(reg, vreg, rm, kLZ, kNone, k0F38, kW0);
    4298             :   emit(op);
    4299             :   emit_operand(reg, rm);
    4300          60 : }
    4301             : 
    4302             : 
    4303          39 : void Assembler::tzcntq(Register dst, Register src) {
    4304             :   DCHECK(IsEnabled(BMI1));
    4305             :   EnsureSpace ensure_space(this);
    4306             :   emit(0xF3);
    4307             :   emit_rex_64(dst, src);
    4308             :   emit(0x0F);
    4309             :   emit(0xBC);
    4310             :   emit_modrm(dst, src);
    4311          39 : }
    4312             : 
    4313             : 
    4314          24 : void Assembler::tzcntq(Register dst, const Operand& src) {
    4315             :   DCHECK(IsEnabled(BMI1));
    4316             :   EnsureSpace ensure_space(this);
    4317             :   emit(0xF3);
    4318             :   emit_rex_64(dst, src);
    4319             :   emit(0x0F);
    4320             :   emit(0xBC);
    4321             :   emit_operand(dst, src);
    4322          12 : }
    4323             : 
    4324             : 
    4325         869 : void Assembler::tzcntl(Register dst, Register src) {
    4326             :   DCHECK(IsEnabled(BMI1));
    4327             :   EnsureSpace ensure_space(this);
    4328             :   emit(0xF3);
    4329             :   emit_optional_rex_32(dst, src);
    4330             :   emit(0x0F);
    4331             :   emit(0xBC);
    4332             :   emit_modrm(dst, src);
    4333         869 : }
    4334             : 
    4335             : 
    4336          24 : void Assembler::tzcntl(Register dst, const Operand& src) {
    4337             :   DCHECK(IsEnabled(BMI1));
    4338             :   EnsureSpace ensure_space(this);
    4339             :   emit(0xF3);
    4340             :   emit_optional_rex_32(dst, src);
    4341             :   emit(0x0F);
    4342             :   emit(0xBC);
    4343             :   emit_operand(dst, src);
    4344          12 : }
    4345             : 
    4346             : 
    4347          49 : void Assembler::lzcntq(Register dst, Register src) {
    4348             :   DCHECK(IsEnabled(LZCNT));
    4349             :   EnsureSpace ensure_space(this);
    4350             :   emit(0xF3);
    4351             :   emit_rex_64(dst, src);
    4352             :   emit(0x0F);
    4353             :   emit(0xBD);
    4354             :   emit_modrm(dst, src);
    4355          49 : }
    4356             : 
    4357             : 
    4358          24 : void Assembler::lzcntq(Register dst, const Operand& src) {
    4359             :   DCHECK(IsEnabled(LZCNT));
    4360             :   EnsureSpace ensure_space(this);
    4361             :   emit(0xF3);
    4362             :   emit_rex_64(dst, src);
    4363             :   emit(0x0F);
    4364             :   emit(0xBD);
    4365             :   emit_operand(dst, src);
    4366          12 : }
    4367             : 
    4368             : 
    4369        1705 : void Assembler::lzcntl(Register dst, Register src) {
    4370             :   DCHECK(IsEnabled(LZCNT));
    4371             :   EnsureSpace ensure_space(this);
    4372             :   emit(0xF3);
    4373             :   emit_optional_rex_32(dst, src);
    4374             :   emit(0x0F);
    4375             :   emit(0xBD);
    4376             :   emit_modrm(dst, src);
    4377        1705 : }
    4378             : 
    4379             : 
    4380         344 : void Assembler::lzcntl(Register dst, const Operand& src) {
    4381             :   DCHECK(IsEnabled(LZCNT));
    4382             :   EnsureSpace ensure_space(this);
    4383             :   emit(0xF3);
    4384             :   emit_optional_rex_32(dst, src);
    4385             :   emit(0x0F);
    4386             :   emit(0xBD);
    4387             :   emit_operand(dst, src);
    4388         172 : }
    4389             : 
    4390             : 
    4391          61 : void Assembler::popcntq(Register dst, Register src) {
    4392             :   DCHECK(IsEnabled(POPCNT));
    4393             :   EnsureSpace ensure_space(this);
    4394             :   emit(0xF3);
    4395             :   emit_rex_64(dst, src);
    4396             :   emit(0x0F);
    4397             :   emit(0xB8);
    4398             :   emit_modrm(dst, src);
    4399          61 : }
    4400             : 
    4401             : 
    4402          24 : void Assembler::popcntq(Register dst, const Operand& src) {
    4403             :   DCHECK(IsEnabled(POPCNT));
    4404             :   EnsureSpace ensure_space(this);
    4405             :   emit(0xF3);
    4406             :   emit_rex_64(dst, src);
    4407             :   emit(0x0F);
    4408             :   emit(0xB8);
    4409             :   emit_operand(dst, src);
    4410          12 : }
    4411             : 
    4412             : 
    4413         169 : void Assembler::popcntl(Register dst, Register src) {
    4414             :   DCHECK(IsEnabled(POPCNT));
    4415             :   EnsureSpace ensure_space(this);
    4416             :   emit(0xF3);
    4417             :   emit_optional_rex_32(dst, src);
    4418             :   emit(0x0F);
    4419             :   emit(0xB8);
    4420             :   emit_modrm(dst, src);
    4421         169 : }
    4422             : 
    4423             : 
    4424          24 : void Assembler::popcntl(Register dst, const Operand& src) {
    4425             :   DCHECK(IsEnabled(POPCNT));
    4426             :   EnsureSpace ensure_space(this);
    4427             :   emit(0xF3);
    4428             :   emit_optional_rex_32(dst, src);
    4429             :   emit(0x0F);
    4430             :   emit(0xB8);
    4431             :   emit_operand(dst, src);
    4432          12 : }
    4433             : 
    4434             : 
    4435          84 : void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
    4436             :                       Register rm) {
    4437             :   DCHECK(IsEnabled(BMI2));
    4438             :   EnsureSpace ensure_space(this);
    4439             :   emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1);
    4440             :   emit(op);
    4441             :   emit_modrm(reg, rm);
    4442          84 : }
    4443             : 
    4444             : 
    4445          84 : void Assembler::bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
    4446             :                       const Operand& rm) {
    4447             :   DCHECK(IsEnabled(BMI2));
    4448             :   EnsureSpace ensure_space(this);
    4449             :   emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW1);
    4450             :   emit(op);
    4451             :   emit_operand(reg, rm);
    4452          84 : }
    4453             : 
    4454             : 
    4455          84 : void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
    4456             :                       Register rm) {
    4457             :   DCHECK(IsEnabled(BMI2));
    4458             :   EnsureSpace ensure_space(this);
    4459             :   emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0);
    4460             :   emit(op);
    4461             :   emit_modrm(reg, rm);
    4462          84 : }
    4463             : 
    4464             : 
    4465          84 : void Assembler::bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
    4466             :                       const Operand& rm) {
    4467             :   DCHECK(IsEnabled(BMI2));
    4468             :   EnsureSpace ensure_space(this);
    4469             :   emit_vex_prefix(reg, vreg, rm, kLZ, pp, k0F38, kW0);
    4470             :   emit(op);
    4471             :   emit_operand(reg, rm);
    4472          84 : }
    4473             : 
    4474             : 
    4475          12 : void Assembler::rorxq(Register dst, Register src, byte imm8) {
    4476             :   DCHECK(IsEnabled(BMI2));
    4477             :   DCHECK(is_uint8(imm8));
    4478             :   Register vreg = Register::from_code<0>();  // VEX.vvvv unused
    4479             :   EnsureSpace ensure_space(this);
    4480             :   emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
    4481             :   emit(0xF0);
    4482             :   emit_modrm(dst, src);
    4483             :   emit(imm8);
    4484          12 : }
    4485             : 
    4486             : 
    4487          12 : void Assembler::rorxq(Register dst, const Operand& src, byte imm8) {
    4488             :   DCHECK(IsEnabled(BMI2));
    4489             :   DCHECK(is_uint8(imm8));
    4490             :   Register vreg = Register::from_code<0>();  // VEX.vvvv unused
    4491             :   EnsureSpace ensure_space(this);
    4492             :   emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
    4493             :   emit(0xF0);
    4494             :   emit_operand(dst, src);
    4495             :   emit(imm8);
    4496          12 : }
    4497             : 
    4498             : 
    4499          12 : void Assembler::rorxl(Register dst, Register src, byte imm8) {
    4500             :   DCHECK(IsEnabled(BMI2));
    4501             :   DCHECK(is_uint8(imm8));
    4502             :   Register vreg = Register::from_code<0>();  // VEX.vvvv unused
    4503             :   EnsureSpace ensure_space(this);
    4504             :   emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
    4505             :   emit(0xF0);
    4506             :   emit_modrm(dst, src);
    4507             :   emit(imm8);
    4508          12 : }
    4509             : 
    4510             : 
    4511          12 : void Assembler::rorxl(Register dst, const Operand& src, byte imm8) {
    4512             :   DCHECK(IsEnabled(BMI2));
    4513             :   DCHECK(is_uint8(imm8));
    4514             :   Register vreg = Register::from_code<0>();  // VEX.vvvv unused
    4515             :   EnsureSpace ensure_space(this);
    4516             :   emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
    4517             :   emit(0xF0);
    4518             :   emit_operand(dst, src);
    4519             :   emit(imm8);
    4520          12 : }
    4521             : 
    4522           6 : void Assembler::minps(XMMRegister dst, XMMRegister src) {
    4523             :   EnsureSpace ensure_space(this);
    4524             :   emit_optional_rex_32(dst, src);
    4525             :   emit(0x0F);
    4526             :   emit(0x5D);
    4527             :   emit_sse_operand(dst, src);
    4528           6 : }
    4529             : 
    4530          12 : void Assembler::minps(XMMRegister dst, const Operand& src) {
    4531             :   EnsureSpace ensure_space(this);
    4532             :   emit_optional_rex_32(dst, src);
    4533             :   emit(0x0F);
    4534             :   emit(0x5D);
    4535             :   emit_sse_operand(dst, src);
    4536           6 : }
    4537             : 
    4538           6 : void Assembler::maxps(XMMRegister dst, XMMRegister src) {
    4539             :   EnsureSpace ensure_space(this);
    4540             :   emit_optional_rex_32(dst, src);
    4541             :   emit(0x0F);
    4542             :   emit(0x5F);
    4543             :   emit_sse_operand(dst, src);
    4544           6 : }
    4545             : 
    4546          12 : void Assembler::maxps(XMMRegister dst, const Operand& src) {
    4547             :   EnsureSpace ensure_space(this);
    4548             :   emit_optional_rex_32(dst, src);
    4549             :   emit(0x0F);
    4550             :   emit(0x5F);
    4551             :   emit_sse_operand(dst, src);
    4552           6 : }
    4553             : 
    4554           6 : void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
    4555             :   EnsureSpace ensure_space(this);
    4556             :   emit_optional_rex_32(dst, src);
    4557             :   emit(0x0F);
    4558             :   emit(0x53);
    4559             :   emit_sse_operand(dst, src);
    4560           6 : }
    4561             : 
    4562          12 : void Assembler::rcpps(XMMRegister dst, const Operand& src) {
    4563             :   EnsureSpace ensure_space(this);
    4564             :   emit_optional_rex_32(dst, src);
    4565             :   emit(0x0F);
    4566             :   emit(0x53);
    4567             :   emit_sse_operand(dst, src);
    4568           6 : }
    4569             : 
    4570           0 : void Assembler::rsqrtps(XMMRegister dst, XMMRegister src) {
    4571             :   EnsureSpace ensure_space(this);
    4572             :   emit_optional_rex_32(dst, src);
    4573             :   emit(0x0F);
    4574             :   emit(0x52);
    4575             :   emit_sse_operand(dst, src);
    4576           0 : }
    4577             : 
    4578           0 : void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
    4579             :   EnsureSpace ensure_space(this);
    4580             :   emit_optional_rex_32(dst, src);
    4581             :   emit(0x0F);
    4582             :   emit(0x52);
    4583             :   emit_sse_operand(dst, src);
    4584           0 : }
    4585             : 
    4586           6 : void Assembler::sqrtps(XMMRegister dst, XMMRegister src) {
    4587             :   EnsureSpace ensure_space(this);
    4588             :   emit_optional_rex_32(dst, src);
    4589             :   emit(0x0F);
    4590             :   emit(0x51);
    4591             :   emit_sse_operand(dst, src);
    4592           6 : }
    4593             : 
    4594          12 : void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
    4595             :   EnsureSpace ensure_space(this);
    4596             :   emit_optional_rex_32(dst, src);
    4597             :   emit(0x0F);
    4598             :   emit(0x51);
    4599             :   emit_sse_operand(dst, src);
    4600           6 : }
    4601             : 
    4602           6 : void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
    4603             :   EnsureSpace ensure_space(this);
    4604             :   emit_optional_rex_32(dst, src);
    4605             :   emit(0x0F);
    4606             :   emit(0x5B);
    4607             :   emit_sse_operand(dst, src);
    4608           6 : }
    4609             : 
    4610          12 : void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
    4611             :   EnsureSpace ensure_space(this);
    4612             :   emit_optional_rex_32(dst, src);
    4613             :   emit(0x0F);
    4614             :   emit(0x5B);
    4615             :   emit_sse_operand(dst, src);
    4616           6 : }
    4617             : 
    4618           6 : void Assembler::movups(XMMRegister dst, XMMRegister src) {
    4619             :   EnsureSpace ensure_space(this);
    4620           6 :   if (src.low_bits() == 4) {
    4621             :     // Try to avoid an unnecessary SIB byte.
    4622             :     emit_optional_rex_32(src, dst);
    4623             :     emit(0x0F);
    4624             :     emit(0x11);
    4625             :     emit_sse_operand(src, dst);
    4626             :   } else {
    4627             :     emit_optional_rex_32(dst, src);
    4628             :     emit(0x0F);
    4629             :     emit(0x10);
    4630             :     emit_sse_operand(dst, src);
    4631             :   }
    4632           6 : }
    4633             : 
    4634          12 : void Assembler::movups(XMMRegister dst, const Operand& src) {
    4635             :   EnsureSpace ensure_space(this);
    4636             :   emit_optional_rex_32(dst, src);
    4637             :   emit(0x0F);
    4638             :   emit(0x10);
    4639             :   emit_sse_operand(dst, src);
    4640           6 : }
    4641             : 
    4642          12 : void Assembler::movups(const Operand& dst, XMMRegister src) {
    4643             :   EnsureSpace ensure_space(this);
    4644             :   emit_optional_rex_32(src, dst);
    4645             :   emit(0x0F);
    4646             :   emit(0x11);
    4647             :   emit_sse_operand(src, dst);
    4648           6 : }
    4649             : 
    4650         988 : void Assembler::sse2_instr(XMMRegister dst, XMMRegister src, byte prefix,
    4651             :                            byte escape, byte opcode) {
    4652             :   EnsureSpace ensure_space(this);
    4653             :   emit(prefix);
    4654             :   emit_optional_rex_32(dst, src);
    4655             :   emit(escape);
    4656             :   emit(opcode);
    4657             :   emit_sse_operand(dst, src);
    4658         988 : }
    4659             : 
    4660         504 : void Assembler::sse2_instr(XMMRegister dst, const Operand& src, byte prefix,
    4661             :                            byte escape, byte opcode) {
    4662             :   EnsureSpace ensure_space(this);
    4663             :   emit(prefix);
    4664             :   emit_optional_rex_32(dst, src);
    4665             :   emit(escape);
    4666             :   emit(opcode);
    4667             :   emit_sse_operand(dst, src);
    4668         252 : }
    4669             : 
    4670         378 : void Assembler::ssse3_instr(XMMRegister dst, XMMRegister src, byte prefix,
    4671             :                             byte escape1, byte escape2, byte opcode) {
    4672             :   DCHECK(IsEnabled(SSSE3));
    4673             :   EnsureSpace ensure_space(this);
    4674             :   emit(prefix);
    4675             :   emit_optional_rex_32(dst, src);
    4676             :   emit(escape1);
    4677             :   emit(escape2);
    4678             :   emit(opcode);
    4679             :   emit_sse_operand(dst, src);
    4680         378 : }
    4681             : 
    4682         108 : void Assembler::ssse3_instr(XMMRegister dst, const Operand& src, byte prefix,
    4683             :                             byte escape1, byte escape2, byte opcode) {
    4684             :   DCHECK(IsEnabled(SSSE3));
    4685             :   EnsureSpace ensure_space(this);
    4686             :   emit(prefix);
    4687             :   emit_optional_rex_32(dst, src);
    4688             :   emit(escape1);
    4689             :   emit(escape2);
    4690             :   emit(opcode);
    4691             :   emit_sse_operand(dst, src);
    4692          54 : }
    4693             : 
    4694         210 : void Assembler::sse4_instr(XMMRegister dst, XMMRegister src, byte prefix,
    4695             :                            byte escape1, byte escape2, byte opcode) {
    4696             :   DCHECK(IsEnabled(SSE4_1));
    4697             :   EnsureSpace ensure_space(this);
    4698             :   emit(prefix);
    4699             :   emit_optional_rex_32(dst, src);
    4700             :   emit(escape1);
    4701             :   emit(escape2);
    4702             :   emit(opcode);
    4703             :   emit_sse_operand(dst, src);
    4704         210 : }
    4705             : 
    4706         144 : void Assembler::sse4_instr(XMMRegister dst, const Operand& src, byte prefix,
    4707             :                            byte escape1, byte escape2, byte opcode) {
    4708             :   DCHECK(IsEnabled(SSE4_1));
    4709             :   EnsureSpace ensure_space(this);
    4710             :   emit(prefix);
    4711             :   emit_optional_rex_32(dst, src);
    4712             :   emit(escape1);
    4713             :   emit(escape2);
    4714             :   emit(opcode);
    4715             :   emit_sse_operand(dst, src);
    4716          72 : }
    4717             : 
    4718          12 : void Assembler::lddqu(XMMRegister dst, const Operand& src) {
    4719             :   DCHECK(IsEnabled(SSE3));
    4720             :   EnsureSpace ensure_space(this);
    4721             :   emit(0xF2);
    4722             :   emit_optional_rex_32(dst, src);
    4723             :   emit(0x0F);
    4724             :   emit(0xF0);
    4725             :   emit_sse_operand(dst, src);
    4726           6 : }
    4727             : 
    4728           6 : void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
    4729             :   EnsureSpace ensure_space(this);
    4730             :   emit(0x66);
    4731             :   emit_optional_rex_32(dst);
    4732             :   emit(0x0F);
    4733             :   emit(0x73);
    4734             :   emit_sse_operand(dst);
    4735             :   emit(shift);
    4736           6 : }
    4737             : 
    4738         330 : void Assembler::pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
    4739             :   EnsureSpace ensure_space(this);
    4740             :   emit(0xF3);
    4741             :   emit_optional_rex_32(dst, src);
    4742             :   emit(0x0F);
    4743             :   emit(0x70);
    4744             :   emit_sse_operand(dst, src);
    4745             :   emit(shuffle);
    4746         330 : }
    4747             : 
    4748         330 : void Assembler::pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
    4749             :   EnsureSpace ensure_space(this);
    4750             :   emit(0xF2);
    4751             :   emit_optional_rex_32(dst, src);
    4752             :   emit(0x0F);
    4753             :   emit(0x70);
    4754             :   emit_sse_operand(dst, src);
    4755             :   emit(shuffle);
    4756         330 : }
    4757             : 
    4758         684 : void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
    4759             :   EnsureSpace ensure_space(this);
    4760             :   emit(0x66);
    4761             :   emit_optional_rex_32(dst, src);
    4762             :   emit(0x0F);
    4763             :   emit(0x70);
    4764             :   emit_sse_operand(dst, src);
    4765             :   emit(shuffle);
    4766         684 : }
    4767             : 
    4768           0 : void Assembler::pshufd(XMMRegister dst, const Operand& src, uint8_t shuffle) {
    4769             :   EnsureSpace ensure_space(this);
    4770             :   emit(0x66);
    4771             :   emit_optional_rex_32(dst, src);
    4772             :   emit(0x0F);
    4773             :   emit(0x70);
    4774             :   emit_sse_operand(dst, src);
    4775             :   emit(shuffle);
    4776           0 : }
    4777             : 
    4778           0 : void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
    4779             :   Register ireg = Register::from_code(reg.code());
    4780             :   emit_operand(ireg, adr);
    4781           0 : }
    4782             : 
    4783             : 
    4784           0 : void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
    4785             :   emit_operand(reg, adr);
    4786           0 : }
    4787             : 
    4788             : 
    4789           0 : void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
    4790     2850198 :   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
    4791           0 : }
    4792             : 
    4793             : 
    4794           0 : void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
    4795     1208236 :   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
    4796           0 : }
    4797             : 
    4798             : 
    4799           0 : void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
    4800        1224 :   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
    4801           0 : }
    4802             : 
    4803           0 : void Assembler::emit_sse_operand(XMMRegister dst) {
    4804           6 :   emit(0xD8 | dst.low_bits());
    4805           0 : }
    4806             : 
    4807       10574 : void Assembler::RecordProtectedInstructionLanding(int pc_offset) {
    4808             :   EnsureSpace ensure_space(this);
    4809             :   RelocInfo rinfo(pc(), RelocInfo::WASM_PROTECTED_INSTRUCTION_LANDING,
    4810        5287 :                   pc_offset, nullptr);
    4811        5287 :   reloc_info_writer.Write(&rinfo);
    4812        5292 : }
    4813             : 
    4814             : 
    4815    14717245 : void Assembler::db(uint8_t data) {
    4816             :   EnsureSpace ensure_space(this);
    4817             :   emit(data);
    4818    14717245 : }
    4819             : 
    4820             : 
    4821    15337317 : void Assembler::dd(uint32_t data) {
    4822             :   EnsureSpace ensure_space(this);
    4823             :   emitl(data);
    4824    15337317 : }
    4825             : 
    4826             : 
    4827           0 : void Assembler::dq(uint64_t data) {
    4828             :   EnsureSpace ensure_space(this);
    4829             :   emitq(data);
    4830           0 : }
    4831             : 
    4832             : 
    4833      975792 : void Assembler::dq(Label* label) {
    4834             :   EnsureSpace ensure_space(this);
    4835      325264 :   if (label->is_bound()) {
    4836      969648 :     internal_reference_positions_.push_back(pc_offset());
    4837      644384 :     emitp(buffer_ + label->pos(), RelocInfo::INTERNAL_REFERENCE);
    4838             :   } else {
    4839        3072 :     RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
    4840             :     emitl(0);  // Zero for the first 32bit marks it as 64bit absolute address.
    4841        3072 :     if (label->is_linked()) {
    4842           0 :       emitl(label->pos());
    4843           0 :       label->link_to(pc_offset() - sizeof(int32_t));
    4844             :     } else {
    4845             :       DCHECK(label->is_unused());
    4846             :       int32_t current = pc_offset();
    4847        3072 :       emitl(current);
    4848             :       label->link_to(current);
    4849             :     }
    4850             :   }
    4851      325264 : }
    4852             : 
    4853             : 
    4854             : // Relocation information implementations.
    4855             : 
    4856    18808601 : void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
    4857             :   DCHECK(!RelocInfo::IsNone(rmode));
    4858             :   // Don't record external references unless the heap will be serialized.
    4859    22040505 :   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
    4860    21413787 :       !serializer_enabled() && !emit_debug_code()) {
    4861     2604913 :     return;
    4862             :   }
    4863    16203688 :   RelocInfo rinfo(pc_, rmode, data, nullptr);
    4864    16203688 :   reloc_info_writer.Write(&rinfo);
    4865             : }
    4866             : 
    4867             : const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
    4868             :                                   1 << RelocInfo::RUNTIME_ENTRY |
    4869             :                                   1 << RelocInfo::INTERNAL_REFERENCE;
    4870             : 
    4871     2581542 : bool RelocInfo::IsCodedSpecially() {
    4872             :   // The deserializer needs to know whether a pointer is specially coded.  Being
    4873             :   // specially coded on x64 means that it is a relative 32 bit address, as used
    4874             :   // by branch instructions.
    4875     2581542 :   return (1 << rmode_) & kApplyMask;
    4876             : }
    4877             : 
    4878             : 
    4879      396097 : bool RelocInfo::IsInConstantPool() {
    4880      396097 :   return false;
    4881             : }
    4882             : 
    4883             : 
    4884             : }  // namespace internal
    4885             : }  // namespace v8
    4886             : 
    4887             : #endif  // V8_TARGET_ARCH_X64

Generated by: LCOV version 1.10