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