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/macro-assembler.h"
10 #include "src/serialize.h"
15 // -----------------------------------------------------------------------------
16 // Implementation of CpuFeatures
18 void CpuFeatures::ProbeImpl(bool cross_compile) {
20 CHECK(cpu.has_sse2()); // SSE2 support is mandatory.
21 CHECK(cpu.has_cmov()); // CMOV support is mandatory.
23 // Only use statically determined features for cross compile (snapshot).
24 if (cross_compile) return;
26 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
27 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
28 // SAHF is not generally available in long mode.
29 if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF;
33 void CpuFeatures::PrintTarget() { }
34 void CpuFeatures::PrintFeatures() { }
37 // -----------------------------------------------------------------------------
38 // Implementation of RelocInfo
40 // Patch the code at the current PC with a call to the target address.
41 // Additional guard int3 instructions can be added if required.
42 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
43 int code_size = Assembler::kCallSequenceLength + guard_bytes;
45 // Create a code patcher.
46 CodePatcher patcher(pc_, code_size);
48 // Add a label for checking the size of the code used for returning.
51 patcher.masm()->bind(&check_codesize);
55 patcher.masm()->movp(kScratchRegister, reinterpret_cast<void*>(target),
56 Assembler::RelocInfoNone());
57 patcher.masm()->call(kScratchRegister);
59 // Check that the size of the code generated is as expected.
60 ASSERT_EQ(Assembler::kCallSequenceLength,
61 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
63 // Add the requested number of int3 instructions after the call.
64 for (int i = 0; i < guard_bytes; i++) {
65 patcher.masm()->int3();
70 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
71 // Patch the code at the current address with the supplied instructions.
72 for (int i = 0; i < instruction_count; i++) {
73 *(pc_ + i) = *(instructions + i);
76 // Indicate that code has changed.
77 CPU::FlushICache(pc_, instruction_count);
81 // -----------------------------------------------------------------------------
82 // Register constants.
85 Register::kRegisterCodeByAllocationIndex[kMaxNumAllocatableRegisters] = {
86 // rax, rbx, rdx, rcx, rsi, rdi, r8, r9, r11, r14, r15
87 0, 3, 2, 1, 6, 7, 8, 9, 11, 14, 15
90 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
91 0, 3, 2, 1, -1, -1, 4, 5, 6, 7, -1, 8, -1, -1, 9, 10
95 // -----------------------------------------------------------------------------
96 // Implementation of Operand
98 Operand::Operand(Register base, int32_t disp) : rex_(0) {
100 if (base.is(rsp) || base.is(r12)) {
101 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
102 set_sib(times_1, rsp, base);
105 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
107 } else if (is_int8(disp)) {
117 Operand::Operand(Register base,
120 int32_t disp) : rex_(0) {
121 ASSERT(!index.is(rsp));
123 set_sib(scale, index, base);
124 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
125 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
126 // possibly set by set_sib.
128 } else if (is_int8(disp)) {
138 Operand::Operand(Register index,
140 int32_t disp) : rex_(0) {
141 ASSERT(!index.is(rsp));
144 set_sib(scale, index, rbp);
149 Operand::Operand(const Operand& operand, int32_t offset) {
150 ASSERT(operand.len_ >= 1);
151 // Operand encodes REX ModR/M [SIB] [Disp].
152 byte modrm = operand.buf_[0];
153 ASSERT(modrm < 0xC0); // Disallow mode 3 (register target).
154 bool has_sib = ((modrm & 0x07) == 0x04);
155 byte mode = modrm & 0xC0;
156 int disp_offset = has_sib ? 2 : 1;
157 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
158 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
160 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
161 int32_t disp_value = 0;
162 if (mode == 0x80 || is_baseless) {
163 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
164 disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]);
165 } else if (mode == 0x40) {
166 // Mode 1: Byte displacement.
167 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
170 // Write new operand with same registers, but with modified displacement.
171 ASSERT(offset >= 0 ? disp_value + offset > disp_value
172 : disp_value + offset < disp_value); // No overflow.
173 disp_value += offset;
175 if (!is_int8(disp_value) || is_baseless) {
176 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
177 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
178 len_ = disp_offset + 4;
179 Memory::int32_at(&buf_[disp_offset]) = disp_value;
180 } else if (disp_value != 0 || (base_reg == 0x05)) {
181 // Need 8 bits of displacement.
182 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
183 len_ = disp_offset + 1;
184 buf_[disp_offset] = static_cast<byte>(disp_value);
186 // Need no displacement.
187 buf_[0] = (modrm & 0x3f); // Mode 0.
191 buf_[1] = operand.buf_[1];
196 bool Operand::AddressUsesRegister(Register reg) const {
197 int code = reg.code();
198 ASSERT((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
199 // Start with only low three bits of base register. Initial decoding doesn't
200 // distinguish on the REX.B bit.
201 int base_code = buf_[0] & 0x07;
202 if (base_code == rsp.code()) {
203 // SIB byte present in buf_[1].
204 // Check the index register from the SIB byte + REX.X prefix.
205 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
206 // Index code (including REX.X) of 0x04 (rsp) means no index register.
207 if (index_code != rsp.code() && index_code == code) return true;
208 // Add REX.B to get the full base register code.
209 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
210 // A base register of 0x05 (rbp) with mod = 0 means no base register.
211 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
212 return code == base_code;
214 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
216 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
217 base_code |= ((rex_ & 0x01) << 3);
218 return code == base_code;
223 // -----------------------------------------------------------------------------
224 // Implementation of Assembler.
226 #ifdef GENERATED_CODE_COVERAGE
227 static void InitCoverageLog();
230 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
231 : AssemblerBase(isolate, buffer, buffer_size),
233 positions_recorder_(this) {
234 // Clear the buffer in debug mode unless it was provided by the
235 // caller in which case we can't be sure it's okay to overwrite
236 // existing code in it.
239 memset(buffer_, 0xCC, buffer_size_); // int3
243 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
246 #ifdef GENERATED_CODE_COVERAGE
252 void Assembler::GetCode(CodeDesc* desc) {
253 // Finalize code (at this point overflow() may be true, but the gap ensures
254 // that we are still not overlapping instructions and relocation info).
255 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
256 // Set up code descriptor.
257 desc->buffer = buffer_;
258 desc->buffer_size = buffer_size_;
259 desc->instr_size = pc_offset();
260 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system.
262 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
267 void Assembler::Align(int m) {
268 ASSERT(IsPowerOf2(m));
269 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
274 void Assembler::CodeTargetAlign() {
275 Align(16); // Preferred alignment of jump targets on x64.
279 bool Assembler::IsNop(Address addr) {
281 while (*a == 0x66) a++;
282 if (*a == 0x90) return true;
283 if (a[0] == 0xf && a[1] == 0x1f) return true;
288 void Assembler::bind_to(Label* L, int pos) {
289 ASSERT(!L->is_bound()); // Label may only be bound once.
290 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid.
291 if (L->is_linked()) {
292 int current = L->pos();
293 int next = long_at(current);
294 while (next != current) {
295 // Relative address, relative to point after address.
296 int imm32 = pos - (current + sizeof(int32_t));
297 long_at_put(current, imm32);
299 next = long_at(next);
301 // Fix up last fixup on linked list.
302 int last_imm32 = pos - (current + sizeof(int32_t));
303 long_at_put(current, last_imm32);
305 while (L->is_near_linked()) {
306 int fixup_pos = L->near_link_pos();
308 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
309 ASSERT(offset_to_next <= 0);
310 int disp = pos - (fixup_pos + sizeof(int8_t));
311 CHECK(is_int8(disp));
312 set_byte_at(fixup_pos, disp);
313 if (offset_to_next < 0) {
314 L->link_to(fixup_pos + offset_to_next, Label::kNear);
323 void Assembler::bind(Label* L) {
324 bind_to(L, pc_offset());
328 void Assembler::GrowBuffer() {
329 ASSERT(buffer_overflow());
330 if (!own_buffer_) FATAL("external code buffer is too small");
332 // Compute new buffer size.
333 CodeDesc desc; // the new buffer
334 if (buffer_size_ < 4*KB) {
335 desc.buffer_size = 4*KB;
337 desc.buffer_size = 2*buffer_size_;
339 // Some internal data structures overflow for very large buffers,
340 // they must ensure that kMaximalBufferSize is not too large.
341 if ((desc.buffer_size > kMaximalBufferSize) ||
342 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
343 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
346 // Set up new buffer.
347 desc.buffer = NewArray<byte>(desc.buffer_size);
348 desc.instr_size = pc_offset();
350 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
352 // Clear the buffer in debug mode. Use 'int3' instructions to make
353 // sure to get into problems if we ever run uninitialized code.
355 memset(desc.buffer, 0xCC, desc.buffer_size);
359 intptr_t pc_delta = desc.buffer - buffer_;
360 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
361 (buffer_ + buffer_size_);
362 MemMove(desc.buffer, buffer_, desc.instr_size);
363 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
367 if (isolate() != NULL &&
368 isolate()->assembler_spare_buffer() == NULL &&
369 buffer_size_ == kMinimalBufferSize) {
370 isolate()->set_assembler_spare_buffer(buffer_);
372 DeleteArray(buffer_);
374 buffer_ = desc.buffer;
375 buffer_size_ = desc.buffer_size;
377 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
378 reloc_info_writer.last_pc() + pc_delta);
380 // Relocate runtime entries.
381 for (RelocIterator it(desc); !it.done(); it.next()) {
382 RelocInfo::Mode rmode = it.rinfo()->rmode();
383 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
384 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
385 if (*p != 0) { // 0 means uninitialized.
391 ASSERT(!buffer_overflow());
395 void Assembler::emit_operand(int code, const Operand& adr) {
396 ASSERT(is_uint3(code));
397 const unsigned length = adr.len_;
400 // Emit updated ModR/M byte containing the given register.
401 ASSERT((adr.buf_[0] & 0x38) == 0);
402 pc_[0] = adr.buf_[0] | code << 3;
404 // Emit the rest of the encoded operand.
405 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
410 // Assembler Instruction implementations.
412 void Assembler::arithmetic_op(byte opcode,
416 EnsureSpace ensure_space(this);
417 emit_rex(reg, op, size);
419 emit_operand(reg, op);
423 void Assembler::arithmetic_op(byte opcode,
427 EnsureSpace ensure_space(this);
428 ASSERT((opcode & 0xC6) == 2);
429 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
430 // Swap reg and rm_reg and change opcode operand order.
431 emit_rex(rm_reg, reg, size);
433 emit_modrm(rm_reg, reg);
435 emit_rex(reg, rm_reg, size);
437 emit_modrm(reg, rm_reg);
442 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
443 EnsureSpace ensure_space(this);
444 ASSERT((opcode & 0xC6) == 2);
445 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
446 // Swap reg and rm_reg and change opcode operand order.
448 emit_optional_rex_32(rm_reg, reg);
450 emit_modrm(rm_reg, reg);
453 emit_optional_rex_32(reg, rm_reg);
455 emit_modrm(reg, rm_reg);
460 void Assembler::arithmetic_op_16(byte opcode,
462 const Operand& rm_reg) {
463 EnsureSpace ensure_space(this);
465 emit_optional_rex_32(reg, rm_reg);
467 emit_operand(reg, rm_reg);
471 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
472 EnsureSpace ensure_space(this);
473 if (!reg.is_byte_register()) {
474 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
478 emit_operand(reg, op);
482 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
483 EnsureSpace ensure_space(this);
484 ASSERT((opcode & 0xC6) == 2);
485 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
486 // Swap reg and rm_reg and change opcode operand order.
487 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
488 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
489 emit_rex_32(rm_reg, reg);
492 emit_modrm(rm_reg, reg);
494 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
495 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
496 emit_rex_32(reg, rm_reg);
499 emit_modrm(reg, rm_reg);
504 void Assembler::immediate_arithmetic_op(byte subcode,
508 EnsureSpace ensure_space(this);
510 if (is_int8(src.value_)) {
512 emit_modrm(subcode, dst);
514 } else if (dst.is(rax)) {
515 emit(0x05 | (subcode << 3));
519 emit_modrm(subcode, dst);
524 void Assembler::immediate_arithmetic_op(byte subcode,
528 EnsureSpace ensure_space(this);
530 if (is_int8(src.value_)) {
532 emit_operand(subcode, dst);
536 emit_operand(subcode, dst);
542 void Assembler::immediate_arithmetic_op_16(byte subcode,
545 EnsureSpace ensure_space(this);
546 emit(0x66); // Operand size override prefix.
547 emit_optional_rex_32(dst);
548 if (is_int8(src.value_)) {
550 emit_modrm(subcode, dst);
552 } else if (dst.is(rax)) {
553 emit(0x05 | (subcode << 3));
557 emit_modrm(subcode, dst);
563 void Assembler::immediate_arithmetic_op_16(byte subcode,
566 EnsureSpace ensure_space(this);
567 emit(0x66); // Operand size override prefix.
568 emit_optional_rex_32(dst);
569 if (is_int8(src.value_)) {
571 emit_operand(subcode, dst);
575 emit_operand(subcode, dst);
581 void Assembler::immediate_arithmetic_op_8(byte subcode,
584 EnsureSpace ensure_space(this);
585 emit_optional_rex_32(dst);
586 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
588 emit_operand(subcode, dst);
593 void Assembler::immediate_arithmetic_op_8(byte subcode,
596 EnsureSpace ensure_space(this);
597 if (!dst.is_byte_register()) {
598 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
601 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
603 emit_modrm(subcode, dst);
608 void Assembler::shift(Register dst,
609 Immediate shift_amount,
612 EnsureSpace ensure_space(this);
613 ASSERT(size == kInt64Size ? is_uint6(shift_amount.value_)
614 : is_uint5(shift_amount.value_));
615 if (shift_amount.value_ == 1) {
618 emit_modrm(subcode, dst);
622 emit_modrm(subcode, dst);
623 emit(shift_amount.value_);
628 void Assembler::shift(Register dst, int subcode, int size) {
629 EnsureSpace ensure_space(this);
632 emit_modrm(subcode, dst);
636 void Assembler::bt(const Operand& dst, Register src) {
637 EnsureSpace ensure_space(this);
638 emit_rex_64(src, dst);
641 emit_operand(src, dst);
645 void Assembler::bts(const Operand& dst, Register src) {
646 EnsureSpace ensure_space(this);
647 emit_rex_64(src, dst);
650 emit_operand(src, dst);
654 void Assembler::bsrl(Register dst, Register src) {
655 EnsureSpace ensure_space(this);
656 emit_optional_rex_32(dst, src);
659 emit_modrm(dst, src);
663 void Assembler::call(Label* L) {
664 positions_recorder()->WriteRecordedPositions();
665 EnsureSpace ensure_space(this);
666 // 1110 1000 #32-bit disp.
669 int offset = L->pos() - pc_offset() - sizeof(int32_t);
672 } else if (L->is_linked()) {
674 L->link_to(pc_offset() - sizeof(int32_t));
676 ASSERT(L->is_unused());
677 int32_t current = pc_offset();
684 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
685 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
686 positions_recorder()->WriteRecordedPositions();
687 EnsureSpace ensure_space(this);
688 // 1110 1000 #32-bit disp.
690 emit_runtime_entry(entry, rmode);
694 void Assembler::call(Handle<Code> target,
695 RelocInfo::Mode rmode,
696 TypeFeedbackId ast_id) {
697 positions_recorder()->WriteRecordedPositions();
698 EnsureSpace ensure_space(this);
699 // 1110 1000 #32-bit disp.
701 emit_code_target(target, rmode, ast_id);
705 void Assembler::call(Register adr) {
706 positions_recorder()->WriteRecordedPositions();
707 EnsureSpace ensure_space(this);
708 // Opcode: FF /2 r64.
709 emit_optional_rex_32(adr);
711 emit_modrm(0x2, adr);
715 void Assembler::call(const Operand& op) {
716 positions_recorder()->WriteRecordedPositions();
717 EnsureSpace ensure_space(this);
718 // Opcode: FF /2 m64.
719 emit_optional_rex_32(op);
721 emit_operand(0x2, op);
725 // Calls directly to the given address using a relative offset.
726 // Should only ever be used in Code objects for calls within the
727 // same Code object. Should not be used when generating new code (use labels),
728 // but only when patching existing code.
729 void Assembler::call(Address target) {
730 positions_recorder()->WriteRecordedPositions();
731 EnsureSpace ensure_space(this);
732 // 1110 1000 #32-bit disp.
734 Address source = pc_ + 4;
735 intptr_t displacement = target - source;
736 ASSERT(is_int32(displacement));
737 emitl(static_cast<int32_t>(displacement));
741 void Assembler::clc() {
742 EnsureSpace ensure_space(this);
747 void Assembler::cld() {
748 EnsureSpace ensure_space(this);
753 void Assembler::cdq() {
754 EnsureSpace ensure_space(this);
759 void Assembler::cmovq(Condition cc, Register dst, Register src) {
762 } else if (cc == never) {
765 // No need to check CpuInfo for CMOV support, it's a required part of the
766 // 64-bit architecture.
767 ASSERT(cc >= 0); // Use mov for unconditional moves.
768 EnsureSpace ensure_space(this);
769 // Opcode: REX.W 0f 40 + cc /r.
770 emit_rex_64(dst, src);
773 emit_modrm(dst, src);
777 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
780 } else if (cc == never) {
784 EnsureSpace ensure_space(this);
785 // Opcode: REX.W 0f 40 + cc /r.
786 emit_rex_64(dst, src);
789 emit_operand(dst, src);
793 void Assembler::cmovl(Condition cc, Register dst, Register src) {
796 } else if (cc == never) {
800 EnsureSpace ensure_space(this);
801 // Opcode: 0f 40 + cc /r.
802 emit_optional_rex_32(dst, src);
805 emit_modrm(dst, src);
809 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
812 } else if (cc == never) {
816 EnsureSpace ensure_space(this);
817 // Opcode: 0f 40 + cc /r.
818 emit_optional_rex_32(dst, src);
821 emit_operand(dst, src);
825 void Assembler::cmpb_al(Immediate imm8) {
826 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
827 EnsureSpace ensure_space(this);
833 void Assembler::cpuid() {
834 EnsureSpace ensure_space(this);
840 void Assembler::cqo() {
841 EnsureSpace ensure_space(this);
847 void Assembler::emit_dec(Register dst, int size) {
848 EnsureSpace ensure_space(this);
851 emit_modrm(0x1, dst);
855 void Assembler::emit_dec(const Operand& dst, int size) {
856 EnsureSpace ensure_space(this);
859 emit_operand(1, dst);
863 void Assembler::decb(Register dst) {
864 EnsureSpace ensure_space(this);
865 if (!dst.is_byte_register()) {
866 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
870 emit_modrm(0x1, dst);
874 void Assembler::decb(const Operand& dst) {
875 EnsureSpace ensure_space(this);
876 emit_optional_rex_32(dst);
878 emit_operand(1, dst);
882 void Assembler::enter(Immediate size) {
883 EnsureSpace ensure_space(this);
885 emitw(size.value_); // 16 bit operand, always.
890 void Assembler::hlt() {
891 EnsureSpace ensure_space(this);
896 void Assembler::emit_idiv(Register src, int size) {
897 EnsureSpace ensure_space(this);
900 emit_modrm(0x7, src);
904 void Assembler::emit_imul(Register src, int size) {
905 EnsureSpace ensure_space(this);
908 emit_modrm(0x5, src);
912 void Assembler::emit_imul(Register dst, Register src, int size) {
913 EnsureSpace ensure_space(this);
914 emit_rex(dst, src, size);
917 emit_modrm(dst, src);
921 void Assembler::emit_imul(Register dst, const Operand& src, int size) {
922 EnsureSpace ensure_space(this);
923 emit_rex(dst, src, size);
926 emit_operand(dst, src);
930 void Assembler::emit_imul(Register dst, Register src, Immediate imm, int size) {
931 EnsureSpace ensure_space(this);
932 emit_rex(dst, src, size);
933 if (is_int8(imm.value_)) {
935 emit_modrm(dst, src);
939 emit_modrm(dst, src);
945 void Assembler::emit_inc(Register dst, int size) {
946 EnsureSpace ensure_space(this);
949 emit_modrm(0x0, dst);
953 void Assembler::emit_inc(const Operand& dst, int size) {
954 EnsureSpace ensure_space(this);
957 emit_operand(0, dst);
961 void Assembler::int3() {
962 EnsureSpace ensure_space(this);
967 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
971 } else if (cc == never) {
974 EnsureSpace ensure_space(this);
975 ASSERT(is_uint4(cc));
977 const int short_size = 2;
978 const int long_size = 6;
979 int offs = L->pos() - pc_offset();
981 // Determine whether we can use 1-byte offsets for backwards branches,
982 // which have a max range of 128 bytes.
984 // We also need to check predictable_code_size() flag here, because on x64,
985 // when the full code generator recompiles code for debugging, some places
986 // need to be padded out to a certain size. The debugger is keeping track of
987 // how often it did this so that it can adjust return addresses on the
988 // stack, but if the size of jump instructions can also change, that's not
989 // enough and the calculated offsets would be incorrect.
990 if (is_int8(offs - short_size) && !predictable_code_size()) {
991 // 0111 tttn #8-bit disp.
993 emit((offs - short_size) & 0xFF);
995 // 0000 1111 1000 tttn #32-bit disp.
998 emitl(offs - long_size);
1000 } else if (distance == Label::kNear) {
1001 // 0111 tttn #8-bit disp
1004 if (L->is_near_linked()) {
1005 int offset = L->near_link_pos() - pc_offset();
1006 ASSERT(is_int8(offset));
1007 disp = static_cast<byte>(offset & 0xFF);
1009 L->link_to(pc_offset(), Label::kNear);
1011 } else if (L->is_linked()) {
1012 // 0000 1111 1000 tttn #32-bit disp.
1016 L->link_to(pc_offset() - sizeof(int32_t));
1018 ASSERT(L->is_unused());
1021 int32_t current = pc_offset();
1023 L->link_to(current);
1028 void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1029 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1030 EnsureSpace ensure_space(this);
1031 ASSERT(is_uint4(cc));
1034 emit_runtime_entry(entry, rmode);
1038 void Assembler::j(Condition cc,
1039 Handle<Code> target,
1040 RelocInfo::Mode rmode) {
1041 EnsureSpace ensure_space(this);
1042 ASSERT(is_uint4(cc));
1043 // 0000 1111 1000 tttn #32-bit disp.
1046 emit_code_target(target, rmode);
1050 void Assembler::jmp(Label* L, Label::Distance distance) {
1051 EnsureSpace ensure_space(this);
1052 const int short_size = sizeof(int8_t);
1053 const int long_size = sizeof(int32_t);
1054 if (L->is_bound()) {
1055 int offs = L->pos() - pc_offset() - 1;
1057 if (is_int8(offs - short_size) && !predictable_code_size()) {
1058 // 1110 1011 #8-bit disp.
1060 emit((offs - short_size) & 0xFF);
1062 // 1110 1001 #32-bit disp.
1064 emitl(offs - long_size);
1066 } else if (distance == Label::kNear) {
1069 if (L->is_near_linked()) {
1070 int offset = L->near_link_pos() - pc_offset();
1071 ASSERT(is_int8(offset));
1072 disp = static_cast<byte>(offset & 0xFF);
1074 L->link_to(pc_offset(), Label::kNear);
1076 } else if (L->is_linked()) {
1077 // 1110 1001 #32-bit disp.
1080 L->link_to(pc_offset() - long_size);
1082 // 1110 1001 #32-bit disp.
1083 ASSERT(L->is_unused());
1085 int32_t current = pc_offset();
1087 L->link_to(current);
1092 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1093 EnsureSpace ensure_space(this);
1094 // 1110 1001 #32-bit disp.
1096 emit_code_target(target, rmode);
1100 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1101 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1102 EnsureSpace ensure_space(this);
1103 ASSERT(RelocInfo::IsRuntimeEntry(rmode));
1105 emit_runtime_entry(entry, rmode);
1109 void Assembler::jmp(Register target) {
1110 EnsureSpace ensure_space(this);
1112 emit_optional_rex_32(target);
1114 emit_modrm(0x4, target);
1118 void Assembler::jmp(const Operand& src) {
1119 EnsureSpace ensure_space(this);
1121 emit_optional_rex_32(src);
1123 emit_operand(0x4, src);
1127 void Assembler::emit_lea(Register dst, const Operand& src, int size) {
1128 EnsureSpace ensure_space(this);
1129 emit_rex(dst, src, size);
1131 emit_operand(dst, src);
1135 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1136 EnsureSpace ensure_space(this);
1137 if (kPointerSize == kInt64Size) {
1138 emit(0x48); // REX.W
1142 ASSERT(kPointerSize == kInt32Size);
1145 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1146 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1147 // Developer's Manual Volume 2.
1153 void Assembler::load_rax(ExternalReference ref) {
1154 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1158 void Assembler::leave() {
1159 EnsureSpace ensure_space(this);
1164 void Assembler::movb(Register dst, const Operand& src) {
1165 EnsureSpace ensure_space(this);
1166 if (!dst.is_byte_register()) {
1167 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1168 emit_rex_32(dst, src);
1170 emit_optional_rex_32(dst, src);
1173 emit_operand(dst, src);
1177 void Assembler::movb(Register dst, Immediate imm) {
1178 EnsureSpace ensure_space(this);
1179 if (!dst.is_byte_register()) {
1182 emit(0xB0 + dst.low_bits());
1187 void Assembler::movb(const Operand& dst, Register src) {
1188 EnsureSpace ensure_space(this);
1189 if (!src.is_byte_register()) {
1190 emit_rex_32(src, dst);
1192 emit_optional_rex_32(src, dst);
1195 emit_operand(src, dst);
1199 void Assembler::movb(const Operand& dst, Immediate imm) {
1200 EnsureSpace ensure_space(this);
1201 emit_optional_rex_32(dst);
1203 emit_operand(0x0, dst);
1204 emit(static_cast<byte>(imm.value_));
1208 void Assembler::movw(Register dst, const Operand& src) {
1209 EnsureSpace ensure_space(this);
1211 emit_optional_rex_32(dst, src);
1213 emit_operand(dst, src);
1217 void Assembler::movw(const Operand& dst, Register src) {
1218 EnsureSpace ensure_space(this);
1220 emit_optional_rex_32(src, dst);
1222 emit_operand(src, dst);
1226 void Assembler::movw(const Operand& dst, Immediate imm) {
1227 EnsureSpace ensure_space(this);
1229 emit_optional_rex_32(dst);
1231 emit_operand(0x0, dst);
1232 emit(static_cast<byte>(imm.value_ & 0xff));
1233 emit(static_cast<byte>(imm.value_ >> 8));
1237 void Assembler::emit_mov(Register dst, const Operand& src, int size) {
1238 EnsureSpace ensure_space(this);
1239 emit_rex(dst, src, size);
1241 emit_operand(dst, src);
1245 void Assembler::emit_mov(Register dst, Register src, int size) {
1246 EnsureSpace ensure_space(this);
1247 if (src.low_bits() == 4) {
1248 emit_rex(src, dst, size);
1250 emit_modrm(src, dst);
1252 emit_rex(dst, src, size);
1254 emit_modrm(dst, src);
1259 void Assembler::emit_mov(const Operand& dst, Register src, int size) {
1260 EnsureSpace ensure_space(this);
1261 emit_rex(src, dst, size);
1263 emit_operand(src, dst);
1267 void Assembler::emit_mov(Register dst, Immediate value, int size) {
1268 EnsureSpace ensure_space(this);
1269 emit_rex(dst, size);
1270 if (size == kInt64Size) {
1272 emit_modrm(0x0, dst);
1274 ASSERT(size == kInt32Size);
1275 emit(0xB8 + dst.low_bits());
1281 void Assembler::emit_mov(const Operand& dst, Immediate value, int size) {
1282 EnsureSpace ensure_space(this);
1283 emit_rex(dst, size);
1285 emit_operand(0x0, dst);
1290 void Assembler::movp(Register dst, void* value, RelocInfo::Mode rmode) {
1291 EnsureSpace ensure_space(this);
1292 emit_rex(dst, kPointerSize);
1293 emit(0xB8 | dst.low_bits());
1294 emitp(value, rmode);
1298 void Assembler::movq(Register dst, int64_t value) {
1299 EnsureSpace ensure_space(this);
1301 emit(0xB8 | dst.low_bits());
1306 void Assembler::movq(Register dst, uint64_t value) {
1307 movq(dst, static_cast<int64_t>(value));
1311 // Loads the ip-relative location of the src label into the target location
1312 // (as a 32-bit offset sign extended to 64-bit).
1313 void Assembler::movl(const Operand& dst, Label* src) {
1314 EnsureSpace ensure_space(this);
1315 emit_optional_rex_32(dst);
1317 emit_operand(0, dst);
1318 if (src->is_bound()) {
1319 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1320 ASSERT(offset <= 0);
1322 } else if (src->is_linked()) {
1324 src->link_to(pc_offset() - sizeof(int32_t));
1326 ASSERT(src->is_unused());
1327 int32_t current = pc_offset();
1329 src->link_to(current);
1334 void Assembler::movsxbl(Register dst, const Operand& src) {
1335 EnsureSpace ensure_space(this);
1336 emit_optional_rex_32(dst, src);
1339 emit_operand(dst, src);
1343 void Assembler::movsxbq(Register dst, const Operand& src) {
1344 EnsureSpace ensure_space(this);
1345 emit_rex_64(dst, src);
1348 emit_operand(dst, src);
1352 void Assembler::movsxwl(Register dst, const Operand& src) {
1353 EnsureSpace ensure_space(this);
1354 emit_optional_rex_32(dst, src);
1357 emit_operand(dst, src);
1361 void Assembler::movsxwq(Register dst, const Operand& src) {
1362 EnsureSpace ensure_space(this);
1363 emit_rex_64(dst, src);
1366 emit_operand(dst, src);
1370 void Assembler::movsxlq(Register dst, Register src) {
1371 EnsureSpace ensure_space(this);
1372 emit_rex_64(dst, src);
1374 emit_modrm(dst, src);
1378 void Assembler::movsxlq(Register dst, const Operand& src) {
1379 EnsureSpace ensure_space(this);
1380 emit_rex_64(dst, src);
1382 emit_operand(dst, src);
1386 void Assembler::emit_movzxb(Register dst, const Operand& src, int size) {
1387 EnsureSpace ensure_space(this);
1388 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1389 // there is no need to make this a 64 bit operation.
1390 emit_optional_rex_32(dst, src);
1393 emit_operand(dst, src);
1397 void Assembler::emit_movzxw(Register dst, const Operand& src, int size) {
1398 EnsureSpace ensure_space(this);
1399 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1400 // there is no need to make this a 64 bit operation.
1401 emit_optional_rex_32(dst, src);
1404 emit_operand(dst, src);
1408 void Assembler::emit_movzxw(Register dst, Register src, int size) {
1409 EnsureSpace ensure_space(this);
1410 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1411 // there is no need to make this a 64 bit operation.
1412 emit_optional_rex_32(dst, src);
1415 emit_modrm(dst, src);
1419 void Assembler::repmovsb() {
1420 EnsureSpace ensure_space(this);
1426 void Assembler::repmovsw() {
1427 EnsureSpace ensure_space(this);
1428 emit(0x66); // Operand size override.
1434 void Assembler::emit_repmovs(int size) {
1435 EnsureSpace ensure_space(this);
1442 void Assembler::mul(Register src) {
1443 EnsureSpace ensure_space(this);
1446 emit_modrm(0x4, src);
1450 void Assembler::emit_neg(Register dst, int size) {
1451 EnsureSpace ensure_space(this);
1452 emit_rex(dst, size);
1454 emit_modrm(0x3, dst);
1458 void Assembler::emit_neg(const Operand& dst, int size) {
1459 EnsureSpace ensure_space(this);
1462 emit_operand(3, dst);
1466 void Assembler::nop() {
1467 EnsureSpace ensure_space(this);
1472 void Assembler::emit_not(Register dst, int size) {
1473 EnsureSpace ensure_space(this);
1474 emit_rex(dst, size);
1476 emit_modrm(0x2, dst);
1480 void Assembler::emit_not(const Operand& dst, int size) {
1481 EnsureSpace ensure_space(this);
1482 emit_rex(dst, size);
1484 emit_operand(2, dst);
1488 void Assembler::Nop(int n) {
1489 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1490 // and IA-32 Architectures Software Developer's Manual.
1492 // Length Assembly Byte Sequence
1493 // 2 bytes 66 NOP 66 90H
1494 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1495 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1496 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1497 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1498 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1499 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1500 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1503 EnsureSpace ensure_space(this);
1565 void Assembler::popq(Register dst) {
1566 EnsureSpace ensure_space(this);
1567 emit_optional_rex_32(dst);
1568 emit(0x58 | dst.low_bits());
1572 void Assembler::popq(const Operand& dst) {
1573 EnsureSpace ensure_space(this);
1574 emit_optional_rex_32(dst);
1576 emit_operand(0, dst);
1580 void Assembler::popfq() {
1581 EnsureSpace ensure_space(this);
1586 void Assembler::pushq(Register src) {
1587 EnsureSpace ensure_space(this);
1588 emit_optional_rex_32(src);
1589 emit(0x50 | src.low_bits());
1593 void Assembler::pushq(const Operand& src) {
1594 EnsureSpace ensure_space(this);
1595 emit_optional_rex_32(src);
1597 emit_operand(6, src);
1601 void Assembler::pushq(Immediate value) {
1602 EnsureSpace ensure_space(this);
1603 if (is_int8(value.value_)) {
1605 emit(value.value_); // Emit low byte of value.
1608 emitl(value.value_);
1613 void Assembler::pushq_imm32(int32_t imm32) {
1614 EnsureSpace ensure_space(this);
1620 void Assembler::pushfq() {
1621 EnsureSpace ensure_space(this);
1626 void Assembler::ret(int imm16) {
1627 EnsureSpace ensure_space(this);
1628 ASSERT(is_uint16(imm16));
1634 emit((imm16 >> 8) & 0xFF);
1639 void Assembler::setcc(Condition cc, Register reg) {
1640 if (cc > last_condition) {
1641 movb(reg, Immediate(cc == always ? 1 : 0));
1644 EnsureSpace ensure_space(this);
1645 ASSERT(is_uint4(cc));
1646 if (!reg.is_byte_register()) { // Use x64 byte registers, where different.
1651 emit_modrm(0x0, reg);
1655 void Assembler::shld(Register dst, Register src) {
1656 EnsureSpace ensure_space(this);
1657 emit_rex_64(src, dst);
1660 emit_modrm(src, dst);
1664 void Assembler::shrd(Register dst, Register src) {
1665 EnsureSpace ensure_space(this);
1666 emit_rex_64(src, dst);
1669 emit_modrm(src, dst);
1673 void Assembler::emit_xchg(Register dst, Register src, int size) {
1674 EnsureSpace ensure_space(this);
1675 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1676 Register other = src.is(rax) ? dst : src;
1677 emit_rex(other, size);
1678 emit(0x90 | other.low_bits());
1679 } else if (dst.low_bits() == 4) {
1680 emit_rex(dst, src, size);
1682 emit_modrm(dst, src);
1684 emit_rex(src, dst, size);
1686 emit_modrm(src, dst);
1691 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1692 EnsureSpace ensure_space(this);
1693 if (kPointerSize == kInt64Size) {
1694 emit(0x48); // REX.W
1698 ASSERT(kPointerSize == kInt32Size);
1701 // In 64-bit mode, need to zero extend the operand to 8 bytes.
1702 // See 2.2.1.4 in Intel64 and IA32 Architectures Software
1703 // Developer's Manual Volume 2.
1709 void Assembler::store_rax(ExternalReference ref) {
1710 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1714 void Assembler::testb(Register dst, Register src) {
1715 EnsureSpace ensure_space(this);
1716 if (src.low_bits() == 4) {
1717 emit_rex_32(src, dst);
1719 emit_modrm(src, dst);
1721 if (!dst.is_byte_register() || !src.is_byte_register()) {
1722 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1723 emit_rex_32(dst, src);
1726 emit_modrm(dst, src);
1731 void Assembler::testb(Register reg, Immediate mask) {
1732 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1733 EnsureSpace ensure_space(this);
1736 emit(mask.value_); // Low byte emitted.
1738 if (!reg.is_byte_register()) {
1739 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1743 emit_modrm(0x0, reg);
1744 emit(mask.value_); // Low byte emitted.
1749 void Assembler::testb(const Operand& op, Immediate mask) {
1750 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
1751 EnsureSpace ensure_space(this);
1752 emit_optional_rex_32(rax, op);
1754 emit_operand(rax, op); // Operation code 0
1755 emit(mask.value_); // Low byte emitted.
1759 void Assembler::testb(const Operand& op, Register reg) {
1760 EnsureSpace ensure_space(this);
1761 if (!reg.is_byte_register()) {
1762 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1763 emit_rex_32(reg, op);
1765 emit_optional_rex_32(reg, op);
1768 emit_operand(reg, op);
1772 void Assembler::emit_test(Register dst, Register src, int size) {
1773 EnsureSpace ensure_space(this);
1774 if (src.low_bits() == 4) {
1775 emit_rex(src, dst, size);
1777 emit_modrm(src, dst);
1779 emit_rex(dst, src, size);
1781 emit_modrm(dst, src);
1786 void Assembler::emit_test(Register reg, Immediate mask, int size) {
1787 // testl with a mask that fits in the low byte is exactly testb.
1788 if (is_uint8(mask.value_)) {
1792 EnsureSpace ensure_space(this);
1794 emit_rex(rax, size);
1798 emit_rex(reg, size);
1800 emit_modrm(0x0, reg);
1806 void Assembler::emit_test(const Operand& op, Immediate mask, int size) {
1807 // testl with a mask that fits in the low byte is exactly testb.
1808 if (is_uint8(mask.value_)) {
1812 EnsureSpace ensure_space(this);
1813 emit_rex(rax, op, size);
1815 emit_operand(rax, op); // Operation code 0
1820 void Assembler::emit_test(const Operand& op, Register reg, int size) {
1821 EnsureSpace ensure_space(this);
1822 emit_rex(reg, op, size);
1824 emit_operand(reg, op);
1828 // FPU instructions.
1831 void Assembler::fld(int i) {
1832 EnsureSpace ensure_space(this);
1833 emit_farith(0xD9, 0xC0, i);
1837 void Assembler::fld1() {
1838 EnsureSpace ensure_space(this);
1844 void Assembler::fldz() {
1845 EnsureSpace ensure_space(this);
1851 void Assembler::fldpi() {
1852 EnsureSpace ensure_space(this);
1858 void Assembler::fldln2() {
1859 EnsureSpace ensure_space(this);
1865 void Assembler::fld_s(const Operand& adr) {
1866 EnsureSpace ensure_space(this);
1867 emit_optional_rex_32(adr);
1869 emit_operand(0, adr);
1873 void Assembler::fld_d(const Operand& adr) {
1874 EnsureSpace ensure_space(this);
1875 emit_optional_rex_32(adr);
1877 emit_operand(0, adr);
1881 void Assembler::fstp_s(const Operand& adr) {
1882 EnsureSpace ensure_space(this);
1883 emit_optional_rex_32(adr);
1885 emit_operand(3, adr);
1889 void Assembler::fstp_d(const Operand& adr) {
1890 EnsureSpace ensure_space(this);
1891 emit_optional_rex_32(adr);
1893 emit_operand(3, adr);
1897 void Assembler::fstp(int index) {
1898 ASSERT(is_uint3(index));
1899 EnsureSpace ensure_space(this);
1900 emit_farith(0xDD, 0xD8, index);
1904 void Assembler::fild_s(const Operand& adr) {
1905 EnsureSpace ensure_space(this);
1906 emit_optional_rex_32(adr);
1908 emit_operand(0, adr);
1912 void Assembler::fild_d(const Operand& adr) {
1913 EnsureSpace ensure_space(this);
1914 emit_optional_rex_32(adr);
1916 emit_operand(5, adr);
1920 void Assembler::fistp_s(const Operand& adr) {
1921 EnsureSpace ensure_space(this);
1922 emit_optional_rex_32(adr);
1924 emit_operand(3, adr);
1928 void Assembler::fisttp_s(const Operand& adr) {
1929 ASSERT(IsEnabled(SSE3));
1930 EnsureSpace ensure_space(this);
1931 emit_optional_rex_32(adr);
1933 emit_operand(1, adr);
1937 void Assembler::fisttp_d(const Operand& adr) {
1938 ASSERT(IsEnabled(SSE3));
1939 EnsureSpace ensure_space(this);
1940 emit_optional_rex_32(adr);
1942 emit_operand(1, adr);
1946 void Assembler::fist_s(const Operand& adr) {
1947 EnsureSpace ensure_space(this);
1948 emit_optional_rex_32(adr);
1950 emit_operand(2, adr);
1954 void Assembler::fistp_d(const Operand& adr) {
1955 EnsureSpace ensure_space(this);
1956 emit_optional_rex_32(adr);
1958 emit_operand(7, adr);
1962 void Assembler::fabs() {
1963 EnsureSpace ensure_space(this);
1969 void Assembler::fchs() {
1970 EnsureSpace ensure_space(this);
1976 void Assembler::fcos() {
1977 EnsureSpace ensure_space(this);
1983 void Assembler::fsin() {
1984 EnsureSpace ensure_space(this);
1990 void Assembler::fptan() {
1991 EnsureSpace ensure_space(this);
1997 void Assembler::fyl2x() {
1998 EnsureSpace ensure_space(this);
2004 void Assembler::f2xm1() {
2005 EnsureSpace ensure_space(this);
2011 void Assembler::fscale() {
2012 EnsureSpace ensure_space(this);
2018 void Assembler::fninit() {
2019 EnsureSpace ensure_space(this);
2025 void Assembler::fadd(int i) {
2026 EnsureSpace ensure_space(this);
2027 emit_farith(0xDC, 0xC0, i);
2031 void Assembler::fsub(int i) {
2032 EnsureSpace ensure_space(this);
2033 emit_farith(0xDC, 0xE8, i);
2037 void Assembler::fisub_s(const Operand& adr) {
2038 EnsureSpace ensure_space(this);
2039 emit_optional_rex_32(adr);
2041 emit_operand(4, adr);
2045 void Assembler::fmul(int i) {
2046 EnsureSpace ensure_space(this);
2047 emit_farith(0xDC, 0xC8, i);
2051 void Assembler::fdiv(int i) {
2052 EnsureSpace ensure_space(this);
2053 emit_farith(0xDC, 0xF8, i);
2057 void Assembler::faddp(int i) {
2058 EnsureSpace ensure_space(this);
2059 emit_farith(0xDE, 0xC0, i);
2063 void Assembler::fsubp(int i) {
2064 EnsureSpace ensure_space(this);
2065 emit_farith(0xDE, 0xE8, i);
2069 void Assembler::fsubrp(int i) {
2070 EnsureSpace ensure_space(this);
2071 emit_farith(0xDE, 0xE0, i);
2075 void Assembler::fmulp(int i) {
2076 EnsureSpace ensure_space(this);
2077 emit_farith(0xDE, 0xC8, i);
2081 void Assembler::fdivp(int i) {
2082 EnsureSpace ensure_space(this);
2083 emit_farith(0xDE, 0xF8, i);
2087 void Assembler::fprem() {
2088 EnsureSpace ensure_space(this);
2094 void Assembler::fprem1() {
2095 EnsureSpace ensure_space(this);
2101 void Assembler::fxch(int i) {
2102 EnsureSpace ensure_space(this);
2103 emit_farith(0xD9, 0xC8, i);
2107 void Assembler::fincstp() {
2108 EnsureSpace ensure_space(this);
2114 void Assembler::ffree(int i) {
2115 EnsureSpace ensure_space(this);
2116 emit_farith(0xDD, 0xC0, i);
2120 void Assembler::ftst() {
2121 EnsureSpace ensure_space(this);
2127 void Assembler::fucomp(int i) {
2128 EnsureSpace ensure_space(this);
2129 emit_farith(0xDD, 0xE8, i);
2133 void Assembler::fucompp() {
2134 EnsureSpace ensure_space(this);
2140 void Assembler::fucomi(int i) {
2141 EnsureSpace ensure_space(this);
2147 void Assembler::fucomip() {
2148 EnsureSpace ensure_space(this);
2154 void Assembler::fcompp() {
2155 EnsureSpace ensure_space(this);
2161 void Assembler::fnstsw_ax() {
2162 EnsureSpace ensure_space(this);
2168 void Assembler::fwait() {
2169 EnsureSpace ensure_space(this);
2174 void Assembler::frndint() {
2175 EnsureSpace ensure_space(this);
2181 void Assembler::fnclex() {
2182 EnsureSpace ensure_space(this);
2188 void Assembler::sahf() {
2189 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2190 // in 64-bit mode. Test CpuID.
2191 ASSERT(IsEnabled(SAHF));
2192 EnsureSpace ensure_space(this);
2197 void Assembler::emit_farith(int b1, int b2, int i) {
2198 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2199 ASSERT(is_uint3(i)); // illegal stack offset
2207 void Assembler::andps(XMMRegister dst, XMMRegister src) {
2208 EnsureSpace ensure_space(this);
2209 emit_optional_rex_32(dst, src);
2212 emit_sse_operand(dst, src);
2216 void Assembler::andps(XMMRegister dst, const Operand& src) {
2217 EnsureSpace ensure_space(this);
2218 emit_optional_rex_32(dst, src);
2221 emit_sse_operand(dst, src);
2225 void Assembler::orps(XMMRegister dst, XMMRegister src) {
2226 EnsureSpace ensure_space(this);
2227 emit_optional_rex_32(dst, src);
2230 emit_sse_operand(dst, src);
2234 void Assembler::orps(XMMRegister dst, const Operand& src) {
2235 EnsureSpace ensure_space(this);
2236 emit_optional_rex_32(dst, src);
2239 emit_sse_operand(dst, src);
2243 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2244 EnsureSpace ensure_space(this);
2245 emit_optional_rex_32(dst, src);
2248 emit_sse_operand(dst, src);
2252 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2253 EnsureSpace ensure_space(this);
2254 emit_optional_rex_32(dst, src);
2257 emit_sse_operand(dst, src);
2261 void Assembler::addps(XMMRegister dst, XMMRegister src) {
2262 EnsureSpace ensure_space(this);
2263 emit_optional_rex_32(dst, src);
2266 emit_sse_operand(dst, src);
2270 void Assembler::addps(XMMRegister dst, const Operand& src) {
2271 EnsureSpace ensure_space(this);
2272 emit_optional_rex_32(dst, src);
2275 emit_sse_operand(dst, src);
2279 void Assembler::subps(XMMRegister dst, XMMRegister src) {
2280 EnsureSpace ensure_space(this);
2281 emit_optional_rex_32(dst, src);
2284 emit_sse_operand(dst, src);
2288 void Assembler::subps(XMMRegister dst, const Operand& src) {
2289 EnsureSpace ensure_space(this);
2290 emit_optional_rex_32(dst, src);
2293 emit_sse_operand(dst, src);
2297 void Assembler::mulps(XMMRegister dst, XMMRegister src) {
2298 EnsureSpace ensure_space(this);
2299 emit_optional_rex_32(dst, src);
2302 emit_sse_operand(dst, src);
2306 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2307 EnsureSpace ensure_space(this);
2308 emit_optional_rex_32(dst, src);
2311 emit_sse_operand(dst, src);
2315 void Assembler::divps(XMMRegister dst, XMMRegister src) {
2316 EnsureSpace ensure_space(this);
2317 emit_optional_rex_32(dst, src);
2320 emit_sse_operand(dst, src);
2324 void Assembler::divps(XMMRegister dst, const Operand& src) {
2325 EnsureSpace ensure_space(this);
2326 emit_optional_rex_32(dst, src);
2329 emit_sse_operand(dst, src);
2333 void Assembler::addpd(XMMRegister dst, XMMRegister src) {
2334 EnsureSpace ensure_space(this);
2336 emit_optional_rex_32(dst, src);
2339 emit_sse_operand(dst, src);
2343 void Assembler::addpd(XMMRegister dst, const Operand& src) {
2344 EnsureSpace ensure_space(this);
2346 emit_optional_rex_32(dst, src);
2349 emit_sse_operand(dst, src);
2353 void Assembler::subpd(XMMRegister dst, XMMRegister src) {
2354 EnsureSpace ensure_space(this);
2356 emit_optional_rex_32(dst, src);
2359 emit_sse_operand(dst, src);
2363 void Assembler::subpd(XMMRegister dst, const Operand& src) {
2364 EnsureSpace ensure_space(this);
2366 emit_optional_rex_32(dst, src);
2369 emit_sse_operand(dst, src);
2373 void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
2374 EnsureSpace ensure_space(this);
2376 emit_optional_rex_32(dst, src);
2379 emit_sse_operand(dst, src);
2383 void Assembler::mulpd(XMMRegister dst, const Operand& src) {
2384 EnsureSpace ensure_space(this);
2386 emit_optional_rex_32(dst, src);
2389 emit_sse_operand(dst, src);
2393 void Assembler::divpd(XMMRegister dst, XMMRegister src) {
2394 EnsureSpace ensure_space(this);
2396 emit_optional_rex_32(dst, src);
2399 emit_sse_operand(dst, src);
2403 void Assembler::divpd(XMMRegister dst, const Operand& src) {
2404 EnsureSpace ensure_space(this);
2406 emit_optional_rex_32(dst, src);
2409 emit_sse_operand(dst, src);
2413 // SSE 2 operations.
2415 void Assembler::movd(XMMRegister dst, Register src) {
2416 EnsureSpace ensure_space(this);
2418 emit_optional_rex_32(dst, src);
2421 emit_sse_operand(dst, src);
2425 void Assembler::movd(Register dst, XMMRegister src) {
2426 EnsureSpace ensure_space(this);
2428 emit_optional_rex_32(src, dst);
2431 emit_sse_operand(src, dst);
2435 void Assembler::movq(XMMRegister dst, Register src) {
2436 EnsureSpace ensure_space(this);
2438 emit_rex_64(dst, src);
2441 emit_sse_operand(dst, src);
2445 void Assembler::movq(Register dst, XMMRegister src) {
2446 EnsureSpace ensure_space(this);
2448 emit_rex_64(src, dst);
2451 emit_sse_operand(src, dst);
2455 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2456 EnsureSpace ensure_space(this);
2457 if (dst.low_bits() == 4) {
2458 // Avoid unnecessary SIB byte.
2460 emit_optional_rex_32(dst, src);
2463 emit_sse_operand(dst, src);
2466 emit_optional_rex_32(src, dst);
2469 emit_sse_operand(src, dst);
2474 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2475 EnsureSpace ensure_space(this);
2477 emit_rex_64(src, dst);
2480 emit_sse_operand(src, dst);
2484 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2485 EnsureSpace ensure_space(this);
2487 emit_rex_64(dst, src);
2490 emit_sse_operand(dst, src);
2494 void Assembler::movdqu(const Operand& dst, XMMRegister src) {
2495 EnsureSpace ensure_space(this);
2497 emit_rex_64(src, dst);
2500 emit_sse_operand(src, dst);
2504 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2505 EnsureSpace ensure_space(this);
2507 emit_rex_64(dst, src);
2510 emit_sse_operand(dst, src);
2514 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2515 ASSERT(IsEnabled(SSE4_1));
2516 ASSERT(is_uint8(imm8));
2517 EnsureSpace ensure_space(this);
2519 emit_optional_rex_32(src, dst);
2523 emit_sse_operand(src, dst);
2528 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
2529 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2530 ASSERT(is_uint8(imm8));
2531 EnsureSpace ensure_space(this);
2533 emit_optional_rex_32(dst, src);
2537 emit_sse_operand(dst, src);
2542 void Assembler::pinsrd(XMMRegister dst, Register src, byte imm8) {
2543 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2544 ASSERT(is_uint8(imm8));
2545 EnsureSpace ensure_space(this);
2547 emit_optional_rex_32(dst, src);
2551 emit_sse_operand(dst, src);
2556 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2557 EnsureSpace ensure_space(this);
2558 emit(0xF2); // double
2559 emit_optional_rex_32(src, dst);
2561 emit(0x11); // store
2562 emit_sse_operand(src, dst);
2566 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2567 EnsureSpace ensure_space(this);
2568 emit(0xF2); // double
2569 emit_optional_rex_32(dst, src);
2572 emit_sse_operand(dst, src);
2576 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2577 EnsureSpace ensure_space(this);
2578 emit(0xF2); // double
2579 emit_optional_rex_32(dst, src);
2582 emit_sse_operand(dst, src);
2586 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2587 EnsureSpace ensure_space(this);
2588 if (src.low_bits() == 4) {
2589 // Try to avoid an unnecessary SIB byte.
2590 emit_optional_rex_32(src, dst);
2593 emit_sse_operand(src, dst);
2595 emit_optional_rex_32(dst, src);
2598 emit_sse_operand(dst, src);
2603 void Assembler::movups(XMMRegister dst, const Operand& src) {
2604 EnsureSpace ensure_space(this);
2605 emit_optional_rex_32(dst, src);
2608 emit_sse_operand(dst, src);
2612 void Assembler::movups(const Operand& dst, XMMRegister src) {
2613 EnsureSpace ensure_space(this);
2614 emit_optional_rex_32(src, dst);
2617 emit_sse_operand(src, dst);
2621 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2622 ASSERT(is_uint8(imm8));
2623 EnsureSpace ensure_space(this);
2624 emit_optional_rex_32(dst, src);
2627 emit_sse_operand(dst, src);
2632 void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) {
2633 ASSERT(is_uint8(imm8));
2634 EnsureSpace ensure_space(this);
2636 emit_optional_rex_32(dst, src);
2639 emit_sse_operand(dst, src);
2644 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2645 EnsureSpace ensure_space(this);
2646 if (src.low_bits() == 4) {
2647 // Try to avoid an unnecessary SIB byte.
2649 emit_optional_rex_32(src, dst);
2652 emit_sse_operand(src, dst);
2655 emit_optional_rex_32(dst, src);
2658 emit_sse_operand(dst, src);
2663 void Assembler::movss(XMMRegister dst, const Operand& src) {
2664 EnsureSpace ensure_space(this);
2665 emit(0xF3); // single
2666 emit_optional_rex_32(dst, src);
2669 emit_sse_operand(dst, src);
2673 void Assembler::movss(const Operand& src, XMMRegister dst) {
2674 EnsureSpace ensure_space(this);
2675 emit(0xF3); // single
2676 emit_optional_rex_32(dst, src);
2678 emit(0x11); // store
2679 emit_sse_operand(dst, src);
2683 void Assembler::psllq(XMMRegister reg, byte imm8) {
2684 EnsureSpace ensure_space(this);
2688 emit_sse_operand(rsi, reg); // rsi == 6
2693 void Assembler::cvttss2si(Register dst, const Operand& src) {
2694 EnsureSpace ensure_space(this);
2696 emit_optional_rex_32(dst, src);
2699 emit_operand(dst, src);
2703 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2704 EnsureSpace ensure_space(this);
2706 emit_optional_rex_32(dst, src);
2709 emit_sse_operand(dst, src);
2713 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2714 EnsureSpace ensure_space(this);
2716 emit_optional_rex_32(dst, src);
2719 emit_operand(dst, src);
2723 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2724 EnsureSpace ensure_space(this);
2726 emit_optional_rex_32(dst, src);
2729 emit_sse_operand(dst, src);
2733 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2734 EnsureSpace ensure_space(this);
2736 emit_rex_64(dst, src);
2739 emit_sse_operand(dst, src);
2743 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2744 EnsureSpace ensure_space(this);
2746 emit_optional_rex_32(dst, src);
2749 emit_sse_operand(dst, src);
2753 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2754 EnsureSpace ensure_space(this);
2756 emit_optional_rex_32(dst, src);
2759 emit_sse_operand(dst, src);
2763 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2764 EnsureSpace ensure_space(this);
2766 emit_optional_rex_32(dst, src);
2769 emit_sse_operand(dst, src);
2773 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2774 EnsureSpace ensure_space(this);
2776 emit_rex_64(dst, src);
2779 emit_sse_operand(dst, src);
2783 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2784 EnsureSpace ensure_space(this);
2786 emit_optional_rex_32(dst, src);
2789 emit_sse_operand(dst, src);
2793 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2794 EnsureSpace ensure_space(this);
2796 emit_optional_rex_32(dst, src);
2799 emit_sse_operand(dst, src);
2803 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2804 EnsureSpace ensure_space(this);
2806 emit_optional_rex_32(dst, src);
2809 emit_sse_operand(dst, src);
2813 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2814 EnsureSpace ensure_space(this);
2816 emit_optional_rex_32(dst, src);
2819 emit_sse_operand(dst, src);
2823 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2824 EnsureSpace ensure_space(this);
2826 emit_rex_64(dst, src);
2829 emit_sse_operand(dst, src);
2833 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2834 EnsureSpace ensure_space(this);
2836 emit_optional_rex_32(dst, src);
2839 emit_sse_operand(dst, src);
2843 void Assembler::addsd(XMMRegister dst, const Operand& src) {
2844 EnsureSpace ensure_space(this);
2846 emit_optional_rex_32(dst, src);
2849 emit_sse_operand(dst, src);
2853 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2854 EnsureSpace ensure_space(this);
2856 emit_optional_rex_32(dst, src);
2859 emit_sse_operand(dst, src);
2863 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
2864 EnsureSpace ensure_space(this);
2866 emit_optional_rex_32(dst, src);
2869 emit_sse_operand(dst, src);
2873 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2874 EnsureSpace ensure_space(this);
2876 emit_optional_rex_32(dst, src);
2879 emit_sse_operand(dst, src);
2883 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2884 EnsureSpace ensure_space(this);
2886 emit_optional_rex_32(dst, src);
2889 emit_sse_operand(dst, src);
2893 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2894 EnsureSpace ensure_space(this);
2896 emit_optional_rex_32(dst, src);
2899 emit_sse_operand(dst, src);
2903 void Assembler::andpd(XMMRegister dst, const Operand& src) {
2904 EnsureSpace ensure_space(this);
2906 emit_optional_rex_32(dst, src);
2909 emit_sse_operand(dst, src);
2913 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2914 EnsureSpace ensure_space(this);
2916 emit_optional_rex_32(dst, src);
2919 emit_sse_operand(dst, src);
2923 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2924 EnsureSpace ensure_space(this);
2926 emit_optional_rex_32(dst, src);
2929 emit_sse_operand(dst, src);
2933 void Assembler::xorpd(XMMRegister dst, const Operand& src) {
2934 EnsureSpace ensure_space(this);
2936 emit_optional_rex_32(dst, src);
2939 emit_sse_operand(dst, src);
2943 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2944 EnsureSpace ensure_space(this);
2946 emit_optional_rex_32(dst, src);
2949 emit_sse_operand(dst, src);
2953 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
2954 EnsureSpace ensure_space(this);
2956 emit_optional_rex_32(dst, src);
2959 emit_sse_operand(dst, src);
2963 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2964 EnsureSpace ensure_space(this);
2966 emit_optional_rex_32(dst, src);
2969 emit_sse_operand(dst, src);
2973 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2974 EnsureSpace ensure_space(this);
2976 emit_optional_rex_32(dst, src);
2979 emit_sse_operand(dst, src);
2983 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2984 EnsureSpace ensure_space(this);
2986 emit_optional_rex_32(dst, src);
2989 emit_sse_operand(dst, src);
2990 emit(0x01); // LT == 1
2994 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
2995 EnsureSpace ensure_space(this);
2996 emit_optional_rex_32(dst, src);
2999 emit_sse_operand(dst, src);
3004 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) {
3005 cmpps(dst, src, 0x0);
3009 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) {
3010 cmpps(dst, src, 0x1);
3014 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) {
3015 cmpps(dst, src, 0x2);
3019 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) {
3020 cmpps(dst, src, 0x4);
3024 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) {
3025 cmpps(dst, src, 0x5);
3029 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) {
3030 cmpps(dst, src, 0x6);
3034 void Assembler::pslld(XMMRegister reg, int8_t shift) {
3035 EnsureSpace ensure_space(this);
3037 emit_optional_rex_32(reg);
3040 emit_sse_operand(rsi, reg); // rsi == 6
3045 void Assembler::pslld(XMMRegister dst, XMMRegister src) {
3046 EnsureSpace ensure_space(this);
3048 emit_optional_rex_32(dst, src);
3051 emit_sse_operand(dst, src);
3055 void Assembler::psrld(XMMRegister reg, int8_t shift) {
3056 EnsureSpace ensure_space(this);
3058 emit_optional_rex_32(reg);
3061 emit_sse_operand(rdx, reg); // rdx == 2
3066 void Assembler::psrld(XMMRegister dst, XMMRegister src) {
3067 EnsureSpace ensure_space(this);
3069 emit_optional_rex_32(dst, src);
3072 emit_sse_operand(dst, src);
3076 void Assembler::psrad(XMMRegister reg, int8_t shift) {
3077 EnsureSpace ensure_space(this);
3079 emit_optional_rex_32(reg);
3082 emit_sse_operand(rsp, reg); // rsp == 4
3087 void Assembler::psrad(XMMRegister dst, XMMRegister src) {
3088 EnsureSpace ensure_space(this);
3090 emit_optional_rex_32(dst, src);
3093 emit_sse_operand(dst, src);
3097 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
3098 EnsureSpace ensure_space(this);
3100 emit_optional_rex_32(dst, src);
3103 emit_sse_operand(dst, src);
3107 void Assembler::pcmpgtd(XMMRegister dst, XMMRegister src) {
3108 EnsureSpace ensure_space(this);
3110 emit_optional_rex_32(dst, src);
3113 emit_sse_operand(dst, src);
3117 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
3118 Assembler::RoundingMode mode) {
3119 ASSERT(IsEnabled(SSE4_1));
3120 EnsureSpace ensure_space(this);
3122 emit_optional_rex_32(dst, src);
3126 emit_sse_operand(dst, src);
3127 // Mask precision exeption.
3128 emit(static_cast<byte>(mode) | 0x8);
3132 void Assembler::movmskpd(Register dst, XMMRegister src) {
3133 EnsureSpace ensure_space(this);
3135 emit_optional_rex_32(dst, src);
3138 emit_sse_operand(dst, src);
3142 void Assembler::movmskps(Register dst, XMMRegister src) {
3143 EnsureSpace ensure_space(this);
3144 emit_optional_rex_32(dst, src);
3147 emit_sse_operand(dst, src);
3151 void Assembler::minps(XMMRegister dst, XMMRegister src) {
3152 EnsureSpace ensure_space(this);
3153 emit_optional_rex_32(dst, src);
3156 emit_sse_operand(dst, src);
3160 void Assembler::minps(XMMRegister dst, const Operand& src) {
3161 EnsureSpace ensure_space(this);
3162 emit_optional_rex_32(dst, src);
3165 emit_sse_operand(dst, src);
3169 void Assembler::maxps(XMMRegister dst, XMMRegister src) {
3170 EnsureSpace ensure_space(this);
3171 emit_optional_rex_32(dst, src);
3174 emit_sse_operand(dst, src);
3178 void Assembler::maxps(XMMRegister dst, const Operand& src) {
3179 EnsureSpace ensure_space(this);
3180 emit_optional_rex_32(dst, src);
3183 emit_sse_operand(dst, src);
3187 void Assembler::minpd(XMMRegister dst, XMMRegister src) {
3188 EnsureSpace ensure_space(this);
3190 emit_optional_rex_32(dst, src);
3193 emit_sse_operand(dst, src);
3197 void Assembler::minpd(XMMRegister dst, const Operand& src) {
3198 EnsureSpace ensure_space(this);
3200 emit_optional_rex_32(dst, src);
3203 emit_sse_operand(dst, src);
3207 void Assembler::maxpd(XMMRegister dst, XMMRegister src) {
3208 EnsureSpace ensure_space(this);
3210 emit_optional_rex_32(dst, src);
3213 emit_sse_operand(dst, src);
3217 void Assembler::maxpd(XMMRegister dst, const Operand& src) {
3218 EnsureSpace ensure_space(this);
3220 emit_optional_rex_32(dst, src);
3223 emit_sse_operand(dst, src);
3227 void Assembler::rcpps(XMMRegister dst, XMMRegister src) {
3228 EnsureSpace ensure_space(this);
3229 emit_optional_rex_32(dst, src);
3232 emit_sse_operand(dst, src);
3236 void Assembler::rcpps(XMMRegister dst, const Operand& src) {
3237 EnsureSpace ensure_space(this);
3238 emit_optional_rex_32(dst, src);
3241 emit_sse_operand(dst, src);
3245 void Assembler::rsqrtps(XMMRegister dst, XMMRegister src) {
3246 EnsureSpace ensure_space(this);
3247 emit_optional_rex_32(dst, src);
3250 emit_sse_operand(dst, src);
3254 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
3255 EnsureSpace ensure_space(this);
3256 emit_optional_rex_32(dst, src);
3259 emit_sse_operand(dst, src);
3263 void Assembler::sqrtps(XMMRegister dst, XMMRegister src) {
3264 EnsureSpace ensure_space(this);
3265 emit_optional_rex_32(dst, src);
3268 emit_sse_operand(dst, src);
3272 void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
3273 EnsureSpace ensure_space(this);
3274 emit_optional_rex_32(dst, src);
3277 emit_sse_operand(dst, src);
3281 void Assembler::sqrtpd(XMMRegister dst, XMMRegister src) {
3282 EnsureSpace ensure_space(this);
3284 emit_optional_rex_32(dst, src);
3287 emit_sse_operand(dst, src);
3291 void Assembler::sqrtpd(XMMRegister dst, const Operand& src) {
3292 EnsureSpace ensure_space(this);
3294 emit_optional_rex_32(dst, src);
3297 emit_sse_operand(dst, src);
3301 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
3302 EnsureSpace ensure_space(this);
3303 emit_optional_rex_32(dst, src);
3306 emit_sse_operand(dst, src);
3310 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
3311 EnsureSpace ensure_space(this);
3312 emit_optional_rex_32(dst, src);
3315 emit_sse_operand(dst, src);
3319 void Assembler::paddd(XMMRegister dst, XMMRegister src) {
3320 EnsureSpace ensure_space(this);
3322 emit_optional_rex_32(dst, src);
3325 emit_sse_operand(dst, src);
3329 void Assembler::paddd(XMMRegister dst, const Operand& src) {
3330 EnsureSpace ensure_space(this);
3332 emit_optional_rex_32(dst, src);
3335 emit_sse_operand(dst, src);
3339 void Assembler::psubd(XMMRegister dst, XMMRegister src) {
3340 EnsureSpace ensure_space(this);
3342 emit_optional_rex_32(dst, src);
3345 emit_sse_operand(dst, src);
3349 void Assembler::psubd(XMMRegister dst, const Operand& src) {
3350 EnsureSpace ensure_space(this);
3352 emit_optional_rex_32(dst, src);
3355 emit_sse_operand(dst, src);
3359 void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
3360 ASSERT(IsEnabled(SSE4_1));
3361 EnsureSpace ensure_space(this);
3363 emit_optional_rex_32(dst, src);
3367 emit_sse_operand(dst, src);
3371 void Assembler::pmulld(XMMRegister dst, const Operand& src) {
3372 EnsureSpace ensure_space(this);
3374 emit_optional_rex_32(dst, src);
3377 emit_sse_operand(dst, src);
3381 void Assembler::pmuludq(XMMRegister dst, XMMRegister src) {
3382 EnsureSpace ensure_space(this);
3384 emit_optional_rex_32(dst, src);
3387 emit_sse_operand(dst, src);
3391 void Assembler::pmuludq(XMMRegister dst, const Operand& src) {
3392 EnsureSpace ensure_space(this);
3394 emit_optional_rex_32(dst, src);
3397 emit_sse_operand(dst, src);
3401 void Assembler::punpackldq(XMMRegister dst, XMMRegister src) {
3402 EnsureSpace ensure_space(this);
3404 emit_optional_rex_32(dst, src);
3407 emit_sse_operand(dst, src);
3411 void Assembler::punpackldq(XMMRegister dst, const Operand& src) {
3412 EnsureSpace ensure_space(this);
3414 emit_optional_rex_32(dst, src);
3417 emit_sse_operand(dst, src);
3421 void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
3422 EnsureSpace ensure_space(this);
3424 emit_optional_rex_32(dst);
3427 emit_sse_operand(dst);
3432 void Assembler::cvtps2dq(XMMRegister dst, XMMRegister src) {
3433 EnsureSpace ensure_space(this);
3435 emit_optional_rex_32(dst, src);
3438 emit_sse_operand(dst, src);
3442 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) {
3443 EnsureSpace ensure_space(this);
3445 emit_optional_rex_32(dst, src);
3448 emit_sse_operand(dst, src);
3452 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
3453 EnsureSpace ensure_space(this);
3455 emit_optional_rex_32(dst, src);
3458 emit_sse_operand(dst, src);
3463 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
3464 Register ireg = { reg.code() };
3465 emit_operand(ireg, adr);
3469 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3470 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3474 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3475 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3479 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3480 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
3484 void Assembler::emit_sse_operand(XMMRegister dst) {
3485 emit(0xD8 | dst.low_bits());
3489 void Assembler::db(uint8_t data) {
3490 EnsureSpace ensure_space(this);
3495 void Assembler::dd(uint32_t data) {
3496 EnsureSpace ensure_space(this);
3501 // Relocation information implementations.
3503 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3504 ASSERT(!RelocInfo::IsNone(rmode));
3505 // Don't record external references unless the heap will be serialized.
3506 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
3507 !serializer_enabled() && !emit_debug_code()) {
3509 } else if (rmode == RelocInfo::CODE_AGE_SEQUENCE) {
3510 // Don't record psuedo relocation info for code age sequence mode.
3513 RelocInfo rinfo(pc_, rmode, data, NULL);
3514 reloc_info_writer.Write(&rinfo);
3518 void Assembler::RecordJSReturn() {
3519 positions_recorder()->WriteRecordedPositions();
3520 EnsureSpace ensure_space(this);
3521 RecordRelocInfo(RelocInfo::JS_RETURN);
3525 void Assembler::RecordDebugBreakSlot() {
3526 positions_recorder()->WriteRecordedPositions();
3527 EnsureSpace ensure_space(this);
3528 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3532 void Assembler::RecordComment(const char* msg, bool force) {
3533 if (FLAG_code_comments || force) {
3534 EnsureSpace ensure_space(this);
3535 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3540 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3541 // No out-of-line constant pool support.
3542 ASSERT(!FLAG_enable_ool_constant_pool);
3543 return isolate->factory()->empty_constant_pool_array();
3547 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3548 // No out-of-line constant pool support.
3549 ASSERT(!FLAG_enable_ool_constant_pool);
3554 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3555 1 << RelocInfo::RUNTIME_ENTRY |
3556 1 << RelocInfo::INTERNAL_REFERENCE |
3557 1 << RelocInfo::CODE_AGE_SEQUENCE;
3560 bool RelocInfo::IsCodedSpecially() {
3561 // The deserializer needs to know whether a pointer is specially coded. Being
3562 // specially coded on x64 means that it is a relative 32 bit address, as used
3563 // by branch instructions.
3564 return (1 << rmode_) & kApplyMask;
3568 bool RelocInfo::IsInConstantPool() {
3573 } } // namespace v8::internal
3575 #endif // V8_TARGET_ARCH_X64