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