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