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.
9 #include "src/base/bits.h"
10 #include "src/macro-assembler.h"
11 #include "src/serialize.h"
16 // -----------------------------------------------------------------------------
17 // Implementation of CpuFeatures
19 void CpuFeatures::ProbeImpl(bool cross_compile) {
21 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
22 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
24 // Only use statically determined features for cross compile (snapshot).
25 if (cross_compile) return;
27 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
28 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
29 // SAHF is not generally available in long mode.
30 if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF;
34 void CpuFeatures::PrintTarget() { }
35 void CpuFeatures::PrintFeatures() { }
38 // -----------------------------------------------------------------------------
39 // Implementation of RelocInfo
41 // Patch the code at the current PC with a call to the target address.
42 // Additional guard int3 instructions can be added if required.
43 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
44 int code_size = Assembler::kCallSequenceLength + guard_bytes;
46 // Create a code patcher.
47 CodePatcher patcher(pc_, code_size);
49 // Add a label for checking the size of the code used for returning.
52 patcher.masm()->bind(&check_codesize);
56 patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target),
57 Assembler::RelocInfoNone());
58 patcher.masm()->call(kScratchRegister);
60 // Check that the size of the code generated is as expected.
61 DCHECK_EQ(Assembler::kCallSequenceLength,
62 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
64 // Add the requested number of int3 instructions after the call.
65 for (int i = 0; i < guard_bytes; i++) {
66 patcher.masm()->int3();
71 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
72 // Patch the code at the current address with the supplied instructions.
73 for (int i = 0; i < instruction_count; i++) {
74 *(pc_ + i) = *(instructions + i);
77 // Indicate that code has changed.
78 CpuFeatures::FlushICache(pc_, instruction_count);
82 // -----------------------------------------------------------------------------
83 // Register constants.
86 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
87 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r14, r15
88 0, 3, 2, 1, 6, 7, 8, 9, 11, 14, 15
91 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
92 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, -1, -1, 9, 10
96 // -----------------------------------------------------------------------------
97 // Implementation of Operand
99 Operand::Operand(Register base, int32_t disp) : rex_(0) {
101 if (base.is(rsp) || base.is(r12)) {
102 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
103 set_sib(times_1, rsp, base);
106 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
108 } else if (is_int8(disp)) {
118 Operand::Operand(Register base,
121 int32_t disp) : rex_(0) {
122 DCHECK(!index.is(rsp));
124 set_sib(scale, index, base);
125 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
126 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
127 // possibly set by set_sib.
129 } else if (is_int8(disp)) {
139 Operand::Operand(Register index,
141 int32_t disp) : rex_(0) {
142 DCHECK(!index.is(rsp));
145 set_sib(scale, index, rbp);
150 Operand::Operand(const Operand& operand, int32_t offset) {
151 DCHECK(operand.len_ >= 1);
152 // Operand encodes REX ModR/M [SIB] [Disp].
153 byte modrm = operand.buf_[0];
154 DCHECK(modrm < 0xC0); // Disallow mode 3 (register target).
155 bool has_sib = ((modrm & 0x07) == 0x04);
156 byte mode = modrm & 0xC0;
157 int disp_offset = has_sib ? 2 : 1;
158 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
159 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
161 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
162 int32_t disp_value = 0;
163 if (mode == 0x80 || is_baseless) {
164 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
165 disp_value = *bit_cast<const int32_t*>(&operand.buf_[disp_offset]);
166 } else if (mode == 0x40) {
167 // Mode 1: Byte displacement.
168 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
171 // Write new operand with same registers, but with modified displacement.
172 DCHECK(offset >= 0 ? disp_value + offset > disp_value
173 : disp_value + offset < disp_value); // No overflow.
174 disp_value += offset;
176 if (!is_int8(disp_value) || is_baseless) {
177 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
178 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
179 len_ = disp_offset + 4;
180 Memory::int32_at(&buf_[disp_offset]) = disp_value;
181 } else if (disp_value != 0 || (base_reg == 0x05)) {
182 // Need 8 bits of displacement.
183 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
184 len_ = disp_offset + 1;
185 buf_[disp_offset] = static_cast<byte>(disp_value);
187 // Need no displacement.
188 buf_[0] = (modrm & 0x3f); // Mode 0.
192 buf_[1] = operand.buf_[1];
197 bool Operand::AddressUsesRegister(Register reg) const {
198 int code = reg.code();
199 DCHECK((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
200 // Start with only low three bits of base register. Initial decoding doesn't
201 // distinguish on the REX.B bit.
202 int base_code = buf_[0] & 0x07;
203 if (base_code == rsp.code()) {
204 // SIB byte present in buf_[1].
205 // Check the index register from the SIB byte + REX.X prefix.
206 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
207 // Index code (including REX.X) of 0x04 (rsp) means no index register.
208 if (index_code != rsp.code() && index_code == code) return true;
209 // Add REX.B to get the full base register code.
210 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
211 // A base register of 0x05 (rbp) with mod = 0 means no base register.
212 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
213 return code == base_code;
215 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
217 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
218 base_code |= ((rex_ & 0x01) << 3);
219 return code == base_code;
224 // -----------------------------------------------------------------------------
225 // Implementation of Assembler.
227 #ifdef GENERATED_CODE_COVERAGE
228 static void InitCoverageLog();
231 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
232 : AssemblerBase(isolate, buffer, buffer_size),
234 positions_recorder_(this) {
235 // Clear the buffer in debug mode unless it was provided by the
236 // caller in which case we can't be sure it's okay to overwrite
237 // existing code in it.
240 memset(buffer_, 0xCC, buffer_size_); // int3
244 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
247 #ifdef GENERATED_CODE_COVERAGE
253 void Assembler::GetCode(CodeDesc* desc) {
254 // Finalize code (at this point overflow() may be true, but the gap ensures
255 // that we are still not overlapping instructions and relocation info).
256 DCHECK(pc_ <= reloc_info_writer.pos()); // No overlap.
257 // Set up code descriptor.
258 desc->buffer = buffer_;
259 desc->buffer_size = buffer_size_;
260 desc->instr_size = pc_offset();
261 DCHECK(desc->instr_size > 0); // Zero-size code objects upset the system.
263 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
268 void Assembler::Align(int m) {
269 DCHECK(base::bits::IsPowerOfTwo32(m));
270 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
275 void Assembler::CodeTargetAlign() {
276 Align(16); // Preferred alignment of jump targets on x64.
280 bool Assembler::IsNop(Address addr) {
282 while (*a == 0x66) a++;
283 if (*a == 0x90) return true;
284 if (a[0] == 0xf && a[1] == 0x1f) return true;
289 void Assembler::bind_to(Label* L, int pos) {
290 DCHECK(!L->is_bound()); // Label may only be bound once.
291 DCHECK(0 <= pos && pos <= pc_offset()); // Position must be valid.
292 if (L->is_linked()) {
293 int current = L->pos();
294 int next = long_at(current);
295 while (next != current) {
296 // Relative address, relative to point after address.
297 int imm32 = pos - (current + sizeof(int32_t));
298 long_at_put(current, imm32);
300 next = long_at(next);
302 // Fix up last fixup on linked list.
303 int last_imm32 = pos - (current + sizeof(int32_t));
304 long_at_put(current, last_imm32);
306 while (L->is_near_linked()) {
307 int fixup_pos = L->near_link_pos();
309 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
310 DCHECK(offset_to_next <= 0);
311 int disp = pos - (fixup_pos + sizeof(int8_t));
312 CHECK(is_int8(disp));
313 set_byte_at(fixup_pos, disp);
314 if (offset_to_next < 0) {
315 L->link_to(fixup_pos + offset_to_next, Label::kNear);
324 void Assembler::bind(Label* L) {
325 bind_to(L, pc_offset());
329 void Assembler::GrowBuffer() {
330 DCHECK(buffer_overflow());
331 if (!own_buffer_) FATAL("external code buffer is too small");
333 // Compute new buffer size.
334 CodeDesc desc; // the new buffer
335 desc.buffer_size = 2 * buffer_size_;
337 // Some internal data structures overflow for very large buffers,
338 // they must ensure that kMaximalBufferSize is not too large.
339 if ((desc.buffer_size > kMaximalBufferSize) ||
340 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
341 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
344 // Set up new buffer.
345 desc.buffer = NewArray<byte>(desc.buffer_size);
346 desc.instr_size = pc_offset();
348 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
350 // Clear the buffer in debug mode. Use 'int3' instructions to make
351 // sure to get into problems if we ever run uninitialized code.
353 memset(desc.buffer, 0xCC, desc.buffer_size);
357 intptr_t pc_delta = desc.buffer - buffer_;
358 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
359 (buffer_ + buffer_size_);
360 MemMove(desc.buffer, buffer_, desc.instr_size);
361 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
365 DeleteArray(buffer_);
366 buffer_ = desc.buffer;
367 buffer_size_ = desc.buffer_size;
369 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
370 reloc_info_writer.last_pc() + pc_delta);
372 // Relocate runtime entries.
373 for (RelocIterator it(desc); !it.done(); it.next()) {
374 RelocInfo::Mode rmode = it.rinfo()->rmode();
375 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
376 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
377 if (*p != 0) { // 0 means uninitialized.
383 DCHECK(!buffer_overflow());
387 void Assembler::emit_operand(int code, const Operand& adr) {
388 DCHECK(is_uint3(code));
389 const unsigned length = adr.len_;
392 // Emit updated ModR/M byte containing the given register.
393 DCHECK((adr.buf_[0] & 0x38) == 0);
394 pc_[0] = adr.buf_[0] | code << 3;
396 // Emit the rest of the encoded operand.
397 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
402 // Assembler Instruction implementations.
404 void Assembler::arithmetic_op(byte opcode,
408 EnsureSpace ensure_space(this);
409 emit_rex(reg, op, size);
411 emit_operand(reg, op);
415 void Assembler::arithmetic_op(byte opcode,
419 EnsureSpace ensure_space(this);
420 DCHECK((opcode & 0xC6) == 2);
421 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
422 // Swap reg and rm_reg and change opcode operand order.
423 emit_rex(rm_reg, reg, size);
425 emit_modrm(rm_reg, reg);
427 emit_rex(reg, rm_reg, size);
429 emit_modrm(reg, rm_reg);
434 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
435 EnsureSpace ensure_space(this);
436 DCHECK((opcode & 0xC6) == 2);
437 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
438 // Swap reg and rm_reg and change opcode operand order.
440 emit_optional_rex_32(rm_reg, reg);
442 emit_modrm(rm_reg, reg);
445 emit_optional_rex_32(reg, rm_reg);
447 emit_modrm(reg, rm_reg);
452 void Assembler::arithmetic_op_16(byte opcode,
454 const Operand& rm_reg) {
455 EnsureSpace ensure_space(this);
457 emit_optional_rex_32(reg, rm_reg);
459 emit_operand(reg, rm_reg);
463 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
464 EnsureSpace ensure_space(this);
465 if (!reg.is_byte_register()) {
466 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
470 emit_operand(reg, op);
474 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
475 EnsureSpace ensure_space(this);
476 DCHECK((opcode & 0xC6) == 2);
477 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
478 // Swap reg and rm_reg and change opcode operand order.
479 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
480 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
481 emit_rex_32(rm_reg, reg);
484 emit_modrm(rm_reg, reg);
486 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
487 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
488 emit_rex_32(reg, rm_reg);
491 emit_modrm(reg, rm_reg);
496 void Assembler::immediate_arithmetic_op(byte subcode,
500 EnsureSpace ensure_space(this);
502 if (is_int8(src.value_)) {
504 emit_modrm(subcode, dst);
506 } else if (dst.is(rax)) {
507 emit(0x05 | (subcode << 3));
511 emit_modrm(subcode, dst);
516 void Assembler::immediate_arithmetic_op(byte subcode,
520 EnsureSpace ensure_space(this);
522 if (is_int8(src.value_)) {
524 emit_operand(subcode, dst);
528 emit_operand(subcode, dst);
534 void Assembler::immediate_arithmetic_op_16(byte subcode,
537 EnsureSpace ensure_space(this);
538 emit(0x66); // Operand size override prefix.
539 emit_optional_rex_32(dst);
540 if (is_int8(src.value_)) {
542 emit_modrm(subcode, dst);
544 } else if (dst.is(rax)) {
545 emit(0x05 | (subcode << 3));
549 emit_modrm(subcode, dst);
555 void Assembler::immediate_arithmetic_op_16(byte subcode,
558 EnsureSpace ensure_space(this);
559 emit(0x66); // Operand size override prefix.
560 emit_optional_rex_32(dst);
561 if (is_int8(src.value_)) {
563 emit_operand(subcode, dst);
567 emit_operand(subcode, dst);
573 void Assembler::immediate_arithmetic_op_8(byte subcode,
576 EnsureSpace ensure_space(this);
577 emit_optional_rex_32(dst);
578 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
580 emit_operand(subcode, dst);
585 void Assembler::immediate_arithmetic_op_8(byte subcode,
588 EnsureSpace ensure_space(this);
589 if (!dst.is_byte_register()) {
590 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
593 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
595 emit_modrm(subcode, dst);
600 void Assembler::shift(Register dst,
601 Immediate shift_amount,
604 EnsureSpace ensure_space(this);
605 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
606 : is_uint5(shift_amount.value_));
607 if (shift_amount.value_ == 1) {
610 emit_modrm(subcode, dst);
614 emit_modrm(subcode, dst);
615 emit(shift_amount.value_);
620 void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
622 EnsureSpace ensure_space(this);
623 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
624 : is_uint5(shift_amount.value_));
625 if (shift_amount.value_ == 1) {
628 emit_operand(subcode, dst);
632 emit_operand(subcode, dst);
633 emit(shift_amount.value_);
638 void Assembler::shift(Register dst, int subcode, int size) {
639 EnsureSpace ensure_space(this);
642 emit_modrm(subcode, dst);
646 void Assembler::shift(Operand dst, int subcode, int size) {
647 EnsureSpace ensure_space(this);
650 emit_operand(subcode, dst);
654 void Assembler::bt(const Operand& dst, Register src) {
655 EnsureSpace ensure_space(this);
656 emit_rex_64(src, dst);
659 emit_operand(src, dst);
663 void Assembler::bts(const Operand& dst, Register src) {
664 EnsureSpace ensure_space(this);
665 emit_rex_64(src, dst);
668 emit_operand(src, dst);
672 void Assembler::bsrl(Register dst, Register src) {
673 EnsureSpace ensure_space(this);
674 emit_optional_rex_32(dst, src);
677 emit_modrm(dst, src);
681 void Assembler::call(Label* L) {
682 positions_recorder()->WriteRecordedPositions();
683 EnsureSpace ensure_space(this);
684 // 1110 1000 #32-bit disp.
687 int offset = L->pos() - pc_offset() - sizeof(int32_t);
690 } else if (L->is_linked()) {
692 L->link_to(pc_offset() - sizeof(int32_t));
694 DCHECK(L->is_unused());
695 int32_t current = pc_offset();
702 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
703 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
704 positions_recorder()->WriteRecordedPositions();
705 EnsureSpace ensure_space(this);
706 // 1110 1000 #32-bit disp.
708 emit_runtime_entry(entry, rmode);
712 void Assembler::call(Handle<Code> target,
713 RelocInfo::Mode rmode,
714 TypeFeedbackId ast_id) {
715 positions_recorder()->WriteRecordedPositions();
716 EnsureSpace ensure_space(this);
717 // 1110 1000 #32-bit disp.
719 emit_code_target(target, rmode, ast_id);
723 void Assembler::call(Register adr) {
724 positions_recorder()->WriteRecordedPositions();
725 EnsureSpace ensure_space(this);
726 // Opcode: FF /2 r64.
727 emit_optional_rex_32(adr);
729 emit_modrm(0x2, adr);
733 void Assembler::call(const Operand& op) {
734 positions_recorder()->WriteRecordedPositions();
735 EnsureSpace ensure_space(this);
736 // Opcode: FF /2 m64.
737 emit_optional_rex_32(op);
739 emit_operand(0x2, op);
743 // Calls directly to the given address using a relative offset.
744 // Should only ever be used in Code objects for calls within the
745 // same Code object. Should not be used when generating new code (use labels),
746 // but only when patching existing code.
747 void Assembler::call(Address target) {
748 positions_recorder()->WriteRecordedPositions();
749 EnsureSpace ensure_space(this);
750 // 1110 1000 #32-bit disp.
752 Address source = pc_ + 4;
753 intptr_t displacement = target - source;
754 DCHECK(is_int32(displacement));
755 emitl(static_cast<int32_t>(displacement));
759 void Assembler::clc() {
760 EnsureSpace ensure_space(this);
765 void Assembler::cld() {
766 EnsureSpace ensure_space(this);
771 void Assembler::cdq() {
772 EnsureSpace ensure_space(this);
777 void Assembler::cmovq(Condition cc, Register dst, Register src) {
780 } else if (cc == never) {
783 // No need to check CpuInfo for CMOV support, it's a required part of the
784 // 64-bit architecture.
785 DCHECK(cc >= 0); // Use mov for unconditional moves.
786 EnsureSpace ensure_space(this);
787 // Opcode: REX.W 0f 40 + cc /r.
788 emit_rex_64(dst, src);
791 emit_modrm(dst, src);
795 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
798 } else if (cc == never) {
802 EnsureSpace ensure_space(this);
803 // Opcode: REX.W 0f 40 + cc /r.
804 emit_rex_64(dst, src);
807 emit_operand(dst, src);
811 void Assembler::cmovl(Condition cc, Register dst, Register src) {
814 } else if (cc == never) {
818 EnsureSpace ensure_space(this);
819 // Opcode: 0f 40 + cc /r.
820 emit_optional_rex_32(dst, src);
823 emit_modrm(dst, src);
827 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
830 } else if (cc == never) {
834 EnsureSpace ensure_space(this);
835 // Opcode: 0f 40 + cc /r.
836 emit_optional_rex_32(dst, src);
839 emit_operand(dst, src);
843 void Assembler::cmpb_al(Immediate imm8) {
844 DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
845 EnsureSpace ensure_space(this);
851 void Assembler::cpuid() {
852 EnsureSpace ensure_space(this);
858 void Assembler::cqo() {
859 EnsureSpace ensure_space(this);
865 void Assembler::emit_dec(Register dst, int size) {
866 EnsureSpace ensure_space(this);
869 emit_modrm(0x1, dst);
873 void Assembler::emit_dec(const Operand& dst, int size) {
874 EnsureSpace ensure_space(this);
877 emit_operand(1, dst);
881 void Assembler::decb(Register dst) {
882 EnsureSpace ensure_space(this);
883 if (!dst.is_byte_register()) {
884 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
888 emit_modrm(0x1, dst);
892 void Assembler::decb(const Operand& dst) {
893 EnsureSpace ensure_space(this);
894 emit_optional_rex_32(dst);
896 emit_operand(1, dst);
900 void Assembler::enter(Immediate size) {
901 EnsureSpace ensure_space(this);
903 emitw(size.value_); // 16 bit operand, always.
908 void Assembler::hlt() {
909 EnsureSpace ensure_space(this);
914 void Assembler::emit_idiv(Register src, int size) {
915 EnsureSpace ensure_space(this);
918 emit_modrm(0x7, src);
922 void Assembler::emit_div(Register src, int size) {
923 EnsureSpace ensure_space(this);
926 emit_modrm(0x6, src);
930 void Assembler::emit_imul(Register src, int size) {
931 EnsureSpace ensure_space(this);
934 emit_modrm(0x5, src);
938 void Assembler::emit_imul(const Operand& src, int size) {
939 EnsureSpace ensure_space(this);
942 emit_operand(0x5, src);
946 void Assembler::emit_imul(Register dst, Register src, int size) {
947 EnsureSpace ensure_space(this);
948 emit_rex(dst, src, size);
951 emit_modrm(dst, src);
955 void Assembler::emit_imul(Register dst, const Operand& src, int size) {
956 EnsureSpace ensure_space(this);
957 emit_rex(dst, src, size);
960 emit_operand(dst, src);
964 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
965 EnsureSpace ensure_space(this);
966 emit_rex(dst, src, size);
967 if (is_int8(imm.value_)) {
969 emit_modrm(dst, src);
973 emit_modrm(dst, src);
979 void Assembler::emit_imul(Register dst, const Operand& src, Immediate imm,
981 EnsureSpace ensure_space(this);
982 emit_rex(dst, src, size);
983 if (is_int8(imm.value_)) {
985 emit_operand(dst, src);
989 emit_operand(dst, src);
995 void Assembler::emit_inc(Register dst, int size) {
996 EnsureSpace ensure_space(this);
999 emit_modrm(0x0, dst);
1003 void Assembler::emit_inc(const Operand& dst, int size) {
1004 EnsureSpace ensure_space(this);
1005 emit_rex(dst, size);
1007 emit_operand(0, dst);
1011 void Assembler::int3() {
1012 EnsureSpace ensure_space(this);
1017 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1021 } else if (cc == never) {
1024 EnsureSpace ensure_space(this);
1025 DCHECK(is_uint4(cc));
1026 if (L->is_bound()) {
1027 const int short_size = 2;
1028 const int long_size = 6;
1029 int offs = L->pos() - pc_offset();
1031 // Determine whether we can use 1-byte offsets for backwards branches,
1032 // which have a max range of 128 bytes.
1034 // We also need to check predictable_code_size() flag here, because on x64,
1035 // when the full code generator recompiles code for debugging, some places
1036 // need to be padded out to a certain size. The debugger is keeping track of
1037 // how often it did this so that it can adjust return addresses on the
1038 // stack, but if the size of jump instructions can also change, that's not
1039 // enough and the calculated offsets would be incorrect.
1040 if (is_int8(offs - short_size) && !predictable_code_size()) {
1041 // 0111 tttn #8-bit disp.
1043 emit((offs - short_size) & 0xFF);
1045 // 0000 1111 1000 tttn #32-bit disp.
1048 emitl(offs - long_size);
1050 } else if (distance == Label::kNear) {
1051 // 0111 tttn #8-bit disp
1054 if (L->is_near_linked()) {
1055 int offset = L->near_link_pos() - pc_offset();
1056 DCHECK(is_int8(offset));
1057 disp = static_cast<byte>(offset & 0xFF);
1059 L->link_to(pc_offset(), Label::kNear);
1061 } else if (L->is_linked()) {
1062 // 0000 1111 1000 tttn #32-bit disp.
1066 L->link_to(pc_offset() - sizeof(int32_t));
1068 DCHECK(L->is_unused());
1071 int32_t current = pc_offset();
1073 L->link_to(current);
1078 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1079 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1080 EnsureSpace ensure_space(this);
1081 DCHECK(is_uint4(cc));
1084 emit_runtime_entry(entry, rmode);
1088 void Assembler::j(Condition cc,
1089 Handle<Code> target,
1090 RelocInfo::Mode rmode) {
1091 EnsureSpace ensure_space(this);
1092 DCHECK(is_uint4(cc));
1093 // 0000 1111 1000 tttn #32-bit disp.
1096 emit_code_target(target, rmode);
1100 void Assembler::jmp(Label* L, Label::Distance distance) {
1101 EnsureSpace ensure_space(this);
1102 const int short_size = sizeof(int8_t);
1103 const int long_size = sizeof(int32_t);
1104 if (L->is_bound()) {
1105 int offs = L->pos() - pc_offset() - 1;
1107 if (is_int8(offs - short_size) && !predictable_code_size()) {
1108 // 1110 1011 #8-bit disp.
1110 emit((offs - short_size) & 0xFF);
1112 // 1110 1001 #32-bit disp.
1114 emitl(offs - long_size);
1116 } else if (distance == Label::kNear) {
1119 if (L->is_near_linked()) {
1120 int offset = L->near_link_pos() - pc_offset();
1121 DCHECK(is_int8(offset));
1122 disp = static_cast<byte>(offset & 0xFF);
1124 L->link_to(pc_offset(), Label::kNear);
1126 } else if (L->is_linked()) {
1127 // 1110 1001 #32-bit disp.
1130 L->link_to(pc_offset() - long_size);
1132 // 1110 1001 #32-bit disp.
1133 DCHECK(L->is_unused());
1135 int32_t current = pc_offset();
1137 L->link_to(current);
1142 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1143 EnsureSpace ensure_space(this);
1144 // 1110 1001 #32-bit disp.
1146 emit_code_target(target, rmode);
1150 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1151 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1152 EnsureSpace ensure_space(this);
1153 DCHECK(RelocInfo::IsRuntimeEntry(rmode));
1155 emit_runtime_entry(entry, rmode);
1159 void Assembler::jmp(Register target) {
1160 EnsureSpace ensure_space(this);
1162 emit_optional_rex_32(target);
1164 emit_modrm(0x4, target);
1168 void Assembler::jmp(const Operand& src) {
1169 EnsureSpace ensure_space(this);
1171 emit_optional_rex_32(src);
1173 emit_operand(0x4, src);
1177 void Assembler::emit_lea(Register dst, const Operand& src, int size) {
1178 EnsureSpace ensure_space(this);
1179 emit_rex(dst, src, size);
1181 emit_operand(dst, src);
1185 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1186 EnsureSpace ensure_space(this);
1187 if (kPointerSize == kInt64Size) {
1188 emit(0x48); // REX.W
1192 DCHECK(kPointerSize == kInt32Size);
1195 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1196 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1197 // Developer's Manual Volume 2.
1203 void Assembler::load_rax(ExternalReference ref) {
1204 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1208 void Assembler::leave() {
1209 EnsureSpace ensure_space(this);
1214 void Assembler::movb(Register dst, const Operand& src) {
1215 EnsureSpace ensure_space(this);
1216 if (!dst.is_byte_register()) {
1217 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1218 emit_rex_32(dst, src);
1220 emit_optional_rex_32(dst, src);
1223 emit_operand(dst, src);
1227 void Assembler::movb(Register dst, Immediate imm) {
1228 EnsureSpace ensure_space(this);
1229 if (!dst.is_byte_register()) {
1230 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1233 emit(0xB0 + dst.low_bits());
1238 void Assembler::movb(const Operand& dst, Register src) {
1239 EnsureSpace ensure_space(this);
1240 if (!src.is_byte_register()) {
1241 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1242 emit_rex_32(src, dst);
1244 emit_optional_rex_32(src, dst);
1247 emit_operand(src, dst);
1251 void Assembler::movb(const Operand& dst, Immediate imm) {
1252 EnsureSpace ensure_space(this);
1253 emit_optional_rex_32(dst);
1255 emit_operand(0x0, dst);
1256 emit(static_cast<byte>(imm.value_));
1260 void Assembler::movw(Register dst, const Operand& src) {
1261 EnsureSpace ensure_space(this);
1263 emit_optional_rex_32(dst, src);
1265 emit_operand(dst, src);
1269 void Assembler::movw(const Operand& dst, Register src) {
1270 EnsureSpace ensure_space(this);
1272 emit_optional_rex_32(src, dst);
1274 emit_operand(src, dst);
1278 void Assembler::movw(const Operand& dst, Immediate imm) {
1279 EnsureSpace ensure_space(this);
1281 emit_optional_rex_32(dst);
1283 emit_operand(0x0, dst);
1284 emit(static_cast<byte>(imm.value_ & 0xff));
1285 emit(static_cast<byte>(imm.value_ >> 8));
1289 void Assembler::emit_mov(Register dst, const Operand& src, int size) {
1290 EnsureSpace ensure_space(this);
1291 emit_rex(dst, src, size);
1293 emit_operand(dst, src);
1297 void Assembler::emit_mov(Register dst, Register src, int size) {
1298 EnsureSpace ensure_space(this);
1299 if (src.low_bits() == 4) {
1300 emit_rex(src, dst, size);
1302 emit_modrm(src, dst);
1304 emit_rex(dst, src, size);
1306 emit_modrm(dst, src);
1311 void Assembler::emit_mov(const Operand& dst, Register src, int size) {
1312 EnsureSpace ensure_space(this);
1313 emit_rex(src, dst, size);
1315 emit_operand(src, dst);
1319 void Assembler::emit_mov(Register dst, Immediate value, int size) {
1320 EnsureSpace ensure_space(this);
1321 emit_rex(dst, size);
1322 if (size == kInt64Size) {
1324 emit_modrm(0x0, dst);
1326 DCHECK(size == kInt32Size);
1327 emit(0xB8 + dst.low_bits());
1333 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
1334 EnsureSpace ensure_space(this);
1335 emit_rex(dst, size);
1337 emit_operand(0x0, dst);
1342 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
1343 EnsureSpace ensure_space(this);
1344 emit_rex(dst, kPointerSize);
1345 emit(0xB8 | dst.low_bits());
1346 emitp(value, rmode);
1350 void Assembler::movq(Register dst, int64_t value) {
1351 EnsureSpace ensure_space(this);
1353 emit(0xB8 | dst.low_bits());
1358 void Assembler::movq(Register dst, uint64_t value) {
1359 movq(dst, static_cast<int64_t>(value));
1363 // Loads the ip-relative location of the src label into the target location
1364 // (as a 32-bit offset sign extended to 64-bit).
1365 void Assembler::movl(const Operand& dst, Label* src) {
1366 EnsureSpace ensure_space(this);
1367 emit_optional_rex_32(dst);
1369 emit_operand(0, dst);
1370 if (src->is_bound()) {
1371 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1372 DCHECK(offset <= 0);
1374 } else if (src->is_linked()) {
1376 src->link_to(pc_offset() - sizeof(int32_t));
1378 DCHECK(src->is_unused());
1379 int32_t current = pc_offset();
1381 src->link_to(current);
1386 void Assembler::movsxbl(Register dst, const Operand& src) {
1387 EnsureSpace ensure_space(this);
1388 emit_optional_rex_32(dst, src);
1391 emit_operand(dst, src);
1395 void Assembler::movsxbq(Register dst, const Operand& src) {
1396 EnsureSpace ensure_space(this);
1397 emit_rex_64(dst, src);
1400 emit_operand(dst, src);
1404 void Assembler::movsxwl(Register dst, const Operand& src) {
1405 EnsureSpace ensure_space(this);
1406 emit_optional_rex_32(dst, src);
1409 emit_operand(dst, src);
1413 void Assembler::movsxwq(Register dst, const Operand& src) {
1414 EnsureSpace ensure_space(this);
1415 emit_rex_64(dst, src);
1418 emit_operand(dst, src);
1422 void Assembler::movsxlq(Register dst, Register src) {
1423 EnsureSpace ensure_space(this);
1424 emit_rex_64(dst, src);
1426 emit_modrm(dst, src);
1430 void Assembler::movsxlq(Register dst, const Operand& src) {
1431 EnsureSpace ensure_space(this);
1432 emit_rex_64(dst, src);
1434 emit_operand(dst, src);
1438 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
1439 EnsureSpace ensure_space(this);
1440 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1441 // there is no need to make this a 64 bit operation.
1442 emit_optional_rex_32(dst, src);
1445 emit_operand(dst, src);
1449 void Assembler::emit_movzxb(Register dst, Register src, int size) {
1450 EnsureSpace ensure_space(this);
1451 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1452 // there is no need to make this a 64 bit operation.
1453 if (!src.is_byte_register()) {
1454 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1455 emit_rex_32(dst, src);
1457 emit_optional_rex_32(dst, src);
1461 emit_modrm(dst, src);
1465 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
1466 EnsureSpace ensure_space(this);
1467 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1468 // there is no need to make this a 64 bit operation.
1469 emit_optional_rex_32(dst, src);
1472 emit_operand(dst, src);
1476 void Assembler::emit_movzxw(Register dst, Register src, int size) {
1477 EnsureSpace ensure_space(this);
1478 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1479 // there is no need to make this a 64 bit operation.
1480 emit_optional_rex_32(dst, src);
1483 emit_modrm(dst, src);
1487 void Assembler::repmovsb() {
1488 EnsureSpace ensure_space(this);
1494 void Assembler::repmovsw() {
1495 EnsureSpace ensure_space(this);
1496 emit(0x66); // Operand size override.
1502 void Assembler::emit_repmovs(int size) {
1503 EnsureSpace ensure_space(this);
1510 void Assembler::mull(Register src) {
1511 EnsureSpace ensure_space(this);
1512 emit_optional_rex_32(src);
1514 emit_modrm(0x4, src);
1518 void Assembler::mull(const Operand& src) {
1519 EnsureSpace ensure_space(this);
1520 emit_optional_rex_32(src);
1522 emit_operand(0x4, src);
1526 void Assembler::mulq(Register src) {
1527 EnsureSpace ensure_space(this);
1530 emit_modrm(0x4, src);
1534 void Assembler::emit_neg(Register dst, int size) {
1535 EnsureSpace ensure_space(this);
1536 emit_rex(dst, size);
1538 emit_modrm(0x3, dst);
1542 void Assembler::emit_neg(const Operand& dst, int size) {
1543 EnsureSpace ensure_space(this);
1546 emit_operand(3, dst);
1550 void Assembler::nop() {
1551 EnsureSpace ensure_space(this);
1556 void Assembler::emit_not(Register dst, int size) {
1557 EnsureSpace ensure_space(this);
1558 emit_rex(dst, size);
1560 emit_modrm(0x2, dst);
1564 void Assembler::emit_not(const Operand& dst, int size) {
1565 EnsureSpace ensure_space(this);
1566 emit_rex(dst, size);
1568 emit_operand(2, dst);
1572 void Assembler::Nop(int n) {
1573 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1574 // and IA-32 Architectures Software Developer's Manual.
1576 // Length Assembly Byte Sequence
1577 // 2 bytes 66 NOP 66 90H
1578 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1579 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1580 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1581 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1582 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1583 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1584 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1587 EnsureSpace ensure_space(this);
1649 void Assembler::popq(Register dst) {
1650 EnsureSpace ensure_space(this);
1651 emit_optional_rex_32(dst);
1652 emit(0x58 | dst.low_bits());
1656 void Assembler::popq(const Operand& dst) {
1657 EnsureSpace ensure_space(this);
1658 emit_optional_rex_32(dst);
1660 emit_operand(0, dst);
1664 void Assembler::popfq() {
1665 EnsureSpace ensure_space(this);
1670 void Assembler::pushq(Register src) {
1671 EnsureSpace ensure_space(this);
1672 emit_optional_rex_32(src);
1673 emit(0x50 | src.low_bits());
1677 void Assembler::pushq(const Operand& src) {
1678 EnsureSpace ensure_space(this);
1679 emit_optional_rex_32(src);
1681 emit_operand(6, src);
1685 void Assembler::pushq(Immediate value) {
1686 EnsureSpace ensure_space(this);
1687 if (is_int8(value.value_)) {
1689 emit(value.value_); // Emit low byte of value.
1692 emitl(value.value_);
1697 void Assembler::pushq_imm32(int32_t imm32) {
1698 EnsureSpace ensure_space(this);
1704 void Assembler::pushfq() {
1705 EnsureSpace ensure_space(this);
1710 void Assembler::ret(int imm16) {
1711 EnsureSpace ensure_space(this);
1712 DCHECK(is_uint16(imm16));
1718 emit((imm16 >> 8) & 0xFF);
1723 void Assembler::setcc(Condition cc, Register reg) {
1724 if (cc > last_condition) {
1725 movb(reg, Immediate(cc == always ? 1 : 0));
1728 EnsureSpace ensure_space(this);
1729 DCHECK(is_uint4(cc));
1730 if (!reg.is_byte_register()) {
1731 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1736 emit_modrm(0x0, reg);
1740 void Assembler::shld(Register dst, Register src) {
1741 EnsureSpace ensure_space(this);
1742 emit_rex_64(src, dst);
1745 emit_modrm(src, dst);
1749 void Assembler::shrd(Register dst, Register src) {
1750 EnsureSpace ensure_space(this);
1751 emit_rex_64(src, dst);
1754 emit_modrm(src, dst);
1758 void Assembler::emit_xchg(Register dst, Register src, int size) {
1759 EnsureSpace ensure_space(this);
1760 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1761 Register other = src.is(rax) ? dst : src;
1762 emit_rex(other, size);
1763 emit(0x90 | other.low_bits());
1764 } else if (dst.low_bits() == 4) {
1765 emit_rex(dst, src, size);
1767 emit_modrm(dst, src);
1769 emit_rex(src, dst, size);
1771 emit_modrm(src, dst);
1776 void Assembler::emit_xchg(Register dst, const Operand& src, int size) {
1777 EnsureSpace ensure_space(this);
1778 emit_rex(dst, src, size);
1780 emit_operand(dst, src);
1784 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1785 EnsureSpace ensure_space(this);
1786 if (kPointerSize == kInt64Size) {
1787 emit(0x48); // REX.W
1791 DCHECK(kPointerSize == kInt32Size);
1794 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1795 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1796 // Developer's Manual Volume 2.
1802 void Assembler::store_rax(ExternalReference ref) {
1803 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1807 void Assembler::testb(Register dst, Register src) {
1808 EnsureSpace ensure_space(this);
1809 if (src.low_bits() == 4) {
1810 emit_rex_32(src, dst);
1812 emit_modrm(src, dst);
1814 if (!dst.is_byte_register() || !src.is_byte_register()) {
1815 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1816 emit_rex_32(dst, src);
1819 emit_modrm(dst, src);
1824 void Assembler::testb(Register reg, Immediate mask) {
1825 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1826 EnsureSpace ensure_space(this);
1829 emit(mask.value_); // Low byte emitted.
1831 if (!reg.is_byte_register()) {
1832 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1836 emit_modrm(0x0, reg);
1837 emit(mask.value_); // Low byte emitted.
1842 void Assembler::testb(const Operand& op, Immediate mask) {
1843 DCHECK(is_int8(mask.value_) || is_uint8(mask.value_));
1844 EnsureSpace ensure_space(this);
1845 emit_optional_rex_32(rax, op);
1847 emit_operand(rax, op); // Operation code 0
1848 emit(mask.value_); // Low byte emitted.
1852 void Assembler::testb(const Operand& op, Register reg) {
1853 EnsureSpace ensure_space(this);
1854 if (!reg.is_byte_register()) {
1855 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1856 emit_rex_32(reg, op);
1858 emit_optional_rex_32(reg, op);
1861 emit_operand(reg, op);
1865 void Assembler::emit_test(Register dst, Register src, int size) {
1866 EnsureSpace ensure_space(this);
1867 if (src.low_bits() == 4) {
1868 emit_rex(src, dst, size);
1870 emit_modrm(src, dst);
1872 emit_rex(dst, src, size);
1874 emit_modrm(dst, src);
1879 void Assembler::emit_test(Register reg, Immediate mask, int size) {
1880 // testl with a mask that fits in the low byte is exactly testb.
1881 if (is_uint8(mask.value_)) {
1885 EnsureSpace ensure_space(this);
1887 emit_rex(rax, size);
1891 emit_rex(reg, size);
1893 emit_modrm(0x0, reg);
1899 void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
1900 // testl with a mask that fits in the low byte is exactly testb.
1901 if (is_uint8(mask.value_)) {
1905 EnsureSpace ensure_space(this);
1906 emit_rex(rax, op, size);
1908 emit_operand(rax, op); // Operation code 0
1913 void Assembler::emit_test(const Operand& op, Register reg, int size) {
1914 EnsureSpace ensure_space(this);
1915 emit_rex(reg, op, size);
1917 emit_operand(reg, op);
1921 // FPU instructions.
1924 void Assembler::fld(int i) {
1925 EnsureSpace ensure_space(this);
1926 emit_farith(0xD9, 0xC0, i);
1930 void Assembler::fld1() {
1931 EnsureSpace ensure_space(this);
1937 void Assembler::fldz() {
1938 EnsureSpace ensure_space(this);
1944 void Assembler::fldpi() {
1945 EnsureSpace ensure_space(this);
1951 void Assembler::fldln2() {
1952 EnsureSpace ensure_space(this);
1958 void Assembler::fld_s(const Operand& adr) {
1959 EnsureSpace ensure_space(this);
1960 emit_optional_rex_32(adr);
1962 emit_operand(0, adr);
1966 void Assembler::fld_d(const Operand& adr) {
1967 EnsureSpace ensure_space(this);
1968 emit_optional_rex_32(adr);
1970 emit_operand(0, adr);
1974 void Assembler::fstp_s(const Operand& adr) {
1975 EnsureSpace ensure_space(this);
1976 emit_optional_rex_32(adr);
1978 emit_operand(3, adr);
1982 void Assembler::fstp_d(const Operand& adr) {
1983 EnsureSpace ensure_space(this);
1984 emit_optional_rex_32(adr);
1986 emit_operand(3, adr);
1990 void Assembler::fstp(int index) {
1991 DCHECK(is_uint3(index));
1992 EnsureSpace ensure_space(this);
1993 emit_farith(0xDD, 0xD8, index);
1997 void Assembler::fild_s(const Operand& adr) {
1998 EnsureSpace ensure_space(this);
1999 emit_optional_rex_32(adr);
2001 emit_operand(0, adr);
2005 void Assembler::fild_d(const Operand& adr) {
2006 EnsureSpace ensure_space(this);
2007 emit_optional_rex_32(adr);
2009 emit_operand(5, adr);
2013 void Assembler::fistp_s(const Operand& adr) {
2014 EnsureSpace ensure_space(this);
2015 emit_optional_rex_32(adr);
2017 emit_operand(3, adr);
2021 void Assembler::fisttp_s(const Operand& adr) {
2022 DCHECK(IsEnabled(SSE3));
2023 EnsureSpace ensure_space(this);
2024 emit_optional_rex_32(adr);
2026 emit_operand(1, adr);
2030 void Assembler::fisttp_d(const Operand& adr) {
2031 DCHECK(IsEnabled(SSE3));
2032 EnsureSpace ensure_space(this);
2033 emit_optional_rex_32(adr);
2035 emit_operand(1, adr);
2039 void Assembler::fist_s(const Operand& adr) {
2040 EnsureSpace ensure_space(this);
2041 emit_optional_rex_32(adr);
2043 emit_operand(2, adr);
2047 void Assembler::fistp_d(const Operand& adr) {
2048 EnsureSpace ensure_space(this);
2049 emit_optional_rex_32(adr);
2051 emit_operand(7, adr);
2055 void Assembler::fabs() {
2056 EnsureSpace ensure_space(this);
2062 void Assembler::fchs() {
2063 EnsureSpace ensure_space(this);
2069 void Assembler::fcos() {
2070 EnsureSpace ensure_space(this);
2076 void Assembler::fsin() {
2077 EnsureSpace ensure_space(this);
2083 void Assembler::fptan() {
2084 EnsureSpace ensure_space(this);
2090 void Assembler::fyl2x() {
2091 EnsureSpace ensure_space(this);
2097 void Assembler::f2xm1() {
2098 EnsureSpace ensure_space(this);
2104 void Assembler::fscale() {
2105 EnsureSpace ensure_space(this);
2111 void Assembler::fninit() {
2112 EnsureSpace ensure_space(this);
2118 void Assembler::fadd(int i) {
2119 EnsureSpace ensure_space(this);
2120 emit_farith(0xDC, 0xC0, i);
2124 void Assembler::fsub(int i) {
2125 EnsureSpace ensure_space(this);
2126 emit_farith(0xDC, 0xE8, i);
2130 void Assembler::fisub_s(const Operand& adr) {
2131 EnsureSpace ensure_space(this);
2132 emit_optional_rex_32(adr);
2134 emit_operand(4, adr);
2138 void Assembler::fmul(int i) {
2139 EnsureSpace ensure_space(this);
2140 emit_farith(0xDC, 0xC8, i);
2144 void Assembler::fdiv(int i) {
2145 EnsureSpace ensure_space(this);
2146 emit_farith(0xDC, 0xF8, i);
2150 void Assembler::faddp(int i) {
2151 EnsureSpace ensure_space(this);
2152 emit_farith(0xDE, 0xC0, i);
2156 void Assembler::fsubp(int i) {
2157 EnsureSpace ensure_space(this);
2158 emit_farith(0xDE, 0xE8, i);
2162 void Assembler::fsubrp(int i) {
2163 EnsureSpace ensure_space(this);
2164 emit_farith(0xDE, 0xE0, i);
2168 void Assembler::fmulp(int i) {
2169 EnsureSpace ensure_space(this);
2170 emit_farith(0xDE, 0xC8, i);
2174 void Assembler::fdivp(int i) {
2175 EnsureSpace ensure_space(this);
2176 emit_farith(0xDE, 0xF8, i);
2180 void Assembler::fprem() {
2181 EnsureSpace ensure_space(this);
2187 void Assembler::fprem1() {
2188 EnsureSpace ensure_space(this);
2194 void Assembler::fxch(int i) {
2195 EnsureSpace ensure_space(this);
2196 emit_farith(0xD9, 0xC8, i);
2200 void Assembler::fincstp() {
2201 EnsureSpace ensure_space(this);
2207 void Assembler::ffree(int i) {
2208 EnsureSpace ensure_space(this);
2209 emit_farith(0xDD, 0xC0, i);
2213 void Assembler::ftst() {
2214 EnsureSpace ensure_space(this);
2220 void Assembler::fucomp(int i) {
2221 EnsureSpace ensure_space(this);
2222 emit_farith(0xDD, 0xE8, i);
2226 void Assembler::fucompp() {
2227 EnsureSpace ensure_space(this);
2233 void Assembler::fucomi(int i) {
2234 EnsureSpace ensure_space(this);
2240 void Assembler::fucomip() {
2241 EnsureSpace ensure_space(this);
2247 void Assembler::fcompp() {
2248 EnsureSpace ensure_space(this);
2254 void Assembler::fnstsw_ax() {
2255 EnsureSpace ensure_space(this);
2261 void Assembler::fwait() {
2262 EnsureSpace ensure_space(this);
2267 void Assembler::frndint() {
2268 EnsureSpace ensure_space(this);
2274 void Assembler::fnclex() {
2275 EnsureSpace ensure_space(this);
2281 void Assembler::sahf() {
2282 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2283 // in 64-bit mode. Test CpuID.
2284 DCHECK(IsEnabled(SAHF));
2285 EnsureSpace ensure_space(this);
2290 void Assembler::emit_farith(int b1, int b2, int i) {
2291 DCHECK(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2292 DCHECK(is_uint3(i)); // illegal stack offset
2300 void Assembler::andps(XMMRegister dst, XMMRegister src) {
2301 EnsureSpace ensure_space(this);
2302 emit_optional_rex_32(dst, src);
2305 emit_sse_operand(dst, src);
2309 void Assembler::andps(XMMRegister dst, const Operand& src) {
2310 EnsureSpace ensure_space(this);
2311 emit_optional_rex_32(dst, src);
2314 emit_sse_operand(dst, src);
2318 void Assembler::orps(XMMRegister dst, XMMRegister src) {
2319 EnsureSpace ensure_space(this);
2320 emit_optional_rex_32(dst, src);
2323 emit_sse_operand(dst, src);
2327 void Assembler::orps(XMMRegister dst, const Operand& src) {
2328 EnsureSpace ensure_space(this);
2329 emit_optional_rex_32(dst, src);
2332 emit_sse_operand(dst, src);
2336 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2337 EnsureSpace ensure_space(this);
2338 emit_optional_rex_32(dst, src);
2341 emit_sse_operand(dst, src);
2345 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2346 EnsureSpace ensure_space(this);
2347 emit_optional_rex_32(dst, src);
2350 emit_sse_operand(dst, src);
2354 void Assembler::addps(XMMRegister dst, XMMRegister src) {
2355 EnsureSpace ensure_space(this);
2356 emit_optional_rex_32(dst, src);
2359 emit_sse_operand(dst, src);
2363 void Assembler::addps(XMMRegister dst, const Operand& src) {
2364 EnsureSpace ensure_space(this);
2365 emit_optional_rex_32(dst, src);
2368 emit_sse_operand(dst, src);
2372 void Assembler::subps(XMMRegister dst, XMMRegister src) {
2373 EnsureSpace ensure_space(this);
2374 emit_optional_rex_32(dst, src);
2377 emit_sse_operand(dst, src);
2381 void Assembler::subps(XMMRegister dst, const Operand& src) {
2382 EnsureSpace ensure_space(this);
2383 emit_optional_rex_32(dst, src);
2386 emit_sse_operand(dst, src);
2390 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2391 EnsureSpace ensure_space(this);
2392 emit_optional_rex_32(dst, src);
2395 emit_sse_operand(dst, src);
2399 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2400 EnsureSpace ensure_space(this);
2401 emit_optional_rex_32(dst, src);
2404 emit_sse_operand(dst, src);
2408 void Assembler::divps(XMMRegister dst, XMMRegister src) {
2409 EnsureSpace ensure_space(this);
2410 emit_optional_rex_32(dst, src);
2413 emit_sse_operand(dst, src);
2417 void Assembler::divps(XMMRegister dst, const Operand& src) {
2418 EnsureSpace ensure_space(this);
2419 emit_optional_rex_32(dst, src);
2422 emit_sse_operand(dst, src);
2426 void Assembler::addpd(XMMRegister dst, XMMRegister src) {
2427 EnsureSpace ensure_space(this);
2429 emit_optional_rex_32(dst, src);
2432 emit_sse_operand(dst, src);
2436 void Assembler::addpd(XMMRegister dst, const Operand& src) {
2437 EnsureSpace ensure_space(this);
2439 emit_optional_rex_32(dst, src);
2442 emit_sse_operand(dst, src);
2446 void Assembler::subpd(XMMRegister dst, XMMRegister src) {
2447 EnsureSpace ensure_space(this);
2449 emit_optional_rex_32(dst, src);
2452 emit_sse_operand(dst, src);
2456 void Assembler::subpd(XMMRegister dst, const Operand& src) {
2457 EnsureSpace ensure_space(this);
2459 emit_optional_rex_32(dst, src);
2462 emit_sse_operand(dst, src);
2466 void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
2467 EnsureSpace ensure_space(this);
2469 emit_optional_rex_32(dst, src);
2472 emit_sse_operand(dst, src);
2476 void Assembler::mulpd(XMMRegister dst, const Operand& src) {
2477 EnsureSpace ensure_space(this);
2479 emit_optional_rex_32(dst, src);
2482 emit_sse_operand(dst, src);
2486 void Assembler::divpd(XMMRegister dst, XMMRegister src) {
2487 EnsureSpace ensure_space(this);
2489 emit_optional_rex_32(dst, src);
2492 emit_sse_operand(dst, src);
2496 void Assembler::divpd(XMMRegister dst, const Operand& src) {
2497 EnsureSpace ensure_space(this);
2499 emit_optional_rex_32(dst, src);
2502 emit_sse_operand(dst, src);
2506 // SSE 2 operations.
2508 void Assembler::movd(XMMRegister dst, Register src) {
2509 EnsureSpace ensure_space(this);
2511 emit_optional_rex_32(dst, src);
2514 emit_sse_operand(dst, src);
2518 void Assembler::movd(Register dst, XMMRegister src) {
2519 EnsureSpace ensure_space(this);
2521 emit_optional_rex_32(src, dst);
2524 emit_sse_operand(src, dst);
2528 void Assembler::movq(XMMRegister dst, Register src) {
2529 EnsureSpace ensure_space(this);
2531 emit_rex_64(dst, src);
2534 emit_sse_operand(dst, src);
2538 void Assembler::movq(Register dst, XMMRegister src) {
2539 EnsureSpace ensure_space(this);
2541 emit_rex_64(src, dst);
2544 emit_sse_operand(src, dst);
2548 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2549 EnsureSpace ensure_space(this);
2550 if (dst.low_bits() == 4) {
2551 // Avoid unnecessary SIB byte.
2553 emit_optional_rex_32(dst, src);
2556 emit_sse_operand(dst, src);
2559 emit_optional_rex_32(src, dst);
2562 emit_sse_operand(src, dst);
2567 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2568 EnsureSpace ensure_space(this);
2570 emit_rex_64(src, dst);
2573 emit_sse_operand(src, dst);
2577 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2578 EnsureSpace ensure_space(this);
2580 emit_rex_64(dst, src);
2583 emit_sse_operand(dst, src);
2587 void Assembler::movdqu(const Operand& dst, XMMRegister src) {
2588 EnsureSpace ensure_space(this);
2590 emit_rex_64(src, dst);
2593 emit_sse_operand(src, dst);
2597 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2598 EnsureSpace ensure_space(this);
2600 emit_rex_64(dst, src);
2603 emit_sse_operand(dst, src);
2607 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2608 DCHECK(IsEnabled(SSE4_1));
2609 DCHECK(is_uint8(imm8));
2610 EnsureSpace ensure_space(this);
2612 emit_optional_rex_32(src, dst);
2616 emit_sse_operand(src, dst);
2621 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
2622 DCHECK(CpuFeatures::IsSupported(SSE4_1));
2623 DCHECK(is_uint8(imm8));
2624 EnsureSpace ensure_space(this);
2626 emit_optional_rex_32(dst, src);
2630 emit_sse_operand(dst, src);
2635 void Assembler::pinsrd(XMMRegister dst, Register src, byte imm8) {
2636 DCHECK(CpuFeatures::IsSupported(SSE4_1));
2637 DCHECK(is_uint8(imm8));
2638 EnsureSpace ensure_space(this);
2640 emit_optional_rex_32(dst, src);
2644 emit_sse_operand(dst, src);
2649 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2650 EnsureSpace ensure_space(this);
2651 emit(0xF2); // double
2652 emit_optional_rex_32(src, dst);
2654 emit(0x11); // store
2655 emit_sse_operand(src, dst);
2659 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2660 EnsureSpace ensure_space(this);
2661 emit(0xF2); // double
2662 emit_optional_rex_32(dst, src);
2665 emit_sse_operand(dst, src);
2669 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2670 EnsureSpace ensure_space(this);
2671 emit(0xF2); // double
2672 emit_optional_rex_32(dst, src);
2675 emit_sse_operand(dst, src);
2679 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2680 EnsureSpace ensure_space(this);
2681 if (src.low_bits() == 4) {
2682 // Try to avoid an unnecessary SIB byte.
2683 emit_optional_rex_32(src, dst);
2686 emit_sse_operand(src, dst);
2688 emit_optional_rex_32(dst, src);
2691 emit_sse_operand(dst, src);
2696 void Assembler::movups(XMMRegister dst, const Operand& src) {
2697 EnsureSpace ensure_space(this);
2698 emit_optional_rex_32(dst, src);
2701 emit_sse_operand(dst, src);
2705 void Assembler::movups(const Operand& dst, XMMRegister src) {
2706 EnsureSpace ensure_space(this);
2707 emit_optional_rex_32(src, dst);
2710 emit_sse_operand(src, dst);
2714 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2715 DCHECK(is_uint8(imm8));
2716 EnsureSpace ensure_space(this);
2717 emit_optional_rex_32(dst, src);
2720 emit_sse_operand(dst, src);
2725 void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) {
2726 DCHECK(is_uint8(imm8));
2727 EnsureSpace ensure_space(this);
2729 emit_optional_rex_32(dst, src);
2732 emit_sse_operand(dst, src);
2737 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2738 EnsureSpace ensure_space(this);
2739 if (src.low_bits() == 4) {
2740 // Try to avoid an unnecessary SIB byte.
2742 emit_optional_rex_32(src, dst);
2745 emit_sse_operand(src, dst);
2748 emit_optional_rex_32(dst, src);
2751 emit_sse_operand(dst, src);
2756 void Assembler::movss(XMMRegister dst, const Operand& src) {
2757 EnsureSpace ensure_space(this);
2758 emit(0xF3); // single
2759 emit_optional_rex_32(dst, src);
2762 emit_sse_operand(dst, src);
2766 void Assembler::movss(const Operand& src, XMMRegister dst) {
2767 EnsureSpace ensure_space(this);
2768 emit(0xF3); // single
2769 emit_optional_rex_32(dst, src);
2771 emit(0x11); // store
2772 emit_sse_operand(dst, src);
2776 void Assembler::psllq(XMMRegister reg, byte imm8) {
2777 EnsureSpace ensure_space(this);
2779 emit_optional_rex_32(reg);
2782 emit_sse_operand(rsi, reg); // rsi == 6
2787 void Assembler::psrlq(XMMRegister reg, byte imm8) {
2788 EnsureSpace ensure_space(this);
2790 emit_optional_rex_32(reg);
2793 emit_sse_operand(rdx, reg); // rdx == 2
2798 void Assembler::pslld(XMMRegister reg, byte imm8) {
2799 EnsureSpace ensure_space(this);
2801 emit_optional_rex_32(reg);
2804 emit_sse_operand(rsi, reg); // rsi == 6
2809 void Assembler::psrld(XMMRegister reg, byte imm8) {
2810 EnsureSpace ensure_space(this);
2812 emit_optional_rex_32(reg);
2815 emit_sse_operand(rdx, reg); // rdx == 2
2820 void Assembler::cvttss2si(Register dst, const Operand& src) {
2821 EnsureSpace ensure_space(this);
2823 emit_optional_rex_32(dst, src);
2826 emit_operand(dst, src);
2830 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2831 EnsureSpace ensure_space(this);
2833 emit_optional_rex_32(dst, src);
2836 emit_sse_operand(dst, src);
2840 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2841 EnsureSpace ensure_space(this);
2843 emit_optional_rex_32(dst, src);
2846 emit_operand(dst, src);
2850 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2851 EnsureSpace ensure_space(this);
2853 emit_optional_rex_32(dst, src);
2856 emit_sse_operand(dst, src);
2860 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2861 EnsureSpace ensure_space(this);
2863 emit_rex_64(dst, src);
2866 emit_sse_operand(dst, src);
2870 void Assembler::cvttsd2siq(Register dst, const Operand& src) {
2871 EnsureSpace ensure_space(this);
2873 emit_rex_64(dst, src);
2876 emit_sse_operand(dst, src);
2880 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2881 EnsureSpace ensure_space(this);
2883 emit_optional_rex_32(dst, src);
2886 emit_sse_operand(dst, src);
2890 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2891 EnsureSpace ensure_space(this);
2893 emit_optional_rex_32(dst, src);
2896 emit_sse_operand(dst, src);
2900 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2901 EnsureSpace ensure_space(this);
2903 emit_optional_rex_32(dst, src);
2906 emit_sse_operand(dst, src);
2910 void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
2911 EnsureSpace ensure_space(this);
2913 emit_rex_64(dst, src);
2916 emit_sse_operand(dst, src);
2920 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2921 EnsureSpace ensure_space(this);
2923 emit_rex_64(dst, src);
2926 emit_sse_operand(dst, src);
2930 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2931 EnsureSpace ensure_space(this);
2933 emit_optional_rex_32(dst, src);
2936 emit_sse_operand(dst, src);
2940 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2941 EnsureSpace ensure_space(this);
2943 emit_optional_rex_32(dst, src);
2946 emit_sse_operand(dst, src);
2950 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2951 EnsureSpace ensure_space(this);
2953 emit_optional_rex_32(dst, src);
2956 emit_sse_operand(dst, src);
2960 void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
2961 EnsureSpace ensure_space(this);
2963 emit_optional_rex_32(dst, src);
2966 emit_sse_operand(dst, src);
2970 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2971 EnsureSpace ensure_space(this);
2973 emit_optional_rex_32(dst, src);
2976 emit_sse_operand(dst, src);
2980 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2981 EnsureSpace ensure_space(this);
2983 emit_rex_64(dst, src);
2986 emit_sse_operand(dst, src);
2990 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2991 EnsureSpace ensure_space(this);
2993 emit_optional_rex_32(dst, src);
2996 emit_sse_operand(dst, src);
3000 void Assembler::addsd(XMMRegister dst, const Operand& src) {
3001 EnsureSpace ensure_space(this);
3003 emit_optional_rex_32(dst, src);
3006 emit_sse_operand(dst, src);
3010 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
3011 EnsureSpace ensure_space(this);
3013 emit_optional_rex_32(dst, src);
3016 emit_sse_operand(dst, src);
3020 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
3021 EnsureSpace ensure_space(this);
3023 emit_optional_rex_32(dst, src);
3026 emit_sse_operand(dst, src);
3030 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
3031 EnsureSpace ensure_space(this);
3033 emit_optional_rex_32(dst, src);
3036 emit_sse_operand(dst, src);
3040 void Assembler::subsd(XMMRegister dst, const Operand& src) {
3041 EnsureSpace ensure_space(this);
3043 emit_optional_rex_32(dst, src);
3046 emit_sse_operand(dst, src);
3050 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
3051 EnsureSpace ensure_space(this);
3053 emit_optional_rex_32(dst, src);
3056 emit_sse_operand(dst, src);
3060 void Assembler::divsd(XMMRegister dst, const Operand& src) {
3061 EnsureSpace ensure_space(this);
3063 emit_optional_rex_32(dst, src);
3066 emit_sse_operand(dst, src);
3070 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
3071 EnsureSpace ensure_space(this);
3073 emit_optional_rex_32(dst, src);
3076 emit_sse_operand(dst, src);
3080 void Assembler::andpd(XMMRegister dst, const Operand& src) {
3081 EnsureSpace ensure_space(this);
3083 emit_optional_rex_32(dst, src);
3086 emit_sse_operand(dst, src);
3090 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
3091 EnsureSpace ensure_space(this);
3093 emit_optional_rex_32(dst, src);
3096 emit_sse_operand(dst, src);
3100 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
3101 EnsureSpace ensure_space(this);
3103 emit_optional_rex_32(dst, src);
3106 emit_sse_operand(dst, src);
3110 void Assembler::xorpd(XMMRegister dst, const Operand& src) {
3111 EnsureSpace ensure_space(this);
3113 emit_optional_rex_32(dst, src);
3116 emit_sse_operand(dst, src);
3120 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
3121 EnsureSpace ensure_space(this);
3123 emit_optional_rex_32(dst, src);
3126 emit_sse_operand(dst, src);
3130 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
3131 EnsureSpace ensure_space(this);
3133 emit_optional_rex_32(dst, src);
3136 emit_sse_operand(dst, src);
3140 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
3141 EnsureSpace ensure_space(this);
3143 emit_optional_rex_32(dst, src);
3146 emit_sse_operand(dst, src);
3150 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
3151 EnsureSpace ensure_space(this);
3153 emit_optional_rex_32(dst, src);
3156 emit_sse_operand(dst, src);
3160 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
3161 EnsureSpace ensure_space(this);
3163 emit_optional_rex_32(dst, src);
3166 emit_sse_operand(dst, src);
3167 emit(0x01); // LT == 1
3171 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
3172 EnsureSpace ensure_space(this);
3173 emit_optional_rex_32(dst, src);
3176 emit_sse_operand(dst, src);
3181 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) {
3182 cmpps(dst, src, 0x0);
3186 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) {
3187 cmpps(dst, src, 0x1);
3191 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) {
3192 cmpps(dst, src, 0x2);
3196 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) {
3197 cmpps(dst, src, 0x4);
3201 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) {
3202 cmpps(dst, src, 0x5);
3206 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) {
3207 cmpps(dst, src, 0x6);
3211 void Assembler::pslld(XMMRegister dst, XMMRegister src) {
3212 EnsureSpace ensure_space(this);
3214 emit_optional_rex_32(dst, src);
3217 emit_sse_operand(dst, src);
3221 void Assembler::psrld(XMMRegister dst, XMMRegister src) {
3222 EnsureSpace ensure_space(this);
3224 emit_optional_rex_32(dst, src);
3227 emit_sse_operand(dst, src);
3231 void Assembler::psrad(XMMRegister reg, int8_t shift) {
3232 EnsureSpace ensure_space(this);
3234 emit_optional_rex_32(reg);
3237 emit_sse_operand(rsp, reg); // rsp == 4
3242 void Assembler::psrad(XMMRegister dst, XMMRegister src) {
3243 EnsureSpace ensure_space(this);
3245 emit_optional_rex_32(dst, src);
3248 emit_sse_operand(dst, src);
3252 void Assembler::pcmpgtd(XMMRegister dst, XMMRegister src) {
3253 EnsureSpace ensure_space(this);
3255 emit_optional_rex_32(dst, src);
3258 emit_sse_operand(dst, src);
3262 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
3263 Assembler::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::minps(XMMRegister dst, XMMRegister src) {
3307 EnsureSpace ensure_space(this);
3308 emit_optional_rex_32(dst, src);
3311 emit_sse_operand(dst, src);
3315 void Assembler::minps(XMMRegister dst, const Operand& src) {
3316 EnsureSpace ensure_space(this);
3317 emit_optional_rex_32(dst, src);
3320 emit_sse_operand(dst, src);
3324 void Assembler::maxps(XMMRegister dst, XMMRegister src) {
3325 EnsureSpace ensure_space(this);
3326 emit_optional_rex_32(dst, src);
3329 emit_sse_operand(dst, src);
3333 void Assembler::maxps(XMMRegister dst, const Operand& src) {
3334 EnsureSpace ensure_space(this);
3335 emit_optional_rex_32(dst, src);
3338 emit_sse_operand(dst, src);
3342 void Assembler::minpd(XMMRegister dst, XMMRegister src) {
3343 EnsureSpace ensure_space(this);
3345 emit_optional_rex_32(dst, src);
3348 emit_sse_operand(dst, src);
3352 void Assembler::minpd(XMMRegister dst, const Operand& src) {
3353 EnsureSpace ensure_space(this);
3355 emit_optional_rex_32(dst, src);
3358 emit_sse_operand(dst, src);
3362 void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
3363 EnsureSpace ensure_space(this);
3365 emit_optional_rex_32(dst, src);
3368 emit_sse_operand(dst, src);
3372 void Assembler::maxpd(XMMRegister dst, const Operand& src) {
3373 EnsureSpace ensure_space(this);
3375 emit_optional_rex_32(dst, src);
3378 emit_sse_operand(dst, src);
3382 void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
3383 EnsureSpace ensure_space(this);
3384 emit_optional_rex_32(dst, src);
3387 emit_sse_operand(dst, src);
3391 void Assembler::rcpps(XMMRegister dst, const Operand& src) {
3392 EnsureSpace ensure_space(this);
3393 emit_optional_rex_32(dst, src);
3396 emit_sse_operand(dst, src);
3400 void Assembler::rsqrtps(XMMRegister dst, XMMRegister src) {
3401 EnsureSpace ensure_space(this);
3402 emit_optional_rex_32(dst, src);
3405 emit_sse_operand(dst, src);
3409 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
3410 EnsureSpace ensure_space(this);
3411 emit_optional_rex_32(dst, src);
3414 emit_sse_operand(dst, src);
3418 void Assembler::sqrtps(XMMRegister dst, XMMRegister src) {
3419 EnsureSpace ensure_space(this);
3420 emit_optional_rex_32(dst, src);
3423 emit_sse_operand(dst, src);
3427 void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
3428 EnsureSpace ensure_space(this);
3429 emit_optional_rex_32(dst, src);
3432 emit_sse_operand(dst, src);
3436 void Assembler::sqrtpd(XMMRegister dst, XMMRegister src) {
3437 EnsureSpace ensure_space(this);
3439 emit_optional_rex_32(dst, src);
3442 emit_sse_operand(dst, src);
3446 void Assembler::sqrtpd(XMMRegister dst, const Operand& src) {
3447 EnsureSpace ensure_space(this);
3449 emit_optional_rex_32(dst, src);
3452 emit_sse_operand(dst, src);
3456 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
3457 EnsureSpace ensure_space(this);
3458 emit_optional_rex_32(dst, src);
3461 emit_sse_operand(dst, src);
3465 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
3466 EnsureSpace ensure_space(this);
3467 emit_optional_rex_32(dst, src);
3470 emit_sse_operand(dst, src);
3474 void Assembler::paddd(XMMRegister dst, XMMRegister src) {
3475 EnsureSpace ensure_space(this);
3477 emit_optional_rex_32(dst, src);
3480 emit_sse_operand(dst, src);
3484 void Assembler::paddd(XMMRegister dst, const Operand& src) {
3485 EnsureSpace ensure_space(this);
3487 emit_optional_rex_32(dst, src);
3490 emit_sse_operand(dst, src);
3494 void Assembler::psubd(XMMRegister dst, XMMRegister src) {
3495 EnsureSpace ensure_space(this);
3497 emit_optional_rex_32(dst, src);
3500 emit_sse_operand(dst, src);
3504 void Assembler::psubd(XMMRegister dst, const Operand& src) {
3505 EnsureSpace ensure_space(this);
3507 emit_optional_rex_32(dst, src);
3510 emit_sse_operand(dst, src);
3514 void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
3515 DCHECK(IsEnabled(SSE4_1));
3516 EnsureSpace ensure_space(this);
3518 emit_optional_rex_32(dst, src);
3522 emit_sse_operand(dst, src);
3526 void Assembler::pmulld(XMMRegister dst, const Operand& src) {
3527 EnsureSpace ensure_space(this);
3529 emit_optional_rex_32(dst, src);
3532 emit_sse_operand(dst, src);
3536 void Assembler::pmuludq(XMMRegister dst, XMMRegister src) {
3537 EnsureSpace ensure_space(this);
3539 emit_optional_rex_32(dst, src);
3542 emit_sse_operand(dst, src);
3546 void Assembler::pmuludq(XMMRegister dst, const Operand& src) {
3547 EnsureSpace ensure_space(this);
3549 emit_optional_rex_32(dst, src);
3552 emit_sse_operand(dst, src);
3556 void Assembler::punpackldq(XMMRegister dst, XMMRegister src) {
3557 EnsureSpace ensure_space(this);
3559 emit_optional_rex_32(dst, src);
3562 emit_sse_operand(dst, src);
3566 void Assembler::punpackldq(XMMRegister dst, const Operand& src) {
3567 EnsureSpace ensure_space(this);
3569 emit_optional_rex_32(dst, src);
3572 emit_sse_operand(dst, src);
3576 void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
3577 EnsureSpace ensure_space(this);
3579 emit_optional_rex_32(dst);
3582 emit_sse_operand(dst);
3587 void Assembler::cvtps2dq(XMMRegister dst, XMMRegister src) {
3588 EnsureSpace ensure_space(this);
3590 emit_optional_rex_32(dst, src);
3593 emit_sse_operand(dst, src);
3597 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) {
3598 EnsureSpace ensure_space(this);
3600 emit_optional_rex_32(dst, src);
3603 emit_sse_operand(dst, src);
3607 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
3608 EnsureSpace ensure_space(this);
3610 emit_optional_rex_32(dst, src);
3613 emit_sse_operand(dst, src);
3618 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
3619 Register ireg = { reg.code() };
3620 emit_operand(ireg, adr);
3624 void Assembler::emit_sse_operand(Register reg, const Operand& adr) {
3625 Register ireg = {reg.code()};
3626 emit_operand(ireg, adr);
3630 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3631 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3635 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3636 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3640 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3641 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3645 void Assembler::emit_sse_operand(XMMRegister dst) {
3646 emit(0xD8 | dst.low_bits());
3650 void Assembler::db(uint8_t data) {
3651 EnsureSpace ensure_space(this);
3656 void Assembler::dd(uint32_t data) {
3657 EnsureSpace ensure_space(this);
3662 // Relocation information implementations.
3664 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3665 DCHECK(!RelocInfo::IsNone(rmode));
3666 // Don't record external references unless the heap will be serialized.
3667 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
3668 !serializer_enabled() && !emit_debug_code()) {
3670 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
3671 // Don't record psuedo relocation info for code age sequence mode.
3674 RelocInfo rinfo(pc_, rmode, data, NULL);
3675 reloc_info_writer.Write(&rinfo);
3679 void Assembler::RecordJSReturn() {
3680 positions_recorder()->WriteRecordedPositions();
3681 EnsureSpace ensure_space(this);
3682 RecordRelocInfo(RelocInfo::JS_RETURN);
3686 void Assembler::RecordDebugBreakSlot() {
3687 positions_recorder()->WriteRecordedPositions();
3688 EnsureSpace ensure_space(this);
3689 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3693 void Assembler::RecordComment(const char* msg, bool force) {
3694 if (FLAG_code_comments || force) {
3695 EnsureSpace ensure_space(this);
3696 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3701 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3702 // No out-of-line constant pool support.
3703 DCHECK(!FLAG_enable_ool_constant_pool);
3704 return isolate->factory()->empty_constant_pool_array();
3708 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3709 // No out-of-line constant pool support.
3710 DCHECK(!FLAG_enable_ool_constant_pool);
3715 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3716 1 << RelocInfo::RUNTIME_ENTRY |
3717 1 << RelocInfo::INTERNAL_REFERENCE |
3718 1 << RelocInfo::CODE_AGE_SEQUENCE;
3721 bool RelocInfo::IsCodedSpecially() {
3722 // The deserializer needs to know whether a pointer is specially coded. Being
3723 // specially coded on x64 means that it is a relative 32 bit address, as used
3724 // by branch instructions.
3725 return (1 << rmode_) & kApplyMask;
3729 bool RelocInfo::IsInConstantPool() {
3734 } } // namespace v8::internal
3736 #endif // V8_TARGET_ARCH_X64