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 "macro-assembler.h"
10 #include "serialize.h"
15 // -----------------------------------------------------------------------------
16 // Implementation of CpuFeatures
20 bool CpuFeatures::initialized_ = false;
22 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
23 uint64_t CpuFeatures::found_by_runtime_probing_only_ = 0;
24 uint64_t CpuFeatures::cross_compile_ = 0;
26 ExternalReference ExternalReference::cpu_features() {
27 ASSERT(CpuFeatures::initialized_);
28 return ExternalReference(&CpuFeatures::supported_);
32 void CpuFeatures::Probe(bool serializer_enabled) {
33 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
37 supported_ = kDefaultCpuFeatures;
38 if (serializer_enabled) {
39 supported_ |= OS::CpuFeaturesImpliedByPlatform();
40 return; // No features if we might serialize.
43 uint64_t probed_features = 0;
45 if (cpu.has_sse41()) {
46 probed_features |= static_cast<uint64_t>(1) << SSE4_1;
49 probed_features |= static_cast<uint64_t>(1) << SSE3;
52 // SSE2 must be available on every x64 CPU.
53 ASSERT(cpu.has_sse2());
54 probed_features |= static_cast<uint64_t>(1) << SSE2;
56 // CMOV must be available on every x64 CPU.
57 ASSERT(cpu.has_cmov());
58 probed_features |= static_cast<uint64_t>(1) << CMOV;
60 // SAHF is not generally available in long mode.
62 probed_features |= static_cast<uint64_t>(1) << SAHF;
65 uint64_t platform_features = OS::CpuFeaturesImpliedByPlatform();
66 supported_ = probed_features | platform_features;
67 found_by_runtime_probing_only_
68 = probed_features & ~kDefaultCpuFeatures & ~platform_features;
72 // -----------------------------------------------------------------------------
73 // Implementation of RelocInfo
75 // Patch the code at the current PC with a call to the target address.
76 // Additional guard int3 instructions can be added if required.
77 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
78 int code_size = Assembler::kCallSequenceLength + guard_bytes;
80 // Create a code patcher.
81 CodePatcher patcher(pc_, code_size);
83 // Add a label for checking the size of the code used for returning.
86 patcher.masm()->bind(&check_codesize);
90 patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target),
91 Assembler::RelocInfoNone());
92 patcher.masm()->call(kScratchRegister);
94 // Check that the size of the code generated is as expected.
95 ASSERT_EQ(Assembler::kCallSequenceLength,
96 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
98 // Add the requested number of int3 instructions after the call.
99 for (int i = 0; i < guard_bytes; i++) {
100 patcher.masm()->int3();
105 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
106 // Patch the code at the current address with the supplied instructions.
107 for (int i = 0; i < instruction_count; i++) {
108 *(pc_ + i) = *(instructions + i);
111 // Indicate that code has changed.
112 CPU::FlushICache(pc_, instruction_count);
116 // -----------------------------------------------------------------------------
117 // Register constants.
120 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
121 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r14, r15
122 0, 3, 2, 1, 6, 7, 8, 9, 11, 14, 15
125 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
126 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, -1, -1, 9, 10
130 // -----------------------------------------------------------------------------
131 // Implementation of Operand
133 Operand::Operand(Register base, int32_t disp) : rex_(0) {
135 if (base.is(rsp) || base.is(r12)) {
136 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
137 set_sib(times_1, rsp, base);
140 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
142 } else if (is_int8(disp)) {
152 Operand::Operand(Register base,
155 int32_t disp) : rex_(0) {
156 ASSERT(!index.is(rsp));
158 set_sib(scale, index, base);
159 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
160 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
161 // possibly set by set_sib.
163 } else if (is_int8(disp)) {
173 Operand::Operand(Register index,
175 int32_t disp) : rex_(0) {
176 ASSERT(!index.is(rsp));
179 set_sib(scale, index, rbp);
184 Operand::Operand(const Operand& operand, int32_t offset) {
185 ASSERT(operand.len_ >= 1);
186 // Operand encodes REX ModR/M [SIB] [Disp].
187 byte modrm = operand.buf_[0];
188 ASSERT(modrm < 0xC0); // Disallow mode 3 (register target).
189 bool has_sib = ((modrm & 0x07) == 0x04);
190 byte mode = modrm & 0xC0;
191 int disp_offset = has_sib ? 2 : 1;
192 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
193 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
195 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
196 int32_t disp_value = 0;
197 if (mode == 0x80 || is_baseless) {
198 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
199 disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]);
200 } else if (mode == 0x40) {
201 // Mode 1: Byte displacement.
202 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
205 // Write new operand with same registers, but with modified displacement.
206 ASSERT(offset >= 0 ? disp_value + offset > disp_value
207 : disp_value + offset < disp_value); // No overflow.
208 disp_value += offset;
210 if (!is_int8(disp_value) || is_baseless) {
211 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
212 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
213 len_ = disp_offset + 4;
214 Memory::int32_at(&buf_[disp_offset]) = disp_value;
215 } else if (disp_value != 0 || (base_reg == 0x05)) {
216 // Need 8 bits of displacement.
217 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
218 len_ = disp_offset + 1;
219 buf_[disp_offset] = static_cast<byte>(disp_value);
221 // Need no displacement.
222 buf_[0] = (modrm & 0x3f); // Mode 0.
226 buf_[1] = operand.buf_[1];
231 bool Operand::AddressUsesRegister(Register reg) const {
232 int code = reg.code();
233 ASSERT((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
234 // Start with only low three bits of base register. Initial decoding doesn't
235 // distinguish on the REX.B bit.
236 int base_code = buf_[0] & 0x07;
237 if (base_code == rsp.code()) {
238 // SIB byte present in buf_[1].
239 // Check the index register from the SIB byte + REX.X prefix.
240 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
241 // Index code (including REX.X) of 0x04 (rsp) means no index register.
242 if (index_code != rsp.code() && index_code == code) return true;
243 // Add REX.B to get the full base register code.
244 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
245 // A base register of 0x05 (rbp) with mod = 0 means no base register.
246 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
247 return code == base_code;
249 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
251 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
252 base_code |= ((rex_ & 0x01) << 3);
253 return code == base_code;
258 // -----------------------------------------------------------------------------
259 // Implementation of Assembler.
261 #ifdef GENERATED_CODE_COVERAGE
262 static void InitCoverageLog();
265 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
266 : AssemblerBase(isolate, buffer, buffer_size),
268 positions_recorder_(this) {
269 // Clear the buffer in debug mode unless it was provided by the
270 // caller in which case we can't be sure it's okay to overwrite
271 // existing code in it.
274 memset(buffer_, 0xCC, buffer_size_); // int3
278 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
281 #ifdef GENERATED_CODE_COVERAGE
287 void Assembler::GetCode(CodeDesc* desc) {
288 // Finalize code (at this point overflow() may be true, but the gap ensures
289 // that we are still not overlapping instructions and relocation info).
290 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
291 // Set up code descriptor.
292 desc->buffer = buffer_;
293 desc->buffer_size = buffer_size_;
294 desc->instr_size = pc_offset();
295 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system.
297 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
302 void Assembler::Align(int m) {
303 ASSERT(IsPowerOf2(m));
304 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
309 void Assembler::CodeTargetAlign() {
310 Align(16); // Preferred alignment of jump targets on x64.
314 bool Assembler::IsNop(Address addr) {
316 while (*a == 0x66) a++;
317 if (*a == 0x90) return true;
318 if (a[0] == 0xf && a[1] == 0x1f) return true;
323 void Assembler::bind_to(Label* L, int pos) {
324 ASSERT(!L->is_bound()); // Label may only be bound once.
325 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid.
326 if (L->is_linked()) {
327 int current = L->pos();
328 int next = long_at(current);
329 while (next != current) {
330 // Relative address, relative to point after address.
331 int imm32 = pos - (current + sizeof(int32_t));
332 long_at_put(current, imm32);
334 next = long_at(next);
336 // Fix up last fixup on linked list.
337 int last_imm32 = pos - (current + sizeof(int32_t));
338 long_at_put(current, last_imm32);
340 while (L->is_near_linked()) {
341 int fixup_pos = L->near_link_pos();
343 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
344 ASSERT(offset_to_next <= 0);
345 int disp = pos - (fixup_pos + sizeof(int8_t));
346 CHECK(is_int8(disp));
347 set_byte_at(fixup_pos, disp);
348 if (offset_to_next < 0) {
349 L->link_to(fixup_pos + offset_to_next, Label::kNear);
358 void Assembler::bind(Label* L) {
359 bind_to(L, pc_offset());
363 void Assembler::GrowBuffer() {
364 ASSERT(buffer_overflow());
365 if (!own_buffer_) FATAL("external code buffer is too small");
367 // Compute new buffer size.
368 CodeDesc desc; // the new buffer
369 if (buffer_size_ < 4*KB) {
370 desc.buffer_size = 4*KB;
372 desc.buffer_size = 2*buffer_size_;
374 // Some internal data structures overflow for very large buffers,
375 // they must ensure that kMaximalBufferSize is not too large.
376 if ((desc.buffer_size > kMaximalBufferSize) ||
377 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
378 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
381 // Set up new buffer.
382 desc.buffer = NewArray<byte>(desc.buffer_size);
383 desc.instr_size = pc_offset();
385 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
387 // Clear the buffer in debug mode. Use 'int3' instructions to make
388 // sure to get into problems if we ever run uninitialized code.
390 memset(desc.buffer, 0xCC, desc.buffer_size);
394 intptr_t pc_delta = desc.buffer - buffer_;
395 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
396 (buffer_ + buffer_size_);
397 OS::MemMove(desc.buffer, buffer_, desc.instr_size);
398 OS::MemMove(rc_delta + reloc_info_writer.pos(),
399 reloc_info_writer.pos(), desc.reloc_size);
402 if (isolate() != NULL &&
403 isolate()->assembler_spare_buffer() == NULL &&
404 buffer_size_ == kMinimalBufferSize) {
405 isolate()->set_assembler_spare_buffer(buffer_);
407 DeleteArray(buffer_);
409 buffer_ = desc.buffer;
410 buffer_size_ = desc.buffer_size;
412 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
413 reloc_info_writer.last_pc() + pc_delta);
415 // Relocate runtime entries.
416 for (RelocIterator it(desc); !it.done(); it.next()) {
417 RelocInfo::Mode rmode = it.rinfo()->rmode();
418 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
419 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
420 if (*p != 0) { // 0 means uninitialized.
426 ASSERT(!buffer_overflow());
430 void Assembler::emit_operand(int code, const Operand& adr) {
431 ASSERT(is_uint3(code));
432 const unsigned length = adr.len_;
435 // Emit updated ModR/M byte containing the given register.
436 ASSERT((adr.buf_[0] & 0x38) == 0);
437 pc_[0] = adr.buf_[0] | code << 3;
439 // Emit the rest of the encoded operand.
440 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
445 // Assembler Instruction implementations.
447 void Assembler::arithmetic_op(byte opcode,
451 EnsureSpace ensure_space(this);
452 emit_rex(reg, op, size);
454 emit_operand(reg, op);
458 void Assembler::arithmetic_op(byte opcode,
462 EnsureSpace ensure_space(this);
463 ASSERT((opcode & 0xC6) == 2);
464 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
465 // Swap reg and rm_reg and change opcode operand order.
466 emit_rex(rm_reg, reg, size);
468 emit_modrm(rm_reg, reg);
470 emit_rex(reg, rm_reg, size);
472 emit_modrm(reg, rm_reg);
477 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
478 EnsureSpace ensure_space(this);
479 ASSERT((opcode & 0xC6) == 2);
480 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
481 // Swap reg and rm_reg and change opcode operand order.
483 emit_optional_rex_32(rm_reg, reg);
485 emit_modrm(rm_reg, reg);
488 emit_optional_rex_32(reg, rm_reg);
490 emit_modrm(reg, rm_reg);
495 void Assembler::arithmetic_op_16(byte opcode,
497 const Operand& rm_reg) {
498 EnsureSpace ensure_space(this);
500 emit_optional_rex_32(reg, rm_reg);
502 emit_operand(reg, rm_reg);
506 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
507 EnsureSpace ensure_space(this);
508 if (!reg.is_byte_register()) {
509 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
513 emit_operand(reg, op);
517 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
518 EnsureSpace ensure_space(this);
519 ASSERT((opcode & 0xC6) == 2);
520 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
521 // Swap reg and rm_reg and change opcode operand order.
522 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
523 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
524 emit_rex_32(rm_reg, reg);
527 emit_modrm(rm_reg, reg);
529 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
530 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
531 emit_rex_32(reg, rm_reg);
534 emit_modrm(reg, rm_reg);
539 void Assembler::immediate_arithmetic_op(byte subcode,
543 EnsureSpace ensure_space(this);
545 if (is_int8(src.value_)) {
547 emit_modrm(subcode, dst);
549 } else if (dst.is(rax)) {
550 emit(0x05 | (subcode << 3));
554 emit_modrm(subcode, dst);
559 void Assembler::immediate_arithmetic_op(byte subcode,
563 EnsureSpace ensure_space(this);
565 if (is_int8(src.value_)) {
567 emit_operand(subcode, dst);
571 emit_operand(subcode, dst);
577 void Assembler::immediate_arithmetic_op_16(byte subcode,
580 EnsureSpace ensure_space(this);
581 emit(0x66); // Operand size override prefix.
582 emit_optional_rex_32(dst);
583 if (is_int8(src.value_)) {
585 emit_modrm(subcode, dst);
587 } else if (dst.is(rax)) {
588 emit(0x05 | (subcode << 3));
592 emit_modrm(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_operand(subcode, dst);
610 emit_operand(subcode, dst);
616 void Assembler::immediate_arithmetic_op_8(byte subcode,
619 EnsureSpace ensure_space(this);
620 emit_optional_rex_32(dst);
621 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
623 emit_operand(subcode, dst);
628 void Assembler::immediate_arithmetic_op_8(byte subcode,
631 EnsureSpace ensure_space(this);
632 if (!dst.is_byte_register()) {
633 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
636 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
638 emit_modrm(subcode, dst);
643 void Assembler::shift(Register dst,
644 Immediate shift_amount,
647 EnsureSpace ensure_space(this);
648 ASSERT(size == kInt64Size ? is_uint6(shift_amount.value_)
649 : is_uint5(shift_amount.value_));
650 if (shift_amount.value_ == 1) {
653 emit_modrm(subcode, dst);
657 emit_modrm(subcode, dst);
658 emit(shift_amount.value_);
663 void Assembler::shift(Register dst, int subcode, int size) {
664 EnsureSpace ensure_space(this);
667 emit_modrm(subcode, dst);
671 void Assembler::bt(const Operand& dst, Register src) {
672 EnsureSpace ensure_space(this);
673 emit_rex_64(src, dst);
676 emit_operand(src, dst);
680 void Assembler::bts(const Operand& dst, Register src) {
681 EnsureSpace ensure_space(this);
682 emit_rex_64(src, dst);
685 emit_operand(src, dst);
689 void Assembler::bsrl(Register dst, Register src) {
690 EnsureSpace ensure_space(this);
691 emit_optional_rex_32(dst, src);
694 emit_modrm(dst, src);
698 void Assembler::call(Label* L) {
699 positions_recorder()->WriteRecordedPositions();
700 EnsureSpace ensure_space(this);
701 // 1110 1000 #32-bit disp.
704 int offset = L->pos() - pc_offset() - sizeof(int32_t);
707 } else if (L->is_linked()) {
709 L->link_to(pc_offset() - sizeof(int32_t));
711 ASSERT(L->is_unused());
712 int32_t current = pc_offset();
719 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
720 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
721 positions_recorder()->WriteRecordedPositions();
722 EnsureSpace ensure_space(this);
723 // 1110 1000 #32-bit disp.
725 emit_runtime_entry(entry, rmode);
729 void Assembler::call(Handle<Code> target,
730 RelocInfo::Mode rmode,
731 TypeFeedbackId ast_id) {
732 positions_recorder()->WriteRecordedPositions();
733 EnsureSpace ensure_space(this);
734 // 1110 1000 #32-bit disp.
736 emit_code_target(target, rmode, ast_id);
740 void Assembler::call(Register adr) {
741 positions_recorder()->WriteRecordedPositions();
742 EnsureSpace ensure_space(this);
743 // Opcode: FF /2 r64.
744 emit_optional_rex_32(adr);
746 emit_modrm(0x2, adr);
750 void Assembler::call(const Operand& op) {
751 positions_recorder()->WriteRecordedPositions();
752 EnsureSpace ensure_space(this);
753 // Opcode: FF /2 m64.
754 emit_optional_rex_32(op);
756 emit_operand(0x2, op);
760 // Calls directly to the given address using a relative offset.
761 // Should only ever be used in Code objects for calls within the
762 // same Code object. Should not be used when generating new code (use labels),
763 // but only when patching existing code.
764 void Assembler::call(Address target) {
765 positions_recorder()->WriteRecordedPositions();
766 EnsureSpace ensure_space(this);
767 // 1110 1000 #32-bit disp.
769 Address source = pc_ + 4;
770 intptr_t displacement = target - source;
771 ASSERT(is_int32(displacement));
772 emitl(static_cast<int32_t>(displacement));
776 void Assembler::clc() {
777 EnsureSpace ensure_space(this);
782 void Assembler::cld() {
783 EnsureSpace ensure_space(this);
788 void Assembler::cdq() {
789 EnsureSpace ensure_space(this);
794 void Assembler::cmovq(Condition cc, Register dst, Register src) {
797 } else if (cc == never) {
800 // No need to check CpuInfo for CMOV support, it's a required part of the
801 // 64-bit architecture.
802 ASSERT(cc >= 0); // Use mov for unconditional moves.
803 EnsureSpace ensure_space(this);
804 // Opcode: REX.W 0f 40 + cc /r.
805 emit_rex_64(dst, src);
808 emit_modrm(dst, src);
812 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
815 } else if (cc == never) {
819 EnsureSpace ensure_space(this);
820 // Opcode: REX.W 0f 40 + cc /r.
821 emit_rex_64(dst, src);
824 emit_operand(dst, src);
828 void Assembler::cmovl(Condition cc, Register dst, Register src) {
831 } else if (cc == never) {
835 EnsureSpace ensure_space(this);
836 // Opcode: 0f 40 + cc /r.
837 emit_optional_rex_32(dst, src);
840 emit_modrm(dst, src);
844 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
847 } else if (cc == never) {
851 EnsureSpace ensure_space(this);
852 // Opcode: 0f 40 + cc /r.
853 emit_optional_rex_32(dst, src);
856 emit_operand(dst, src);
860 void Assembler::cmpb_al(Immediate imm8) {
861 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
862 EnsureSpace ensure_space(this);
868 void Assembler::cpuid() {
869 EnsureSpace ensure_space(this);
875 void Assembler::cqo() {
876 EnsureSpace ensure_space(this);
882 void Assembler::emit_dec(Register dst, int size) {
883 EnsureSpace ensure_space(this);
886 emit_modrm(0x1, dst);
890 void Assembler::emit_dec(const Operand& dst, int size) {
891 EnsureSpace ensure_space(this);
894 emit_operand(1, dst);
898 void Assembler::decb(Register dst) {
899 EnsureSpace ensure_space(this);
900 if (!dst.is_byte_register()) {
901 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
905 emit_modrm(0x1, dst);
909 void Assembler::decb(const Operand& dst) {
910 EnsureSpace ensure_space(this);
911 emit_optional_rex_32(dst);
913 emit_operand(1, dst);
917 void Assembler::enter(Immediate size) {
918 EnsureSpace ensure_space(this);
920 emitw(size.value_); // 16 bit operand, always.
925 void Assembler::hlt() {
926 EnsureSpace ensure_space(this);
931 void Assembler::emit_idiv(Register src, int size) {
932 EnsureSpace ensure_space(this);
935 emit_modrm(0x7, src);
939 void Assembler::emit_imul(Register src, int size) {
940 EnsureSpace ensure_space(this);
943 emit_modrm(0x5, src);
947 void Assembler::emit_imul(Register dst, Register src, int size) {
948 EnsureSpace ensure_space(this);
949 emit_rex(dst, src, size);
952 emit_modrm(dst, src);
956 void Assembler::emit_imul(Register dst, const Operand& src, int size) {
957 EnsureSpace ensure_space(this);
958 emit_rex(dst, src, size);
961 emit_operand(dst, src);
965 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
966 EnsureSpace ensure_space(this);
967 emit_rex(dst, src, size);
968 if (is_int8(imm.value_)) {
970 emit_modrm(dst, src);
974 emit_modrm(dst, src);
980 void Assembler::emit_inc(Register dst, int size) {
981 EnsureSpace ensure_space(this);
984 emit_modrm(0x0, dst);
988 void Assembler::emit_inc(const Operand& dst, int size) {
989 EnsureSpace ensure_space(this);
992 emit_operand(0, dst);
996 void Assembler::int3() {
997 EnsureSpace ensure_space(this);
1002 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1006 } else if (cc == never) {
1009 EnsureSpace ensure_space(this);
1010 ASSERT(is_uint4(cc));
1011 if (L->is_bound()) {
1012 const int short_size = 2;
1013 const int long_size = 6;
1014 int offs = L->pos() - pc_offset();
1016 // Determine whether we can use 1-byte offsets for backwards branches,
1017 // which have a max range of 128 bytes.
1019 // We also need to check predictable_code_size() flag here, because on x64,
1020 // when the full code generator recompiles code for debugging, some places
1021 // need to be padded out to a certain size. The debugger is keeping track of
1022 // how often it did this so that it can adjust return addresses on the
1023 // stack, but if the size of jump instructions can also change, that's not
1024 // enough and the calculated offsets would be incorrect.
1025 if (is_int8(offs - short_size) && !predictable_code_size()) {
1026 // 0111 tttn #8-bit disp.
1028 emit((offs - short_size) & 0xFF);
1030 // 0000 1111 1000 tttn #32-bit disp.
1033 emitl(offs - long_size);
1035 } else if (distance == Label::kNear) {
1036 // 0111 tttn #8-bit disp
1039 if (L->is_near_linked()) {
1040 int offset = L->near_link_pos() - pc_offset();
1041 ASSERT(is_int8(offset));
1042 disp = static_cast<byte>(offset & 0xFF);
1044 L->link_to(pc_offset(), Label::kNear);
1046 } else if (L->is_linked()) {
1047 // 0000 1111 1000 tttn #32-bit disp.
1051 L->link_to(pc_offset() - sizeof(int32_t));
1053 ASSERT(L->is_unused());
1056 int32_t current = pc_offset();
1058 L->link_to(current);
1063 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1064 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1065 EnsureSpace ensure_space(this);
1066 ASSERT(is_uint4(cc));
1069 emit_runtime_entry(entry, rmode);
1073 void Assembler::j(Condition cc,
1074 Handle<Code> target,
1075 RelocInfo::Mode rmode) {
1076 EnsureSpace ensure_space(this);
1077 ASSERT(is_uint4(cc));
1078 // 0000 1111 1000 tttn #32-bit disp.
1081 emit_code_target(target, rmode);
1085 void Assembler::jmp(Label* L, Label::Distance distance) {
1086 EnsureSpace ensure_space(this);
1087 const int short_size = sizeof(int8_t);
1088 const int long_size = sizeof(int32_t);
1089 if (L->is_bound()) {
1090 int offs = L->pos() - pc_offset() - 1;
1092 if (is_int8(offs - short_size) && !predictable_code_size()) {
1093 // 1110 1011 #8-bit disp.
1095 emit((offs - short_size) & 0xFF);
1097 // 1110 1001 #32-bit disp.
1099 emitl(offs - long_size);
1101 } else if (distance == Label::kNear) {
1104 if (L->is_near_linked()) {
1105 int offset = L->near_link_pos() - pc_offset();
1106 ASSERT(is_int8(offset));
1107 disp = static_cast<byte>(offset & 0xFF);
1109 L->link_to(pc_offset(), Label::kNear);
1111 } else if (L->is_linked()) {
1112 // 1110 1001 #32-bit disp.
1115 L->link_to(pc_offset() - long_size);
1117 // 1110 1001 #32-bit disp.
1118 ASSERT(L->is_unused());
1120 int32_t current = pc_offset();
1122 L->link_to(current);
1127 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1128 EnsureSpace ensure_space(this);
1129 // 1110 1001 #32-bit disp.
1131 emit_code_target(target, rmode);
1135 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1136 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1137 EnsureSpace ensure_space(this);
1138 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1140 emit_runtime_entry(entry, rmode);
1144 void Assembler::jmp(Register target) {
1145 EnsureSpace ensure_space(this);
1147 emit_optional_rex_32(target);
1149 emit_modrm(0x4, target);
1153 void Assembler::jmp(const Operand& src) {
1154 EnsureSpace ensure_space(this);
1156 emit_optional_rex_32(src);
1158 emit_operand(0x4, src);
1162 void Assembler::emit_lea(Register dst, const Operand& src, int size) {
1163 EnsureSpace ensure_space(this);
1164 emit_rex(dst, src, size);
1166 emit_operand(dst, src);
1170 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1171 EnsureSpace ensure_space(this);
1172 if (kPointerSize == kInt64Size) {
1173 emit(0x48); // REX.W
1177 ASSERT(kPointerSize == kInt32Size);
1180 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1181 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1182 // Developer's Manual Volume 2.
1188 void Assembler::load_rax(ExternalReference ref) {
1189 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1193 void Assembler::leave() {
1194 EnsureSpace ensure_space(this);
1199 void Assembler::movb(Register dst, const Operand& src) {
1200 EnsureSpace ensure_space(this);
1201 if (!dst.is_byte_register()) {
1202 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1203 emit_rex_32(dst, src);
1205 emit_optional_rex_32(dst, src);
1208 emit_operand(dst, src);
1212 void Assembler::movb(Register dst, Immediate imm) {
1213 EnsureSpace ensure_space(this);
1214 if (!dst.is_byte_register()) {
1217 emit(0xB0 + dst.low_bits());
1222 void Assembler::movb(const Operand& dst, Register src) {
1223 EnsureSpace ensure_space(this);
1224 if (!src.is_byte_register()) {
1225 emit_rex_32(src, dst);
1227 emit_optional_rex_32(src, dst);
1230 emit_operand(src, dst);
1234 void Assembler::movb(const Operand& dst, Immediate imm) {
1235 EnsureSpace ensure_space(this);
1236 emit_optional_rex_32(dst);
1238 emit_operand(0x0, dst);
1239 emit(static_cast<byte>(imm.value_));
1243 void Assembler::movw(Register dst, const Operand& src) {
1244 EnsureSpace ensure_space(this);
1246 emit_optional_rex_32(dst, src);
1248 emit_operand(dst, src);
1252 void Assembler::movw(const Operand& dst, Register src) {
1253 EnsureSpace ensure_space(this);
1255 emit_optional_rex_32(src, dst);
1257 emit_operand(src, dst);
1261 void Assembler::movw(const Operand& dst, Immediate imm) {
1262 EnsureSpace ensure_space(this);
1264 emit_optional_rex_32(dst);
1266 emit_operand(0x0, dst);
1267 emit(static_cast<byte>(imm.value_ & 0xff));
1268 emit(static_cast<byte>(imm.value_ >> 8));
1272 void Assembler::emit_mov(Register dst, const Operand& src, int size) {
1273 EnsureSpace ensure_space(this);
1274 emit_rex(dst, src, size);
1276 emit_operand(dst, src);
1280 void Assembler::emit_mov(Register dst, Register src, int size) {
1281 EnsureSpace ensure_space(this);
1282 if (src.low_bits() == 4) {
1283 emit_rex(src, dst, size);
1285 emit_modrm(src, dst);
1287 emit_rex(dst, src, size);
1289 emit_modrm(dst, src);
1294 void Assembler::emit_mov(const Operand& dst, Register src, int size) {
1295 EnsureSpace ensure_space(this);
1296 emit_rex(src, dst, size);
1298 emit_operand(src, dst);
1302 void Assembler::emit_mov(Register dst, Immediate value, int size) {
1303 EnsureSpace ensure_space(this);
1304 emit_rex(dst, size);
1305 if (size == kInt64Size) {
1307 emit_modrm(0x0, dst);
1309 ASSERT(size == kInt32Size);
1310 emit(0xB8 + dst.low_bits());
1316 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
1317 EnsureSpace ensure_space(this);
1318 emit_rex(dst, size);
1320 emit_operand(0x0, dst);
1325 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
1326 EnsureSpace ensure_space(this);
1327 emit_rex(dst, kPointerSize);
1328 emit(0xB8 | dst.low_bits());
1329 emitp(value, rmode);
1333 void Assembler::movq(Register dst, int64_t value) {
1334 EnsureSpace ensure_space(this);
1336 emit(0xB8 | dst.low_bits());
1341 void Assembler::movq(Register dst, uint64_t value) {
1342 movq(dst, static_cast<int64_t>(value));
1346 // Loads the ip-relative location of the src label into the target location
1347 // (as a 32-bit offset sign extended to 64-bit).
1348 void Assembler::movl(const Operand& dst, Label* src) {
1349 EnsureSpace ensure_space(this);
1350 emit_optional_rex_32(dst);
1352 emit_operand(0, dst);
1353 if (src->is_bound()) {
1354 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1355 ASSERT(offset <= 0);
1357 } else if (src->is_linked()) {
1359 src->link_to(pc_offset() - sizeof(int32_t));
1361 ASSERT(src->is_unused());
1362 int32_t current = pc_offset();
1364 src->link_to(current);
1369 void Assembler::movsxbl(Register dst, const Operand& src) {
1370 EnsureSpace ensure_space(this);
1371 emit_optional_rex_32(dst, src);
1374 emit_operand(dst, src);
1378 void Assembler::movsxbq(Register dst, const Operand& src) {
1379 EnsureSpace ensure_space(this);
1380 emit_rex_64(dst, src);
1383 emit_operand(dst, src);
1387 void Assembler::movsxwl(Register dst, const Operand& src) {
1388 EnsureSpace ensure_space(this);
1389 emit_optional_rex_32(dst, src);
1392 emit_operand(dst, src);
1396 void Assembler::movsxwq(Register dst, const Operand& src) {
1397 EnsureSpace ensure_space(this);
1398 emit_rex_64(dst, src);
1401 emit_operand(dst, src);
1405 void Assembler::movsxlq(Register dst, Register src) {
1406 EnsureSpace ensure_space(this);
1407 emit_rex_64(dst, src);
1409 emit_modrm(dst, src);
1413 void Assembler::movsxlq(Register dst, const Operand& src) {
1414 EnsureSpace ensure_space(this);
1415 emit_rex_64(dst, src);
1417 emit_operand(dst, src);
1421 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
1422 EnsureSpace ensure_space(this);
1423 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1424 // there is no need to make this a 64 bit operation.
1425 emit_optional_rex_32(dst, src);
1428 emit_operand(dst, src);
1432 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
1433 EnsureSpace ensure_space(this);
1434 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1435 // there is no need to make this a 64 bit operation.
1436 emit_optional_rex_32(dst, src);
1439 emit_operand(dst, src);
1443 void Assembler::emit_movzxw(Register dst, Register src, int size) {
1444 EnsureSpace ensure_space(this);
1445 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1446 // there is no need to make this a 64 bit operation.
1447 emit_optional_rex_32(dst, src);
1450 emit_modrm(dst, src);
1454 void Assembler::repmovsb() {
1455 EnsureSpace ensure_space(this);
1461 void Assembler::repmovsw() {
1462 EnsureSpace ensure_space(this);
1463 emit(0x66); // Operand size override.
1469 void Assembler::emit_repmovs(int size) {
1470 EnsureSpace ensure_space(this);
1477 void Assembler::mul(Register src) {
1478 EnsureSpace ensure_space(this);
1481 emit_modrm(0x4, src);
1485 void Assembler::emit_neg(Register dst, int size) {
1486 EnsureSpace ensure_space(this);
1487 emit_rex(dst, size);
1489 emit_modrm(0x3, dst);
1493 void Assembler::emit_neg(const Operand& dst, int size) {
1494 EnsureSpace ensure_space(this);
1497 emit_operand(3, dst);
1501 void Assembler::nop() {
1502 EnsureSpace ensure_space(this);
1507 void Assembler::emit_not(Register dst, int size) {
1508 EnsureSpace ensure_space(this);
1509 emit_rex(dst, size);
1511 emit_modrm(0x2, dst);
1515 void Assembler::emit_not(const Operand& dst, int size) {
1516 EnsureSpace ensure_space(this);
1517 emit_rex(dst, size);
1519 emit_operand(2, dst);
1523 void Assembler::Nop(int n) {
1524 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1525 // and IA-32 Architectures Software Developer's Manual.
1527 // Length Assembly Byte Sequence
1528 // 2 bytes 66 NOP 66 90H
1529 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1530 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1531 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1532 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1533 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1534 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1535 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1538 EnsureSpace ensure_space(this);
1600 void Assembler::popq(Register dst) {
1601 EnsureSpace ensure_space(this);
1602 emit_optional_rex_32(dst);
1603 emit(0x58 | dst.low_bits());
1607 void Assembler::popq(const Operand& dst) {
1608 EnsureSpace ensure_space(this);
1609 emit_optional_rex_32(dst);
1611 emit_operand(0, dst);
1615 void Assembler::popfq() {
1616 EnsureSpace ensure_space(this);
1621 void Assembler::pushq(Register src) {
1622 EnsureSpace ensure_space(this);
1623 emit_optional_rex_32(src);
1624 emit(0x50 | src.low_bits());
1628 void Assembler::pushq(const Operand& src) {
1629 EnsureSpace ensure_space(this);
1630 emit_optional_rex_32(src);
1632 emit_operand(6, src);
1636 void Assembler::pushq(Immediate value) {
1637 EnsureSpace ensure_space(this);
1638 if (is_int8(value.value_)) {
1640 emit(value.value_); // Emit low byte of value.
1643 emitl(value.value_);
1648 void Assembler::pushq_imm32(int32_t imm32) {
1649 EnsureSpace ensure_space(this);
1655 void Assembler::pushfq() {
1656 EnsureSpace ensure_space(this);
1661 void Assembler::ret(int imm16) {
1662 EnsureSpace ensure_space(this);
1663 ASSERT(is_uint16(imm16));
1669 emit((imm16 >> 8) & 0xFF);
1674 void Assembler::setcc(Condition cc, Register reg) {
1675 if (cc > last_condition) {
1676 movb(reg, Immediate(cc == always ? 1 : 0));
1679 EnsureSpace ensure_space(this);
1680 ASSERT(is_uint4(cc));
1681 if (!reg.is_byte_register()) { // Use x64 byte registers, where different.
1686 emit_modrm(0x0, reg);
1690 void Assembler::shld(Register dst, Register src) {
1691 EnsureSpace ensure_space(this);
1692 emit_rex_64(src, dst);
1695 emit_modrm(src, dst);
1699 void Assembler::shrd(Register dst, Register src) {
1700 EnsureSpace ensure_space(this);
1701 emit_rex_64(src, dst);
1704 emit_modrm(src, dst);
1708 void Assembler::emit_xchg(Register dst, Register src, int size) {
1709 EnsureSpace ensure_space(this);
1710 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1711 Register other = src.is(rax) ? dst : src;
1712 emit_rex(other, size);
1713 emit(0x90 | other.low_bits());
1714 } else if (dst.low_bits() == 4) {
1715 emit_rex(dst, src, size);
1717 emit_modrm(dst, src);
1719 emit_rex(src, dst, size);
1721 emit_modrm(src, dst);
1726 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1727 EnsureSpace ensure_space(this);
1728 if (kPointerSize == kInt64Size) {
1729 emit(0x48); // REX.W
1733 ASSERT(kPointerSize == kInt32Size);
1736 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1737 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1738 // Developer's Manual Volume 2.
1744 void Assembler::store_rax(ExternalReference ref) {
1745 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1749 void Assembler::testb(Register dst, Register src) {
1750 EnsureSpace ensure_space(this);
1751 if (src.low_bits() == 4) {
1752 emit_rex_32(src, dst);
1754 emit_modrm(src, dst);
1756 if (!dst.is_byte_register() || !src.is_byte_register()) {
1757 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1758 emit_rex_32(dst, src);
1761 emit_modrm(dst, src);
1766 void Assembler::testb(Register reg, Immediate mask) {
1767 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1768 EnsureSpace ensure_space(this);
1771 emit(mask.value_); // Low byte emitted.
1773 if (!reg.is_byte_register()) {
1774 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1778 emit_modrm(0x0, reg);
1779 emit(mask.value_); // Low byte emitted.
1784 void Assembler::testb(const Operand& op, Immediate mask) {
1785 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1786 EnsureSpace ensure_space(this);
1787 emit_optional_rex_32(rax, op);
1789 emit_operand(rax, op); // Operation code 0
1790 emit(mask.value_); // Low byte emitted.
1794 void Assembler::testb(const Operand& op, Register reg) {
1795 EnsureSpace ensure_space(this);
1796 if (!reg.is_byte_register()) {
1797 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1798 emit_rex_32(reg, op);
1800 emit_optional_rex_32(reg, op);
1803 emit_operand(reg, op);
1807 void Assembler::emit_test(Register dst, Register src, int size) {
1808 EnsureSpace ensure_space(this);
1809 if (src.low_bits() == 4) {
1810 emit_rex(src, dst, size);
1812 emit_modrm(src, dst);
1814 emit_rex(dst, src, size);
1816 emit_modrm(dst, src);
1821 void Assembler::emit_test(Register reg, Immediate mask, int size) {
1822 // testl with a mask that fits in the low byte is exactly testb.
1823 if (is_uint8(mask.value_)) {
1827 EnsureSpace ensure_space(this);
1829 emit_rex(rax, size);
1833 emit_rex(reg, size);
1835 emit_modrm(0x0, reg);
1841 void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
1842 // testl with a mask that fits in the low byte is exactly testb.
1843 if (is_uint8(mask.value_)) {
1847 EnsureSpace ensure_space(this);
1848 emit_rex(rax, op, size);
1850 emit_operand(rax, op); // Operation code 0
1855 void Assembler::emit_test(const Operand& op, Register reg, int size) {
1856 EnsureSpace ensure_space(this);
1857 emit_rex(reg, op, size);
1859 emit_operand(reg, op);
1863 // FPU instructions.
1866 void Assembler::fld(int i) {
1867 EnsureSpace ensure_space(this);
1868 emit_farith(0xD9, 0xC0, i);
1872 void Assembler::fld1() {
1873 EnsureSpace ensure_space(this);
1879 void Assembler::fldz() {
1880 EnsureSpace ensure_space(this);
1886 void Assembler::fldpi() {
1887 EnsureSpace ensure_space(this);
1893 void Assembler::fldln2() {
1894 EnsureSpace ensure_space(this);
1900 void Assembler::fld_s(const Operand& adr) {
1901 EnsureSpace ensure_space(this);
1902 emit_optional_rex_32(adr);
1904 emit_operand(0, adr);
1908 void Assembler::fld_d(const Operand& adr) {
1909 EnsureSpace ensure_space(this);
1910 emit_optional_rex_32(adr);
1912 emit_operand(0, adr);
1916 void Assembler::fstp_s(const Operand& adr) {
1917 EnsureSpace ensure_space(this);
1918 emit_optional_rex_32(adr);
1920 emit_operand(3, adr);
1924 void Assembler::fstp_d(const Operand& adr) {
1925 EnsureSpace ensure_space(this);
1926 emit_optional_rex_32(adr);
1928 emit_operand(3, adr);
1932 void Assembler::fstp(int index) {
1933 ASSERT(is_uint3(index));
1934 EnsureSpace ensure_space(this);
1935 emit_farith(0xDD, 0xD8, index);
1939 void Assembler::fild_s(const Operand& adr) {
1940 EnsureSpace ensure_space(this);
1941 emit_optional_rex_32(adr);
1943 emit_operand(0, adr);
1947 void Assembler::fild_d(const Operand& adr) {
1948 EnsureSpace ensure_space(this);
1949 emit_optional_rex_32(adr);
1951 emit_operand(5, adr);
1955 void Assembler::fistp_s(const Operand& adr) {
1956 EnsureSpace ensure_space(this);
1957 emit_optional_rex_32(adr);
1959 emit_operand(3, adr);
1963 void Assembler::fisttp_s(const Operand& adr) {
1964 ASSERT(IsEnabled(SSE3));
1965 EnsureSpace ensure_space(this);
1966 emit_optional_rex_32(adr);
1968 emit_operand(1, adr);
1972 void Assembler::fisttp_d(const Operand& adr) {
1973 ASSERT(IsEnabled(SSE3));
1974 EnsureSpace ensure_space(this);
1975 emit_optional_rex_32(adr);
1977 emit_operand(1, adr);
1981 void Assembler::fist_s(const Operand& adr) {
1982 EnsureSpace ensure_space(this);
1983 emit_optional_rex_32(adr);
1985 emit_operand(2, adr);
1989 void Assembler::fistp_d(const Operand& adr) {
1990 EnsureSpace ensure_space(this);
1991 emit_optional_rex_32(adr);
1993 emit_operand(7, adr);
1997 void Assembler::fabs() {
1998 EnsureSpace ensure_space(this);
2004 void Assembler::fchs() {
2005 EnsureSpace ensure_space(this);
2011 void Assembler::fcos() {
2012 EnsureSpace ensure_space(this);
2018 void Assembler::fsin() {
2019 EnsureSpace ensure_space(this);
2025 void Assembler::fptan() {
2026 EnsureSpace ensure_space(this);
2032 void Assembler::fyl2x() {
2033 EnsureSpace ensure_space(this);
2039 void Assembler::f2xm1() {
2040 EnsureSpace ensure_space(this);
2046 void Assembler::fscale() {
2047 EnsureSpace ensure_space(this);
2053 void Assembler::fninit() {
2054 EnsureSpace ensure_space(this);
2060 void Assembler::fadd(int i) {
2061 EnsureSpace ensure_space(this);
2062 emit_farith(0xDC, 0xC0, i);
2066 void Assembler::fsub(int i) {
2067 EnsureSpace ensure_space(this);
2068 emit_farith(0xDC, 0xE8, i);
2072 void Assembler::fisub_s(const Operand& adr) {
2073 EnsureSpace ensure_space(this);
2074 emit_optional_rex_32(adr);
2076 emit_operand(4, adr);
2080 void Assembler::fmul(int i) {
2081 EnsureSpace ensure_space(this);
2082 emit_farith(0xDC, 0xC8, i);
2086 void Assembler::fdiv(int i) {
2087 EnsureSpace ensure_space(this);
2088 emit_farith(0xDC, 0xF8, i);
2092 void Assembler::faddp(int i) {
2093 EnsureSpace ensure_space(this);
2094 emit_farith(0xDE, 0xC0, i);
2098 void Assembler::fsubp(int i) {
2099 EnsureSpace ensure_space(this);
2100 emit_farith(0xDE, 0xE8, i);
2104 void Assembler::fsubrp(int i) {
2105 EnsureSpace ensure_space(this);
2106 emit_farith(0xDE, 0xE0, i);
2110 void Assembler::fmulp(int i) {
2111 EnsureSpace ensure_space(this);
2112 emit_farith(0xDE, 0xC8, i);
2116 void Assembler::fdivp(int i) {
2117 EnsureSpace ensure_space(this);
2118 emit_farith(0xDE, 0xF8, i);
2122 void Assembler::fprem() {
2123 EnsureSpace ensure_space(this);
2129 void Assembler::fprem1() {
2130 EnsureSpace ensure_space(this);
2136 void Assembler::fxch(int i) {
2137 EnsureSpace ensure_space(this);
2138 emit_farith(0xD9, 0xC8, i);
2142 void Assembler::fincstp() {
2143 EnsureSpace ensure_space(this);
2149 void Assembler::ffree(int i) {
2150 EnsureSpace ensure_space(this);
2151 emit_farith(0xDD, 0xC0, i);
2155 void Assembler::ftst() {
2156 EnsureSpace ensure_space(this);
2162 void Assembler::fucomp(int i) {
2163 EnsureSpace ensure_space(this);
2164 emit_farith(0xDD, 0xE8, i);
2168 void Assembler::fucompp() {
2169 EnsureSpace ensure_space(this);
2175 void Assembler::fucomi(int i) {
2176 EnsureSpace ensure_space(this);
2182 void Assembler::fucomip() {
2183 EnsureSpace ensure_space(this);
2189 void Assembler::fcompp() {
2190 EnsureSpace ensure_space(this);
2196 void Assembler::fnstsw_ax() {
2197 EnsureSpace ensure_space(this);
2203 void Assembler::fwait() {
2204 EnsureSpace ensure_space(this);
2209 void Assembler::frndint() {
2210 EnsureSpace ensure_space(this);
2216 void Assembler::fnclex() {
2217 EnsureSpace ensure_space(this);
2223 void Assembler::sahf() {
2224 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2225 // in 64-bit mode. Test CpuID.
2226 EnsureSpace ensure_space(this);
2231 void Assembler::emit_farith(int b1, int b2, int i) {
2232 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2233 ASSERT(is_uint3(i)); // illegal stack offset
2241 void Assembler::andps(XMMRegister dst, XMMRegister src) {
2242 EnsureSpace ensure_space(this);
2243 emit_optional_rex_32(dst, src);
2246 emit_sse_operand(dst, src);
2250 void Assembler::andps(XMMRegister dst, const Operand& src) {
2251 EnsureSpace ensure_space(this);
2252 emit_optional_rex_32(dst, src);
2255 emit_sse_operand(dst, src);
2259 void Assembler::orps(XMMRegister dst, XMMRegister src) {
2260 EnsureSpace ensure_space(this);
2261 emit_optional_rex_32(dst, src);
2264 emit_sse_operand(dst, src);
2268 void Assembler::orps(XMMRegister dst, const Operand& src) {
2269 EnsureSpace ensure_space(this);
2270 emit_optional_rex_32(dst, src);
2273 emit_sse_operand(dst, src);
2277 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2278 EnsureSpace ensure_space(this);
2279 emit_optional_rex_32(dst, src);
2282 emit_sse_operand(dst, src);
2286 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2287 EnsureSpace ensure_space(this);
2288 emit_optional_rex_32(dst, src);
2291 emit_sse_operand(dst, src);
2295 void Assembler::addps(XMMRegister dst, XMMRegister src) {
2296 EnsureSpace ensure_space(this);
2297 emit_optional_rex_32(dst, src);
2300 emit_sse_operand(dst, src);
2304 void Assembler::addps(XMMRegister dst, const Operand& src) {
2305 EnsureSpace ensure_space(this);
2306 emit_optional_rex_32(dst, src);
2309 emit_sse_operand(dst, src);
2313 void Assembler::subps(XMMRegister dst, XMMRegister src) {
2314 EnsureSpace ensure_space(this);
2315 emit_optional_rex_32(dst, src);
2318 emit_sse_operand(dst, src);
2322 void Assembler::subps(XMMRegister dst, const Operand& src) {
2323 EnsureSpace ensure_space(this);
2324 emit_optional_rex_32(dst, src);
2327 emit_sse_operand(dst, src);
2331 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2332 EnsureSpace ensure_space(this);
2333 emit_optional_rex_32(dst, src);
2336 emit_sse_operand(dst, src);
2340 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2341 EnsureSpace ensure_space(this);
2342 emit_optional_rex_32(dst, src);
2345 emit_sse_operand(dst, src);
2349 void Assembler::divps(XMMRegister dst, XMMRegister src) {
2350 EnsureSpace ensure_space(this);
2351 emit_optional_rex_32(dst, src);
2354 emit_sse_operand(dst, src);
2358 void Assembler::divps(XMMRegister dst, const Operand& src) {
2359 EnsureSpace ensure_space(this);
2360 emit_optional_rex_32(dst, src);
2363 emit_sse_operand(dst, src);
2367 void Assembler::addpd(XMMRegister dst, XMMRegister src) {
2368 EnsureSpace ensure_space(this);
2370 emit_optional_rex_32(dst, src);
2373 emit_sse_operand(dst, src);
2377 void Assembler::addpd(XMMRegister dst, const Operand& src) {
2378 EnsureSpace ensure_space(this);
2380 emit_optional_rex_32(dst, src);
2383 emit_sse_operand(dst, src);
2387 void Assembler::subpd(XMMRegister dst, XMMRegister src) {
2388 EnsureSpace ensure_space(this);
2390 emit_optional_rex_32(dst, src);
2393 emit_sse_operand(dst, src);
2397 void Assembler::subpd(XMMRegister dst, const Operand& src) {
2398 EnsureSpace ensure_space(this);
2400 emit_optional_rex_32(dst, src);
2403 emit_sse_operand(dst, src);
2407 void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
2408 EnsureSpace ensure_space(this);
2410 emit_optional_rex_32(dst, src);
2413 emit_sse_operand(dst, src);
2417 void Assembler::mulpd(XMMRegister dst, const Operand& src) {
2418 EnsureSpace ensure_space(this);
2420 emit_optional_rex_32(dst, src);
2423 emit_sse_operand(dst, src);
2427 void Assembler::divpd(XMMRegister dst, XMMRegister src) {
2428 EnsureSpace ensure_space(this);
2430 emit_optional_rex_32(dst, src);
2433 emit_sse_operand(dst, src);
2437 void Assembler::divpd(XMMRegister dst, const Operand& src) {
2438 EnsureSpace ensure_space(this);
2440 emit_optional_rex_32(dst, src);
2443 emit_sse_operand(dst, src);
2447 // SSE 2 operations.
2449 void Assembler::movd(XMMRegister dst, Register src) {
2450 EnsureSpace ensure_space(this);
2452 emit_optional_rex_32(dst, src);
2455 emit_sse_operand(dst, src);
2459 void Assembler::movd(Register dst, XMMRegister src) {
2460 EnsureSpace ensure_space(this);
2462 emit_optional_rex_32(src, dst);
2465 emit_sse_operand(src, dst);
2469 void Assembler::movq(XMMRegister dst, Register src) {
2470 EnsureSpace ensure_space(this);
2472 emit_rex_64(dst, src);
2475 emit_sse_operand(dst, src);
2479 void Assembler::movq(Register dst, XMMRegister src) {
2480 EnsureSpace ensure_space(this);
2482 emit_rex_64(src, dst);
2485 emit_sse_operand(src, dst);
2489 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2490 EnsureSpace ensure_space(this);
2491 if (dst.low_bits() == 4) {
2492 // Avoid unnecessary SIB byte.
2494 emit_optional_rex_32(dst, src);
2497 emit_sse_operand(dst, src);
2500 emit_optional_rex_32(src, dst);
2503 emit_sse_operand(src, dst);
2508 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2509 EnsureSpace ensure_space(this);
2511 emit_rex_64(src, dst);
2514 emit_sse_operand(src, dst);
2518 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2519 EnsureSpace ensure_space(this);
2521 emit_rex_64(dst, src);
2524 emit_sse_operand(dst, src);
2528 void Assembler::movdqu(const Operand& dst, XMMRegister src) {
2529 EnsureSpace ensure_space(this);
2531 emit_rex_64(src, dst);
2534 emit_sse_operand(src, dst);
2538 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2539 EnsureSpace ensure_space(this);
2541 emit_rex_64(dst, src);
2544 emit_sse_operand(dst, src);
2548 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2549 ASSERT(IsEnabled(SSE4_1));
2550 ASSERT(is_uint8(imm8));
2551 EnsureSpace ensure_space(this);
2553 emit_optional_rex_32(src, dst);
2557 emit_sse_operand(src, dst);
2562 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
2563 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2564 ASSERT(is_uint8(imm8));
2565 EnsureSpace ensure_space(this);
2567 emit_optional_rex_32(dst, src);
2571 emit_sse_operand(dst, src);
2576 void Assembler::pinsrd(XMMRegister dst, Register src, byte imm8) {
2577 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2578 ASSERT(is_uint8(imm8));
2579 EnsureSpace ensure_space(this);
2581 emit_optional_rex_32(dst, src);
2585 emit_sse_operand(dst, src);
2590 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2591 EnsureSpace ensure_space(this);
2592 emit(0xF2); // double
2593 emit_optional_rex_32(src, dst);
2595 emit(0x11); // store
2596 emit_sse_operand(src, dst);
2600 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2601 EnsureSpace ensure_space(this);
2602 emit(0xF2); // double
2603 emit_optional_rex_32(dst, src);
2606 emit_sse_operand(dst, src);
2610 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2611 EnsureSpace ensure_space(this);
2612 emit(0xF2); // double
2613 emit_optional_rex_32(dst, src);
2616 emit_sse_operand(dst, src);
2620 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2621 EnsureSpace ensure_space(this);
2622 if (src.low_bits() == 4) {
2623 // Try to avoid an unnecessary SIB byte.
2624 emit_optional_rex_32(src, dst);
2627 emit_sse_operand(src, dst);
2629 emit_optional_rex_32(dst, src);
2632 emit_sse_operand(dst, src);
2637 void Assembler::movups(XMMRegister dst, const Operand& src) {
2638 EnsureSpace ensure_space(this);
2639 emit_optional_rex_32(dst, src);
2642 emit_sse_operand(dst, src);
2646 void Assembler::movups(const Operand& dst, XMMRegister src) {
2647 EnsureSpace ensure_space(this);
2648 emit_optional_rex_32(src, dst);
2651 emit_sse_operand(src, dst);
2655 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2656 ASSERT(is_uint8(imm8));
2657 EnsureSpace ensure_space(this);
2658 emit_optional_rex_32(dst, src);
2661 emit_sse_operand(dst, src);
2666 void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) {
2667 ASSERT(is_uint8(imm8));
2668 EnsureSpace ensure_space(this);
2670 emit_optional_rex_32(dst, src);
2673 emit_sse_operand(dst, src);
2678 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2679 EnsureSpace ensure_space(this);
2680 if (src.low_bits() == 4) {
2681 // Try to avoid an unnecessary SIB byte.
2683 emit_optional_rex_32(src, dst);
2686 emit_sse_operand(src, dst);
2689 emit_optional_rex_32(dst, src);
2692 emit_sse_operand(dst, src);
2697 void Assembler::movss(XMMRegister dst, const Operand& src) {
2698 EnsureSpace ensure_space(this);
2699 emit(0xF3); // single
2700 emit_optional_rex_32(dst, src);
2703 emit_sse_operand(dst, src);
2707 void Assembler::movss(const Operand& src, XMMRegister dst) {
2708 EnsureSpace ensure_space(this);
2709 emit(0xF3); // single
2710 emit_optional_rex_32(dst, src);
2712 emit(0x11); // store
2713 emit_sse_operand(dst, src);
2717 void Assembler::psllq(XMMRegister reg, byte imm8) {
2718 EnsureSpace ensure_space(this);
2722 emit_sse_operand(rsi, reg); // rsi == 6
2727 void Assembler::cvttss2si(Register dst, const Operand& src) {
2728 EnsureSpace ensure_space(this);
2730 emit_optional_rex_32(dst, src);
2733 emit_operand(dst, src);
2737 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2738 EnsureSpace ensure_space(this);
2740 emit_optional_rex_32(dst, src);
2743 emit_sse_operand(dst, src);
2747 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2748 EnsureSpace ensure_space(this);
2750 emit_optional_rex_32(dst, src);
2753 emit_operand(dst, src);
2757 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2758 EnsureSpace ensure_space(this);
2760 emit_optional_rex_32(dst, src);
2763 emit_sse_operand(dst, src);
2767 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2768 EnsureSpace ensure_space(this);
2770 emit_rex_64(dst, src);
2773 emit_sse_operand(dst, src);
2777 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2778 EnsureSpace ensure_space(this);
2780 emit_optional_rex_32(dst, src);
2783 emit_sse_operand(dst, src);
2787 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2788 EnsureSpace ensure_space(this);
2790 emit_optional_rex_32(dst, src);
2793 emit_sse_operand(dst, src);
2797 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2798 EnsureSpace ensure_space(this);
2800 emit_optional_rex_32(dst, src);
2803 emit_sse_operand(dst, src);
2807 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2808 EnsureSpace ensure_space(this);
2810 emit_rex_64(dst, src);
2813 emit_sse_operand(dst, src);
2817 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2818 EnsureSpace ensure_space(this);
2820 emit_optional_rex_32(dst, src);
2823 emit_sse_operand(dst, src);
2827 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2828 EnsureSpace ensure_space(this);
2830 emit_optional_rex_32(dst, src);
2833 emit_sse_operand(dst, src);
2837 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2838 EnsureSpace ensure_space(this);
2840 emit_optional_rex_32(dst, src);
2843 emit_sse_operand(dst, src);
2847 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2848 EnsureSpace ensure_space(this);
2850 emit_optional_rex_32(dst, src);
2853 emit_sse_operand(dst, src);
2857 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2858 EnsureSpace ensure_space(this);
2860 emit_rex_64(dst, src);
2863 emit_sse_operand(dst, src);
2867 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2868 EnsureSpace ensure_space(this);
2870 emit_optional_rex_32(dst, src);
2873 emit_sse_operand(dst, src);
2877 void Assembler::addsd(XMMRegister dst, const Operand& src) {
2878 EnsureSpace ensure_space(this);
2880 emit_optional_rex_32(dst, src);
2883 emit_sse_operand(dst, src);
2887 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2888 EnsureSpace ensure_space(this);
2890 emit_optional_rex_32(dst, src);
2893 emit_sse_operand(dst, src);
2897 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
2898 EnsureSpace ensure_space(this);
2900 emit_optional_rex_32(dst, src);
2903 emit_sse_operand(dst, src);
2907 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2908 EnsureSpace ensure_space(this);
2910 emit_optional_rex_32(dst, src);
2913 emit_sse_operand(dst, src);
2917 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2918 EnsureSpace ensure_space(this);
2920 emit_optional_rex_32(dst, src);
2923 emit_sse_operand(dst, src);
2927 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2928 EnsureSpace ensure_space(this);
2930 emit_optional_rex_32(dst, src);
2933 emit_sse_operand(dst, src);
2937 void Assembler::andpd(XMMRegister dst, const Operand& src) {
2938 EnsureSpace ensure_space(this);
2940 emit_optional_rex_32(dst, src);
2943 emit_sse_operand(dst, src);
2947 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2948 EnsureSpace ensure_space(this);
2950 emit_optional_rex_32(dst, src);
2953 emit_sse_operand(dst, src);
2957 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2958 EnsureSpace ensure_space(this);
2960 emit_optional_rex_32(dst, src);
2963 emit_sse_operand(dst, src);
2967 void Assembler::xorpd(XMMRegister dst, const Operand& src) {
2968 EnsureSpace ensure_space(this);
2970 emit_optional_rex_32(dst, src);
2973 emit_sse_operand(dst, src);
2977 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2978 EnsureSpace ensure_space(this);
2980 emit_optional_rex_32(dst, src);
2983 emit_sse_operand(dst, src);
2987 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2988 EnsureSpace ensure_space(this);
2990 emit_optional_rex_32(dst, src);
2993 emit_sse_operand(dst, src);
2997 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2998 EnsureSpace ensure_space(this);
3000 emit_optional_rex_32(dst, src);
3003 emit_sse_operand(dst, src);
3007 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
3008 EnsureSpace ensure_space(this);
3010 emit_optional_rex_32(dst, src);
3013 emit_sse_operand(dst, src);
3014 emit(0x01); // LT == 1
3018 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
3019 EnsureSpace ensure_space(this);
3020 emit_optional_rex_32(dst, src);
3023 emit_sse_operand(dst, src);
3028 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) {
3029 cmpps(dst, src, 0x0);
3033 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) {
3034 cmpps(dst, src, 0x1);
3038 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) {
3039 cmpps(dst, src, 0x2);
3043 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) {
3044 cmpps(dst, src, 0x4);
3048 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) {
3049 cmpps(dst, src, 0x5);
3053 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) {
3054 cmpps(dst, src, 0x6);
3058 void Assembler::pslld(XMMRegister reg, int8_t shift) {
3059 EnsureSpace ensure_space(this);
3061 emit_optional_rex_32(reg);
3064 emit_sse_operand(rsi, reg); // rsi == 6
3069 void Assembler::pslld(XMMRegister dst, XMMRegister src) {
3070 EnsureSpace ensure_space(this);
3072 emit_optional_rex_32(dst, src);
3075 emit_sse_operand(dst, src);
3079 void Assembler::psrld(XMMRegister reg, int8_t shift) {
3080 EnsureSpace ensure_space(this);
3082 emit_optional_rex_32(reg);
3085 emit_sse_operand(rdx, reg); // rdx == 2
3090 void Assembler::psrld(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::psrad(XMMRegister reg, int8_t shift) {
3101 EnsureSpace ensure_space(this);
3103 emit_optional_rex_32(reg);
3106 emit_sse_operand(rsp, reg); // rsp == 4
3111 void Assembler::psrad(XMMRegister dst, XMMRegister src) {
3112 EnsureSpace ensure_space(this);
3114 emit_optional_rex_32(dst, src);
3117 emit_sse_operand(dst, src);
3121 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
3122 EnsureSpace ensure_space(this);
3124 emit_optional_rex_32(dst, src);
3127 emit_sse_operand(dst, src);
3131 void Assembler::pcmpgtd(XMMRegister dst, XMMRegister src) {
3132 EnsureSpace ensure_space(this);
3134 emit_optional_rex_32(dst, src);
3137 emit_sse_operand(dst, src);
3141 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
3142 Assembler::RoundingMode mode) {
3143 ASSERT(IsEnabled(SSE4_1));
3144 EnsureSpace ensure_space(this);
3146 emit_optional_rex_32(dst, src);
3150 emit_sse_operand(dst, src);
3151 // Mask precision exeption.
3152 emit(static_cast<byte>(mode) | 0x8);
3156 void Assembler::movmskpd(Register dst, XMMRegister src) {
3157 EnsureSpace ensure_space(this);
3159 emit_optional_rex_32(dst, src);
3162 emit_sse_operand(dst, src);
3166 void Assembler::movmskps(Register dst, XMMRegister src) {
3167 EnsureSpace ensure_space(this);
3168 emit_optional_rex_32(dst, src);
3171 emit_sse_operand(dst, src);
3175 void Assembler::minps(XMMRegister dst, XMMRegister src) {
3176 EnsureSpace ensure_space(this);
3177 emit_optional_rex_32(dst, src);
3180 emit_sse_operand(dst, src);
3184 void Assembler::minps(XMMRegister dst, const Operand& src) {
3185 EnsureSpace ensure_space(this);
3186 emit_optional_rex_32(dst, src);
3189 emit_sse_operand(dst, src);
3193 void Assembler::maxps(XMMRegister dst, XMMRegister src) {
3194 EnsureSpace ensure_space(this);
3195 emit_optional_rex_32(dst, src);
3198 emit_sse_operand(dst, src);
3202 void Assembler::maxps(XMMRegister dst, const Operand& src) {
3203 EnsureSpace ensure_space(this);
3204 emit_optional_rex_32(dst, src);
3207 emit_sse_operand(dst, src);
3211 void Assembler::minpd(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::minpd(XMMRegister dst, const Operand& src) {
3222 EnsureSpace ensure_space(this);
3224 emit_optional_rex_32(dst, src);
3227 emit_sse_operand(dst, src);
3231 void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
3232 EnsureSpace ensure_space(this);
3234 emit_optional_rex_32(dst, src);
3237 emit_sse_operand(dst, src);
3241 void Assembler::maxpd(XMMRegister dst, const Operand& src) {
3242 EnsureSpace ensure_space(this);
3244 emit_optional_rex_32(dst, src);
3247 emit_sse_operand(dst, src);
3251 void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
3252 EnsureSpace ensure_space(this);
3253 emit_optional_rex_32(dst, src);
3256 emit_sse_operand(dst, src);
3260 void Assembler::rcpps(XMMRegister dst, const Operand& src) {
3261 EnsureSpace ensure_space(this);
3262 emit_optional_rex_32(dst, src);
3265 emit_sse_operand(dst, src);
3269 void Assembler::rsqrtps(XMMRegister dst, XMMRegister src) {
3270 EnsureSpace ensure_space(this);
3271 emit_optional_rex_32(dst, src);
3274 emit_sse_operand(dst, src);
3278 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
3279 EnsureSpace ensure_space(this);
3280 emit_optional_rex_32(dst, src);
3283 emit_sse_operand(dst, src);
3287 void Assembler::sqrtps(XMMRegister dst, XMMRegister src) {
3288 EnsureSpace ensure_space(this);
3289 emit_optional_rex_32(dst, src);
3292 emit_sse_operand(dst, src);
3296 void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
3297 EnsureSpace ensure_space(this);
3298 emit_optional_rex_32(dst, src);
3301 emit_sse_operand(dst, src);
3305 void Assembler::sqrtpd(XMMRegister dst, XMMRegister src) {
3306 EnsureSpace ensure_space(this);
3308 emit_optional_rex_32(dst, src);
3311 emit_sse_operand(dst, src);
3315 void Assembler::sqrtpd(XMMRegister dst, const Operand& src) {
3316 EnsureSpace ensure_space(this);
3318 emit_optional_rex_32(dst, src);
3321 emit_sse_operand(dst, src);
3325 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
3326 EnsureSpace ensure_space(this);
3327 emit_optional_rex_32(dst, src);
3330 emit_sse_operand(dst, src);
3334 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
3335 EnsureSpace ensure_space(this);
3336 emit_optional_rex_32(dst, src);
3339 emit_sse_operand(dst, src);
3343 void Assembler::paddd(XMMRegister dst, XMMRegister src) {
3344 EnsureSpace ensure_space(this);
3346 emit_optional_rex_32(dst, src);
3349 emit_sse_operand(dst, src);
3353 void Assembler::paddd(XMMRegister dst, const Operand& src) {
3354 EnsureSpace ensure_space(this);
3356 emit_optional_rex_32(dst, src);
3359 emit_sse_operand(dst, src);
3363 void Assembler::psubd(XMMRegister dst, XMMRegister src) {
3364 EnsureSpace ensure_space(this);
3366 emit_optional_rex_32(dst, src);
3369 emit_sse_operand(dst, src);
3373 void Assembler::psubd(XMMRegister dst, const Operand& src) {
3374 EnsureSpace ensure_space(this);
3376 emit_optional_rex_32(dst, src);
3379 emit_sse_operand(dst, src);
3383 void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
3384 ASSERT(IsEnabled(SSE4_1));
3385 EnsureSpace ensure_space(this);
3387 emit_optional_rex_32(dst, src);
3391 emit_sse_operand(dst, src);
3395 void Assembler::pmulld(XMMRegister dst, const Operand& src) {
3396 EnsureSpace ensure_space(this);
3398 emit_optional_rex_32(dst, src);
3401 emit_sse_operand(dst, src);
3405 void Assembler::pmuludq(XMMRegister dst, XMMRegister src) {
3406 EnsureSpace ensure_space(this);
3408 emit_optional_rex_32(dst, src);
3411 emit_sse_operand(dst, src);
3415 void Assembler::pmuludq(XMMRegister dst, const Operand& src) {
3416 EnsureSpace ensure_space(this);
3418 emit_optional_rex_32(dst, src);
3421 emit_sse_operand(dst, src);
3425 void Assembler::punpackldq(XMMRegister dst, XMMRegister src) {
3426 EnsureSpace ensure_space(this);
3428 emit_optional_rex_32(dst, src);
3431 emit_sse_operand(dst, src);
3435 void Assembler::punpackldq(XMMRegister dst, const Operand& src) {
3436 EnsureSpace ensure_space(this);
3438 emit_optional_rex_32(dst, src);
3441 emit_sse_operand(dst, src);
3445 void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
3446 EnsureSpace ensure_space(this);
3448 emit_optional_rex_32(dst);
3451 emit_sse_operand(dst);
3456 void Assembler::cvtps2dq(XMMRegister dst, XMMRegister src) {
3457 EnsureSpace ensure_space(this);
3459 emit_optional_rex_32(dst, src);
3462 emit_sse_operand(dst, src);
3466 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) {
3467 EnsureSpace ensure_space(this);
3469 emit_optional_rex_32(dst, src);
3472 emit_sse_operand(dst, src);
3476 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
3477 EnsureSpace ensure_space(this);
3479 emit_optional_rex_32(dst, src);
3482 emit_sse_operand(dst, src);
3487 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
3488 Register ireg = { reg.code() };
3489 emit_operand(ireg, adr);
3493 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3494 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3498 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3499 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3503 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3504 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3508 void Assembler::emit_sse_operand(XMMRegister dst) {
3509 emit(0xD8 | dst.low_bits());
3513 void Assembler::db(uint8_t data) {
3514 EnsureSpace ensure_space(this);
3519 void Assembler::dd(uint32_t data) {
3520 EnsureSpace ensure_space(this);
3525 // Relocation information implementations.
3527 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3528 ASSERT(!RelocInfo::IsNone(rmode));
3529 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
3530 // Don't record external references unless the heap will be serialized.
3531 if (!Serializer::enabled(isolate()) && !emit_debug_code()) {
3534 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
3535 // Don't record psuedo relocation info for code age sequence mode.
3538 RelocInfo rinfo(pc_, rmode, data, NULL);
3539 reloc_info_writer.Write(&rinfo);
3543 void Assembler::RecordJSReturn() {
3544 positions_recorder()->WriteRecordedPositions();
3545 EnsureSpace ensure_space(this);
3546 RecordRelocInfo(RelocInfo::JS_RETURN);
3550 void Assembler::RecordDebugBreakSlot() {
3551 positions_recorder()->WriteRecordedPositions();
3552 EnsureSpace ensure_space(this);
3553 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3557 void Assembler::RecordComment(const char* msg, bool force) {
3558 if (FLAG_code_comments || force) {
3559 EnsureSpace ensure_space(this);
3560 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3565 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3566 // No out-of-line constant pool support.
3567 ASSERT(!FLAG_enable_ool_constant_pool);
3568 return isolate->factory()->empty_constant_pool_array();
3572 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3573 // No out-of-line constant pool support.
3574 ASSERT(!FLAG_enable_ool_constant_pool);
3579 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3580 1 << RelocInfo::RUNTIME_ENTRY |
3581 1 << RelocInfo::INTERNAL_REFERENCE |
3582 1 << RelocInfo::CODE_AGE_SEQUENCE;
3585 bool RelocInfo::IsCodedSpecially() {
3586 // The deserializer needs to know whether a pointer is specially coded. Being
3587 // specially coded on x64 means that it is a relative 32 bit address, as used
3588 // by branch instructions.
3589 return (1 << rmode_) & kApplyMask;
3593 bool RelocInfo::IsInConstantPool() {
3598 } } // namespace v8::internal
3600 #endif // V8_TARGET_ARCH_X64