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.
5 #include "src/x64/assembler-x64.h"
12 #include <intrin.h> // _xgetbv()
15 #include <sys/sysctl.h>
18 #include "src/base/bits.h"
19 #include "src/macro-assembler.h"
25 // -----------------------------------------------------------------------------
26 // Implementation of CpuFeatures
32 V8_INLINE uint64_t _xgetbv(unsigned int xcr) {
34 // Check xgetbv; this uses a .byte sequence instead of the instruction
35 // directly because older assemblers do not include support for xgetbv and
36 // there is no easy way to conditionally compile based on the assembler
38 __asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr));
39 return static_cast<uint64_t>(eax) | (static_cast<uint64_t>(edx) << 32);
42 #define _XCR_XFEATURE_ENABLED_MASK 0
44 #endif // !V8_LIBC_MSVCRT
47 bool OSHasAVXSupport() {
49 // Mac OS X up to 10.9 has a bug where AVX transitions were indeed being
50 // caused by ISRs, so we detect that here and disable AVX in that case.
52 size_t buffer_size = arraysize(buffer);
53 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
54 if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
55 V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
57 // The buffer now contains a string of the form XX.YY.ZZ, where
58 // XX is the major kernel version component.
59 char* period_pos = strchr(buffer, '.');
60 DCHECK_NOT_NULL(period_pos);
62 long kernel_version_major = strtol(buffer, nullptr, 10); // NOLINT
63 if (kernel_version_major <= 13) return false;
64 #endif // V8_OS_MACOSX
65 // Check whether OS claims to support AVX.
66 uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
67 return (feature_mask & 0x6) == 0x6;
73 void CpuFeatures::ProbeImpl(bool cross_compile) {
75 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
76 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
78 // Only use statically determined features for cross compile (snapshot).
79 if (cross_compile) return;
81 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
82 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
83 // SAHF is not generally available in long mode.
84 if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
85 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() &&
87 supported_ |= 1u << AVX;
89 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() &&
91 supported_ |= 1u << FMA3;
93 if (strcmp(FLAG_mcpu, "auto") == 0) {
94 if (cpu.is_atom()) supported_ |= 1u << ATOM;
95 } else if (strcmp(FLAG_mcpu, "atom") == 0) {
96 supported_ |= 1u << ATOM;
101 void CpuFeatures::PrintTarget() { }
102 void CpuFeatures::PrintFeatures() {
103 printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d ATOM=%d\n",
104 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1),
105 CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX),
106 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(ATOM));
110 // -----------------------------------------------------------------------------
111 // Register constants.
114 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
115 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r12, r14, r15
116 0, 3, 2, 1, 6, 7, 8, 9, 11, 12, 14, 15
119 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
120 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, 9, -1, 10, 11
124 // -----------------------------------------------------------------------------
125 // Implementation of Operand
127 Operand::Operand(Register base, int32_t disp) : rex_(0) {
129 if (base.is(rsp) || base.is(r12)) {
130 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
131 set_sib(times_1, rsp, base);
134 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
136 } else if (is_int8(disp)) {
146 Operand::Operand(Register base,
149 int32_t disp) : rex_(0) {
150 DCHECK(!index.is(rsp));
152 set_sib(scale, index, base);
153 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
154 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
155 // possibly set by set_sib.
157 } else if (is_int8(disp)) {
167 Operand::Operand(Register index,
169 int32_t disp) : rex_(0) {
170 DCHECK(!index.is(rsp));
173 set_sib(scale, index, rbp);
178 Operand::Operand(Label* label) : rex_(0), len_(1) {
179 DCHECK_NOT_NULL(label);
181 set_disp64(reinterpret_cast<intptr_t>(label));
185 Operand::Operand(const Operand& operand, int32_t offset) {
186 DCHECK(operand.len_ >= 1);
187 // Operand encodes REX ModR/M [SIB] [Disp].
188 byte modrm = operand.buf_[0];
189 DCHECK(modrm < 0xC0); // Disallow mode 3 (register target).
190 bool has_sib = ((modrm & 0x07) == 0x04);
191 byte mode = modrm & 0xC0;
192 int disp_offset = has_sib ? 2 : 1;
193 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
194 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
196 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
197 int32_t disp_value = 0;
198 if (mode == 0x80 || is_baseless) {
199 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
200 disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]);
201 } else if (mode == 0x40) {
202 // Mode 1: Byte displacement.
203 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
206 // Write new operand with same registers, but with modified displacement.
207 DCHECK(offset >= 0 ? disp_value + offset > disp_value
208 : disp_value + offset < disp_value); // No overflow.
209 disp_value += offset;
211 if (!is_int8(disp_value) || is_baseless) {
212 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
213 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
214 len_ = disp_offset + 4;
215 Memory::int32_at(&buf_[disp_offset]) = disp_value;
216 } else if (disp_value != 0 || (base_reg == 0x05)) {
217 // Need 8 bits of displacement.
218 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
219 len_ = disp_offset + 1;
220 buf_[disp_offset] = static_cast<byte>(disp_value);
222 // Need no displacement.
223 buf_[0] = (modrm & 0x3f); // Mode 0.
227 buf_[1] = operand.buf_[1];
232 bool Operand::AddressUsesRegister(Register reg) const {
233 int code = reg.code();
234 DCHECK((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
235 // Start with only low three bits of base register. Initial decoding doesn't
236 // distinguish on the REX.B bit.
237 int base_code = buf_[0] & 0x07;
238 if (base_code == rsp.code()) {
239 // SIB byte present in buf_[1].
240 // Check the index register from the SIB byte + REX.X prefix.
241 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
242 // Index code (including REX.X) of 0x04 (rsp) means no index register.
243 if (index_code != rsp.code() && index_code == code) return true;
244 // Add REX.B to get the full base register code.
245 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
246 // A base register of 0x05 (rbp) with mod = 0 means no base register.
247 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
248 return code == base_code;
250 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
252 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
253 base_code |= ((rex_ & 0x01) << 3);
254 return code == base_code;
259 // -----------------------------------------------------------------------------
260 // Implementation of Assembler.
262 #ifdef GENERATED_CODE_COVERAGE
263 static void InitCoverageLog();
266 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
267 : AssemblerBase(isolate, buffer, buffer_size),
269 positions_recorder_(this) {
270 // Clear the buffer in debug mode unless it was provided by the
271 // caller in which case we can't be sure it's okay to overwrite
272 // existing code in it.
275 memset(buffer_, 0xCC, buffer_size_); // int3
279 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
282 #ifdef GENERATED_CODE_COVERAGE
288 void Assembler::GetCode(CodeDesc* desc) {
289 // Finalize code (at this point overflow() may be true, but the gap ensures
290 // that we are still not overlapping instructions and relocation info).
291 reloc_info_writer.Finish();
292 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
293 // Set up code descriptor.
294 desc->buffer = buffer_;
295 desc->buffer_size = buffer_size_;
296 desc->instr_size = pc_offset();
297 DCHECK(desc->instr_size > 0); // Zero-size code objects upset the system.
299 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
304 void Assembler::Align(int m) {
305 DCHECK(base::bits::IsPowerOfTwo32(m));
306 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
311 void Assembler::CodeTargetAlign() {
312 Align(16); // Preferred alignment of jump targets on x64.
316 bool Assembler::IsNop(Address addr) {
318 while (*a == 0x66) a++;
319 if (*a == 0x90) return true;
320 if (a[0] == 0xf && a[1] == 0x1f) return true;
325 void Assembler::bind_to(Label* L, int pos) {
326 DCHECK(!L->is_bound()); // Label may only be bound once.
327 DCHECK(0 <= pos && pos <= pc_offset()); // Position must be valid.
328 if (L->is_linked()) {
329 int current = L->pos();
330 int next = long_at(current);
331 while (next != current) {
332 if (current >= 4 && long_at(current - 4) == 0) {
334 intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_ + pos);
335 *reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
336 internal_reference_positions_.push_back(current - 4);
338 // Relative address, relative to point after address.
339 int imm32 = pos - (current + sizeof(int32_t));
340 long_at_put(current, imm32);
343 next = long_at(next);
345 // Fix up last fixup on linked list.
346 if (current >= 4 && long_at(current - 4) == 0) {
348 intptr_t imm64 = reinterpret_cast<intptr_t>(buffer_ + pos);
349 *reinterpret_cast<intptr_t*>(addr_at(current - 4)) = imm64;
350 internal_reference_positions_.push_back(current - 4);
352 // Relative address, relative to point after address.
353 int imm32 = pos - (current + sizeof(int32_t));
354 long_at_put(current, imm32);
357 while (L->is_near_linked()) {
358 int fixup_pos = L->near_link_pos();
360 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
361 DCHECK(offset_to_next <= 0);
362 int disp = pos - (fixup_pos + sizeof(int8_t));
363 CHECK(is_int8(disp));
364 set_byte_at(fixup_pos, disp);
365 if (offset_to_next < 0) {
366 L->link_to(fixup_pos + offset_to_next, Label::kNear);
375 void Assembler::bind(Label* L) {
376 bind_to(L, pc_offset());
380 void Assembler::GrowBuffer() {
381 DCHECK(buffer_overflow());
382 if (!own_buffer_) FATAL("external code buffer is too small");
384 // Compute new buffer size.
385 CodeDesc desc; // the new buffer
386 desc.buffer_size = 2 * buffer_size_;
388 // Some internal data structures overflow for very large buffers,
389 // they must ensure that kMaximalBufferSize is not too large.
390 if ((desc.buffer_size > kMaximalBufferSize) ||
391 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
392 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
395 // Set up new buffer.
396 desc.buffer = NewArray<byte>(desc.buffer_size);
397 desc.instr_size = pc_offset();
399 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
401 // Clear the buffer in debug mode. Use 'int3' instructions to make
402 // sure to get into problems if we ever run uninitialized code.
404 memset(desc.buffer, 0xCC, desc.buffer_size);
408 intptr_t pc_delta = desc.buffer - buffer_;
409 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
410 (buffer_ + buffer_size_);
411 MemMove(desc.buffer, buffer_, desc.instr_size);
412 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
416 DeleteArray(buffer_);
417 buffer_ = desc.buffer;
418 buffer_size_ = desc.buffer_size;
420 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
421 reloc_info_writer.last_pc() + pc_delta);
423 // Relocate internal references.
424 for (auto pos : internal_reference_positions_) {
425 intptr_t* p = reinterpret_cast<intptr_t*>(buffer_ + pos);
429 DCHECK(!buffer_overflow());
433 void Assembler::emit_operand(int code, const Operand& adr) {
434 DCHECK(is_uint3(code));
435 const unsigned length = adr.len_;
438 // Emit updated ModR/M byte containing the given register.
439 DCHECK((adr.buf_[0] & 0x38) == 0);
440 *pc_++ = adr.buf_[0] | code << 3;
442 // Recognize RIP relative addressing.
443 if (adr.buf_[0] == 5) {
444 DCHECK_EQ(9u, length);
445 Label* label = *bit_cast<Label* const*>(&adr.buf_[1]);
446 if (label->is_bound()) {
447 int offset = label->pos() - pc_offset() - sizeof(int32_t);
448 DCHECK_GE(0, offset);
450 } else if (label->is_linked()) {
452 label->link_to(pc_offset() - sizeof(int32_t));
454 DCHECK(label->is_unused());
455 int32_t current = pc_offset();
457 label->link_to(current);
460 // Emit the rest of the encoded operand.
461 for (unsigned i = 1; i < length; i++) *pc_++ = adr.buf_[i];
466 // Assembler Instruction implementations.
468 void Assembler::arithmetic_op(byte opcode,
472 EnsureSpace ensure_space(this);
473 emit_rex(reg, op, size);
475 emit_operand(reg, op);
479 void Assembler::arithmetic_op(byte opcode,
483 EnsureSpace ensure_space(this);
484 DCHECK((opcode & 0xC6) == 2);
485 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
486 // Swap reg and rm_reg and change opcode operand order.
487 emit_rex(rm_reg, reg, size);
489 emit_modrm(rm_reg, reg);
491 emit_rex(reg, rm_reg, size);
493 emit_modrm(reg, rm_reg);
498 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
499 EnsureSpace ensure_space(this);
500 DCHECK((opcode & 0xC6) == 2);
501 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
502 // Swap reg and rm_reg and change opcode operand order.
504 emit_optional_rex_32(rm_reg, reg);
506 emit_modrm(rm_reg, reg);
509 emit_optional_rex_32(reg, rm_reg);
511 emit_modrm(reg, rm_reg);
516 void Assembler::arithmetic_op_16(byte opcode,
518 const Operand& rm_reg) {
519 EnsureSpace ensure_space(this);
521 emit_optional_rex_32(reg, rm_reg);
523 emit_operand(reg, rm_reg);
527 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
528 EnsureSpace ensure_space(this);
529 if (!reg.is_byte_register()) {
530 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
534 emit_operand(reg, op);
538 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
539 EnsureSpace ensure_space(this);
540 DCHECK((opcode & 0xC6) == 2);
541 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
542 // Swap reg and rm_reg and change opcode operand order.
543 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
544 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
545 emit_rex_32(rm_reg, reg);
548 emit_modrm(rm_reg, reg);
550 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
551 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
552 emit_rex_32(reg, rm_reg);
555 emit_modrm(reg, rm_reg);
560 void Assembler::immediate_arithmetic_op(byte subcode,
564 EnsureSpace ensure_space(this);
566 if (is_int8(src.value_)) {
568 emit_modrm(subcode, dst);
570 } else if (dst.is(rax)) {
571 emit(0x05 | (subcode << 3));
575 emit_modrm(subcode, dst);
580 void Assembler::immediate_arithmetic_op(byte subcode,
584 EnsureSpace ensure_space(this);
586 if (is_int8(src.value_)) {
588 emit_operand(subcode, dst);
592 emit_operand(subcode, dst);
598 void Assembler::immediate_arithmetic_op_16(byte subcode,
601 EnsureSpace ensure_space(this);
602 emit(0x66); // Operand size override prefix.
603 emit_optional_rex_32(dst);
604 if (is_int8(src.value_)) {
606 emit_modrm(subcode, dst);
608 } else if (dst.is(rax)) {
609 emit(0x05 | (subcode << 3));
613 emit_modrm(subcode, dst);
619 void Assembler::immediate_arithmetic_op_16(byte subcode,
622 EnsureSpace ensure_space(this);
623 emit(0x66); // Operand size override prefix.
624 emit_optional_rex_32(dst);
625 if (is_int8(src.value_)) {
627 emit_operand(subcode, dst);
631 emit_operand(subcode, dst);
637 void Assembler::immediate_arithmetic_op_8(byte subcode,
640 EnsureSpace ensure_space(this);
641 emit_optional_rex_32(dst);
642 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
644 emit_operand(subcode, dst);
649 void Assembler::immediate_arithmetic_op_8(byte subcode,
652 EnsureSpace ensure_space(this);
653 if (!dst.is_byte_register()) {
654 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
657 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
659 emit_modrm(subcode, dst);
664 void Assembler::shift(Register dst,
665 Immediate shift_amount,
668 EnsureSpace ensure_space(this);
669 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
670 : is_uint5(shift_amount.value_));
671 if (shift_amount.value_ == 1) {
674 emit_modrm(subcode, dst);
678 emit_modrm(subcode, dst);
679 emit(shift_amount.value_);
684 void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
686 EnsureSpace ensure_space(this);
687 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
688 : is_uint5(shift_amount.value_));
689 if (shift_amount.value_ == 1) {
692 emit_operand(subcode, dst);
696 emit_operand(subcode, dst);
697 emit(shift_amount.value_);
702 void Assembler::shift(Register dst, int subcode, int size) {
703 EnsureSpace ensure_space(this);
706 emit_modrm(subcode, dst);
710 void Assembler::shift(Operand dst, int subcode, int size) {
711 EnsureSpace ensure_space(this);
714 emit_operand(subcode, dst);
718 void Assembler::bt(const Operand& dst, Register src) {
719 EnsureSpace ensure_space(this);
720 emit_rex_64(src, dst);
723 emit_operand(src, dst);
727 void Assembler::bts(const Operand& dst, Register src) {
728 EnsureSpace ensure_space(this);
729 emit_rex_64(src, dst);
732 emit_operand(src, dst);
736 void Assembler::bsrl(Register dst, Register src) {
737 EnsureSpace ensure_space(this);
738 emit_optional_rex_32(dst, src);
741 emit_modrm(dst, src);
745 void Assembler::bsrl(Register dst, const Operand& src) {
746 EnsureSpace ensure_space(this);
747 emit_optional_rex_32(dst, src);
750 emit_operand(dst, src);
754 void Assembler::call(Label* L) {
755 positions_recorder()->WriteRecordedPositions();
756 EnsureSpace ensure_space(this);
757 // 1110 1000 #32-bit disp.
760 int offset = L->pos() - pc_offset() - sizeof(int32_t);
763 } else if (L->is_linked()) {
765 L->link_to(pc_offset() - sizeof(int32_t));
767 DCHECK(L->is_unused());
768 int32_t current = pc_offset();
775 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
776 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
777 positions_recorder()->WriteRecordedPositions();
778 EnsureSpace ensure_space(this);
779 // 1110 1000 #32-bit disp.
781 emit_runtime_entry(entry, rmode);
785 void Assembler::call(Handle<Code> target,
786 RelocInfo::Mode rmode,
787 TypeFeedbackId ast_id) {
788 positions_recorder()->WriteRecordedPositions();
789 EnsureSpace ensure_space(this);
790 // 1110 1000 #32-bit disp.
792 emit_code_target(target, rmode, ast_id);
796 void Assembler::call(Register adr) {
797 positions_recorder()->WriteRecordedPositions();
798 EnsureSpace ensure_space(this);
799 // Opcode: FF /2 r64.
800 emit_optional_rex_32(adr);
802 emit_modrm(0x2, adr);
806 void Assembler::call(const Operand& op) {
807 positions_recorder()->WriteRecordedPositions();
808 EnsureSpace ensure_space(this);
809 // Opcode: FF /2 m64.
810 emit_optional_rex_32(op);
812 emit_operand(0x2, op);
816 // Calls directly to the given address using a relative offset.
817 // Should only ever be used in Code objects for calls within the
818 // same Code object. Should not be used when generating new code (use labels),
819 // but only when patching existing code.
820 void Assembler::call(Address target) {
821 positions_recorder()->WriteRecordedPositions();
822 EnsureSpace ensure_space(this);
823 // 1110 1000 #32-bit disp.
825 Address source = pc_ + 4;
826 intptr_t displacement = target - source;
827 DCHECK(is_int32(displacement));
828 emitl(static_cast<int32_t>(displacement));
832 void Assembler::clc() {
833 EnsureSpace ensure_space(this);
838 void Assembler::cld() {
839 EnsureSpace ensure_space(this);
844 void Assembler::cdq() {
845 EnsureSpace ensure_space(this);
850 void Assembler::cmovq(Condition cc, Register dst, Register src) {
853 } else if (cc == never) {
856 // No need to check CpuInfo for CMOV support, it's a required part of the
857 // 64-bit architecture.
858 DCHECK(cc >= 0); // Use mov for unconditional moves.
859 EnsureSpace ensure_space(this);
860 // Opcode: REX.W 0f 40 + cc /r.
861 emit_rex_64(dst, src);
864 emit_modrm(dst, src);
868 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
871 } else if (cc == never) {
875 EnsureSpace ensure_space(this);
876 // Opcode: REX.W 0f 40 + cc /r.
877 emit_rex_64(dst, src);
880 emit_operand(dst, src);
884 void Assembler::cmovl(Condition cc, Register dst, Register src) {
887 } else if (cc == never) {
891 EnsureSpace ensure_space(this);
892 // Opcode: 0f 40 + cc /r.
893 emit_optional_rex_32(dst, src);
896 emit_modrm(dst, src);
900 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
903 } else if (cc == never) {
907 EnsureSpace ensure_space(this);
908 // Opcode: 0f 40 + cc /r.
909 emit_optional_rex_32(dst, src);
912 emit_operand(dst, src);
916 void Assembler::cmpb_al(Immediate imm8) {
917 DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
918 EnsureSpace ensure_space(this);
924 void Assembler::cpuid() {
925 EnsureSpace ensure_space(this);
931 void Assembler::cqo() {
932 EnsureSpace ensure_space(this);
938 void Assembler::emit_dec(Register dst, int size) {
939 EnsureSpace ensure_space(this);
942 emit_modrm(0x1, dst);
946 void Assembler::emit_dec(const Operand& dst, int size) {
947 EnsureSpace ensure_space(this);
950 emit_operand(1, dst);
954 void Assembler::decb(Register dst) {
955 EnsureSpace ensure_space(this);
956 if (!dst.is_byte_register()) {
957 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
961 emit_modrm(0x1, dst);
965 void Assembler::decb(const Operand& dst) {
966 EnsureSpace ensure_space(this);
967 emit_optional_rex_32(dst);
969 emit_operand(1, dst);
973 void Assembler::enter(Immediate size) {
974 EnsureSpace ensure_space(this);
976 emitw(size.value_); // 16 bit operand, always.
981 void Assembler::hlt() {
982 EnsureSpace ensure_space(this);
987 void Assembler::emit_idiv(Register src, int size) {
988 EnsureSpace ensure_space(this);
991 emit_modrm(0x7, src);
995 void Assembler::emit_div(Register src, int size) {
996 EnsureSpace ensure_space(this);
999 emit_modrm(0x6, src);
1003 void Assembler::emit_imul(Register src, int size) {
1004 EnsureSpace ensure_space(this);
1005 emit_rex(src, size);
1007 emit_modrm(0x5, src);
1011 void Assembler::emit_imul(const Operand& src, int size) {
1012 EnsureSpace ensure_space(this);
1013 emit_rex(src, size);
1015 emit_operand(0x5, src);
1019 void Assembler::emit_imul(Register dst, Register src, int size) {
1020 EnsureSpace ensure_space(this);
1021 emit_rex(dst, src, size);
1024 emit_modrm(dst, src);
1028 void Assembler::emit_imul(Register dst, const Operand& src, int size) {
1029 EnsureSpace ensure_space(this);
1030 emit_rex(dst, src, size);
1033 emit_operand(dst, src);
1037 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
1038 EnsureSpace ensure_space(this);
1039 emit_rex(dst, src, size);
1040 if (is_int8(imm.value_)) {
1042 emit_modrm(dst, src);
1046 emit_modrm(dst, src);
1052 void Assembler::emit_imul(Register dst, const Operand& src, Immediate imm,
1054 EnsureSpace ensure_space(this);
1055 emit_rex(dst, src, size);
1056 if (is_int8(imm.value_)) {
1058 emit_operand(dst, src);
1062 emit_operand(dst, src);
1068 void Assembler::emit_inc(Register dst, int size) {
1069 EnsureSpace ensure_space(this);
1070 emit_rex(dst, size);
1072 emit_modrm(0x0, dst);
1076 void Assembler::emit_inc(const Operand& dst, int size) {
1077 EnsureSpace ensure_space(this);
1078 emit_rex(dst, size);
1080 emit_operand(0, dst);
1084 void Assembler::int3() {
1085 EnsureSpace ensure_space(this);
1090 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1094 } else if (cc == never) {
1097 EnsureSpace ensure_space(this);
1098 DCHECK(is_uint4(cc));
1099 if (L->is_bound()) {
1100 const int short_size = 2;
1101 const int long_size = 6;
1102 int offs = L->pos() - pc_offset();
1104 // Determine whether we can use 1-byte offsets for backwards branches,
1105 // which have a max range of 128 bytes.
1107 // We also need to check predictable_code_size() flag here, because on x64,
1108 // when the full code generator recompiles code for debugging, some places
1109 // need to be padded out to a certain size. The debugger is keeping track of
1110 // how often it did this so that it can adjust return addresses on the
1111 // stack, but if the size of jump instructions can also change, that's not
1112 // enough and the calculated offsets would be incorrect.
1113 if (is_int8(offs - short_size) && !predictable_code_size()) {
1114 // 0111 tttn #8-bit disp.
1116 emit((offs - short_size) & 0xFF);
1118 // 0000 1111 1000 tttn #32-bit disp.
1121 emitl(offs - long_size);
1123 } else if (distance == Label::kNear) {
1124 // 0111 tttn #8-bit disp
1127 if (L->is_near_linked()) {
1128 int offset = L->near_link_pos() - pc_offset();
1129 DCHECK(is_int8(offset));
1130 disp = static_cast<byte>(offset & 0xFF);
1132 L->link_to(pc_offset(), Label::kNear);
1134 } else if (L->is_linked()) {
1135 // 0000 1111 1000 tttn #32-bit disp.
1139 L->link_to(pc_offset() - sizeof(int32_t));
1141 DCHECK(L->is_unused());
1144 int32_t current = pc_offset();
1146 L->link_to(current);
1151 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1152 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1153 EnsureSpace ensure_space(this);
1154 DCHECK(is_uint4(cc));
1157 emit_runtime_entry(entry, rmode);
1161 void Assembler::j(Condition cc,
1162 Handle<Code> target,
1163 RelocInfo::Mode rmode) {
1164 EnsureSpace ensure_space(this);
1165 DCHECK(is_uint4(cc));
1166 // 0000 1111 1000 tttn #32-bit disp.
1169 emit_code_target(target, rmode);
1173 void Assembler::jmp(Label* L, Label::Distance distance) {
1174 EnsureSpace ensure_space(this);
1175 const int short_size = sizeof(int8_t);
1176 const int long_size = sizeof(int32_t);
1177 if (L->is_bound()) {
1178 int offs = L->pos() - pc_offset() - 1;
1180 if (is_int8(offs - short_size) && !predictable_code_size()) {
1181 // 1110 1011 #8-bit disp.
1183 emit((offs - short_size) & 0xFF);
1185 // 1110 1001 #32-bit disp.
1187 emitl(offs - long_size);
1189 } else if (distance == Label::kNear) {
1192 if (L->is_near_linked()) {
1193 int offset = L->near_link_pos() - pc_offset();
1194 DCHECK(is_int8(offset));
1195 disp = static_cast<byte>(offset & 0xFF);
1197 L->link_to(pc_offset(), Label::kNear);
1199 } else if (L->is_linked()) {
1200 // 1110 1001 #32-bit disp.
1203 L->link_to(pc_offset() - long_size);
1205 // 1110 1001 #32-bit disp.
1206 DCHECK(L->is_unused());
1208 int32_t current = pc_offset();
1210 L->link_to(current);
1215 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1216 EnsureSpace ensure_space(this);
1217 // 1110 1001 #32-bit disp.
1219 emit_code_target(target, rmode);
1223 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1224 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1225 EnsureSpace ensure_space(this);
1226 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1228 emit_runtime_entry(entry, rmode);
1232 void Assembler::jmp(Register target) {
1233 EnsureSpace ensure_space(this);
1235 emit_optional_rex_32(target);
1237 emit_modrm(0x4, target);
1241 void Assembler::jmp(const Operand& src) {
1242 EnsureSpace ensure_space(this);
1244 emit_optional_rex_32(src);
1246 emit_operand(0x4, src);
1250 void Assembler::emit_lea(Register dst, const Operand& src, int size) {
1251 EnsureSpace ensure_space(this);
1252 emit_rex(dst, src, size);
1254 emit_operand(dst, src);
1258 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1259 EnsureSpace ensure_space(this);
1260 if (kPointerSize == kInt64Size) {
1261 emit(0x48); // REX.W
1265 DCHECK(kPointerSize == kInt32Size);
1268 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1269 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1270 // Developer's Manual Volume 2.
1276 void Assembler::load_rax(ExternalReference ref) {
1277 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1281 void Assembler::leave() {
1282 EnsureSpace ensure_space(this);
1287 void Assembler::movb(Register dst, const Operand& src) {
1288 EnsureSpace ensure_space(this);
1289 if (!dst.is_byte_register()) {
1290 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1291 emit_rex_32(dst, src);
1293 emit_optional_rex_32(dst, src);
1296 emit_operand(dst, src);
1300 void Assembler::movb(Register dst, Immediate imm) {
1301 EnsureSpace ensure_space(this);
1302 if (!dst.is_byte_register()) {
1303 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1306 emit(0xB0 + dst.low_bits());
1311 void Assembler::movb(const Operand& dst, Register src) {
1312 EnsureSpace ensure_space(this);
1313 if (!src.is_byte_register()) {
1314 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1315 emit_rex_32(src, dst);
1317 emit_optional_rex_32(src, dst);
1320 emit_operand(src, dst);
1324 void Assembler::movb(const Operand& dst, Immediate imm) {
1325 EnsureSpace ensure_space(this);
1326 emit_optional_rex_32(dst);
1328 emit_operand(0x0, dst);
1329 emit(static_cast<byte>(imm.value_));
1333 void Assembler::movw(Register dst, const Operand& src) {
1334 EnsureSpace ensure_space(this);
1336 emit_optional_rex_32(dst, src);
1338 emit_operand(dst, src);
1342 void Assembler::movw(const Operand& dst, Register src) {
1343 EnsureSpace ensure_space(this);
1345 emit_optional_rex_32(src, dst);
1347 emit_operand(src, dst);
1351 void Assembler::movw(const Operand& dst, Immediate imm) {
1352 EnsureSpace ensure_space(this);
1354 emit_optional_rex_32(dst);
1356 emit_operand(0x0, dst);
1357 emit(static_cast<byte>(imm.value_ & 0xff));
1358 emit(static_cast<byte>(imm.value_ >> 8));
1362 void Assembler::emit_mov(Register dst, const Operand& src, int size) {
1363 EnsureSpace ensure_space(this);
1364 emit_rex(dst, src, size);
1366 emit_operand(dst, src);
1370 void Assembler::emit_mov(Register dst, Register src, int size) {
1371 EnsureSpace ensure_space(this);
1372 if (src.low_bits() == 4) {
1373 emit_rex(src, dst, size);
1375 emit_modrm(src, dst);
1377 emit_rex(dst, src, size);
1379 emit_modrm(dst, src);
1384 void Assembler::emit_mov(const Operand& dst, Register src, int size) {
1385 EnsureSpace ensure_space(this);
1386 emit_rex(src, dst, size);
1388 emit_operand(src, dst);
1392 void Assembler::emit_mov(Register dst, Immediate value, int size) {
1393 EnsureSpace ensure_space(this);
1394 emit_rex(dst, size);
1395 if (size == kInt64Size) {
1397 emit_modrm(0x0, dst);
1399 DCHECK(size == kInt32Size);
1400 emit(0xB8 + dst.low_bits());
1406 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
1407 EnsureSpace ensure_space(this);
1408 emit_rex(dst, size);
1410 emit_operand(0x0, dst);
1415 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
1416 EnsureSpace ensure_space(this);
1417 emit_rex(dst, kPointerSize);
1418 emit(0xB8 | dst.low_bits());
1419 emitp(value, rmode);
1423 void Assembler::movq(Register dst, int64_t value) {
1424 EnsureSpace ensure_space(this);
1426 emit(0xB8 | dst.low_bits());
1431 void Assembler::movq(Register dst, uint64_t value) {
1432 movq(dst, static_cast<int64_t>(value));
1436 // Loads the ip-relative location of the src label into the target location
1437 // (as a 32-bit offset sign extended to 64-bit).
1438 void Assembler::movl(const Operand& dst, Label* src) {
1439 EnsureSpace ensure_space(this);
1440 emit_optional_rex_32(dst);
1442 emit_operand(0, dst);
1443 if (src->is_bound()) {
1444 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1445 DCHECK(offset <= 0);
1447 } else if (src->is_linked()) {
1449 src->link_to(pc_offset() - sizeof(int32_t));
1451 DCHECK(src->is_unused());
1452 int32_t current = pc_offset();
1454 src->link_to(current);
1459 void Assembler::movsxbl(Register dst, Register src) {
1460 EnsureSpace ensure_space(this);
1461 if (!src.is_byte_register()) {
1462 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1463 emit_rex_32(dst, src);
1465 emit_optional_rex_32(dst, src);
1469 emit_modrm(dst, src);
1473 void Assembler::movsxbl(Register dst, const Operand& src) {
1474 EnsureSpace ensure_space(this);
1475 emit_optional_rex_32(dst, src);
1478 emit_operand(dst, src);
1482 void Assembler::movsxbq(Register dst, const Operand& src) {
1483 EnsureSpace ensure_space(this);
1484 emit_rex_64(dst, src);
1487 emit_operand(dst, src);
1491 void Assembler::movsxwl(Register dst, Register src) {
1492 EnsureSpace ensure_space(this);
1493 emit_optional_rex_32(dst, src);
1496 emit_modrm(dst, src);
1500 void Assembler::movsxwl(Register dst, const Operand& src) {
1501 EnsureSpace ensure_space(this);
1502 emit_optional_rex_32(dst, src);
1505 emit_operand(dst, src);
1509 void Assembler::movsxwq(Register dst, const Operand& src) {
1510 EnsureSpace ensure_space(this);
1511 emit_rex_64(dst, src);
1514 emit_operand(dst, src);
1518 void Assembler::movsxlq(Register dst, Register src) {
1519 EnsureSpace ensure_space(this);
1520 emit_rex_64(dst, src);
1522 emit_modrm(dst, src);
1526 void Assembler::movsxlq(Register dst, const Operand& src) {
1527 EnsureSpace ensure_space(this);
1528 emit_rex_64(dst, src);
1530 emit_operand(dst, src);
1534 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
1535 EnsureSpace ensure_space(this);
1536 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1537 // there is no need to make this a 64 bit operation.
1538 emit_optional_rex_32(dst, src);
1541 emit_operand(dst, src);
1545 void Assembler::emit_movzxb(Register dst, Register src, int size) {
1546 EnsureSpace ensure_space(this);
1547 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1548 // there is no need to make this a 64 bit operation.
1549 if (!src.is_byte_register()) {
1550 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1551 emit_rex_32(dst, src);
1553 emit_optional_rex_32(dst, src);
1557 emit_modrm(dst, src);
1561 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
1562 EnsureSpace ensure_space(this);
1563 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1564 // there is no need to make this a 64 bit operation.
1565 emit_optional_rex_32(dst, src);
1568 emit_operand(dst, src);
1572 void Assembler::emit_movzxw(Register dst, Register src, int size) {
1573 EnsureSpace ensure_space(this);
1574 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1575 // there is no need to make this a 64 bit operation.
1576 emit_optional_rex_32(dst, src);
1579 emit_modrm(dst, src);
1583 void Assembler::repmovsb() {
1584 EnsureSpace ensure_space(this);
1590 void Assembler::repmovsw() {
1591 EnsureSpace ensure_space(this);
1592 emit(0x66); // Operand size override.
1598 void Assembler::emit_repmovs(int size) {
1599 EnsureSpace ensure_space(this);
1606 void Assembler::mull(Register src) {
1607 EnsureSpace ensure_space(this);
1608 emit_optional_rex_32(src);
1610 emit_modrm(0x4, src);
1614 void Assembler::mull(const Operand& src) {
1615 EnsureSpace ensure_space(this);
1616 emit_optional_rex_32(src);
1618 emit_operand(0x4, src);
1622 void Assembler::mulq(Register src) {
1623 EnsureSpace ensure_space(this);
1626 emit_modrm(0x4, src);
1630 void Assembler::emit_neg(Register dst, int size) {
1631 EnsureSpace ensure_space(this);
1632 emit_rex(dst, size);
1634 emit_modrm(0x3, dst);
1638 void Assembler::emit_neg(const Operand& dst, int size) {
1639 EnsureSpace ensure_space(this);
1642 emit_operand(3, dst);
1646 void Assembler::nop() {
1647 EnsureSpace ensure_space(this);
1652 void Assembler::emit_not(Register dst, int size) {
1653 EnsureSpace ensure_space(this);
1654 emit_rex(dst, size);
1656 emit_modrm(0x2, dst);
1660 void Assembler::emit_not(const Operand& dst, int size) {
1661 EnsureSpace ensure_space(this);
1662 emit_rex(dst, size);
1664 emit_operand(2, dst);
1668 void Assembler::Nop(int n) {
1669 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1670 // and IA-32 Architectures Software Developer's Manual.
1672 // Length Assembly Byte Sequence
1673 // 2 bytes 66 NOP 66 90H
1674 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1675 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1676 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1677 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1678 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1679 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1680 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1683 EnsureSpace ensure_space(this);
1745 void Assembler::popq(Register dst) {
1746 EnsureSpace ensure_space(this);
1747 emit_optional_rex_32(dst);
1748 emit(0x58 | dst.low_bits());
1752 void Assembler::popq(const Operand& dst) {
1753 EnsureSpace ensure_space(this);
1754 emit_optional_rex_32(dst);
1756 emit_operand(0, dst);
1760 void Assembler::popfq() {
1761 EnsureSpace ensure_space(this);
1766 void Assembler::pushq(Register src) {
1767 EnsureSpace ensure_space(this);
1768 emit_optional_rex_32(src);
1769 emit(0x50 | src.low_bits());
1773 void Assembler::pushq(const Operand& src) {
1774 EnsureSpace ensure_space(this);
1775 emit_optional_rex_32(src);
1777 emit_operand(6, src);
1781 void Assembler::pushq(Immediate value) {
1782 EnsureSpace ensure_space(this);
1783 if (is_int8(value.value_)) {
1785 emit(value.value_); // Emit low byte of value.
1788 emitl(value.value_);
1793 void Assembler::pushq_imm32(int32_t imm32) {
1794 EnsureSpace ensure_space(this);
1800 void Assembler::pushfq() {
1801 EnsureSpace ensure_space(this);
1806 void Assembler::ret(int imm16) {
1807 EnsureSpace ensure_space(this);
1808 DCHECK(is_uint16(imm16));
1814 emit((imm16 >> 8) & 0xFF);
1819 void Assembler::ud2() {
1820 EnsureSpace ensure_space(this);
1826 void Assembler::setcc(Condition cc, Register reg) {
1827 if (cc > last_condition) {
1828 movb(reg, Immediate(cc == always ? 1 : 0));
1831 EnsureSpace ensure_space(this);
1832 DCHECK(is_uint4(cc));
1833 if (!reg.is_byte_register()) {
1834 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1839 emit_modrm(0x0, reg);
1843 void Assembler::shld(Register dst, Register src) {
1844 EnsureSpace ensure_space(this);
1845 emit_rex_64(src, dst);
1848 emit_modrm(src, dst);
1852 void Assembler::shrd(Register dst, Register src) {
1853 EnsureSpace ensure_space(this);
1854 emit_rex_64(src, dst);
1857 emit_modrm(src, dst);
1861 void Assembler::emit_xchg(Register dst, Register src, int size) {
1862 EnsureSpace ensure_space(this);
1863 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1864 Register other = src.is(rax) ? dst : src;
1865 emit_rex(other, size);
1866 emit(0x90 | other.low_bits());
1867 } else if (dst.low_bits() == 4) {
1868 emit_rex(dst, src, size);
1870 emit_modrm(dst, src);
1872 emit_rex(src, dst, size);
1874 emit_modrm(src, dst);
1879 void Assembler::emit_xchg(Register dst, const Operand& src, int size) {
1880 EnsureSpace ensure_space(this);
1881 emit_rex(dst, src, size);
1883 emit_operand(dst, src);
1887 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1888 EnsureSpace ensure_space(this);
1889 if (kPointerSize == kInt64Size) {
1890 emit(0x48); // REX.W
1894 DCHECK(kPointerSize == kInt32Size);
1897 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1898 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1899 // Developer's Manual Volume 2.
1905 void Assembler::store_rax(ExternalReference ref) {
1906 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1910 void Assembler::testb(Register dst, Register src) {
1911 EnsureSpace ensure_space(this);
1912 if (src.low_bits() == 4) {
1913 emit_rex_32(src, dst);
1915 emit_modrm(src, dst);
1917 if (!dst.is_byte_register() || !src.is_byte_register()) {
1918 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1919 emit_rex_32(dst, src);
1922 emit_modrm(dst, src);
1927 void Assembler::testb(Register reg, Immediate mask) {
1928 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1929 EnsureSpace ensure_space(this);
1932 emit(mask.value_); // Low byte emitted.
1934 if (!reg.is_byte_register()) {
1935 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1939 emit_modrm(0x0, reg);
1940 emit(mask.value_); // Low byte emitted.
1945 void Assembler::testb(const Operand& op, Immediate mask) {
1946 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1947 EnsureSpace ensure_space(this);
1948 emit_optional_rex_32(rax, op);
1950 emit_operand(rax, op); // Operation code 0
1951 emit(mask.value_); // Low byte emitted.
1955 void Assembler::testb(const Operand& op, Register reg) {
1956 EnsureSpace ensure_space(this);
1957 if (!reg.is_byte_register()) {
1958 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1959 emit_rex_32(reg, op);
1961 emit_optional_rex_32(reg, op);
1964 emit_operand(reg, op);
1968 void Assembler::emit_test(Register dst, Register src, int size) {
1969 EnsureSpace ensure_space(this);
1970 if (src.low_bits() == 4) {
1971 emit_rex(src, dst, size);
1973 emit_modrm(src, dst);
1975 emit_rex(dst, src, size);
1977 emit_modrm(dst, src);
1982 void Assembler::emit_test(Register reg, Immediate mask, int size) {
1983 // testl with a mask that fits in the low byte is exactly testb.
1984 if (is_uint8(mask.value_)) {
1988 EnsureSpace ensure_space(this);
1990 emit_rex(rax, size);
1994 emit_rex(reg, size);
1996 emit_modrm(0x0, reg);
2002 void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
2003 // testl with a mask that fits in the low byte is exactly testb.
2004 if (is_uint8(mask.value_)) {
2008 EnsureSpace ensure_space(this);
2009 emit_rex(rax, op, size);
2011 emit_operand(rax, op); // Operation code 0
2016 void Assembler::emit_test(const Operand& op, Register reg, int size) {
2017 EnsureSpace ensure_space(this);
2018 emit_rex(reg, op, size);
2020 emit_operand(reg, op);
2024 // FPU instructions.
2027 void Assembler::fld(int i) {
2028 EnsureSpace ensure_space(this);
2029 emit_farith(0xD9, 0xC0, i);
2033 void Assembler::fld1() {
2034 EnsureSpace ensure_space(this);
2040 void Assembler::fldz() {
2041 EnsureSpace ensure_space(this);
2047 void Assembler::fldpi() {
2048 EnsureSpace ensure_space(this);
2054 void Assembler::fldln2() {
2055 EnsureSpace ensure_space(this);
2061 void Assembler::fld_s(const Operand& adr) {
2062 EnsureSpace ensure_space(this);
2063 emit_optional_rex_32(adr);
2065 emit_operand(0, adr);
2069 void Assembler::fld_d(const Operand& adr) {
2070 EnsureSpace ensure_space(this);
2071 emit_optional_rex_32(adr);
2073 emit_operand(0, adr);
2077 void Assembler::fstp_s(const Operand& adr) {
2078 EnsureSpace ensure_space(this);
2079 emit_optional_rex_32(adr);
2081 emit_operand(3, adr);
2085 void Assembler::fstp_d(const Operand& adr) {
2086 EnsureSpace ensure_space(this);
2087 emit_optional_rex_32(adr);
2089 emit_operand(3, adr);
2093 void Assembler::fstp(int index) {
2094 DCHECK(is_uint3(index));
2095 EnsureSpace ensure_space(this);
2096 emit_farith(0xDD, 0xD8, index);
2100 void Assembler::fild_s(const Operand& adr) {
2101 EnsureSpace ensure_space(this);
2102 emit_optional_rex_32(adr);
2104 emit_operand(0, adr);
2108 void Assembler::fild_d(const Operand& adr) {
2109 EnsureSpace ensure_space(this);
2110 emit_optional_rex_32(adr);
2112 emit_operand(5, adr);
2116 void Assembler::fistp_s(const Operand& adr) {
2117 EnsureSpace ensure_space(this);
2118 emit_optional_rex_32(adr);
2120 emit_operand(3, adr);
2124 void Assembler::fisttp_s(const Operand& adr) {
2125 DCHECK(IsEnabled(SSE3));
2126 EnsureSpace ensure_space(this);
2127 emit_optional_rex_32(adr);
2129 emit_operand(1, adr);
2133 void Assembler::fisttp_d(const Operand& adr) {
2134 DCHECK(IsEnabled(SSE3));
2135 EnsureSpace ensure_space(this);
2136 emit_optional_rex_32(adr);
2138 emit_operand(1, adr);
2142 void Assembler::fist_s(const Operand& adr) {
2143 EnsureSpace ensure_space(this);
2144 emit_optional_rex_32(adr);
2146 emit_operand(2, adr);
2150 void Assembler::fistp_d(const Operand& adr) {
2151 EnsureSpace ensure_space(this);
2152 emit_optional_rex_32(adr);
2154 emit_operand(7, adr);
2158 void Assembler::fabs() {
2159 EnsureSpace ensure_space(this);
2165 void Assembler::fchs() {
2166 EnsureSpace ensure_space(this);
2172 void Assembler::fcos() {
2173 EnsureSpace ensure_space(this);
2179 void Assembler::fsin() {
2180 EnsureSpace ensure_space(this);
2186 void Assembler::fptan() {
2187 EnsureSpace ensure_space(this);
2193 void Assembler::fyl2x() {
2194 EnsureSpace ensure_space(this);
2200 void Assembler::f2xm1() {
2201 EnsureSpace ensure_space(this);
2207 void Assembler::fscale() {
2208 EnsureSpace ensure_space(this);
2214 void Assembler::fninit() {
2215 EnsureSpace ensure_space(this);
2221 void Assembler::fadd(int i) {
2222 EnsureSpace ensure_space(this);
2223 emit_farith(0xDC, 0xC0, i);
2227 void Assembler::fsub(int i) {
2228 EnsureSpace ensure_space(this);
2229 emit_farith(0xDC, 0xE8, i);
2233 void Assembler::fisub_s(const Operand& adr) {
2234 EnsureSpace ensure_space(this);
2235 emit_optional_rex_32(adr);
2237 emit_operand(4, adr);
2241 void Assembler::fmul(int i) {
2242 EnsureSpace ensure_space(this);
2243 emit_farith(0xDC, 0xC8, i);
2247 void Assembler::fdiv(int i) {
2248 EnsureSpace ensure_space(this);
2249 emit_farith(0xDC, 0xF8, i);
2253 void Assembler::faddp(int i) {
2254 EnsureSpace ensure_space(this);
2255 emit_farith(0xDE, 0xC0, i);
2259 void Assembler::fsubp(int i) {
2260 EnsureSpace ensure_space(this);
2261 emit_farith(0xDE, 0xE8, i);
2265 void Assembler::fsubrp(int i) {
2266 EnsureSpace ensure_space(this);
2267 emit_farith(0xDE, 0xE0, i);
2271 void Assembler::fmulp(int i) {
2272 EnsureSpace ensure_space(this);
2273 emit_farith(0xDE, 0xC8, i);
2277 void Assembler::fdivp(int i) {
2278 EnsureSpace ensure_space(this);
2279 emit_farith(0xDE, 0xF8, i);
2283 void Assembler::fprem() {
2284 EnsureSpace ensure_space(this);
2290 void Assembler::fprem1() {
2291 EnsureSpace ensure_space(this);
2297 void Assembler::fxch(int i) {
2298 EnsureSpace ensure_space(this);
2299 emit_farith(0xD9, 0xC8, i);
2303 void Assembler::fincstp() {
2304 EnsureSpace ensure_space(this);
2310 void Assembler::ffree(int i) {
2311 EnsureSpace ensure_space(this);
2312 emit_farith(0xDD, 0xC0, i);
2316 void Assembler::ftst() {
2317 EnsureSpace ensure_space(this);
2323 void Assembler::fucomp(int i) {
2324 EnsureSpace ensure_space(this);
2325 emit_farith(0xDD, 0xE8, i);
2329 void Assembler::fucompp() {
2330 EnsureSpace ensure_space(this);
2336 void Assembler::fucomi(int i) {
2337 EnsureSpace ensure_space(this);
2343 void Assembler::fucomip() {
2344 EnsureSpace ensure_space(this);
2350 void Assembler::fcompp() {
2351 EnsureSpace ensure_space(this);
2357 void Assembler::fnstsw_ax() {
2358 EnsureSpace ensure_space(this);
2364 void Assembler::fwait() {
2365 EnsureSpace ensure_space(this);
2370 void Assembler::frndint() {
2371 EnsureSpace ensure_space(this);
2377 void Assembler::fnclex() {
2378 EnsureSpace ensure_space(this);
2384 void Assembler::sahf() {
2385 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2386 // in 64-bit mode. Test CpuID.
2387 DCHECK(IsEnabled(SAHF));
2388 EnsureSpace ensure_space(this);
2393 void Assembler::emit_farith(int b1, int b2, int i) {
2394 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2395 DCHECK(is_uint3(i)); // illegal stack offset
2403 void Assembler::andps(XMMRegister dst, XMMRegister src) {
2404 EnsureSpace ensure_space(this);
2405 emit_optional_rex_32(dst, src);
2408 emit_sse_operand(dst, src);
2412 void Assembler::andps(XMMRegister dst, const Operand& src) {
2413 EnsureSpace ensure_space(this);
2414 emit_optional_rex_32(dst, src);
2417 emit_sse_operand(dst, src);
2421 void Assembler::orps(XMMRegister dst, XMMRegister src) {
2422 EnsureSpace ensure_space(this);
2423 emit_optional_rex_32(dst, src);
2426 emit_sse_operand(dst, src);
2430 void Assembler::orps(XMMRegister dst, const Operand& src) {
2431 EnsureSpace ensure_space(this);
2432 emit_optional_rex_32(dst, src);
2435 emit_sse_operand(dst, src);
2439 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2440 EnsureSpace ensure_space(this);
2441 emit_optional_rex_32(dst, src);
2444 emit_sse_operand(dst, src);
2448 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2449 EnsureSpace ensure_space(this);
2450 emit_optional_rex_32(dst, src);
2453 emit_sse_operand(dst, src);
2457 void Assembler::addps(XMMRegister dst, XMMRegister src) {
2458 EnsureSpace ensure_space(this);
2459 emit_optional_rex_32(dst, src);
2462 emit_sse_operand(dst, src);
2466 void Assembler::addps(XMMRegister dst, const Operand& src) {
2467 EnsureSpace ensure_space(this);
2468 emit_optional_rex_32(dst, src);
2471 emit_sse_operand(dst, src);
2475 void Assembler::subps(XMMRegister dst, XMMRegister src) {
2476 EnsureSpace ensure_space(this);
2477 emit_optional_rex_32(dst, src);
2480 emit_sse_operand(dst, src);
2484 void Assembler::subps(XMMRegister dst, const Operand& src) {
2485 EnsureSpace ensure_space(this);
2486 emit_optional_rex_32(dst, src);
2489 emit_sse_operand(dst, src);
2493 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2494 EnsureSpace ensure_space(this);
2495 emit_optional_rex_32(dst, src);
2498 emit_sse_operand(dst, src);
2502 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2503 EnsureSpace ensure_space(this);
2504 emit_optional_rex_32(dst, src);
2507 emit_sse_operand(dst, src);
2511 void Assembler::divps(XMMRegister dst, XMMRegister src) {
2512 EnsureSpace ensure_space(this);
2513 emit_optional_rex_32(dst, src);
2516 emit_sse_operand(dst, src);
2520 void Assembler::divps(XMMRegister dst, const Operand& src) {
2521 EnsureSpace ensure_space(this);
2522 emit_optional_rex_32(dst, src);
2525 emit_sse_operand(dst, src);
2529 // SSE 2 operations.
2531 void Assembler::movd(XMMRegister dst, Register src) {
2532 EnsureSpace ensure_space(this);
2534 emit_optional_rex_32(dst, src);
2537 emit_sse_operand(dst, src);
2541 void Assembler::movd(XMMRegister dst, const Operand& src) {
2542 EnsureSpace ensure_space(this);
2544 emit_optional_rex_32(dst, src);
2547 emit_sse_operand(dst, src);
2551 void Assembler::movd(Register dst, XMMRegister src) {
2552 EnsureSpace ensure_space(this);
2554 emit_optional_rex_32(src, dst);
2557 emit_sse_operand(src, dst);
2561 void Assembler::movq(XMMRegister dst, Register src) {
2562 EnsureSpace ensure_space(this);
2564 emit_rex_64(dst, src);
2567 emit_sse_operand(dst, src);
2571 void Assembler::movq(Register dst, XMMRegister src) {
2572 EnsureSpace ensure_space(this);
2574 emit_rex_64(src, dst);
2577 emit_sse_operand(src, dst);
2581 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2582 EnsureSpace ensure_space(this);
2583 if (dst.low_bits() == 4) {
2584 // Avoid unnecessary SIB byte.
2586 emit_optional_rex_32(dst, src);
2589 emit_sse_operand(dst, src);
2592 emit_optional_rex_32(src, dst);
2595 emit_sse_operand(src, dst);
2600 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2601 EnsureSpace ensure_space(this);
2603 emit_rex_64(src, dst);
2606 emit_sse_operand(src, dst);
2610 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2611 EnsureSpace ensure_space(this);
2613 emit_rex_64(dst, src);
2616 emit_sse_operand(dst, src);
2620 void Assembler::movdqu(const Operand& dst, XMMRegister src) {
2621 EnsureSpace ensure_space(this);
2623 emit_rex_64(src, dst);
2626 emit_sse_operand(src, dst);
2630 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2631 EnsureSpace ensure_space(this);
2633 emit_rex_64(dst, src);
2636 emit_sse_operand(dst, src);
2640 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2641 DCHECK(IsEnabled(SSE4_1));
2642 DCHECK(is_uint8(imm8));
2643 EnsureSpace ensure_space(this);
2645 emit_optional_rex_32(src, dst);
2649 emit_sse_operand(src, dst);
2654 void Assembler::pextrd(Register dst, XMMRegister src, int8_t imm8) {
2655 DCHECK(IsEnabled(SSE4_1));
2656 EnsureSpace ensure_space(this);
2658 emit_optional_rex_32(src, dst);
2662 emit_sse_operand(src, dst);
2667 void Assembler::pinsrd(XMMRegister dst, Register src, int8_t imm8) {
2668 DCHECK(IsEnabled(SSE4_1));
2669 EnsureSpace ensure_space(this);
2671 emit_optional_rex_32(dst, src);
2675 emit_sse_operand(dst, src);
2680 void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t imm8) {
2681 DCHECK(IsEnabled(SSE4_1));
2682 EnsureSpace ensure_space(this);
2684 emit_optional_rex_32(dst, src);
2688 emit_sse_operand(dst, src);
2693 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2694 EnsureSpace ensure_space(this);
2695 emit(0xF2); // double
2696 emit_optional_rex_32(src, dst);
2698 emit(0x11); // store
2699 emit_sse_operand(src, dst);
2703 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2704 EnsureSpace ensure_space(this);
2705 emit(0xF2); // double
2706 emit_optional_rex_32(dst, src);
2709 emit_sse_operand(dst, src);
2713 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2714 EnsureSpace ensure_space(this);
2715 emit(0xF2); // double
2716 emit_optional_rex_32(dst, src);
2719 emit_sse_operand(dst, src);
2723 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2724 EnsureSpace ensure_space(this);
2725 if (src.low_bits() == 4) {
2726 // Try to avoid an unnecessary SIB byte.
2727 emit_optional_rex_32(src, dst);
2730 emit_sse_operand(src, dst);
2732 emit_optional_rex_32(dst, src);
2735 emit_sse_operand(dst, src);
2740 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2741 DCHECK(is_uint8(imm8));
2742 EnsureSpace ensure_space(this);
2743 emit_optional_rex_32(src, dst);
2746 emit_sse_operand(dst, src);
2751 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2752 EnsureSpace ensure_space(this);
2753 if (src.low_bits() == 4) {
2754 // Try to avoid an unnecessary SIB byte.
2756 emit_optional_rex_32(src, dst);
2759 emit_sse_operand(src, dst);
2762 emit_optional_rex_32(dst, src);
2765 emit_sse_operand(dst, src);
2770 void Assembler::addss(XMMRegister dst, XMMRegister src) {
2771 EnsureSpace ensure_space(this);
2773 emit_optional_rex_32(dst, src);
2776 emit_sse_operand(dst, src);
2780 void Assembler::addss(XMMRegister dst, const Operand& src) {
2781 EnsureSpace ensure_space(this);
2783 emit_optional_rex_32(dst, src);
2786 emit_sse_operand(dst, src);
2790 void Assembler::subss(XMMRegister dst, XMMRegister src) {
2791 EnsureSpace ensure_space(this);
2793 emit_optional_rex_32(dst, src);
2796 emit_sse_operand(dst, src);
2800 void Assembler::subss(XMMRegister dst, const Operand& src) {
2801 EnsureSpace ensure_space(this);
2803 emit_optional_rex_32(dst, src);
2806 emit_sse_operand(dst, src);
2810 void Assembler::mulss(XMMRegister dst, XMMRegister src) {
2811 EnsureSpace ensure_space(this);
2813 emit_optional_rex_32(dst, src);
2816 emit_sse_operand(dst, src);
2820 void Assembler::mulss(XMMRegister dst, const Operand& src) {
2821 EnsureSpace ensure_space(this);
2823 emit_optional_rex_32(dst, src);
2826 emit_sse_operand(dst, src);
2830 void Assembler::divss(XMMRegister dst, XMMRegister src) {
2831 EnsureSpace ensure_space(this);
2833 emit_optional_rex_32(dst, src);
2836 emit_sse_operand(dst, src);
2840 void Assembler::divss(XMMRegister dst, const Operand& src) {
2841 EnsureSpace ensure_space(this);
2843 emit_optional_rex_32(dst, src);
2846 emit_sse_operand(dst, src);
2850 void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
2851 EnsureSpace ensure_space(this);
2852 emit_optional_rex_32(dst, src);
2855 emit_sse_operand(dst, src);
2859 void Assembler::ucomiss(XMMRegister dst, const Operand& src) {
2860 EnsureSpace ensure_space(this);
2861 emit_optional_rex_32(dst, src);
2864 emit_sse_operand(dst, src);
2868 void Assembler::movss(XMMRegister dst, const Operand& src) {
2869 EnsureSpace ensure_space(this);
2870 emit(0xF3); // single
2871 emit_optional_rex_32(dst, src);
2874 emit_sse_operand(dst, src);
2878 void Assembler::movss(const Operand& src, XMMRegister dst) {
2879 EnsureSpace ensure_space(this);
2880 emit(0xF3); // single
2881 emit_optional_rex_32(dst, src);
2883 emit(0x11); // store
2884 emit_sse_operand(dst, src);
2888 void Assembler::psllq(XMMRegister reg, byte imm8) {
2889 EnsureSpace ensure_space(this);
2891 emit_optional_rex_32(reg);
2894 emit_sse_operand(rsi, reg); // rsi == 6
2899 void Assembler::psrlq(XMMRegister reg, byte imm8) {
2900 EnsureSpace ensure_space(this);
2902 emit_optional_rex_32(reg);
2905 emit_sse_operand(rdx, reg); // rdx == 2
2910 void Assembler::pslld(XMMRegister reg, byte imm8) {
2911 EnsureSpace ensure_space(this);
2913 emit_optional_rex_32(reg);
2916 emit_sse_operand(rsi, reg); // rsi == 6
2921 void Assembler::psrld(XMMRegister reg, byte imm8) {
2922 EnsureSpace ensure_space(this);
2924 emit_optional_rex_32(reg);
2927 emit_sse_operand(rdx, reg); // rdx == 2
2932 void Assembler::cvttss2si(Register dst, const Operand& src) {
2933 EnsureSpace ensure_space(this);
2935 emit_optional_rex_32(dst, src);
2938 emit_operand(dst, src);
2942 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2943 EnsureSpace ensure_space(this);
2945 emit_optional_rex_32(dst, src);
2948 emit_sse_operand(dst, src);
2952 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2953 EnsureSpace ensure_space(this);
2955 emit_optional_rex_32(dst, src);
2958 emit_operand(dst, src);
2962 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2963 EnsureSpace ensure_space(this);
2965 emit_optional_rex_32(dst, src);
2968 emit_sse_operand(dst, src);
2972 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2973 EnsureSpace ensure_space(this);
2975 emit_rex_64(dst, src);
2978 emit_sse_operand(dst, src);
2982 void Assembler::cvttsd2siq(Register dst, const Operand& src) {
2983 EnsureSpace ensure_space(this);
2985 emit_rex_64(dst, src);
2988 emit_sse_operand(dst, src);
2992 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2993 EnsureSpace ensure_space(this);
2995 emit_optional_rex_32(dst, src);
2998 emit_sse_operand(dst, src);
3002 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
3003 EnsureSpace ensure_space(this);
3005 emit_optional_rex_32(dst, src);
3008 emit_sse_operand(dst, src);
3012 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
3013 EnsureSpace ensure_space(this);
3015 emit_optional_rex_32(dst, src);
3018 emit_sse_operand(dst, src);
3022 void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
3023 EnsureSpace ensure_space(this);
3025 emit_rex_64(dst, src);
3028 emit_sse_operand(dst, src);
3032 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
3033 EnsureSpace ensure_space(this);
3035 emit_rex_64(dst, src);
3038 emit_sse_operand(dst, src);
3042 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
3043 EnsureSpace ensure_space(this);
3045 emit_optional_rex_32(dst, src);
3048 emit_sse_operand(dst, src);
3052 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
3053 EnsureSpace ensure_space(this);
3055 emit_optional_rex_32(dst, src);
3058 emit_sse_operand(dst, src);
3062 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
3063 EnsureSpace ensure_space(this);
3065 emit_optional_rex_32(dst, src);
3068 emit_sse_operand(dst, src);
3072 void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
3073 EnsureSpace ensure_space(this);
3075 emit_optional_rex_32(dst, src);
3078 emit_sse_operand(dst, src);
3082 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
3083 EnsureSpace ensure_space(this);
3085 emit_optional_rex_32(dst, src);
3088 emit_sse_operand(dst, src);
3092 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
3093 EnsureSpace ensure_space(this);
3095 emit_rex_64(dst, src);
3098 emit_sse_operand(dst, src);
3102 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
3103 EnsureSpace ensure_space(this);
3105 emit_optional_rex_32(dst, src);
3108 emit_sse_operand(dst, src);
3112 void Assembler::addsd(XMMRegister dst, const Operand& src) {
3113 EnsureSpace ensure_space(this);
3115 emit_optional_rex_32(dst, src);
3118 emit_sse_operand(dst, src);
3122 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
3123 EnsureSpace ensure_space(this);
3125 emit_optional_rex_32(dst, src);
3128 emit_sse_operand(dst, src);
3132 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
3133 EnsureSpace ensure_space(this);
3135 emit_optional_rex_32(dst, src);
3138 emit_sse_operand(dst, src);
3142 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
3143 EnsureSpace ensure_space(this);
3145 emit_optional_rex_32(dst, src);
3148 emit_sse_operand(dst, src);
3152 void Assembler::subsd(XMMRegister dst, const Operand& src) {
3153 EnsureSpace ensure_space(this);
3155 emit_optional_rex_32(dst, src);
3158 emit_sse_operand(dst, src);
3162 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
3163 EnsureSpace ensure_space(this);
3165 emit_optional_rex_32(dst, src);
3168 emit_sse_operand(dst, src);
3172 void Assembler::divsd(XMMRegister dst, const Operand& src) {
3173 EnsureSpace ensure_space(this);
3175 emit_optional_rex_32(dst, src);
3178 emit_sse_operand(dst, src);
3182 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
3183 EnsureSpace ensure_space(this);
3185 emit_optional_rex_32(dst, src);
3188 emit_sse_operand(dst, src);
3192 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
3193 EnsureSpace ensure_space(this);
3195 emit_optional_rex_32(dst, src);
3198 emit_sse_operand(dst, src);
3202 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
3203 EnsureSpace ensure_space(this);
3205 emit_optional_rex_32(dst, src);
3208 emit_sse_operand(dst, src);
3212 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
3213 EnsureSpace ensure_space(this);
3215 emit_optional_rex_32(dst, src);
3218 emit_sse_operand(dst, src);
3222 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
3223 EnsureSpace ensure_space(this);
3225 emit_optional_rex_32(dst, src);
3228 emit_sse_operand(dst, src);
3232 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
3233 EnsureSpace ensure_space(this);
3235 emit_optional_rex_32(dst, src);
3238 emit_sse_operand(dst, src);
3242 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
3243 EnsureSpace ensure_space(this);
3245 emit_optional_rex_32(dst, src);
3248 emit_sse_operand(dst, src);
3252 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
3253 EnsureSpace ensure_space(this);
3255 emit_optional_rex_32(dst, src);
3258 emit_sse_operand(dst, src);
3259 emit(0x01); // LT == 1
3263 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3264 DCHECK(IsEnabled(SSE4_1));
3265 EnsureSpace ensure_space(this);
3267 emit_optional_rex_32(dst, src);
3271 emit_sse_operand(dst, src);
3272 // Mask precision exeption.
3273 emit(static_cast<byte>(mode) | 0x8);
3277 void Assembler::movmskpd(Register dst, XMMRegister src) {
3278 EnsureSpace ensure_space(this);
3280 emit_optional_rex_32(dst, src);
3283 emit_sse_operand(dst, src);
3287 void Assembler::movmskps(Register dst, XMMRegister src) {
3288 EnsureSpace ensure_space(this);
3289 emit_optional_rex_32(dst, src);
3292 emit_sse_operand(dst, src);
3296 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
3297 EnsureSpace ensure_space(this);
3299 emit_optional_rex_32(dst, src);
3302 emit_sse_operand(dst, src);
3306 void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
3307 EnsureSpace ensure_space(this);
3309 emit_optional_rex_32(dst, src);
3312 emit_sse_operand(dst, src);
3316 void Assembler::punpckhdq(XMMRegister dst, XMMRegister src) {
3317 EnsureSpace ensure_space(this);
3319 emit_optional_rex_32(dst, src);
3322 emit_sse_operand(dst, src);
3326 void Assembler::maxsd(XMMRegister dst, XMMRegister src) {
3327 EnsureSpace ensure_space(this);
3329 emit_optional_rex_32(dst, src);
3332 emit_sse_operand(dst, src);
3336 void Assembler::maxsd(XMMRegister dst, const Operand& src) {
3337 EnsureSpace ensure_space(this);
3339 emit_optional_rex_32(dst, src);
3342 emit_sse_operand(dst, src);
3346 void Assembler::minsd(XMMRegister dst, XMMRegister src) {
3347 EnsureSpace ensure_space(this);
3349 emit_optional_rex_32(dst, src);
3352 emit_sse_operand(dst, src);
3356 void Assembler::minsd(XMMRegister dst, const Operand& src) {
3357 EnsureSpace ensure_space(this);
3359 emit_optional_rex_32(dst, src);
3362 emit_sse_operand(dst, src);
3367 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
3369 DCHECK(IsEnabled(FMA3));
3370 EnsureSpace ensure_space(this);
3371 emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
3373 emit_sse_operand(dst, src2);
3377 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
3378 const Operand& src2) {
3379 DCHECK(IsEnabled(FMA3));
3380 EnsureSpace ensure_space(this);
3381 emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
3383 emit_sse_operand(dst, src2);
3387 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
3389 DCHECK(IsEnabled(FMA3));
3390 EnsureSpace ensure_space(this);
3391 emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
3393 emit_sse_operand(dst, src2);
3397 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
3398 const Operand& src2) {
3399 DCHECK(IsEnabled(FMA3));
3400 EnsureSpace ensure_space(this);
3401 emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
3403 emit_sse_operand(dst, src2);
3407 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
3409 DCHECK(IsEnabled(AVX));
3410 EnsureSpace ensure_space(this);
3411 emit_vex_prefix(dst, src1, src2, kLIG, kF2, k0F, kWIG);
3413 emit_sse_operand(dst, src2);
3417 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
3418 const Operand& src2) {
3419 DCHECK(IsEnabled(AVX));
3420 EnsureSpace ensure_space(this);
3421 emit_vex_prefix(dst, src1, src2, kLIG, kF2, k0F, kWIG);
3423 emit_sse_operand(dst, src2);
3427 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
3428 Register ireg = { reg.code() };
3429 emit_operand(ireg, adr);
3433 void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
3434 Register ireg = {reg.code()};
3435 emit_operand(ireg, adr);
3439 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3440 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3444 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3445 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3449 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3450 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3454 void Assembler::db(uint8_t data) {
3455 EnsureSpace ensure_space(this);
3460 void Assembler::dd(uint32_t data) {
3461 EnsureSpace ensure_space(this);
3466 void Assembler::dq(Label* label) {
3467 EnsureSpace ensure_space(this);
3468 if (label->is_bound()) {
3469 internal_reference_positions_.push_back(pc_offset());
3470 emitp(buffer_ + label->pos(), RelocInfo::INTERNAL_REFERENCE);
3472 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3473 emitl(0); // Zero for the first 32bit marks it as 64bit absolute address.
3474 if (label->is_linked()) {
3475 emitl(label->pos());
3476 label->link_to(pc_offset() - sizeof(int32_t));
3478 DCHECK(label->is_unused());
3479 int32_t current = pc_offset();
3481 label->link_to(current);
3487 // Relocation information implementations.
3489 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3490 DCHECK(!RelocInfo::IsNone(rmode));
3491 // Don't record external references unless the heap will be serialized.
3492 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
3493 !serializer_enabled() && !emit_debug_code()) {
3495 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
3496 // Don't record psuedo relocation info for code age sequence mode.
3499 RelocInfo rinfo(pc_, rmode, data, NULL);
3500 reloc_info_writer.Write(&rinfo);
3504 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3505 // No out-of-line constant pool support.
3506 DCHECK(!FLAG_enable_ool_constant_pool);
3507 return isolate->factory()->empty_constant_pool_array();
3511 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3512 // No out-of-line constant pool support.
3513 DCHECK(!FLAG_enable_ool_constant_pool);
3518 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3519 1 << RelocInfo::RUNTIME_ENTRY |
3520 1 << RelocInfo::INTERNAL_REFERENCE |
3521 1 << RelocInfo::CODE_AGE_SEQUENCE;
3524 bool RelocInfo::IsCodedSpecially() {
3525 // The deserializer needs to know whether a pointer is specially coded. Being
3526 // specially coded on x64 means that it is a relative 32 bit address, as used
3527 // by branch instructions.
3528 return (1 << rmode_) & kApplyMask;
3532 bool RelocInfo::IsInConstantPool() {
3537 } } // namespace v8::internal
3539 #endif // V8_TARGET_ARCH_X64