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