1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #if defined(V8_TARGET_ARCH_X64)
31
32 #include "macro-assembler.h"
33 #include "serialize.h"
34
35 namespace v8 {
36 namespace internal {
37
38 // -----------------------------------------------------------------------------
39 // Implementation of CpuFeatures
40
41
42 #ifdef DEBUG
43 bool CpuFeatures::initialized_ = false;
44 #endif
45 uint64_t CpuFeatures::supported_ = CpuFeatures::kDefaultCpuFeatures;
46 uint64_t CpuFeatures::found_by_runtime_probing_ = 0;
47
48
Probe()49 void CpuFeatures::Probe() {
50 ASSERT(supported_ == CpuFeatures::kDefaultCpuFeatures);
51 #ifdef DEBUG
52 initialized_ = true;
53 #endif
54 supported_ = kDefaultCpuFeatures;
55 if (Serializer::enabled()) {
56 supported_ |= OS::CpuFeaturesImpliedByPlatform();
57 return; // No features if we might serialize.
58 }
59
60 const int kBufferSize = 4 * KB;
61 VirtualMemory* memory = new VirtualMemory(kBufferSize);
62 if (!memory->IsReserved()) {
63 delete memory;
64 return;
65 }
66 ASSERT(memory->size() >= static_cast<size_t>(kBufferSize));
67 if (!memory->Commit(memory->address(), kBufferSize, true/*executable*/)) {
68 delete memory;
69 return;
70 }
71
72 Assembler assm(NULL, memory->address(), kBufferSize);
73 Label cpuid, done;
74 #define __ assm.
75 // Save old rsp, since we are going to modify the stack.
76 __ push(rbp);
77 __ pushfq();
78 __ push(rcx);
79 __ push(rbx);
80 __ movq(rbp, rsp);
81
82 // If we can modify bit 21 of the EFLAGS register, then CPUID is supported.
83 __ pushfq();
84 __ pop(rax);
85 __ movq(rdx, rax);
86 __ xor_(rax, Immediate(0x200000)); // Flip bit 21.
87 __ push(rax);
88 __ popfq();
89 __ pushfq();
90 __ pop(rax);
91 __ xor_(rax, rdx); // Different if CPUID is supported.
92 __ j(not_zero, &cpuid);
93
94 // CPUID not supported. Clear the supported features in rax.
95 __ xor_(rax, rax);
96 __ jmp(&done);
97
98 // Invoke CPUID with 1 in eax to get feature information in
99 // ecx:edx. Temporarily enable CPUID support because we know it's
100 // safe here.
101 __ bind(&cpuid);
102 __ movl(rax, Immediate(1));
103 supported_ = kDefaultCpuFeatures | (1 << CPUID);
104 { Scope fscope(CPUID);
105 __ cpuid();
106 // Move the result from ecx:edx to rdi.
107 __ movl(rdi, rdx); // Zero-extended to 64 bits.
108 __ shl(rcx, Immediate(32));
109 __ or_(rdi, rcx);
110
111 // Get the sahf supported flag, from CPUID(0x80000001)
112 __ movq(rax, 0x80000001, RelocInfo::NONE);
113 __ cpuid();
114 }
115 supported_ = kDefaultCpuFeatures;
116
117 // Put the CPU flags in rax.
118 // rax = (rcx & 1) | (rdi & ~1) | (1 << CPUID).
119 __ movl(rax, Immediate(1));
120 __ and_(rcx, rax); // Bit 0 is set if SAHF instruction supported.
121 __ not_(rax);
122 __ and_(rax, rdi);
123 __ or_(rax, rcx);
124 __ or_(rax, Immediate(1 << CPUID));
125
126 // Done.
127 __ bind(&done);
128 __ movq(rsp, rbp);
129 __ pop(rbx);
130 __ pop(rcx);
131 __ popfq();
132 __ pop(rbp);
133 __ ret(0);
134 #undef __
135
136 typedef uint64_t (*F0)();
137 F0 probe = FUNCTION_CAST<F0>(reinterpret_cast<Address>(memory->address()));
138 supported_ = probe();
139 found_by_runtime_probing_ = supported_;
140 found_by_runtime_probing_ &= ~kDefaultCpuFeatures;
141 uint64_t os_guarantees = OS::CpuFeaturesImpliedByPlatform();
142 supported_ |= os_guarantees;
143 found_by_runtime_probing_ &= ~os_guarantees;
144 // SSE2 and CMOV must be available on an X64 CPU.
145 ASSERT(IsSupported(CPUID));
146 ASSERT(IsSupported(SSE2));
147 ASSERT(IsSupported(CMOV));
148
149 delete memory;
150 }
151
152
153 // -----------------------------------------------------------------------------
154 // Implementation of RelocInfo
155
156 // Patch the code at the current PC with a call to the target address.
157 // Additional guard int3 instructions can be added if required.
PatchCodeWithCall(Address target,int guard_bytes)158 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
159 // Load register with immediate 64 and call through a register instructions
160 // takes up 13 bytes and int3 takes up one byte.
161 static const int kCallCodeSize = 13;
162 int code_size = kCallCodeSize + guard_bytes;
163
164 // Create a code patcher.
165 CodePatcher patcher(pc_, code_size);
166
167 // Add a label for checking the size of the code used for returning.
168 #ifdef DEBUG
169 Label check_codesize;
170 patcher.masm()->bind(&check_codesize);
171 #endif
172
173 // Patch the code.
174 patcher.masm()->movq(r10, target, RelocInfo::NONE);
175 patcher.masm()->call(r10);
176
177 // Check that the size of the code generated is as expected.
178 ASSERT_EQ(kCallCodeSize,
179 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
180
181 // Add the requested number of int3 instructions after the call.
182 for (int i = 0; i < guard_bytes; i++) {
183 patcher.masm()->int3();
184 }
185 }
186
187
PatchCode(byte * instructions,int instruction_count)188 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
189 // Patch the code at the current address with the supplied instructions.
190 for (int i = 0; i < instruction_count; i++) {
191 *(pc_ + i) = *(instructions + i);
192 }
193
194 // Indicate that code has changed.
195 CPU::FlushICache(pc_, instruction_count);
196 }
197
198
199 // -----------------------------------------------------------------------------
200 // Register constants.
201
202 const int Register::kRegisterCodeByAllocationIndex[kNumAllocatableRegisters] = {
203 // rax, rbx, rdx, rcx, rdi, r8, r9, r11, r14, r15
204 0, 3, 2, 1, 7, 8, 9, 11, 14, 15
205 };
206
207 const int Register::kAllocationIndexByRegisterCode[kNumRegisters] = {
208 0, 3, 2, 1, -1, -1, -1, 4, 5, 6, -1, 7, -1, -1, 8, 9
209 };
210
211
212 // -----------------------------------------------------------------------------
213 // Implementation of Operand
214
Operand(Register base,int32_t disp)215 Operand::Operand(Register base, int32_t disp) : rex_(0) {
216 len_ = 1;
217 if (base.is(rsp) || base.is(r12)) {
218 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
219 set_sib(times_1, rsp, base);
220 }
221
222 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
223 set_modrm(0, base);
224 } else if (is_int8(disp)) {
225 set_modrm(1, base);
226 set_disp8(disp);
227 } else {
228 set_modrm(2, base);
229 set_disp32(disp);
230 }
231 }
232
233
Operand(Register base,Register index,ScaleFactor scale,int32_t disp)234 Operand::Operand(Register base,
235 Register index,
236 ScaleFactor scale,
237 int32_t disp) : rex_(0) {
238 ASSERT(!index.is(rsp));
239 len_ = 1;
240 set_sib(scale, index, base);
241 if (disp == 0 && !base.is(rbp) && !base.is(r13)) {
242 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
243 // possibly set by set_sib.
244 set_modrm(0, rsp);
245 } else if (is_int8(disp)) {
246 set_modrm(1, rsp);
247 set_disp8(disp);
248 } else {
249 set_modrm(2, rsp);
250 set_disp32(disp);
251 }
252 }
253
254
Operand(Register index,ScaleFactor scale,int32_t disp)255 Operand::Operand(Register index,
256 ScaleFactor scale,
257 int32_t disp) : rex_(0) {
258 ASSERT(!index.is(rsp));
259 len_ = 1;
260 set_modrm(0, rsp);
261 set_sib(scale, index, rbp);
262 set_disp32(disp);
263 }
264
265
Operand(const Operand & operand,int32_t offset)266 Operand::Operand(const Operand& operand, int32_t offset) {
267 ASSERT(operand.len_ >= 1);
268 // Operand encodes REX ModR/M [SIB] [Disp].
269 byte modrm = operand.buf_[0];
270 ASSERT(modrm < 0xC0); // Disallow mode 3 (register target).
271 bool has_sib = ((modrm & 0x07) == 0x04);
272 byte mode = modrm & 0xC0;
273 int disp_offset = has_sib ? 2 : 1;
274 int base_reg = (has_sib ? operand.buf_[1] : modrm) & 0x07;
275 // Mode 0 with rbp/r13 as ModR/M or SIB base register always has a 32-bit
276 // displacement.
277 bool is_baseless = (mode == 0) && (base_reg == 0x05); // No base or RIP base.
278 int32_t disp_value = 0;
279 if (mode == 0x80 || is_baseless) {
280 // Mode 2 or mode 0 with rbp/r13 as base: Word displacement.
281 disp_value = *BitCast<const int32_t*>(&operand.buf_[disp_offset]);
282 } else if (mode == 0x40) {
283 // Mode 1: Byte displacement.
284 disp_value = static_cast<signed char>(operand.buf_[disp_offset]);
285 }
286
287 // Write new operand with same registers, but with modified displacement.
288 ASSERT(offset >= 0 ? disp_value + offset > disp_value
289 : disp_value + offset < disp_value); // No overflow.
290 disp_value += offset;
291 rex_ = operand.rex_;
292 if (!is_int8(disp_value) || is_baseless) {
293 // Need 32 bits of displacement, mode 2 or mode 1 with register rbp/r13.
294 buf_[0] = (modrm & 0x3f) | (is_baseless ? 0x00 : 0x80);
295 len_ = disp_offset + 4;
296 Memory::int32_at(&buf_[disp_offset]) = disp_value;
297 } else if (disp_value != 0 || (base_reg == 0x05)) {
298 // Need 8 bits of displacement.
299 buf_[0] = (modrm & 0x3f) | 0x40; // Mode 1.
300 len_ = disp_offset + 1;
301 buf_[disp_offset] = static_cast<byte>(disp_value);
302 } else {
303 // Need no displacement.
304 buf_[0] = (modrm & 0x3f); // Mode 0.
305 len_ = disp_offset;
306 }
307 if (has_sib) {
308 buf_[1] = operand.buf_[1];
309 }
310 }
311
312
AddressUsesRegister(Register reg) const313 bool Operand::AddressUsesRegister(Register reg) const {
314 int code = reg.code();
315 ASSERT((buf_[0] & 0xC0) != 0xC0); // Always a memory operand.
316 // Start with only low three bits of base register. Initial decoding doesn't
317 // distinguish on the REX.B bit.
318 int base_code = buf_[0] & 0x07;
319 if (base_code == rsp.code()) {
320 // SIB byte present in buf_[1].
321 // Check the index register from the SIB byte + REX.X prefix.
322 int index_code = ((buf_[1] >> 3) & 0x07) | ((rex_ & 0x02) << 2);
323 // Index code (including REX.X) of 0x04 (rsp) means no index register.
324 if (index_code != rsp.code() && index_code == code) return true;
325 // Add REX.B to get the full base register code.
326 base_code = (buf_[1] & 0x07) | ((rex_ & 0x01) << 3);
327 // A base register of 0x05 (rbp) with mod = 0 means no base register.
328 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
329 return code == base_code;
330 } else {
331 // A base register with low bits of 0x05 (rbp or r13) and mod = 0 means
332 // no base register.
333 if (base_code == rbp.code() && ((buf_[0] & 0xC0) == 0)) return false;
334 base_code |= ((rex_ & 0x01) << 3);
335 return code == base_code;
336 }
337 }
338
339
340 // -----------------------------------------------------------------------------
341 // Implementation of Assembler.
342
343 #ifdef GENERATED_CODE_COVERAGE
344 static void InitCoverageLog();
345 #endif
346
Assembler(Isolate * arg_isolate,void * buffer,int buffer_size)347 Assembler::Assembler(Isolate* arg_isolate, void* buffer, int buffer_size)
348 : AssemblerBase(arg_isolate),
349 code_targets_(100),
350 positions_recorder_(this),
351 emit_debug_code_(FLAG_debug_code) {
352 if (buffer == NULL) {
353 // Do our own buffer management.
354 if (buffer_size <= kMinimalBufferSize) {
355 buffer_size = kMinimalBufferSize;
356
357 if (isolate() != NULL && isolate()->assembler_spare_buffer() != NULL) {
358 buffer = isolate()->assembler_spare_buffer();
359 isolate()->set_assembler_spare_buffer(NULL);
360 }
361 }
362 if (buffer == NULL) {
363 buffer_ = NewArray<byte>(buffer_size);
364 } else {
365 buffer_ = static_cast<byte*>(buffer);
366 }
367 buffer_size_ = buffer_size;
368 own_buffer_ = true;
369 } else {
370 // Use externally provided buffer instead.
371 ASSERT(buffer_size > 0);
372 buffer_ = static_cast<byte*>(buffer);
373 buffer_size_ = buffer_size;
374 own_buffer_ = false;
375 }
376
377 // Clear the buffer in debug mode unless it was provided by the
378 // caller in which case we can't be sure it's okay to overwrite
379 // existing code in it.
380 #ifdef DEBUG
381 if (own_buffer_) {
382 memset(buffer_, 0xCC, buffer_size); // int3
383 }
384 #endif
385
386 // Set up buffer pointers.
387 ASSERT(buffer_ != NULL);
388 pc_ = buffer_;
389 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_);
390
391
392 #ifdef GENERATED_CODE_COVERAGE
393 InitCoverageLog();
394 #endif
395 }
396
397
~Assembler()398 Assembler::~Assembler() {
399 if (own_buffer_) {
400 if (isolate() != NULL &&
401 isolate()->assembler_spare_buffer() == NULL &&
402 buffer_size_ == kMinimalBufferSize) {
403 isolate()->set_assembler_spare_buffer(buffer_);
404 } else {
405 DeleteArray(buffer_);
406 }
407 }
408 }
409
410
GetCode(CodeDesc * desc)411 void Assembler::GetCode(CodeDesc* desc) {
412 // Finalize code (at this point overflow() may be true, but the gap ensures
413 // that we are still not overlapping instructions and relocation info).
414 ASSERT(pc_ <= reloc_info_writer.pos()); // No overlap.
415 // Set up code descriptor.
416 desc->buffer = buffer_;
417 desc->buffer_size = buffer_size_;
418 desc->instr_size = pc_offset();
419 ASSERT(desc->instr_size > 0); // Zero-size code objects upset the system.
420 desc->reloc_size =
421 static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
422 desc->origin = this;
423 }
424
425
Align(int m)426 void Assembler::Align(int m) {
427 ASSERT(IsPowerOf2(m));
428 int delta = (m - (pc_offset() & (m - 1))) & (m - 1);
429 Nop(delta);
430 }
431
432
CodeTargetAlign()433 void Assembler::CodeTargetAlign() {
434 Align(16); // Preferred alignment of jump targets on x64.
435 }
436
437
IsNop(Address addr)438 bool Assembler::IsNop(Address addr) {
439 Address a = addr;
440 while (*a == 0x66) a++;
441 if (*a == 0x90) return true;
442 if (a[0] == 0xf && a[1] == 0x1f) return true;
443 return false;
444 }
445
446
bind_to(Label * L,int pos)447 void Assembler::bind_to(Label* L, int pos) {
448 ASSERT(!L->is_bound()); // Label may only be bound once.
449 ASSERT(0 <= pos && pos <= pc_offset()); // Position must be valid.
450 if (L->is_linked()) {
451 int current = L->pos();
452 int next = long_at(current);
453 while (next != current) {
454 // Relative address, relative to point after address.
455 int imm32 = pos - (current + sizeof(int32_t));
456 long_at_put(current, imm32);
457 current = next;
458 next = long_at(next);
459 }
460 // Fix up last fixup on linked list.
461 int last_imm32 = pos - (current + sizeof(int32_t));
462 long_at_put(current, last_imm32);
463 }
464 while (L->is_near_linked()) {
465 int fixup_pos = L->near_link_pos();
466 int offset_to_next =
467 static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
468 ASSERT(offset_to_next <= 0);
469 int disp = pos - (fixup_pos + sizeof(int8_t));
470 ASSERT(is_int8(disp));
471 set_byte_at(fixup_pos, disp);
472 if (offset_to_next < 0) {
473 L->link_to(fixup_pos + offset_to_next, Label::kNear);
474 } else {
475 L->UnuseNear();
476 }
477 }
478 L->bind_to(pos);
479 }
480
481
bind(Label * L)482 void Assembler::bind(Label* L) {
483 bind_to(L, pc_offset());
484 }
485
486
GrowBuffer()487 void Assembler::GrowBuffer() {
488 ASSERT(buffer_overflow());
489 if (!own_buffer_) FATAL("external code buffer is too small");
490
491 // Compute new buffer size.
492 CodeDesc desc; // the new buffer
493 if (buffer_size_ < 4*KB) {
494 desc.buffer_size = 4*KB;
495 } else {
496 desc.buffer_size = 2*buffer_size_;
497 }
498 // Some internal data structures overflow for very large buffers,
499 // they must ensure that kMaximalBufferSize is not too large.
500 if ((desc.buffer_size > kMaximalBufferSize) ||
501 (desc.buffer_size > HEAP->MaxOldGenerationSize())) {
502 V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
503 }
504
505 // Set up new buffer.
506 desc.buffer = NewArray<byte>(desc.buffer_size);
507 desc.instr_size = pc_offset();
508 desc.reloc_size =
509 static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
510
511 // Clear the buffer in debug mode. Use 'int3' instructions to make
512 // sure to get into problems if we ever run uninitialized code.
513 #ifdef DEBUG
514 memset(desc.buffer, 0xCC, desc.buffer_size);
515 #endif
516
517 // Copy the data.
518 intptr_t pc_delta = desc.buffer - buffer_;
519 intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
520 (buffer_ + buffer_size_);
521 memmove(desc.buffer, buffer_, desc.instr_size);
522 memmove(rc_delta + reloc_info_writer.pos(),
523 reloc_info_writer.pos(), desc.reloc_size);
524
525 // Switch buffers.
526 if (isolate() != NULL &&
527 isolate()->assembler_spare_buffer() == NULL &&
528 buffer_size_ == kMinimalBufferSize) {
529 isolate()->set_assembler_spare_buffer(buffer_);
530 } else {
531 DeleteArray(buffer_);
532 }
533 buffer_ = desc.buffer;
534 buffer_size_ = desc.buffer_size;
535 pc_ += pc_delta;
536 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
537 reloc_info_writer.last_pc() + pc_delta);
538
539 // Relocate runtime entries.
540 for (RelocIterator it(desc); !it.done(); it.next()) {
541 RelocInfo::Mode rmode = it.rinfo()->rmode();
542 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
543 intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
544 if (*p != 0) { // 0 means uninitialized.
545 *p += pc_delta;
546 }
547 }
548 }
549
550 ASSERT(!buffer_overflow());
551 }
552
553
emit_operand(int code,const Operand & adr)554 void Assembler::emit_operand(int code, const Operand& adr) {
555 ASSERT(is_uint3(code));
556 const unsigned length = adr.len_;
557 ASSERT(length > 0);
558
559 // Emit updated ModR/M byte containing the given register.
560 ASSERT((adr.buf_[0] & 0x38) == 0);
561 pc_[0] = adr.buf_[0] | code << 3;
562
563 // Emit the rest of the encoded operand.
564 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
565 pc_ += length;
566 }
567
568
569 // Assembler Instruction implementations.
570
arithmetic_op(byte opcode,Register reg,const Operand & op)571 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
572 EnsureSpace ensure_space(this);
573 emit_rex_64(reg, op);
574 emit(opcode);
575 emit_operand(reg, op);
576 }
577
578
arithmetic_op(byte opcode,Register reg,Register rm_reg)579 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
580 EnsureSpace ensure_space(this);
581 ASSERT((opcode & 0xC6) == 2);
582 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
583 // Swap reg and rm_reg and change opcode operand order.
584 emit_rex_64(rm_reg, reg);
585 emit(opcode ^ 0x02);
586 emit_modrm(rm_reg, reg);
587 } else {
588 emit_rex_64(reg, rm_reg);
589 emit(opcode);
590 emit_modrm(reg, rm_reg);
591 }
592 }
593
594
arithmetic_op_16(byte opcode,Register reg,Register rm_reg)595 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
596 EnsureSpace ensure_space(this);
597 ASSERT((opcode & 0xC6) == 2);
598 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
599 // Swap reg and rm_reg and change opcode operand order.
600 emit(0x66);
601 emit_optional_rex_32(rm_reg, reg);
602 emit(opcode ^ 0x02);
603 emit_modrm(rm_reg, reg);
604 } else {
605 emit(0x66);
606 emit_optional_rex_32(reg, rm_reg);
607 emit(opcode);
608 emit_modrm(reg, rm_reg);
609 }
610 }
611
612
arithmetic_op_16(byte opcode,Register reg,const Operand & rm_reg)613 void Assembler::arithmetic_op_16(byte opcode,
614 Register reg,
615 const Operand& rm_reg) {
616 EnsureSpace ensure_space(this);
617 emit(0x66);
618 emit_optional_rex_32(reg, rm_reg);
619 emit(opcode);
620 emit_operand(reg, rm_reg);
621 }
622
623
arithmetic_op_32(byte opcode,Register reg,Register rm_reg)624 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
625 EnsureSpace ensure_space(this);
626 ASSERT((opcode & 0xC6) == 2);
627 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
628 // Swap reg and rm_reg and change opcode operand order.
629 emit_optional_rex_32(rm_reg, reg);
630 emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD.
631 emit_modrm(rm_reg, reg);
632 } else {
633 emit_optional_rex_32(reg, rm_reg);
634 emit(opcode);
635 emit_modrm(reg, rm_reg);
636 }
637 }
638
639
arithmetic_op_32(byte opcode,Register reg,const Operand & rm_reg)640 void Assembler::arithmetic_op_32(byte opcode,
641 Register reg,
642 const Operand& rm_reg) {
643 EnsureSpace ensure_space(this);
644 emit_optional_rex_32(reg, rm_reg);
645 emit(opcode);
646 emit_operand(reg, rm_reg);
647 }
648
649
immediate_arithmetic_op(byte subcode,Register dst,Immediate src)650 void Assembler::immediate_arithmetic_op(byte subcode,
651 Register dst,
652 Immediate src) {
653 EnsureSpace ensure_space(this);
654 emit_rex_64(dst);
655 if (is_int8(src.value_)) {
656 emit(0x83);
657 emit_modrm(subcode, dst);
658 emit(src.value_);
659 } else if (dst.is(rax)) {
660 emit(0x05 | (subcode << 3));
661 emitl(src.value_);
662 } else {
663 emit(0x81);
664 emit_modrm(subcode, dst);
665 emitl(src.value_);
666 }
667 }
668
immediate_arithmetic_op(byte subcode,const Operand & dst,Immediate src)669 void Assembler::immediate_arithmetic_op(byte subcode,
670 const Operand& dst,
671 Immediate src) {
672 EnsureSpace ensure_space(this);
673 emit_rex_64(dst);
674 if (is_int8(src.value_)) {
675 emit(0x83);
676 emit_operand(subcode, dst);
677 emit(src.value_);
678 } else {
679 emit(0x81);
680 emit_operand(subcode, dst);
681 emitl(src.value_);
682 }
683 }
684
685
immediate_arithmetic_op_16(byte subcode,Register dst,Immediate src)686 void Assembler::immediate_arithmetic_op_16(byte subcode,
687 Register dst,
688 Immediate src) {
689 EnsureSpace ensure_space(this);
690 emit(0x66); // Operand size override prefix.
691 emit_optional_rex_32(dst);
692 if (is_int8(src.value_)) {
693 emit(0x83);
694 emit_modrm(subcode, dst);
695 emit(src.value_);
696 } else if (dst.is(rax)) {
697 emit(0x05 | (subcode << 3));
698 emitw(src.value_);
699 } else {
700 emit(0x81);
701 emit_modrm(subcode, dst);
702 emitw(src.value_);
703 }
704 }
705
706
immediate_arithmetic_op_16(byte subcode,const Operand & dst,Immediate src)707 void Assembler::immediate_arithmetic_op_16(byte subcode,
708 const Operand& dst,
709 Immediate src) {
710 EnsureSpace ensure_space(this);
711 emit(0x66); // Operand size override prefix.
712 emit_optional_rex_32(dst);
713 if (is_int8(src.value_)) {
714 emit(0x83);
715 emit_operand(subcode, dst);
716 emit(src.value_);
717 } else {
718 emit(0x81);
719 emit_operand(subcode, dst);
720 emitw(src.value_);
721 }
722 }
723
724
immediate_arithmetic_op_32(byte subcode,Register dst,Immediate src)725 void Assembler::immediate_arithmetic_op_32(byte subcode,
726 Register dst,
727 Immediate src) {
728 EnsureSpace ensure_space(this);
729 emit_optional_rex_32(dst);
730 if (is_int8(src.value_)) {
731 emit(0x83);
732 emit_modrm(subcode, dst);
733 emit(src.value_);
734 } else if (dst.is(rax)) {
735 emit(0x05 | (subcode << 3));
736 emitl(src.value_);
737 } else {
738 emit(0x81);
739 emit_modrm(subcode, dst);
740 emitl(src.value_);
741 }
742 }
743
744
immediate_arithmetic_op_32(byte subcode,const Operand & dst,Immediate src)745 void Assembler::immediate_arithmetic_op_32(byte subcode,
746 const Operand& dst,
747 Immediate src) {
748 EnsureSpace ensure_space(this);
749 emit_optional_rex_32(dst);
750 if (is_int8(src.value_)) {
751 emit(0x83);
752 emit_operand(subcode, dst);
753 emit(src.value_);
754 } else {
755 emit(0x81);
756 emit_operand(subcode, dst);
757 emitl(src.value_);
758 }
759 }
760
761
immediate_arithmetic_op_8(byte subcode,const Operand & dst,Immediate src)762 void Assembler::immediate_arithmetic_op_8(byte subcode,
763 const Operand& dst,
764 Immediate src) {
765 EnsureSpace ensure_space(this);
766 emit_optional_rex_32(dst);
767 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
768 emit(0x80);
769 emit_operand(subcode, dst);
770 emit(src.value_);
771 }
772
773
immediate_arithmetic_op_8(byte subcode,Register dst,Immediate src)774 void Assembler::immediate_arithmetic_op_8(byte subcode,
775 Register dst,
776 Immediate src) {
777 EnsureSpace ensure_space(this);
778 if (!dst.is_byte_register()) {
779 // Use 64-bit mode byte registers.
780 emit_rex_64(dst);
781 }
782 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
783 emit(0x80);
784 emit_modrm(subcode, dst);
785 emit(src.value_);
786 }
787
788
shift(Register dst,Immediate shift_amount,int subcode)789 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
790 EnsureSpace ensure_space(this);
791 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count
792 if (shift_amount.value_ == 1) {
793 emit_rex_64(dst);
794 emit(0xD1);
795 emit_modrm(subcode, dst);
796 } else {
797 emit_rex_64(dst);
798 emit(0xC1);
799 emit_modrm(subcode, dst);
800 emit(shift_amount.value_);
801 }
802 }
803
804
shift(Register dst,int subcode)805 void Assembler::shift(Register dst, int subcode) {
806 EnsureSpace ensure_space(this);
807 emit_rex_64(dst);
808 emit(0xD3);
809 emit_modrm(subcode, dst);
810 }
811
812
shift_32(Register dst,int subcode)813 void Assembler::shift_32(Register dst, int subcode) {
814 EnsureSpace ensure_space(this);
815 emit_optional_rex_32(dst);
816 emit(0xD3);
817 emit_modrm(subcode, dst);
818 }
819
820
shift_32(Register dst,Immediate shift_amount,int subcode)821 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
822 EnsureSpace ensure_space(this);
823 ASSERT(is_uint5(shift_amount.value_)); // illegal shift count
824 if (shift_amount.value_ == 1) {
825 emit_optional_rex_32(dst);
826 emit(0xD1);
827 emit_modrm(subcode, dst);
828 } else {
829 emit_optional_rex_32(dst);
830 emit(0xC1);
831 emit_modrm(subcode, dst);
832 emit(shift_amount.value_);
833 }
834 }
835
836
bt(const Operand & dst,Register src)837 void Assembler::bt(const Operand& dst, Register src) {
838 EnsureSpace ensure_space(this);
839 emit_rex_64(src, dst);
840 emit(0x0F);
841 emit(0xA3);
842 emit_operand(src, dst);
843 }
844
845
bts(const Operand & dst,Register src)846 void Assembler::bts(const Operand& dst, Register src) {
847 EnsureSpace ensure_space(this);
848 emit_rex_64(src, dst);
849 emit(0x0F);
850 emit(0xAB);
851 emit_operand(src, dst);
852 }
853
854
call(Label * L)855 void Assembler::call(Label* L) {
856 positions_recorder()->WriteRecordedPositions();
857 EnsureSpace ensure_space(this);
858 // 1110 1000 #32-bit disp.
859 emit(0xE8);
860 if (L->is_bound()) {
861 int offset = L->pos() - pc_offset() - sizeof(int32_t);
862 ASSERT(offset <= 0);
863 emitl(offset);
864 } else if (L->is_linked()) {
865 emitl(L->pos());
866 L->link_to(pc_offset() - sizeof(int32_t));
867 } else {
868 ASSERT(L->is_unused());
869 int32_t current = pc_offset();
870 emitl(current);
871 L->link_to(current);
872 }
873 }
874
875
call(Handle<Code> target,RelocInfo::Mode rmode,unsigned ast_id)876 void Assembler::call(Handle<Code> target,
877 RelocInfo::Mode rmode,
878 unsigned ast_id) {
879 positions_recorder()->WriteRecordedPositions();
880 EnsureSpace ensure_space(this);
881 // 1110 1000 #32-bit disp.
882 emit(0xE8);
883 emit_code_target(target, rmode, ast_id);
884 }
885
886
call(Register adr)887 void Assembler::call(Register adr) {
888 positions_recorder()->WriteRecordedPositions();
889 EnsureSpace ensure_space(this);
890 // Opcode: FF /2 r64.
891 emit_optional_rex_32(adr);
892 emit(0xFF);
893 emit_modrm(0x2, adr);
894 }
895
896
call(const Operand & op)897 void Assembler::call(const Operand& op) {
898 positions_recorder()->WriteRecordedPositions();
899 EnsureSpace ensure_space(this);
900 // Opcode: FF /2 m64.
901 emit_optional_rex_32(op);
902 emit(0xFF);
903 emit_operand(0x2, op);
904 }
905
906
907 // Calls directly to the given address using a relative offset.
908 // Should only ever be used in Code objects for calls within the
909 // same Code object. Should not be used when generating new code (use labels),
910 // but only when patching existing code.
call(Address target)911 void Assembler::call(Address target) {
912 positions_recorder()->WriteRecordedPositions();
913 EnsureSpace ensure_space(this);
914 // 1110 1000 #32-bit disp.
915 emit(0xE8);
916 Address source = pc_ + 4;
917 intptr_t displacement = target - source;
918 ASSERT(is_int32(displacement));
919 emitl(static_cast<int32_t>(displacement));
920 }
921
922
clc()923 void Assembler::clc() {
924 EnsureSpace ensure_space(this);
925 emit(0xF8);
926 }
927
cld()928 void Assembler::cld() {
929 EnsureSpace ensure_space(this);
930 emit(0xFC);
931 }
932
cdq()933 void Assembler::cdq() {
934 EnsureSpace ensure_space(this);
935 emit(0x99);
936 }
937
938
cmovq(Condition cc,Register dst,Register src)939 void Assembler::cmovq(Condition cc, Register dst, Register src) {
940 if (cc == always) {
941 movq(dst, src);
942 } else if (cc == never) {
943 return;
944 }
945 // No need to check CpuInfo for CMOV support, it's a required part of the
946 // 64-bit architecture.
947 ASSERT(cc >= 0); // Use mov for unconditional moves.
948 EnsureSpace ensure_space(this);
949 // Opcode: REX.W 0f 40 + cc /r.
950 emit_rex_64(dst, src);
951 emit(0x0f);
952 emit(0x40 + cc);
953 emit_modrm(dst, src);
954 }
955
956
cmovq(Condition cc,Register dst,const Operand & src)957 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
958 if (cc == always) {
959 movq(dst, src);
960 } else if (cc == never) {
961 return;
962 }
963 ASSERT(cc >= 0);
964 EnsureSpace ensure_space(this);
965 // Opcode: REX.W 0f 40 + cc /r.
966 emit_rex_64(dst, src);
967 emit(0x0f);
968 emit(0x40 + cc);
969 emit_operand(dst, src);
970 }
971
972
cmovl(Condition cc,Register dst,Register src)973 void Assembler::cmovl(Condition cc, Register dst, Register src) {
974 if (cc == always) {
975 movl(dst, src);
976 } else if (cc == never) {
977 return;
978 }
979 ASSERT(cc >= 0);
980 EnsureSpace ensure_space(this);
981 // Opcode: 0f 40 + cc /r.
982 emit_optional_rex_32(dst, src);
983 emit(0x0f);
984 emit(0x40 + cc);
985 emit_modrm(dst, src);
986 }
987
988
cmovl(Condition cc,Register dst,const Operand & src)989 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
990 if (cc == always) {
991 movl(dst, src);
992 } else if (cc == never) {
993 return;
994 }
995 ASSERT(cc >= 0);
996 EnsureSpace ensure_space(this);
997 // Opcode: 0f 40 + cc /r.
998 emit_optional_rex_32(dst, src);
999 emit(0x0f);
1000 emit(0x40 + cc);
1001 emit_operand(dst, src);
1002 }
1003
1004
cmpb_al(Immediate imm8)1005 void Assembler::cmpb_al(Immediate imm8) {
1006 ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
1007 EnsureSpace ensure_space(this);
1008 emit(0x3c);
1009 emit(imm8.value_);
1010 }
1011
1012
cpuid()1013 void Assembler::cpuid() {
1014 ASSERT(CpuFeatures::IsEnabled(CPUID));
1015 EnsureSpace ensure_space(this);
1016 emit(0x0F);
1017 emit(0xA2);
1018 }
1019
1020
cqo()1021 void Assembler::cqo() {
1022 EnsureSpace ensure_space(this);
1023 emit_rex_64();
1024 emit(0x99);
1025 }
1026
1027
decq(Register dst)1028 void Assembler::decq(Register dst) {
1029 EnsureSpace ensure_space(this);
1030 emit_rex_64(dst);
1031 emit(0xFF);
1032 emit_modrm(0x1, dst);
1033 }
1034
1035
decq(const Operand & dst)1036 void Assembler::decq(const Operand& dst) {
1037 EnsureSpace ensure_space(this);
1038 emit_rex_64(dst);
1039 emit(0xFF);
1040 emit_operand(1, dst);
1041 }
1042
1043
decl(Register dst)1044 void Assembler::decl(Register dst) {
1045 EnsureSpace ensure_space(this);
1046 emit_optional_rex_32(dst);
1047 emit(0xFF);
1048 emit_modrm(0x1, dst);
1049 }
1050
1051
decl(const Operand & dst)1052 void Assembler::decl(const Operand& dst) {
1053 EnsureSpace ensure_space(this);
1054 emit_optional_rex_32(dst);
1055 emit(0xFF);
1056 emit_operand(1, dst);
1057 }
1058
1059
decb(Register dst)1060 void Assembler::decb(Register dst) {
1061 EnsureSpace ensure_space(this);
1062 if (!dst.is_byte_register()) {
1063 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1064 emit_rex_32(dst);
1065 }
1066 emit(0xFE);
1067 emit_modrm(0x1, dst);
1068 }
1069
1070
decb(const Operand & dst)1071 void Assembler::decb(const Operand& dst) {
1072 EnsureSpace ensure_space(this);
1073 emit_optional_rex_32(dst);
1074 emit(0xFE);
1075 emit_operand(1, dst);
1076 }
1077
1078
enter(Immediate size)1079 void Assembler::enter(Immediate size) {
1080 EnsureSpace ensure_space(this);
1081 emit(0xC8);
1082 emitw(size.value_); // 16 bit operand, always.
1083 emit(0);
1084 }
1085
1086
hlt()1087 void Assembler::hlt() {
1088 EnsureSpace ensure_space(this);
1089 emit(0xF4);
1090 }
1091
1092
idivq(Register src)1093 void Assembler::idivq(Register src) {
1094 EnsureSpace ensure_space(this);
1095 emit_rex_64(src);
1096 emit(0xF7);
1097 emit_modrm(0x7, src);
1098 }
1099
1100
idivl(Register src)1101 void Assembler::idivl(Register src) {
1102 EnsureSpace ensure_space(this);
1103 emit_optional_rex_32(src);
1104 emit(0xF7);
1105 emit_modrm(0x7, src);
1106 }
1107
1108
imul(Register src)1109 void Assembler::imul(Register src) {
1110 EnsureSpace ensure_space(this);
1111 emit_rex_64(src);
1112 emit(0xF7);
1113 emit_modrm(0x5, src);
1114 }
1115
1116
imul(Register dst,Register src)1117 void Assembler::imul(Register dst, Register src) {
1118 EnsureSpace ensure_space(this);
1119 emit_rex_64(dst, src);
1120 emit(0x0F);
1121 emit(0xAF);
1122 emit_modrm(dst, src);
1123 }
1124
1125
imul(Register dst,const Operand & src)1126 void Assembler::imul(Register dst, const Operand& src) {
1127 EnsureSpace ensure_space(this);
1128 emit_rex_64(dst, src);
1129 emit(0x0F);
1130 emit(0xAF);
1131 emit_operand(dst, src);
1132 }
1133
1134
imul(Register dst,Register src,Immediate imm)1135 void Assembler::imul(Register dst, Register src, Immediate imm) {
1136 EnsureSpace ensure_space(this);
1137 emit_rex_64(dst, src);
1138 if (is_int8(imm.value_)) {
1139 emit(0x6B);
1140 emit_modrm(dst, src);
1141 emit(imm.value_);
1142 } else {
1143 emit(0x69);
1144 emit_modrm(dst, src);
1145 emitl(imm.value_);
1146 }
1147 }
1148
1149
imull(Register dst,Register src)1150 void Assembler::imull(Register dst, Register src) {
1151 EnsureSpace ensure_space(this);
1152 emit_optional_rex_32(dst, src);
1153 emit(0x0F);
1154 emit(0xAF);
1155 emit_modrm(dst, src);
1156 }
1157
1158
imull(Register dst,const Operand & src)1159 void Assembler::imull(Register dst, const Operand& src) {
1160 EnsureSpace ensure_space(this);
1161 emit_optional_rex_32(dst, src);
1162 emit(0x0F);
1163 emit(0xAF);
1164 emit_operand(dst, src);
1165 }
1166
1167
imull(Register dst,Register src,Immediate imm)1168 void Assembler::imull(Register dst, Register src, Immediate imm) {
1169 EnsureSpace ensure_space(this);
1170 emit_optional_rex_32(dst, src);
1171 if (is_int8(imm.value_)) {
1172 emit(0x6B);
1173 emit_modrm(dst, src);
1174 emit(imm.value_);
1175 } else {
1176 emit(0x69);
1177 emit_modrm(dst, src);
1178 emitl(imm.value_);
1179 }
1180 }
1181
1182
incq(Register dst)1183 void Assembler::incq(Register dst) {
1184 EnsureSpace ensure_space(this);
1185 emit_rex_64(dst);
1186 emit(0xFF);
1187 emit_modrm(0x0, dst);
1188 }
1189
1190
incq(const Operand & dst)1191 void Assembler::incq(const Operand& dst) {
1192 EnsureSpace ensure_space(this);
1193 emit_rex_64(dst);
1194 emit(0xFF);
1195 emit_operand(0, dst);
1196 }
1197
1198
incl(const Operand & dst)1199 void Assembler::incl(const Operand& dst) {
1200 EnsureSpace ensure_space(this);
1201 emit_optional_rex_32(dst);
1202 emit(0xFF);
1203 emit_operand(0, dst);
1204 }
1205
1206
incl(Register dst)1207 void Assembler::incl(Register dst) {
1208 EnsureSpace ensure_space(this);
1209 emit_optional_rex_32(dst);
1210 emit(0xFF);
1211 emit_modrm(0, dst);
1212 }
1213
1214
int3()1215 void Assembler::int3() {
1216 EnsureSpace ensure_space(this);
1217 emit(0xCC);
1218 }
1219
1220
j(Condition cc,Label * L,Label::Distance distance)1221 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1222 if (cc == always) {
1223 jmp(L);
1224 return;
1225 } else if (cc == never) {
1226 return;
1227 }
1228 EnsureSpace ensure_space(this);
1229 ASSERT(is_uint4(cc));
1230 if (L->is_bound()) {
1231 const int short_size = 2;
1232 const int long_size = 6;
1233 int offs = L->pos() - pc_offset();
1234 ASSERT(offs <= 0);
1235 if (is_int8(offs - short_size)) {
1236 // 0111 tttn #8-bit disp.
1237 emit(0x70 | cc);
1238 emit((offs - short_size) & 0xFF);
1239 } else {
1240 // 0000 1111 1000 tttn #32-bit disp.
1241 emit(0x0F);
1242 emit(0x80 | cc);
1243 emitl(offs - long_size);
1244 }
1245 } else if (distance == Label::kNear) {
1246 // 0111 tttn #8-bit disp
1247 emit(0x70 | cc);
1248 byte disp = 0x00;
1249 if (L->is_near_linked()) {
1250 int offset = L->near_link_pos() - pc_offset();
1251 ASSERT(is_int8(offset));
1252 disp = static_cast<byte>(offset & 0xFF);
1253 }
1254 L->link_to(pc_offset(), Label::kNear);
1255 emit(disp);
1256 } else if (L->is_linked()) {
1257 // 0000 1111 1000 tttn #32-bit disp.
1258 emit(0x0F);
1259 emit(0x80 | cc);
1260 emitl(L->pos());
1261 L->link_to(pc_offset() - sizeof(int32_t));
1262 } else {
1263 ASSERT(L->is_unused());
1264 emit(0x0F);
1265 emit(0x80 | cc);
1266 int32_t current = pc_offset();
1267 emitl(current);
1268 L->link_to(current);
1269 }
1270 }
1271
1272
j(Condition cc,Handle<Code> target,RelocInfo::Mode rmode)1273 void Assembler::j(Condition cc,
1274 Handle<Code> target,
1275 RelocInfo::Mode rmode) {
1276 EnsureSpace ensure_space(this);
1277 ASSERT(is_uint4(cc));
1278 // 0000 1111 1000 tttn #32-bit disp.
1279 emit(0x0F);
1280 emit(0x80 | cc);
1281 emit_code_target(target, rmode);
1282 }
1283
1284
jmp(Label * L,Label::Distance distance)1285 void Assembler::jmp(Label* L, Label::Distance distance) {
1286 EnsureSpace ensure_space(this);
1287 const int short_size = sizeof(int8_t);
1288 const int long_size = sizeof(int32_t);
1289 if (L->is_bound()) {
1290 int offs = L->pos() - pc_offset() - 1;
1291 ASSERT(offs <= 0);
1292 if (is_int8(offs - short_size)) {
1293 // 1110 1011 #8-bit disp.
1294 emit(0xEB);
1295 emit((offs - short_size) & 0xFF);
1296 } else {
1297 // 1110 1001 #32-bit disp.
1298 emit(0xE9);
1299 emitl(offs - long_size);
1300 }
1301 } else if (distance == Label::kNear) {
1302 emit(0xEB);
1303 byte disp = 0x00;
1304 if (L->is_near_linked()) {
1305 int offset = L->near_link_pos() - pc_offset();
1306 ASSERT(is_int8(offset));
1307 disp = static_cast<byte>(offset & 0xFF);
1308 }
1309 L->link_to(pc_offset(), Label::kNear);
1310 emit(disp);
1311 } else if (L->is_linked()) {
1312 // 1110 1001 #32-bit disp.
1313 emit(0xE9);
1314 emitl(L->pos());
1315 L->link_to(pc_offset() - long_size);
1316 } else {
1317 // 1110 1001 #32-bit disp.
1318 ASSERT(L->is_unused());
1319 emit(0xE9);
1320 int32_t current = pc_offset();
1321 emitl(current);
1322 L->link_to(current);
1323 }
1324 }
1325
1326
jmp(Handle<Code> target,RelocInfo::Mode rmode)1327 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1328 EnsureSpace ensure_space(this);
1329 // 1110 1001 #32-bit disp.
1330 emit(0xE9);
1331 emit_code_target(target, rmode);
1332 }
1333
1334
jmp(Register target)1335 void Assembler::jmp(Register target) {
1336 EnsureSpace ensure_space(this);
1337 // Opcode FF/4 r64.
1338 emit_optional_rex_32(target);
1339 emit(0xFF);
1340 emit_modrm(0x4, target);
1341 }
1342
1343
jmp(const Operand & src)1344 void Assembler::jmp(const Operand& src) {
1345 EnsureSpace ensure_space(this);
1346 // Opcode FF/4 m64.
1347 emit_optional_rex_32(src);
1348 emit(0xFF);
1349 emit_operand(0x4, src);
1350 }
1351
1352
lea(Register dst,const Operand & src)1353 void Assembler::lea(Register dst, const Operand& src) {
1354 EnsureSpace ensure_space(this);
1355 emit_rex_64(dst, src);
1356 emit(0x8D);
1357 emit_operand(dst, src);
1358 }
1359
1360
leal(Register dst,const Operand & src)1361 void Assembler::leal(Register dst, const Operand& src) {
1362 EnsureSpace ensure_space(this);
1363 emit_optional_rex_32(dst, src);
1364 emit(0x8D);
1365 emit_operand(dst, src);
1366 }
1367
1368
load_rax(void * value,RelocInfo::Mode mode)1369 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1370 EnsureSpace ensure_space(this);
1371 emit(0x48); // REX.W
1372 emit(0xA1);
1373 emitq(reinterpret_cast<uintptr_t>(value), mode);
1374 }
1375
1376
load_rax(ExternalReference ref)1377 void Assembler::load_rax(ExternalReference ref) {
1378 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1379 }
1380
1381
leave()1382 void Assembler::leave() {
1383 EnsureSpace ensure_space(this);
1384 emit(0xC9);
1385 }
1386
1387
movb(Register dst,const Operand & src)1388 void Assembler::movb(Register dst, const Operand& src) {
1389 EnsureSpace ensure_space(this);
1390 if (!dst.is_byte_register()) {
1391 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
1392 emit_rex_32(dst, src);
1393 } else {
1394 emit_optional_rex_32(dst, src);
1395 }
1396 emit(0x8A);
1397 emit_operand(dst, src);
1398 }
1399
1400
movb(Register dst,Immediate imm)1401 void Assembler::movb(Register dst, Immediate imm) {
1402 EnsureSpace ensure_space(this);
1403 if (!dst.is_byte_register()) {
1404 emit_rex_32(dst);
1405 }
1406 emit(0xB0 + dst.low_bits());
1407 emit(imm.value_);
1408 }
1409
1410
movb(const Operand & dst,Register src)1411 void Assembler::movb(const Operand& dst, Register src) {
1412 EnsureSpace ensure_space(this);
1413 if (!src.is_byte_register()) {
1414 emit_rex_32(src, dst);
1415 } else {
1416 emit_optional_rex_32(src, dst);
1417 }
1418 emit(0x88);
1419 emit_operand(src, dst);
1420 }
1421
1422
movw(const Operand & dst,Register src)1423 void Assembler::movw(const Operand& dst, Register src) {
1424 EnsureSpace ensure_space(this);
1425 emit(0x66);
1426 emit_optional_rex_32(src, dst);
1427 emit(0x89);
1428 emit_operand(src, dst);
1429 }
1430
1431
movl(Register dst,const Operand & src)1432 void Assembler::movl(Register dst, const Operand& src) {
1433 EnsureSpace ensure_space(this);
1434 emit_optional_rex_32(dst, src);
1435 emit(0x8B);
1436 emit_operand(dst, src);
1437 }
1438
1439
movl(Register dst,Register src)1440 void Assembler::movl(Register dst, Register src) {
1441 EnsureSpace ensure_space(this);
1442 if (src.low_bits() == 4) {
1443 emit_optional_rex_32(src, dst);
1444 emit(0x89);
1445 emit_modrm(src, dst);
1446 } else {
1447 emit_optional_rex_32(dst, src);
1448 emit(0x8B);
1449 emit_modrm(dst, src);
1450 }
1451 }
1452
1453
movl(const Operand & dst,Register src)1454 void Assembler::movl(const Operand& dst, Register src) {
1455 EnsureSpace ensure_space(this);
1456 emit_optional_rex_32(src, dst);
1457 emit(0x89);
1458 emit_operand(src, dst);
1459 }
1460
1461
movl(const Operand & dst,Immediate value)1462 void Assembler::movl(const Operand& dst, Immediate value) {
1463 EnsureSpace ensure_space(this);
1464 emit_optional_rex_32(dst);
1465 emit(0xC7);
1466 emit_operand(0x0, dst);
1467 emit(value);
1468 }
1469
1470
movl(Register dst,Immediate value)1471 void Assembler::movl(Register dst, Immediate value) {
1472 EnsureSpace ensure_space(this);
1473 emit_optional_rex_32(dst);
1474 emit(0xB8 + dst.low_bits());
1475 emit(value);
1476 }
1477
1478
movq(Register dst,const Operand & src)1479 void Assembler::movq(Register dst, const Operand& src) {
1480 EnsureSpace ensure_space(this);
1481 emit_rex_64(dst, src);
1482 emit(0x8B);
1483 emit_operand(dst, src);
1484 }
1485
1486
movq(Register dst,Register src)1487 void Assembler::movq(Register dst, Register src) {
1488 EnsureSpace ensure_space(this);
1489 if (src.low_bits() == 4) {
1490 emit_rex_64(src, dst);
1491 emit(0x89);
1492 emit_modrm(src, dst);
1493 } else {
1494 emit_rex_64(dst, src);
1495 emit(0x8B);
1496 emit_modrm(dst, src);
1497 }
1498 }
1499
1500
movq(Register dst,Immediate value)1501 void Assembler::movq(Register dst, Immediate value) {
1502 EnsureSpace ensure_space(this);
1503 emit_rex_64(dst);
1504 emit(0xC7);
1505 emit_modrm(0x0, dst);
1506 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
1507 }
1508
1509
movq(const Operand & dst,Register src)1510 void Assembler::movq(const Operand& dst, Register src) {
1511 EnsureSpace ensure_space(this);
1512 emit_rex_64(src, dst);
1513 emit(0x89);
1514 emit_operand(src, dst);
1515 }
1516
1517
movq(Register dst,void * value,RelocInfo::Mode rmode)1518 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
1519 // This method must not be used with heap object references. The stored
1520 // address is not GC safe. Use the handle version instead.
1521 ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
1522 EnsureSpace ensure_space(this);
1523 emit_rex_64(dst);
1524 emit(0xB8 | dst.low_bits());
1525 emitq(reinterpret_cast<uintptr_t>(value), rmode);
1526 }
1527
1528
movq(Register dst,int64_t value,RelocInfo::Mode rmode)1529 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
1530 // Non-relocatable values might not need a 64-bit representation.
1531 if (rmode == RelocInfo::NONE) {
1532 // Sadly, there is no zero or sign extending move for 8-bit immediates.
1533 if (is_int32(value)) {
1534 movq(dst, Immediate(static_cast<int32_t>(value)));
1535 return;
1536 } else if (is_uint32(value)) {
1537 movl(dst, Immediate(static_cast<int32_t>(value)));
1538 return;
1539 }
1540 // Value cannot be represented by 32 bits, so do a full 64 bit immediate
1541 // value.
1542 }
1543 EnsureSpace ensure_space(this);
1544 emit_rex_64(dst);
1545 emit(0xB8 | dst.low_bits());
1546 emitq(value, rmode);
1547 }
1548
1549
movq(Register dst,ExternalReference ref)1550 void Assembler::movq(Register dst, ExternalReference ref) {
1551 int64_t value = reinterpret_cast<int64_t>(ref.address());
1552 movq(dst, value, RelocInfo::EXTERNAL_REFERENCE);
1553 }
1554
1555
movq(const Operand & dst,Immediate value)1556 void Assembler::movq(const Operand& dst, Immediate value) {
1557 EnsureSpace ensure_space(this);
1558 emit_rex_64(dst);
1559 emit(0xC7);
1560 emit_operand(0, dst);
1561 emit(value);
1562 }
1563
1564
1565 // Loads the ip-relative location of the src label into the target location
1566 // (as a 32-bit offset sign extended to 64-bit).
movl(const Operand & dst,Label * src)1567 void Assembler::movl(const Operand& dst, Label* src) {
1568 EnsureSpace ensure_space(this);
1569 emit_optional_rex_32(dst);
1570 emit(0xC7);
1571 emit_operand(0, dst);
1572 if (src->is_bound()) {
1573 int offset = src->pos() - pc_offset() - sizeof(int32_t);
1574 ASSERT(offset <= 0);
1575 emitl(offset);
1576 } else if (src->is_linked()) {
1577 emitl(src->pos());
1578 src->link_to(pc_offset() - sizeof(int32_t));
1579 } else {
1580 ASSERT(src->is_unused());
1581 int32_t current = pc_offset();
1582 emitl(current);
1583 src->link_to(current);
1584 }
1585 }
1586
1587
movq(Register dst,Handle<Object> value,RelocInfo::Mode mode)1588 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
1589 // If there is no relocation info, emit the value of the handle efficiently
1590 // (possibly using less that 8 bytes for the value).
1591 if (mode == RelocInfo::NONE) {
1592 // There is no possible reason to store a heap pointer without relocation
1593 // info, so it must be a smi.
1594 ASSERT(value->IsSmi());
1595 movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE);
1596 } else {
1597 EnsureSpace ensure_space(this);
1598 ASSERT(value->IsHeapObject());
1599 ASSERT(!HEAP->InNewSpace(*value));
1600 emit_rex_64(dst);
1601 emit(0xB8 | dst.low_bits());
1602 emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
1603 }
1604 }
1605
1606
movsxbq(Register dst,const Operand & src)1607 void Assembler::movsxbq(Register dst, const Operand& src) {
1608 EnsureSpace ensure_space(this);
1609 emit_rex_64(dst, src);
1610 emit(0x0F);
1611 emit(0xBE);
1612 emit_operand(dst, src);
1613 }
1614
1615
movsxwq(Register dst,const Operand & src)1616 void Assembler::movsxwq(Register dst, const Operand& src) {
1617 EnsureSpace ensure_space(this);
1618 emit_rex_64(dst, src);
1619 emit(0x0F);
1620 emit(0xBF);
1621 emit_operand(dst, src);
1622 }
1623
1624
movsxlq(Register dst,Register src)1625 void Assembler::movsxlq(Register dst, Register src) {
1626 EnsureSpace ensure_space(this);
1627 emit_rex_64(dst, src);
1628 emit(0x63);
1629 emit_modrm(dst, src);
1630 }
1631
1632
movsxlq(Register dst,const Operand & src)1633 void Assembler::movsxlq(Register dst, const Operand& src) {
1634 EnsureSpace ensure_space(this);
1635 emit_rex_64(dst, src);
1636 emit(0x63);
1637 emit_operand(dst, src);
1638 }
1639
1640
movzxbq(Register dst,const Operand & src)1641 void Assembler::movzxbq(Register dst, const Operand& src) {
1642 EnsureSpace ensure_space(this);
1643 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
1644 // there is no need to make this a 64 bit operation.
1645 emit_optional_rex_32(dst, src);
1646 emit(0x0F);
1647 emit(0xB6);
1648 emit_operand(dst, src);
1649 }
1650
1651
movzxbl(Register dst,const Operand & src)1652 void Assembler::movzxbl(Register dst, const Operand& src) {
1653 EnsureSpace ensure_space(this);
1654 emit_optional_rex_32(dst, src);
1655 emit(0x0F);
1656 emit(0xB6);
1657 emit_operand(dst, src);
1658 }
1659
1660
movzxwq(Register dst,const Operand & src)1661 void Assembler::movzxwq(Register dst, const Operand& src) {
1662 EnsureSpace ensure_space(this);
1663 emit_optional_rex_32(dst, src);
1664 emit(0x0F);
1665 emit(0xB7);
1666 emit_operand(dst, src);
1667 }
1668
1669
movzxwl(Register dst,const Operand & src)1670 void Assembler::movzxwl(Register dst, const Operand& src) {
1671 EnsureSpace ensure_space(this);
1672 emit_optional_rex_32(dst, src);
1673 emit(0x0F);
1674 emit(0xB7);
1675 emit_operand(dst, src);
1676 }
1677
1678
repmovsb()1679 void Assembler::repmovsb() {
1680 EnsureSpace ensure_space(this);
1681 emit(0xF3);
1682 emit(0xA4);
1683 }
1684
1685
repmovsw()1686 void Assembler::repmovsw() {
1687 EnsureSpace ensure_space(this);
1688 emit(0x66); // Operand size override.
1689 emit(0xF3);
1690 emit(0xA4);
1691 }
1692
1693
repmovsl()1694 void Assembler::repmovsl() {
1695 EnsureSpace ensure_space(this);
1696 emit(0xF3);
1697 emit(0xA5);
1698 }
1699
1700
repmovsq()1701 void Assembler::repmovsq() {
1702 EnsureSpace ensure_space(this);
1703 emit(0xF3);
1704 emit_rex_64();
1705 emit(0xA5);
1706 }
1707
1708
mul(Register src)1709 void Assembler::mul(Register src) {
1710 EnsureSpace ensure_space(this);
1711 emit_rex_64(src);
1712 emit(0xF7);
1713 emit_modrm(0x4, src);
1714 }
1715
1716
neg(Register dst)1717 void Assembler::neg(Register dst) {
1718 EnsureSpace ensure_space(this);
1719 emit_rex_64(dst);
1720 emit(0xF7);
1721 emit_modrm(0x3, dst);
1722 }
1723
1724
negl(Register dst)1725 void Assembler::negl(Register dst) {
1726 EnsureSpace ensure_space(this);
1727 emit_optional_rex_32(dst);
1728 emit(0xF7);
1729 emit_modrm(0x3, dst);
1730 }
1731
1732
neg(const Operand & dst)1733 void Assembler::neg(const Operand& dst) {
1734 EnsureSpace ensure_space(this);
1735 emit_rex_64(dst);
1736 emit(0xF7);
1737 emit_operand(3, dst);
1738 }
1739
1740
nop()1741 void Assembler::nop() {
1742 EnsureSpace ensure_space(this);
1743 emit(0x90);
1744 }
1745
1746
not_(Register dst)1747 void Assembler::not_(Register dst) {
1748 EnsureSpace ensure_space(this);
1749 emit_rex_64(dst);
1750 emit(0xF7);
1751 emit_modrm(0x2, dst);
1752 }
1753
1754
not_(const Operand & dst)1755 void Assembler::not_(const Operand& dst) {
1756 EnsureSpace ensure_space(this);
1757 emit_rex_64(dst);
1758 emit(0xF7);
1759 emit_operand(2, dst);
1760 }
1761
1762
notl(Register dst)1763 void Assembler::notl(Register dst) {
1764 EnsureSpace ensure_space(this);
1765 emit_optional_rex_32(dst);
1766 emit(0xF7);
1767 emit_modrm(0x2, dst);
1768 }
1769
1770
Nop(int n)1771 void Assembler::Nop(int n) {
1772 // The recommended muti-byte sequences of NOP instructions from the Intel 64
1773 // and IA-32 Architectures Software Developer's Manual.
1774 //
1775 // Length Assembly Byte Sequence
1776 // 2 bytes 66 NOP 66 90H
1777 // 3 bytes NOP DWORD ptr [EAX] 0F 1F 00H
1778 // 4 bytes NOP DWORD ptr [EAX + 00H] 0F 1F 40 00H
1779 // 5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H] 0F 1F 44 00 00H
1780 // 6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H] 66 0F 1F 44 00 00H
1781 // 7 bytes NOP DWORD ptr [EAX + 00000000H] 0F 1F 80 00 00 00 00H
1782 // 8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1783 // 9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 66 0F 1F 84 00 00 00 00
1784 // 00000000H] 00H
1785
1786 EnsureSpace ensure_space(this);
1787 while (n > 0) {
1788 switch (n) {
1789 case 2:
1790 emit(0x66);
1791 case 1:
1792 emit(0x90);
1793 return;
1794 case 3:
1795 emit(0x0f);
1796 emit(0x1f);
1797 emit(0x00);
1798 return;
1799 case 4:
1800 emit(0x0f);
1801 emit(0x1f);
1802 emit(0x40);
1803 emit(0x00);
1804 return;
1805 case 6:
1806 emit(0x66);
1807 case 5:
1808 emit(0x0f);
1809 emit(0x1f);
1810 emit(0x44);
1811 emit(0x00);
1812 emit(0x00);
1813 return;
1814 case 7:
1815 emit(0x0f);
1816 emit(0x1f);
1817 emit(0x80);
1818 emit(0x00);
1819 emit(0x00);
1820 emit(0x00);
1821 emit(0x00);
1822 return;
1823 default:
1824 case 11:
1825 emit(0x66);
1826 n--;
1827 case 10:
1828 emit(0x66);
1829 n--;
1830 case 9:
1831 emit(0x66);
1832 n--;
1833 case 8:
1834 emit(0x0f);
1835 emit(0x1f);
1836 emit(0x84);
1837 emit(0x00);
1838 emit(0x00);
1839 emit(0x00);
1840 emit(0x00);
1841 emit(0x00);
1842 n -= 8;
1843 }
1844 }
1845 }
1846
1847
pop(Register dst)1848 void Assembler::pop(Register dst) {
1849 EnsureSpace ensure_space(this);
1850 emit_optional_rex_32(dst);
1851 emit(0x58 | dst.low_bits());
1852 }
1853
1854
pop(const Operand & dst)1855 void Assembler::pop(const Operand& dst) {
1856 EnsureSpace ensure_space(this);
1857 emit_optional_rex_32(dst);
1858 emit(0x8F);
1859 emit_operand(0, dst);
1860 }
1861
1862
popfq()1863 void Assembler::popfq() {
1864 EnsureSpace ensure_space(this);
1865 emit(0x9D);
1866 }
1867
1868
push(Register src)1869 void Assembler::push(Register src) {
1870 EnsureSpace ensure_space(this);
1871 emit_optional_rex_32(src);
1872 emit(0x50 | src.low_bits());
1873 }
1874
1875
push(const Operand & src)1876 void Assembler::push(const Operand& src) {
1877 EnsureSpace ensure_space(this);
1878 emit_optional_rex_32(src);
1879 emit(0xFF);
1880 emit_operand(6, src);
1881 }
1882
1883
push(Immediate value)1884 void Assembler::push(Immediate value) {
1885 EnsureSpace ensure_space(this);
1886 if (is_int8(value.value_)) {
1887 emit(0x6A);
1888 emit(value.value_); // Emit low byte of value.
1889 } else {
1890 emit(0x68);
1891 emitl(value.value_);
1892 }
1893 }
1894
1895
push_imm32(int32_t imm32)1896 void Assembler::push_imm32(int32_t imm32) {
1897 EnsureSpace ensure_space(this);
1898 emit(0x68);
1899 emitl(imm32);
1900 }
1901
1902
pushfq()1903 void Assembler::pushfq() {
1904 EnsureSpace ensure_space(this);
1905 emit(0x9C);
1906 }
1907
1908
rdtsc()1909 void Assembler::rdtsc() {
1910 EnsureSpace ensure_space(this);
1911 emit(0x0F);
1912 emit(0x31);
1913 }
1914
1915
ret(int imm16)1916 void Assembler::ret(int imm16) {
1917 EnsureSpace ensure_space(this);
1918 ASSERT(is_uint16(imm16));
1919 if (imm16 == 0) {
1920 emit(0xC3);
1921 } else {
1922 emit(0xC2);
1923 emit(imm16 & 0xFF);
1924 emit((imm16 >> 8) & 0xFF);
1925 }
1926 }
1927
1928
setcc(Condition cc,Register reg)1929 void Assembler::setcc(Condition cc, Register reg) {
1930 if (cc > last_condition) {
1931 movb(reg, Immediate(cc == always ? 1 : 0));
1932 return;
1933 }
1934 EnsureSpace ensure_space(this);
1935 ASSERT(is_uint4(cc));
1936 if (!reg.is_byte_register()) { // Use x64 byte registers, where different.
1937 emit_rex_32(reg);
1938 }
1939 emit(0x0F);
1940 emit(0x90 | cc);
1941 emit_modrm(0x0, reg);
1942 }
1943
1944
shld(Register dst,Register src)1945 void Assembler::shld(Register dst, Register src) {
1946 EnsureSpace ensure_space(this);
1947 emit_rex_64(src, dst);
1948 emit(0x0F);
1949 emit(0xA5);
1950 emit_modrm(src, dst);
1951 }
1952
1953
shrd(Register dst,Register src)1954 void Assembler::shrd(Register dst, Register src) {
1955 EnsureSpace ensure_space(this);
1956 emit_rex_64(src, dst);
1957 emit(0x0F);
1958 emit(0xAD);
1959 emit_modrm(src, dst);
1960 }
1961
1962
xchg(Register dst,Register src)1963 void Assembler::xchg(Register dst, Register src) {
1964 EnsureSpace ensure_space(this);
1965 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding
1966 Register other = src.is(rax) ? dst : src;
1967 emit_rex_64(other);
1968 emit(0x90 | other.low_bits());
1969 } else if (dst.low_bits() == 4) {
1970 emit_rex_64(dst, src);
1971 emit(0x87);
1972 emit_modrm(dst, src);
1973 } else {
1974 emit_rex_64(src, dst);
1975 emit(0x87);
1976 emit_modrm(src, dst);
1977 }
1978 }
1979
1980
store_rax(void * dst,RelocInfo::Mode mode)1981 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
1982 EnsureSpace ensure_space(this);
1983 emit(0x48); // REX.W
1984 emit(0xA3);
1985 emitq(reinterpret_cast<uintptr_t>(dst), mode);
1986 }
1987
1988
store_rax(ExternalReference ref)1989 void Assembler::store_rax(ExternalReference ref) {
1990 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1991 }
1992
1993
testb(Register dst,Register src)1994 void Assembler::testb(Register dst, Register src) {
1995 EnsureSpace ensure_space(this);
1996 if (src.low_bits() == 4) {
1997 emit_rex_32(src, dst);
1998 emit(0x84);
1999 emit_modrm(src, dst);
2000 } else {
2001 if (!dst.is_byte_register() || !src.is_byte_register()) {
2002 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2003 emit_rex_32(dst, src);
2004 }
2005 emit(0x84);
2006 emit_modrm(dst, src);
2007 }
2008 }
2009
2010
testb(Register reg,Immediate mask)2011 void Assembler::testb(Register reg, Immediate mask) {
2012 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
2013 EnsureSpace ensure_space(this);
2014 if (reg.is(rax)) {
2015 emit(0xA8);
2016 emit(mask.value_); // Low byte emitted.
2017 } else {
2018 if (!reg.is_byte_register()) {
2019 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2020 emit_rex_32(reg);
2021 }
2022 emit(0xF6);
2023 emit_modrm(0x0, reg);
2024 emit(mask.value_); // Low byte emitted.
2025 }
2026 }
2027
2028
testb(const Operand & op,Immediate mask)2029 void Assembler::testb(const Operand& op, Immediate mask) {
2030 ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
2031 EnsureSpace ensure_space(this);
2032 emit_optional_rex_32(rax, op);
2033 emit(0xF6);
2034 emit_operand(rax, op); // Operation code 0
2035 emit(mask.value_); // Low byte emitted.
2036 }
2037
2038
testb(const Operand & op,Register reg)2039 void Assembler::testb(const Operand& op, Register reg) {
2040 EnsureSpace ensure_space(this);
2041 if (!reg.is_byte_register()) {
2042 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
2043 emit_rex_32(reg, op);
2044 } else {
2045 emit_optional_rex_32(reg, op);
2046 }
2047 emit(0x84);
2048 emit_operand(reg, op);
2049 }
2050
2051
testl(Register dst,Register src)2052 void Assembler::testl(Register dst, Register src) {
2053 EnsureSpace ensure_space(this);
2054 if (src.low_bits() == 4) {
2055 emit_optional_rex_32(src, dst);
2056 emit(0x85);
2057 emit_modrm(src, dst);
2058 } else {
2059 emit_optional_rex_32(dst, src);
2060 emit(0x85);
2061 emit_modrm(dst, src);
2062 }
2063 }
2064
2065
testl(Register reg,Immediate mask)2066 void Assembler::testl(Register reg, Immediate mask) {
2067 // testl with a mask that fits in the low byte is exactly testb.
2068 if (is_uint8(mask.value_)) {
2069 testb(reg, mask);
2070 return;
2071 }
2072 EnsureSpace ensure_space(this);
2073 if (reg.is(rax)) {
2074 emit(0xA9);
2075 emit(mask);
2076 } else {
2077 emit_optional_rex_32(rax, reg);
2078 emit(0xF7);
2079 emit_modrm(0x0, reg);
2080 emit(mask);
2081 }
2082 }
2083
2084
testl(const Operand & op,Immediate mask)2085 void Assembler::testl(const Operand& op, Immediate mask) {
2086 // testl with a mask that fits in the low byte is exactly testb.
2087 if (is_uint8(mask.value_)) {
2088 testb(op, mask);
2089 return;
2090 }
2091 EnsureSpace ensure_space(this);
2092 emit_optional_rex_32(rax, op);
2093 emit(0xF7);
2094 emit_operand(rax, op); // Operation code 0
2095 emit(mask);
2096 }
2097
2098
testq(const Operand & op,Register reg)2099 void Assembler::testq(const Operand& op, Register reg) {
2100 EnsureSpace ensure_space(this);
2101 emit_rex_64(reg, op);
2102 emit(0x85);
2103 emit_operand(reg, op);
2104 }
2105
2106
testq(Register dst,Register src)2107 void Assembler::testq(Register dst, Register src) {
2108 EnsureSpace ensure_space(this);
2109 if (src.low_bits() == 4) {
2110 emit_rex_64(src, dst);
2111 emit(0x85);
2112 emit_modrm(src, dst);
2113 } else {
2114 emit_rex_64(dst, src);
2115 emit(0x85);
2116 emit_modrm(dst, src);
2117 }
2118 }
2119
2120
testq(Register dst,Immediate mask)2121 void Assembler::testq(Register dst, Immediate mask) {
2122 EnsureSpace ensure_space(this);
2123 if (dst.is(rax)) {
2124 emit_rex_64();
2125 emit(0xA9);
2126 emit(mask);
2127 } else {
2128 emit_rex_64(dst);
2129 emit(0xF7);
2130 emit_modrm(0, dst);
2131 emit(mask);
2132 }
2133 }
2134
2135
2136 // FPU instructions.
2137
2138
fld(int i)2139 void Assembler::fld(int i) {
2140 EnsureSpace ensure_space(this);
2141 emit_farith(0xD9, 0xC0, i);
2142 }
2143
2144
fld1()2145 void Assembler::fld1() {
2146 EnsureSpace ensure_space(this);
2147 emit(0xD9);
2148 emit(0xE8);
2149 }
2150
2151
fldz()2152 void Assembler::fldz() {
2153 EnsureSpace ensure_space(this);
2154 emit(0xD9);
2155 emit(0xEE);
2156 }
2157
2158
fldpi()2159 void Assembler::fldpi() {
2160 EnsureSpace ensure_space(this);
2161 emit(0xD9);
2162 emit(0xEB);
2163 }
2164
2165
fldln2()2166 void Assembler::fldln2() {
2167 EnsureSpace ensure_space(this);
2168 emit(0xD9);
2169 emit(0xED);
2170 }
2171
2172
fld_s(const Operand & adr)2173 void Assembler::fld_s(const Operand& adr) {
2174 EnsureSpace ensure_space(this);
2175 emit_optional_rex_32(adr);
2176 emit(0xD9);
2177 emit_operand(0, adr);
2178 }
2179
2180
fld_d(const Operand & adr)2181 void Assembler::fld_d(const Operand& adr) {
2182 EnsureSpace ensure_space(this);
2183 emit_optional_rex_32(adr);
2184 emit(0xDD);
2185 emit_operand(0, adr);
2186 }
2187
2188
fstp_s(const Operand & adr)2189 void Assembler::fstp_s(const Operand& adr) {
2190 EnsureSpace ensure_space(this);
2191 emit_optional_rex_32(adr);
2192 emit(0xD9);
2193 emit_operand(3, adr);
2194 }
2195
2196
fstp_d(const Operand & adr)2197 void Assembler::fstp_d(const Operand& adr) {
2198 EnsureSpace ensure_space(this);
2199 emit_optional_rex_32(adr);
2200 emit(0xDD);
2201 emit_operand(3, adr);
2202 }
2203
2204
fstp(int index)2205 void Assembler::fstp(int index) {
2206 ASSERT(is_uint3(index));
2207 EnsureSpace ensure_space(this);
2208 emit_farith(0xDD, 0xD8, index);
2209 }
2210
2211
fild_s(const Operand & adr)2212 void Assembler::fild_s(const Operand& adr) {
2213 EnsureSpace ensure_space(this);
2214 emit_optional_rex_32(adr);
2215 emit(0xDB);
2216 emit_operand(0, adr);
2217 }
2218
2219
fild_d(const Operand & adr)2220 void Assembler::fild_d(const Operand& adr) {
2221 EnsureSpace ensure_space(this);
2222 emit_optional_rex_32(adr);
2223 emit(0xDF);
2224 emit_operand(5, adr);
2225 }
2226
2227
fistp_s(const Operand & adr)2228 void Assembler::fistp_s(const Operand& adr) {
2229 EnsureSpace ensure_space(this);
2230 emit_optional_rex_32(adr);
2231 emit(0xDB);
2232 emit_operand(3, adr);
2233 }
2234
2235
fisttp_s(const Operand & adr)2236 void Assembler::fisttp_s(const Operand& adr) {
2237 ASSERT(CpuFeatures::IsEnabled(SSE3));
2238 EnsureSpace ensure_space(this);
2239 emit_optional_rex_32(adr);
2240 emit(0xDB);
2241 emit_operand(1, adr);
2242 }
2243
2244
fisttp_d(const Operand & adr)2245 void Assembler::fisttp_d(const Operand& adr) {
2246 ASSERT(CpuFeatures::IsEnabled(SSE3));
2247 EnsureSpace ensure_space(this);
2248 emit_optional_rex_32(adr);
2249 emit(0xDD);
2250 emit_operand(1, adr);
2251 }
2252
2253
fist_s(const Operand & adr)2254 void Assembler::fist_s(const Operand& adr) {
2255 EnsureSpace ensure_space(this);
2256 emit_optional_rex_32(adr);
2257 emit(0xDB);
2258 emit_operand(2, adr);
2259 }
2260
2261
fistp_d(const Operand & adr)2262 void Assembler::fistp_d(const Operand& adr) {
2263 EnsureSpace ensure_space(this);
2264 emit_optional_rex_32(adr);
2265 emit(0xDF);
2266 emit_operand(7, adr);
2267 }
2268
2269
fabs()2270 void Assembler::fabs() {
2271 EnsureSpace ensure_space(this);
2272 emit(0xD9);
2273 emit(0xE1);
2274 }
2275
2276
fchs()2277 void Assembler::fchs() {
2278 EnsureSpace ensure_space(this);
2279 emit(0xD9);
2280 emit(0xE0);
2281 }
2282
2283
fcos()2284 void Assembler::fcos() {
2285 EnsureSpace ensure_space(this);
2286 emit(0xD9);
2287 emit(0xFF);
2288 }
2289
2290
fsin()2291 void Assembler::fsin() {
2292 EnsureSpace ensure_space(this);
2293 emit(0xD9);
2294 emit(0xFE);
2295 }
2296
2297
fptan()2298 void Assembler::fptan() {
2299 EnsureSpace ensure_space(this);
2300 emit(0xD9);
2301 emit(0xF2);
2302 }
2303
2304
fyl2x()2305 void Assembler::fyl2x() {
2306 EnsureSpace ensure_space(this);
2307 emit(0xD9);
2308 emit(0xF1);
2309 }
2310
2311
f2xm1()2312 void Assembler::f2xm1() {
2313 EnsureSpace ensure_space(this);
2314 emit(0xD9);
2315 emit(0xF0);
2316 }
2317
2318
fscale()2319 void Assembler::fscale() {
2320 EnsureSpace ensure_space(this);
2321 emit(0xD9);
2322 emit(0xFD);
2323 }
2324
2325
fninit()2326 void Assembler::fninit() {
2327 EnsureSpace ensure_space(this);
2328 emit(0xDB);
2329 emit(0xE3);
2330 }
2331
2332
fadd(int i)2333 void Assembler::fadd(int i) {
2334 EnsureSpace ensure_space(this);
2335 emit_farith(0xDC, 0xC0, i);
2336 }
2337
2338
fsub(int i)2339 void Assembler::fsub(int i) {
2340 EnsureSpace ensure_space(this);
2341 emit_farith(0xDC, 0xE8, i);
2342 }
2343
2344
fisub_s(const Operand & adr)2345 void Assembler::fisub_s(const Operand& adr) {
2346 EnsureSpace ensure_space(this);
2347 emit_optional_rex_32(adr);
2348 emit(0xDA);
2349 emit_operand(4, adr);
2350 }
2351
2352
fmul(int i)2353 void Assembler::fmul(int i) {
2354 EnsureSpace ensure_space(this);
2355 emit_farith(0xDC, 0xC8, i);
2356 }
2357
2358
fdiv(int i)2359 void Assembler::fdiv(int i) {
2360 EnsureSpace ensure_space(this);
2361 emit_farith(0xDC, 0xF8, i);
2362 }
2363
2364
faddp(int i)2365 void Assembler::faddp(int i) {
2366 EnsureSpace ensure_space(this);
2367 emit_farith(0xDE, 0xC0, i);
2368 }
2369
2370
fsubp(int i)2371 void Assembler::fsubp(int i) {
2372 EnsureSpace ensure_space(this);
2373 emit_farith(0xDE, 0xE8, i);
2374 }
2375
2376
fsubrp(int i)2377 void Assembler::fsubrp(int i) {
2378 EnsureSpace ensure_space(this);
2379 emit_farith(0xDE, 0xE0, i);
2380 }
2381
2382
fmulp(int i)2383 void Assembler::fmulp(int i) {
2384 EnsureSpace ensure_space(this);
2385 emit_farith(0xDE, 0xC8, i);
2386 }
2387
2388
fdivp(int i)2389 void Assembler::fdivp(int i) {
2390 EnsureSpace ensure_space(this);
2391 emit_farith(0xDE, 0xF8, i);
2392 }
2393
2394
fprem()2395 void Assembler::fprem() {
2396 EnsureSpace ensure_space(this);
2397 emit(0xD9);
2398 emit(0xF8);
2399 }
2400
2401
fprem1()2402 void Assembler::fprem1() {
2403 EnsureSpace ensure_space(this);
2404 emit(0xD9);
2405 emit(0xF5);
2406 }
2407
2408
fxch(int i)2409 void Assembler::fxch(int i) {
2410 EnsureSpace ensure_space(this);
2411 emit_farith(0xD9, 0xC8, i);
2412 }
2413
2414
fincstp()2415 void Assembler::fincstp() {
2416 EnsureSpace ensure_space(this);
2417 emit(0xD9);
2418 emit(0xF7);
2419 }
2420
2421
ffree(int i)2422 void Assembler::ffree(int i) {
2423 EnsureSpace ensure_space(this);
2424 emit_farith(0xDD, 0xC0, i);
2425 }
2426
2427
ftst()2428 void Assembler::ftst() {
2429 EnsureSpace ensure_space(this);
2430 emit(0xD9);
2431 emit(0xE4);
2432 }
2433
2434
fucomp(int i)2435 void Assembler::fucomp(int i) {
2436 EnsureSpace ensure_space(this);
2437 emit_farith(0xDD, 0xE8, i);
2438 }
2439
2440
fucompp()2441 void Assembler::fucompp() {
2442 EnsureSpace ensure_space(this);
2443 emit(0xDA);
2444 emit(0xE9);
2445 }
2446
2447
fucomi(int i)2448 void Assembler::fucomi(int i) {
2449 EnsureSpace ensure_space(this);
2450 emit(0xDB);
2451 emit(0xE8 + i);
2452 }
2453
2454
fucomip()2455 void Assembler::fucomip() {
2456 EnsureSpace ensure_space(this);
2457 emit(0xDF);
2458 emit(0xE9);
2459 }
2460
2461
fcompp()2462 void Assembler::fcompp() {
2463 EnsureSpace ensure_space(this);
2464 emit(0xDE);
2465 emit(0xD9);
2466 }
2467
2468
fnstsw_ax()2469 void Assembler::fnstsw_ax() {
2470 EnsureSpace ensure_space(this);
2471 emit(0xDF);
2472 emit(0xE0);
2473 }
2474
2475
fwait()2476 void Assembler::fwait() {
2477 EnsureSpace ensure_space(this);
2478 emit(0x9B);
2479 }
2480
2481
frndint()2482 void Assembler::frndint() {
2483 EnsureSpace ensure_space(this);
2484 emit(0xD9);
2485 emit(0xFC);
2486 }
2487
2488
fnclex()2489 void Assembler::fnclex() {
2490 EnsureSpace ensure_space(this);
2491 emit(0xDB);
2492 emit(0xE2);
2493 }
2494
2495
sahf()2496 void Assembler::sahf() {
2497 // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2498 // in 64-bit mode. Test CpuID.
2499 EnsureSpace ensure_space(this);
2500 emit(0x9E);
2501 }
2502
2503
emit_farith(int b1,int b2,int i)2504 void Assembler::emit_farith(int b1, int b2, int i) {
2505 ASSERT(is_uint8(b1) && is_uint8(b2)); // wrong opcode
2506 ASSERT(is_uint3(i)); // illegal stack offset
2507 emit(b1);
2508 emit(b2 + i);
2509 }
2510
2511 // SSE 2 operations.
2512
movd(XMMRegister dst,Register src)2513 void Assembler::movd(XMMRegister dst, Register src) {
2514 EnsureSpace ensure_space(this);
2515 emit(0x66);
2516 emit_optional_rex_32(dst, src);
2517 emit(0x0F);
2518 emit(0x6E);
2519 emit_sse_operand(dst, src);
2520 }
2521
2522
movd(Register dst,XMMRegister src)2523 void Assembler::movd(Register dst, XMMRegister src) {
2524 EnsureSpace ensure_space(this);
2525 emit(0x66);
2526 emit_optional_rex_32(src, dst);
2527 emit(0x0F);
2528 emit(0x7E);
2529 emit_sse_operand(src, dst);
2530 }
2531
2532
movq(XMMRegister dst,Register src)2533 void Assembler::movq(XMMRegister dst, Register src) {
2534 EnsureSpace ensure_space(this);
2535 emit(0x66);
2536 emit_rex_64(dst, src);
2537 emit(0x0F);
2538 emit(0x6E);
2539 emit_sse_operand(dst, src);
2540 }
2541
2542
movq(Register dst,XMMRegister src)2543 void Assembler::movq(Register dst, XMMRegister src) {
2544 EnsureSpace ensure_space(this);
2545 emit(0x66);
2546 emit_rex_64(src, dst);
2547 emit(0x0F);
2548 emit(0x7E);
2549 emit_sse_operand(src, dst);
2550 }
2551
2552
movq(XMMRegister dst,XMMRegister src)2553 void Assembler::movq(XMMRegister dst, XMMRegister src) {
2554 EnsureSpace ensure_space(this);
2555 if (dst.low_bits() == 4) {
2556 // Avoid unnecessary SIB byte.
2557 emit(0xf3);
2558 emit_optional_rex_32(dst, src);
2559 emit(0x0F);
2560 emit(0x7e);
2561 emit_sse_operand(dst, src);
2562 } else {
2563 emit(0x66);
2564 emit_optional_rex_32(src, dst);
2565 emit(0x0F);
2566 emit(0xD6);
2567 emit_sse_operand(src, dst);
2568 }
2569 }
2570
movdqa(const Operand & dst,XMMRegister src)2571 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2572 EnsureSpace ensure_space(this);
2573 emit(0x66);
2574 emit_rex_64(src, dst);
2575 emit(0x0F);
2576 emit(0x7F);
2577 emit_sse_operand(src, dst);
2578 }
2579
2580
movdqa(XMMRegister dst,const Operand & src)2581 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2582 EnsureSpace ensure_space(this);
2583 emit(0x66);
2584 emit_rex_64(dst, src);
2585 emit(0x0F);
2586 emit(0x6F);
2587 emit_sse_operand(dst, src);
2588 }
2589
2590
extractps(Register dst,XMMRegister src,byte imm8)2591 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2592 ASSERT(CpuFeatures::IsSupported(SSE4_1));
2593 ASSERT(is_uint8(imm8));
2594 EnsureSpace ensure_space(this);
2595 emit(0x66);
2596 emit_optional_rex_32(dst, src);
2597 emit(0x0F);
2598 emit(0x3A);
2599 emit(0x17);
2600 emit_sse_operand(dst, src);
2601 emit(imm8);
2602 }
2603
2604
movsd(const Operand & dst,XMMRegister src)2605 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2606 EnsureSpace ensure_space(this);
2607 emit(0xF2); // double
2608 emit_optional_rex_32(src, dst);
2609 emit(0x0F);
2610 emit(0x11); // store
2611 emit_sse_operand(src, dst);
2612 }
2613
2614
movsd(XMMRegister dst,XMMRegister src)2615 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2616 EnsureSpace ensure_space(this);
2617 emit(0xF2); // double
2618 emit_optional_rex_32(dst, src);
2619 emit(0x0F);
2620 emit(0x10); // load
2621 emit_sse_operand(dst, src);
2622 }
2623
2624
movsd(XMMRegister dst,const Operand & src)2625 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2626 EnsureSpace ensure_space(this);
2627 emit(0xF2); // double
2628 emit_optional_rex_32(dst, src);
2629 emit(0x0F);
2630 emit(0x10); // load
2631 emit_sse_operand(dst, src);
2632 }
2633
2634
movaps(XMMRegister dst,XMMRegister src)2635 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2636 EnsureSpace ensure_space(this);
2637 if (src.low_bits() == 4) {
2638 // Try to avoid an unnecessary SIB byte.
2639 emit_optional_rex_32(src, dst);
2640 emit(0x0F);
2641 emit(0x29);
2642 emit_sse_operand(src, dst);
2643 } else {
2644 emit_optional_rex_32(dst, src);
2645 emit(0x0F);
2646 emit(0x28);
2647 emit_sse_operand(dst, src);
2648 }
2649 }
2650
2651
movapd(XMMRegister dst,XMMRegister src)2652 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
2653 EnsureSpace ensure_space(this);
2654 if (src.low_bits() == 4) {
2655 // Try to avoid an unnecessary SIB byte.
2656 emit(0x66);
2657 emit_optional_rex_32(src, dst);
2658 emit(0x0F);
2659 emit(0x29);
2660 emit_sse_operand(src, dst);
2661 } else {
2662 emit(0x66);
2663 emit_optional_rex_32(dst, src);
2664 emit(0x0F);
2665 emit(0x28);
2666 emit_sse_operand(dst, src);
2667 }
2668 }
2669
2670
movss(XMMRegister dst,const Operand & src)2671 void Assembler::movss(XMMRegister dst, const Operand& src) {
2672 EnsureSpace ensure_space(this);
2673 emit(0xF3); // single
2674 emit_optional_rex_32(dst, src);
2675 emit(0x0F);
2676 emit(0x10); // load
2677 emit_sse_operand(dst, src);
2678 }
2679
2680
movss(const Operand & src,XMMRegister dst)2681 void Assembler::movss(const Operand& src, XMMRegister dst) {
2682 EnsureSpace ensure_space(this);
2683 emit(0xF3); // single
2684 emit_optional_rex_32(dst, src);
2685 emit(0x0F);
2686 emit(0x11); // store
2687 emit_sse_operand(dst, src);
2688 }
2689
2690
cvttss2si(Register dst,const Operand & src)2691 void Assembler::cvttss2si(Register dst, const Operand& src) {
2692 EnsureSpace ensure_space(this);
2693 emit(0xF3);
2694 emit_optional_rex_32(dst, src);
2695 emit(0x0F);
2696 emit(0x2C);
2697 emit_operand(dst, src);
2698 }
2699
2700
cvttss2si(Register dst,XMMRegister src)2701 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2702 EnsureSpace ensure_space(this);
2703 emit(0xF3);
2704 emit_optional_rex_32(dst, src);
2705 emit(0x0F);
2706 emit(0x2C);
2707 emit_sse_operand(dst, src);
2708 }
2709
2710
cvttsd2si(Register dst,const Operand & src)2711 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2712 EnsureSpace ensure_space(this);
2713 emit(0xF2);
2714 emit_optional_rex_32(dst, src);
2715 emit(0x0F);
2716 emit(0x2C);
2717 emit_operand(dst, src);
2718 }
2719
2720
cvttsd2si(Register dst,XMMRegister src)2721 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2722 EnsureSpace ensure_space(this);
2723 emit(0xF2);
2724 emit_optional_rex_32(dst, src);
2725 emit(0x0F);
2726 emit(0x2C);
2727 emit_sse_operand(dst, src);
2728 }
2729
2730
cvttsd2siq(Register dst,XMMRegister src)2731 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2732 EnsureSpace ensure_space(this);
2733 emit(0xF2);
2734 emit_rex_64(dst, src);
2735 emit(0x0F);
2736 emit(0x2C);
2737 emit_sse_operand(dst, src);
2738 }
2739
2740
cvtlsi2sd(XMMRegister dst,const Operand & src)2741 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2742 EnsureSpace ensure_space(this);
2743 emit(0xF2);
2744 emit_optional_rex_32(dst, src);
2745 emit(0x0F);
2746 emit(0x2A);
2747 emit_sse_operand(dst, src);
2748 }
2749
2750
cvtlsi2sd(XMMRegister dst,Register src)2751 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2752 EnsureSpace ensure_space(this);
2753 emit(0xF2);
2754 emit_optional_rex_32(dst, src);
2755 emit(0x0F);
2756 emit(0x2A);
2757 emit_sse_operand(dst, src);
2758 }
2759
2760
cvtlsi2ss(XMMRegister dst,Register src)2761 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2762 EnsureSpace ensure_space(this);
2763 emit(0xF3);
2764 emit_optional_rex_32(dst, src);
2765 emit(0x0F);
2766 emit(0x2A);
2767 emit_sse_operand(dst, src);
2768 }
2769
2770
cvtqsi2sd(XMMRegister dst,Register src)2771 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2772 EnsureSpace ensure_space(this);
2773 emit(0xF2);
2774 emit_rex_64(dst, src);
2775 emit(0x0F);
2776 emit(0x2A);
2777 emit_sse_operand(dst, src);
2778 }
2779
2780
cvtss2sd(XMMRegister dst,XMMRegister src)2781 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2782 EnsureSpace ensure_space(this);
2783 emit(0xF3);
2784 emit_optional_rex_32(dst, src);
2785 emit(0x0F);
2786 emit(0x5A);
2787 emit_sse_operand(dst, src);
2788 }
2789
2790
cvtss2sd(XMMRegister dst,const Operand & src)2791 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2792 EnsureSpace ensure_space(this);
2793 emit(0xF3);
2794 emit_optional_rex_32(dst, src);
2795 emit(0x0F);
2796 emit(0x5A);
2797 emit_sse_operand(dst, src);
2798 }
2799
2800
cvtsd2ss(XMMRegister dst,XMMRegister src)2801 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2802 EnsureSpace ensure_space(this);
2803 emit(0xF2);
2804 emit_optional_rex_32(dst, src);
2805 emit(0x0F);
2806 emit(0x5A);
2807 emit_sse_operand(dst, src);
2808 }
2809
2810
cvtsd2si(Register dst,XMMRegister src)2811 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2812 EnsureSpace ensure_space(this);
2813 emit(0xF2);
2814 emit_optional_rex_32(dst, src);
2815 emit(0x0F);
2816 emit(0x2D);
2817 emit_sse_operand(dst, src);
2818 }
2819
2820
cvtsd2siq(Register dst,XMMRegister src)2821 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2822 EnsureSpace ensure_space(this);
2823 emit(0xF2);
2824 emit_rex_64(dst, src);
2825 emit(0x0F);
2826 emit(0x2D);
2827 emit_sse_operand(dst, src);
2828 }
2829
2830
addsd(XMMRegister dst,XMMRegister src)2831 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2832 EnsureSpace ensure_space(this);
2833 emit(0xF2);
2834 emit_optional_rex_32(dst, src);
2835 emit(0x0F);
2836 emit(0x58);
2837 emit_sse_operand(dst, src);
2838 }
2839
2840
mulsd(XMMRegister dst,XMMRegister src)2841 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2842 EnsureSpace ensure_space(this);
2843 emit(0xF2);
2844 emit_optional_rex_32(dst, src);
2845 emit(0x0F);
2846 emit(0x59);
2847 emit_sse_operand(dst, src);
2848 }
2849
2850
subsd(XMMRegister dst,XMMRegister src)2851 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2852 EnsureSpace ensure_space(this);
2853 emit(0xF2);
2854 emit_optional_rex_32(dst, src);
2855 emit(0x0F);
2856 emit(0x5C);
2857 emit_sse_operand(dst, src);
2858 }
2859
2860
divsd(XMMRegister dst,XMMRegister src)2861 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2862 EnsureSpace ensure_space(this);
2863 emit(0xF2);
2864 emit_optional_rex_32(dst, src);
2865 emit(0x0F);
2866 emit(0x5E);
2867 emit_sse_operand(dst, src);
2868 }
2869
2870
andpd(XMMRegister dst,XMMRegister src)2871 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2872 EnsureSpace ensure_space(this);
2873 emit(0x66);
2874 emit_optional_rex_32(dst, src);
2875 emit(0x0F);
2876 emit(0x54);
2877 emit_sse_operand(dst, src);
2878 }
2879
2880
orpd(XMMRegister dst,XMMRegister src)2881 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2882 EnsureSpace ensure_space(this);
2883 emit(0x66);
2884 emit_optional_rex_32(dst, src);
2885 emit(0x0F);
2886 emit(0x56);
2887 emit_sse_operand(dst, src);
2888 }
2889
2890
xorpd(XMMRegister dst,XMMRegister src)2891 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2892 EnsureSpace ensure_space(this);
2893 emit(0x66);
2894 emit_optional_rex_32(dst, src);
2895 emit(0x0F);
2896 emit(0x57);
2897 emit_sse_operand(dst, src);
2898 }
2899
2900
xorps(XMMRegister dst,XMMRegister src)2901 void Assembler::xorps(XMMRegister dst, XMMRegister src) {
2902 EnsureSpace ensure_space(this);
2903 emit_optional_rex_32(dst, src);
2904 emit(0x0F);
2905 emit(0x57);
2906 emit_sse_operand(dst, src);
2907 }
2908
2909
sqrtsd(XMMRegister dst,XMMRegister src)2910 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2911 EnsureSpace ensure_space(this);
2912 emit(0xF2);
2913 emit_optional_rex_32(dst, src);
2914 emit(0x0F);
2915 emit(0x51);
2916 emit_sse_operand(dst, src);
2917 }
2918
2919
ucomisd(XMMRegister dst,XMMRegister src)2920 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2921 EnsureSpace ensure_space(this);
2922 emit(0x66);
2923 emit_optional_rex_32(dst, src);
2924 emit(0x0f);
2925 emit(0x2e);
2926 emit_sse_operand(dst, src);
2927 }
2928
2929
ucomisd(XMMRegister dst,const Operand & src)2930 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2931 EnsureSpace ensure_space(this);
2932 emit(0x66);
2933 emit_optional_rex_32(dst, src);
2934 emit(0x0f);
2935 emit(0x2e);
2936 emit_sse_operand(dst, src);
2937 }
2938
2939
roundsd(XMMRegister dst,XMMRegister src,Assembler::RoundingMode mode)2940 void Assembler::roundsd(XMMRegister dst, XMMRegister src,
2941 Assembler::RoundingMode mode) {
2942 ASSERT(CpuFeatures::IsEnabled(SSE4_1));
2943 EnsureSpace ensure_space(this);
2944 emit(0x66);
2945 emit_optional_rex_32(dst, src);
2946 emit(0x0f);
2947 emit(0x3a);
2948 emit(0x0b);
2949 emit_sse_operand(dst, src);
2950 // Mask precision exeption.
2951 emit(static_cast<byte>(mode) | 0x8);
2952 }
2953
2954
movmskpd(Register dst,XMMRegister src)2955 void Assembler::movmskpd(Register dst, XMMRegister src) {
2956 EnsureSpace ensure_space(this);
2957 emit(0x66);
2958 emit_optional_rex_32(dst, src);
2959 emit(0x0f);
2960 emit(0x50);
2961 emit_sse_operand(dst, src);
2962 }
2963
2964
emit_sse_operand(XMMRegister reg,const Operand & adr)2965 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2966 Register ireg = { reg.code() };
2967 emit_operand(ireg, adr);
2968 }
2969
2970
emit_sse_operand(XMMRegister dst,XMMRegister src)2971 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2972 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2973 }
2974
emit_sse_operand(XMMRegister dst,Register src)2975 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2976 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2977 }
2978
emit_sse_operand(Register dst,XMMRegister src)2979 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2980 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2981 }
2982
2983
db(uint8_t data)2984 void Assembler::db(uint8_t data) {
2985 EnsureSpace ensure_space(this);
2986 emit(data);
2987 }
2988
2989
dd(uint32_t data)2990 void Assembler::dd(uint32_t data) {
2991 EnsureSpace ensure_space(this);
2992 emitl(data);
2993 }
2994
2995
2996 // Relocation information implementations.
2997
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2998 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2999 ASSERT(rmode != RelocInfo::NONE);
3000 // Don't record external references unless the heap will be serialized.
3001 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
3002 #ifdef DEBUG
3003 if (!Serializer::enabled()) {
3004 Serializer::TooLateToEnableNow();
3005 }
3006 #endif
3007 if (!Serializer::enabled() && !emit_debug_code()) {
3008 return;
3009 }
3010 }
3011 RelocInfo rinfo(pc_, rmode, data, NULL);
3012 reloc_info_writer.Write(&rinfo);
3013 }
3014
RecordJSReturn()3015 void Assembler::RecordJSReturn() {
3016 positions_recorder()->WriteRecordedPositions();
3017 EnsureSpace ensure_space(this);
3018 RecordRelocInfo(RelocInfo::JS_RETURN);
3019 }
3020
3021
RecordDebugBreakSlot()3022 void Assembler::RecordDebugBreakSlot() {
3023 positions_recorder()->WriteRecordedPositions();
3024 EnsureSpace ensure_space(this);
3025 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3026 }
3027
3028
RecordComment(const char * msg,bool force)3029 void Assembler::RecordComment(const char* msg, bool force) {
3030 if (FLAG_code_comments || force) {
3031 EnsureSpace ensure_space(this);
3032 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
3033 }
3034 }
3035
3036
3037 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
3038 1 << RelocInfo::INTERNAL_REFERENCE;
3039
3040
IsCodedSpecially()3041 bool RelocInfo::IsCodedSpecially() {
3042 // The deserializer needs to know whether a pointer is specially coded. Being
3043 // specially coded on x64 means that it is a relative 32 bit address, as used
3044 // by branch instructions.
3045 return (1 << rmode_) & kApplyMask;
3046 }
3047
3048 } } // namespace v8::internal
3049
3050 #endif // V8_TARGET_ARCH_X64
3051