• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 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(!initialized_);
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   // Setup 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   // Setup 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   while (delta >= 9) {
430     nop(9);
431     delta -= 9;
432   }
433   if (delta > 0) {
434     nop(delta);
435   }
436 }
437 
438 
CodeTargetAlign()439 void Assembler::CodeTargetAlign() {
440   Align(16);  // Preferred alignment of jump targets on x64.
441 }
442 
443 
bind_to(Label * L,int pos)444 void Assembler::bind_to(Label* L, int pos) {
445   ASSERT(!L->is_bound());  // Label may only be bound once.
446   ASSERT(0 <= pos && pos <= pc_offset());  // Position must be valid.
447   if (L->is_linked()) {
448     int current = L->pos();
449     int next = long_at(current);
450     while (next != current) {
451       // Relative address, relative to point after address.
452       int imm32 = pos - (current + sizeof(int32_t));
453       long_at_put(current, imm32);
454       current = next;
455       next = long_at(next);
456     }
457     // Fix up last fixup on linked list.
458     int last_imm32 = pos - (current + sizeof(int32_t));
459     long_at_put(current, last_imm32);
460   }
461   L->bind_to(pos);
462 }
463 
464 
bind(Label * L)465 void Assembler::bind(Label* L) {
466   bind_to(L, pc_offset());
467 }
468 
469 
bind(NearLabel * L)470 void Assembler::bind(NearLabel* L) {
471   ASSERT(!L->is_bound());
472   while (L->unresolved_branches_ > 0) {
473     int branch_pos = L->unresolved_positions_[L->unresolved_branches_ - 1];
474     int disp = pc_offset() - branch_pos;
475     ASSERT(is_int8(disp));
476     set_byte_at(branch_pos - sizeof(int8_t), disp);
477     L->unresolved_branches_--;
478   }
479   L->bind_to(pc_offset());
480 }
481 
482 
GrowBuffer()483 void Assembler::GrowBuffer() {
484   ASSERT(buffer_overflow());
485   if (!own_buffer_) FATAL("external code buffer is too small");
486 
487   // Compute new buffer size.
488   CodeDesc desc;  // the new buffer
489   if (buffer_size_ < 4*KB) {
490     desc.buffer_size = 4*KB;
491   } else {
492     desc.buffer_size = 2*buffer_size_;
493   }
494   // Some internal data structures overflow for very large buffers,
495   // they must ensure that kMaximalBufferSize is not too large.
496   if ((desc.buffer_size > kMaximalBufferSize) ||
497       (desc.buffer_size > HEAP->MaxOldGenerationSize())) {
498     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
499   }
500 
501   // Setup new buffer.
502   desc.buffer = NewArray<byte>(desc.buffer_size);
503   desc.instr_size = pc_offset();
504   desc.reloc_size =
505       static_cast<int>((buffer_ + buffer_size_) - (reloc_info_writer.pos()));
506 
507   // Clear the buffer in debug mode. Use 'int3' instructions to make
508   // sure to get into problems if we ever run uninitialized code.
509 #ifdef DEBUG
510   memset(desc.buffer, 0xCC, desc.buffer_size);
511 #endif
512 
513   // Copy the data.
514   intptr_t pc_delta = desc.buffer - buffer_;
515   intptr_t rc_delta = (desc.buffer + desc.buffer_size) -
516       (buffer_ + buffer_size_);
517   memmove(desc.buffer, buffer_, desc.instr_size);
518   memmove(rc_delta + reloc_info_writer.pos(),
519           reloc_info_writer.pos(), desc.reloc_size);
520 
521   // Switch buffers.
522   if (isolate() != NULL &&
523       isolate()->assembler_spare_buffer() == NULL &&
524       buffer_size_ == kMinimalBufferSize) {
525     isolate()->set_assembler_spare_buffer(buffer_);
526   } else {
527     DeleteArray(buffer_);
528   }
529   buffer_ = desc.buffer;
530   buffer_size_ = desc.buffer_size;
531   pc_ += pc_delta;
532   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
533                                reloc_info_writer.last_pc() + pc_delta);
534 
535   // Relocate runtime entries.
536   for (RelocIterator it(desc); !it.done(); it.next()) {
537     RelocInfo::Mode rmode = it.rinfo()->rmode();
538     if (rmode == RelocInfo::INTERNAL_REFERENCE) {
539       intptr_t* p = reinterpret_cast<intptr_t*>(it.rinfo()->pc());
540       if (*p != 0) {  // 0 means uninitialized.
541         *p += pc_delta;
542       }
543     }
544   }
545 
546   ASSERT(!buffer_overflow());
547 }
548 
549 
emit_operand(int code,const Operand & adr)550 void Assembler::emit_operand(int code, const Operand& adr) {
551   ASSERT(is_uint3(code));
552   const unsigned length = adr.len_;
553   ASSERT(length > 0);
554 
555   // Emit updated ModR/M byte containing the given register.
556   ASSERT((adr.buf_[0] & 0x38) == 0);
557   pc_[0] = adr.buf_[0] | code << 3;
558 
559   // Emit the rest of the encoded operand.
560   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
561   pc_ += length;
562 }
563 
564 
565 // Assembler Instruction implementations.
566 
arithmetic_op(byte opcode,Register reg,const Operand & op)567 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
568   EnsureSpace ensure_space(this);
569   emit_rex_64(reg, op);
570   emit(opcode);
571   emit_operand(reg, op);
572 }
573 
574 
arithmetic_op(byte opcode,Register reg,Register rm_reg)575 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
576   EnsureSpace ensure_space(this);
577   ASSERT((opcode & 0xC6) == 2);
578   if (rm_reg.low_bits() == 4)  {  // Forces SIB byte.
579     // Swap reg and rm_reg and change opcode operand order.
580     emit_rex_64(rm_reg, reg);
581     emit(opcode ^ 0x02);
582     emit_modrm(rm_reg, reg);
583   } else {
584     emit_rex_64(reg, rm_reg);
585     emit(opcode);
586     emit_modrm(reg, rm_reg);
587   }
588 }
589 
590 
arithmetic_op_16(byte opcode,Register reg,Register rm_reg)591 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
592   EnsureSpace ensure_space(this);
593   ASSERT((opcode & 0xC6) == 2);
594   if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
595     // Swap reg and rm_reg and change opcode operand order.
596     emit(0x66);
597     emit_optional_rex_32(rm_reg, reg);
598     emit(opcode ^ 0x02);
599     emit_modrm(rm_reg, reg);
600   } else {
601     emit(0x66);
602     emit_optional_rex_32(reg, rm_reg);
603     emit(opcode);
604     emit_modrm(reg, rm_reg);
605   }
606 }
607 
608 
arithmetic_op_16(byte opcode,Register reg,const Operand & rm_reg)609 void Assembler::arithmetic_op_16(byte opcode,
610                                  Register reg,
611                                  const Operand& rm_reg) {
612   EnsureSpace ensure_space(this);
613   emit(0x66);
614   emit_optional_rex_32(reg, rm_reg);
615   emit(opcode);
616   emit_operand(reg, rm_reg);
617 }
618 
619 
arithmetic_op_32(byte opcode,Register reg,Register rm_reg)620 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
621   EnsureSpace ensure_space(this);
622   ASSERT((opcode & 0xC6) == 2);
623   if (rm_reg.low_bits() == 4) {  // Forces SIB byte.
624     // Swap reg and rm_reg and change opcode operand order.
625     emit_optional_rex_32(rm_reg, reg);
626     emit(opcode ^ 0x02);  // E.g. 0x03 -> 0x01 for ADD.
627     emit_modrm(rm_reg, reg);
628   } else {
629     emit_optional_rex_32(reg, rm_reg);
630     emit(opcode);
631     emit_modrm(reg, rm_reg);
632   }
633 }
634 
635 
arithmetic_op_32(byte opcode,Register reg,const Operand & rm_reg)636 void Assembler::arithmetic_op_32(byte opcode,
637                                  Register reg,
638                                  const Operand& rm_reg) {
639   EnsureSpace ensure_space(this);
640   emit_optional_rex_32(reg, rm_reg);
641   emit(opcode);
642   emit_operand(reg, rm_reg);
643 }
644 
645 
immediate_arithmetic_op(byte subcode,Register dst,Immediate src)646 void Assembler::immediate_arithmetic_op(byte subcode,
647                                         Register dst,
648                                         Immediate src) {
649   EnsureSpace ensure_space(this);
650   emit_rex_64(dst);
651   if (is_int8(src.value_)) {
652     emit(0x83);
653     emit_modrm(subcode, dst);
654     emit(src.value_);
655   } else if (dst.is(rax)) {
656     emit(0x05 | (subcode << 3));
657     emitl(src.value_);
658   } else {
659     emit(0x81);
660     emit_modrm(subcode, dst);
661     emitl(src.value_);
662   }
663 }
664 
immediate_arithmetic_op(byte subcode,const Operand & dst,Immediate src)665 void Assembler::immediate_arithmetic_op(byte subcode,
666                                         const Operand& dst,
667                                         Immediate src) {
668   EnsureSpace ensure_space(this);
669   emit_rex_64(dst);
670   if (is_int8(src.value_)) {
671     emit(0x83);
672     emit_operand(subcode, dst);
673     emit(src.value_);
674   } else {
675     emit(0x81);
676     emit_operand(subcode, dst);
677     emitl(src.value_);
678   }
679 }
680 
681 
immediate_arithmetic_op_16(byte subcode,Register dst,Immediate src)682 void Assembler::immediate_arithmetic_op_16(byte subcode,
683                                            Register dst,
684                                            Immediate src) {
685   EnsureSpace ensure_space(this);
686   emit(0x66);  // Operand size override prefix.
687   emit_optional_rex_32(dst);
688   if (is_int8(src.value_)) {
689     emit(0x83);
690     emit_modrm(subcode, dst);
691     emit(src.value_);
692   } else if (dst.is(rax)) {
693     emit(0x05 | (subcode << 3));
694     emitw(src.value_);
695   } else {
696     emit(0x81);
697     emit_modrm(subcode, dst);
698     emitw(src.value_);
699   }
700 }
701 
702 
immediate_arithmetic_op_16(byte subcode,const Operand & dst,Immediate src)703 void Assembler::immediate_arithmetic_op_16(byte subcode,
704                                            const Operand& dst,
705                                            Immediate src) {
706   EnsureSpace ensure_space(this);
707   emit(0x66);  // Operand size override prefix.
708   emit_optional_rex_32(dst);
709   if (is_int8(src.value_)) {
710     emit(0x83);
711     emit_operand(subcode, dst);
712     emit(src.value_);
713   } else {
714     emit(0x81);
715     emit_operand(subcode, dst);
716     emitw(src.value_);
717   }
718 }
719 
720 
immediate_arithmetic_op_32(byte subcode,Register dst,Immediate src)721 void Assembler::immediate_arithmetic_op_32(byte subcode,
722                                            Register dst,
723                                            Immediate src) {
724   EnsureSpace ensure_space(this);
725   emit_optional_rex_32(dst);
726   if (is_int8(src.value_)) {
727     emit(0x83);
728     emit_modrm(subcode, dst);
729     emit(src.value_);
730   } else if (dst.is(rax)) {
731     emit(0x05 | (subcode << 3));
732     emitl(src.value_);
733   } else {
734     emit(0x81);
735     emit_modrm(subcode, dst);
736     emitl(src.value_);
737   }
738 }
739 
740 
immediate_arithmetic_op_32(byte subcode,const Operand & dst,Immediate src)741 void Assembler::immediate_arithmetic_op_32(byte subcode,
742                                            const Operand& dst,
743                                            Immediate src) {
744   EnsureSpace ensure_space(this);
745   emit_optional_rex_32(dst);
746   if (is_int8(src.value_)) {
747     emit(0x83);
748     emit_operand(subcode, dst);
749     emit(src.value_);
750   } else {
751     emit(0x81);
752     emit_operand(subcode, dst);
753     emitl(src.value_);
754   }
755 }
756 
757 
immediate_arithmetic_op_8(byte subcode,const Operand & dst,Immediate src)758 void Assembler::immediate_arithmetic_op_8(byte subcode,
759                                           const Operand& dst,
760                                           Immediate src) {
761   EnsureSpace ensure_space(this);
762   emit_optional_rex_32(dst);
763   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
764   emit(0x80);
765   emit_operand(subcode, dst);
766   emit(src.value_);
767 }
768 
769 
immediate_arithmetic_op_8(byte subcode,Register dst,Immediate src)770 void Assembler::immediate_arithmetic_op_8(byte subcode,
771                                           Register dst,
772                                           Immediate src) {
773   EnsureSpace ensure_space(this);
774   if (dst.code() > 3) {
775     // Use 64-bit mode byte registers.
776     emit_rex_64(dst);
777   }
778   ASSERT(is_int8(src.value_) || is_uint8(src.value_));
779   emit(0x80);
780   emit_modrm(subcode, dst);
781   emit(src.value_);
782 }
783 
784 
shift(Register dst,Immediate shift_amount,int subcode)785 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
786   EnsureSpace ensure_space(this);
787   ASSERT(is_uint6(shift_amount.value_));  // illegal shift count
788   if (shift_amount.value_ == 1) {
789     emit_rex_64(dst);
790     emit(0xD1);
791     emit_modrm(subcode, dst);
792   } else {
793     emit_rex_64(dst);
794     emit(0xC1);
795     emit_modrm(subcode, dst);
796     emit(shift_amount.value_);
797   }
798 }
799 
800 
shift(Register dst,int subcode)801 void Assembler::shift(Register dst, int subcode) {
802   EnsureSpace ensure_space(this);
803   emit_rex_64(dst);
804   emit(0xD3);
805   emit_modrm(subcode, dst);
806 }
807 
808 
shift_32(Register dst,int subcode)809 void Assembler::shift_32(Register dst, int subcode) {
810   EnsureSpace ensure_space(this);
811   emit_optional_rex_32(dst);
812   emit(0xD3);
813   emit_modrm(subcode, dst);
814 }
815 
816 
shift_32(Register dst,Immediate shift_amount,int subcode)817 void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
818   EnsureSpace ensure_space(this);
819   ASSERT(is_uint5(shift_amount.value_));  // illegal shift count
820   if (shift_amount.value_ == 1) {
821     emit_optional_rex_32(dst);
822     emit(0xD1);
823     emit_modrm(subcode, dst);
824   } else {
825     emit_optional_rex_32(dst);
826     emit(0xC1);
827     emit_modrm(subcode, dst);
828     emit(shift_amount.value_);
829   }
830 }
831 
832 
bt(const Operand & dst,Register src)833 void Assembler::bt(const Operand& dst, Register src) {
834   EnsureSpace ensure_space(this);
835   emit_rex_64(src, dst);
836   emit(0x0F);
837   emit(0xA3);
838   emit_operand(src, dst);
839 }
840 
841 
bts(const Operand & dst,Register src)842 void Assembler::bts(const Operand& dst, Register src) {
843   EnsureSpace ensure_space(this);
844   emit_rex_64(src, dst);
845   emit(0x0F);
846   emit(0xAB);
847   emit_operand(src, dst);
848 }
849 
850 
call(Label * L)851 void Assembler::call(Label* L) {
852   positions_recorder()->WriteRecordedPositions();
853   EnsureSpace ensure_space(this);
854   // 1110 1000 #32-bit disp.
855   emit(0xE8);
856   if (L->is_bound()) {
857     int offset = L->pos() - pc_offset() - sizeof(int32_t);
858     ASSERT(offset <= 0);
859     emitl(offset);
860   } else if (L->is_linked()) {
861     emitl(L->pos());
862     L->link_to(pc_offset() - sizeof(int32_t));
863   } else {
864     ASSERT(L->is_unused());
865     int32_t current = pc_offset();
866     emitl(current);
867     L->link_to(current);
868   }
869 }
870 
871 
call(Handle<Code> target,RelocInfo::Mode rmode)872 void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
873   positions_recorder()->WriteRecordedPositions();
874   EnsureSpace ensure_space(this);
875   // 1110 1000 #32-bit disp.
876   emit(0xE8);
877   emit_code_target(target, rmode);
878 }
879 
880 
call(Register adr)881 void Assembler::call(Register adr) {
882   positions_recorder()->WriteRecordedPositions();
883   EnsureSpace ensure_space(this);
884   // Opcode: FF /2 r64.
885   emit_optional_rex_32(adr);
886   emit(0xFF);
887   emit_modrm(0x2, adr);
888 }
889 
890 
call(const Operand & op)891 void Assembler::call(const Operand& op) {
892   positions_recorder()->WriteRecordedPositions();
893   EnsureSpace ensure_space(this);
894   // Opcode: FF /2 m64.
895   emit_optional_rex_32(op);
896   emit(0xFF);
897   emit_operand(0x2, op);
898 }
899 
900 
901 // Calls directly to the given address using a relative offset.
902 // Should only ever be used in Code objects for calls within the
903 // same Code object. Should not be used when generating new code (use labels),
904 // but only when patching existing code.
call(Address target)905 void Assembler::call(Address target) {
906   positions_recorder()->WriteRecordedPositions();
907   EnsureSpace ensure_space(this);
908   // 1110 1000 #32-bit disp.
909   emit(0xE8);
910   Address source = pc_ + 4;
911   intptr_t displacement = target - source;
912   ASSERT(is_int32(displacement));
913   emitl(static_cast<int32_t>(displacement));
914 }
915 
916 
clc()917 void Assembler::clc() {
918   EnsureSpace ensure_space(this);
919   emit(0xF8);
920 }
921 
cld()922 void Assembler::cld() {
923   EnsureSpace ensure_space(this);
924   emit(0xFC);
925 }
926 
cdq()927 void Assembler::cdq() {
928   EnsureSpace ensure_space(this);
929   emit(0x99);
930 }
931 
932 
cmovq(Condition cc,Register dst,Register src)933 void Assembler::cmovq(Condition cc, Register dst, Register src) {
934   if (cc == always) {
935     movq(dst, src);
936   } else if (cc == never) {
937     return;
938   }
939   // No need to check CpuInfo for CMOV support, it's a required part of the
940   // 64-bit architecture.
941   ASSERT(cc >= 0);  // Use mov for unconditional moves.
942   EnsureSpace ensure_space(this);
943   // Opcode: REX.W 0f 40 + cc /r.
944   emit_rex_64(dst, src);
945   emit(0x0f);
946   emit(0x40 + cc);
947   emit_modrm(dst, src);
948 }
949 
950 
cmovq(Condition cc,Register dst,const Operand & src)951 void Assembler::cmovq(Condition cc, Register dst, const Operand& src) {
952   if (cc == always) {
953     movq(dst, src);
954   } else if (cc == never) {
955     return;
956   }
957   ASSERT(cc >= 0);
958   EnsureSpace ensure_space(this);
959   // Opcode: REX.W 0f 40 + cc /r.
960   emit_rex_64(dst, src);
961   emit(0x0f);
962   emit(0x40 + cc);
963   emit_operand(dst, src);
964 }
965 
966 
cmovl(Condition cc,Register dst,Register src)967 void Assembler::cmovl(Condition cc, Register dst, Register src) {
968   if (cc == always) {
969     movl(dst, src);
970   } else if (cc == never) {
971     return;
972   }
973   ASSERT(cc >= 0);
974   EnsureSpace ensure_space(this);
975   // Opcode: 0f 40 + cc /r.
976   emit_optional_rex_32(dst, src);
977   emit(0x0f);
978   emit(0x40 + cc);
979   emit_modrm(dst, src);
980 }
981 
982 
cmovl(Condition cc,Register dst,const Operand & src)983 void Assembler::cmovl(Condition cc, Register dst, const Operand& src) {
984   if (cc == always) {
985     movl(dst, src);
986   } else if (cc == never) {
987     return;
988   }
989   ASSERT(cc >= 0);
990   EnsureSpace ensure_space(this);
991   // Opcode: 0f 40 + cc /r.
992   emit_optional_rex_32(dst, src);
993   emit(0x0f);
994   emit(0x40 + cc);
995   emit_operand(dst, src);
996 }
997 
998 
cmpb_al(Immediate imm8)999 void Assembler::cmpb_al(Immediate imm8) {
1000   ASSERT(is_int8(imm8.value_) || is_uint8(imm8.value_));
1001   EnsureSpace ensure_space(this);
1002   emit(0x3c);
1003   emit(imm8.value_);
1004 }
1005 
1006 
cpuid()1007 void Assembler::cpuid() {
1008   ASSERT(CpuFeatures::IsEnabled(CPUID));
1009   EnsureSpace ensure_space(this);
1010   emit(0x0F);
1011   emit(0xA2);
1012 }
1013 
1014 
cqo()1015 void Assembler::cqo() {
1016   EnsureSpace ensure_space(this);
1017   emit_rex_64();
1018   emit(0x99);
1019 }
1020 
1021 
decq(Register dst)1022 void Assembler::decq(Register dst) {
1023   EnsureSpace ensure_space(this);
1024   emit_rex_64(dst);
1025   emit(0xFF);
1026   emit_modrm(0x1, dst);
1027 }
1028 
1029 
decq(const Operand & dst)1030 void Assembler::decq(const Operand& dst) {
1031   EnsureSpace ensure_space(this);
1032   emit_rex_64(dst);
1033   emit(0xFF);
1034   emit_operand(1, dst);
1035 }
1036 
1037 
decl(Register dst)1038 void Assembler::decl(Register dst) {
1039   EnsureSpace ensure_space(this);
1040   emit_optional_rex_32(dst);
1041   emit(0xFF);
1042   emit_modrm(0x1, dst);
1043 }
1044 
1045 
decl(const Operand & dst)1046 void Assembler::decl(const Operand& dst) {
1047   EnsureSpace ensure_space(this);
1048   emit_optional_rex_32(dst);
1049   emit(0xFF);
1050   emit_operand(1, dst);
1051 }
1052 
1053 
decb(Register dst)1054 void Assembler::decb(Register dst) {
1055   EnsureSpace ensure_space(this);
1056   if (dst.code() > 3) {
1057     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
1058     emit_rex_32(dst);
1059   }
1060   emit(0xFE);
1061   emit_modrm(0x1, dst);
1062 }
1063 
1064 
decb(const Operand & dst)1065 void Assembler::decb(const Operand& dst) {
1066   EnsureSpace ensure_space(this);
1067   emit_optional_rex_32(dst);
1068   emit(0xFE);
1069   emit_operand(1, dst);
1070 }
1071 
1072 
enter(Immediate size)1073 void Assembler::enter(Immediate size) {
1074   EnsureSpace ensure_space(this);
1075   emit(0xC8);
1076   emitw(size.value_);  // 16 bit operand, always.
1077   emit(0);
1078 }
1079 
1080 
hlt()1081 void Assembler::hlt() {
1082   EnsureSpace ensure_space(this);
1083   emit(0xF4);
1084 }
1085 
1086 
idivq(Register src)1087 void Assembler::idivq(Register src) {
1088   EnsureSpace ensure_space(this);
1089   emit_rex_64(src);
1090   emit(0xF7);
1091   emit_modrm(0x7, src);
1092 }
1093 
1094 
idivl(Register src)1095 void Assembler::idivl(Register src) {
1096   EnsureSpace ensure_space(this);
1097   emit_optional_rex_32(src);
1098   emit(0xF7);
1099   emit_modrm(0x7, src);
1100 }
1101 
1102 
imul(Register src)1103 void Assembler::imul(Register src) {
1104   EnsureSpace ensure_space(this);
1105   emit_rex_64(src);
1106   emit(0xF7);
1107   emit_modrm(0x5, src);
1108 }
1109 
1110 
imul(Register dst,Register src)1111 void Assembler::imul(Register dst, Register src) {
1112   EnsureSpace ensure_space(this);
1113   emit_rex_64(dst, src);
1114   emit(0x0F);
1115   emit(0xAF);
1116   emit_modrm(dst, src);
1117 }
1118 
1119 
imul(Register dst,const Operand & src)1120 void Assembler::imul(Register dst, const Operand& src) {
1121   EnsureSpace ensure_space(this);
1122   emit_rex_64(dst, src);
1123   emit(0x0F);
1124   emit(0xAF);
1125   emit_operand(dst, src);
1126 }
1127 
1128 
imul(Register dst,Register src,Immediate imm)1129 void Assembler::imul(Register dst, Register src, Immediate imm) {
1130   EnsureSpace ensure_space(this);
1131   emit_rex_64(dst, src);
1132   if (is_int8(imm.value_)) {
1133     emit(0x6B);
1134     emit_modrm(dst, src);
1135     emit(imm.value_);
1136   } else {
1137     emit(0x69);
1138     emit_modrm(dst, src);
1139     emitl(imm.value_);
1140   }
1141 }
1142 
1143 
imull(Register dst,Register src)1144 void Assembler::imull(Register dst, Register src) {
1145   EnsureSpace ensure_space(this);
1146   emit_optional_rex_32(dst, src);
1147   emit(0x0F);
1148   emit(0xAF);
1149   emit_modrm(dst, src);
1150 }
1151 
1152 
imull(Register dst,const Operand & src)1153 void Assembler::imull(Register dst, const Operand& src) {
1154   EnsureSpace ensure_space(this);
1155   emit_optional_rex_32(dst, src);
1156   emit(0x0F);
1157   emit(0xAF);
1158   emit_operand(dst, src);
1159 }
1160 
1161 
imull(Register dst,Register src,Immediate imm)1162 void Assembler::imull(Register dst, Register src, Immediate imm) {
1163   EnsureSpace ensure_space(this);
1164   emit_optional_rex_32(dst, src);
1165   if (is_int8(imm.value_)) {
1166     emit(0x6B);
1167     emit_modrm(dst, src);
1168     emit(imm.value_);
1169   } else {
1170     emit(0x69);
1171     emit_modrm(dst, src);
1172     emitl(imm.value_);
1173   }
1174 }
1175 
1176 
incq(Register dst)1177 void Assembler::incq(Register dst) {
1178   EnsureSpace ensure_space(this);
1179   emit_rex_64(dst);
1180   emit(0xFF);
1181   emit_modrm(0x0, dst);
1182 }
1183 
1184 
incq(const Operand & dst)1185 void Assembler::incq(const Operand& dst) {
1186   EnsureSpace ensure_space(this);
1187   emit_rex_64(dst);
1188   emit(0xFF);
1189   emit_operand(0, dst);
1190 }
1191 
1192 
incl(const Operand & dst)1193 void Assembler::incl(const Operand& dst) {
1194   EnsureSpace ensure_space(this);
1195   emit_optional_rex_32(dst);
1196   emit(0xFF);
1197   emit_operand(0, dst);
1198 }
1199 
1200 
incl(Register dst)1201 void Assembler::incl(Register dst) {
1202   EnsureSpace ensure_space(this);
1203   emit_optional_rex_32(dst);
1204   emit(0xFF);
1205   emit_modrm(0, dst);
1206 }
1207 
1208 
int3()1209 void Assembler::int3() {
1210   EnsureSpace ensure_space(this);
1211   emit(0xCC);
1212 }
1213 
1214 
j(Condition cc,Label * L)1215 void Assembler::j(Condition cc, Label* L) {
1216   if (cc == always) {
1217     jmp(L);
1218     return;
1219   } else if (cc == never) {
1220     return;
1221   }
1222   EnsureSpace ensure_space(this);
1223   ASSERT(is_uint4(cc));
1224   if (L->is_bound()) {
1225     const int short_size = 2;
1226     const int long_size  = 6;
1227     int offs = L->pos() - pc_offset();
1228     ASSERT(offs <= 0);
1229     if (is_int8(offs - short_size)) {
1230       // 0111 tttn #8-bit disp.
1231       emit(0x70 | cc);
1232       emit((offs - short_size) & 0xFF);
1233     } else {
1234       // 0000 1111 1000 tttn #32-bit disp.
1235       emit(0x0F);
1236       emit(0x80 | cc);
1237       emitl(offs - long_size);
1238     }
1239   } else if (L->is_linked()) {
1240     // 0000 1111 1000 tttn #32-bit disp.
1241     emit(0x0F);
1242     emit(0x80 | cc);
1243     emitl(L->pos());
1244     L->link_to(pc_offset() - sizeof(int32_t));
1245   } else {
1246     ASSERT(L->is_unused());
1247     emit(0x0F);
1248     emit(0x80 | cc);
1249     int32_t current = pc_offset();
1250     emitl(current);
1251     L->link_to(current);
1252   }
1253 }
1254 
1255 
j(Condition cc,Handle<Code> target,RelocInfo::Mode rmode)1256 void Assembler::j(Condition cc,
1257                   Handle<Code> target,
1258                   RelocInfo::Mode rmode) {
1259   EnsureSpace ensure_space(this);
1260   ASSERT(is_uint4(cc));
1261   // 0000 1111 1000 tttn #32-bit disp.
1262   emit(0x0F);
1263   emit(0x80 | cc);
1264   emit_code_target(target, rmode);
1265 }
1266 
1267 
j(Condition cc,NearLabel * L,Hint hint)1268 void Assembler::j(Condition cc, NearLabel* L, Hint hint) {
1269   EnsureSpace ensure_space(this);
1270   ASSERT(0 <= cc && cc < 16);
1271   if (FLAG_emit_branch_hints && hint != no_hint) emit(hint);
1272   if (L->is_bound()) {
1273     const int short_size = 2;
1274     int offs = L->pos() - pc_offset();
1275     ASSERT(offs <= 0);
1276     ASSERT(is_int8(offs - short_size));
1277     // 0111 tttn #8-bit disp
1278     emit(0x70 | cc);
1279     emit((offs - short_size) & 0xFF);
1280   } else {
1281     emit(0x70 | cc);
1282     emit(0x00);      // The displacement will be resolved later.
1283     L->link_to(pc_offset());
1284   }
1285 }
1286 
1287 
jmp(Label * L)1288 void Assembler::jmp(Label* L) {
1289   EnsureSpace ensure_space(this);
1290   const int short_size = sizeof(int8_t);
1291   const int long_size = sizeof(int32_t);
1292   if (L->is_bound()) {
1293     int offs = L->pos() - pc_offset() - 1;
1294     ASSERT(offs <= 0);
1295     if (is_int8(offs - short_size)) {
1296       // 1110 1011 #8-bit disp.
1297       emit(0xEB);
1298       emit((offs - short_size) & 0xFF);
1299     } else {
1300       // 1110 1001 #32-bit disp.
1301       emit(0xE9);
1302       emitl(offs - long_size);
1303     }
1304   } else  if (L->is_linked()) {
1305     // 1110 1001 #32-bit disp.
1306     emit(0xE9);
1307     emitl(L->pos());
1308     L->link_to(pc_offset() - long_size);
1309   } else {
1310     // 1110 1001 #32-bit disp.
1311     ASSERT(L->is_unused());
1312     emit(0xE9);
1313     int32_t current = pc_offset();
1314     emitl(current);
1315     L->link_to(current);
1316   }
1317 }
1318 
1319 
jmp(Handle<Code> target,RelocInfo::Mode rmode)1320 void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1321   EnsureSpace ensure_space(this);
1322   // 1110 1001 #32-bit disp.
1323   emit(0xE9);
1324   emit_code_target(target, rmode);
1325 }
1326 
1327 
jmp(NearLabel * L)1328 void Assembler::jmp(NearLabel* L) {
1329   EnsureSpace ensure_space(this);
1330   if (L->is_bound()) {
1331     const int short_size = 2;
1332     int offs = L->pos() - pc_offset();
1333     ASSERT(offs <= 0);
1334     ASSERT(is_int8(offs - short_size));
1335     // 1110 1011 #8-bit disp.
1336     emit(0xEB);
1337     emit((offs - short_size) & 0xFF);
1338   } else {
1339     emit(0xEB);
1340     emit(0x00);      // The displacement will be resolved later.
1341     L->link_to(pc_offset());
1342   }
1343 }
1344 
1345 
jmp(Register target)1346 void Assembler::jmp(Register target) {
1347   EnsureSpace ensure_space(this);
1348   // Opcode FF/4 r64.
1349   emit_optional_rex_32(target);
1350   emit(0xFF);
1351   emit_modrm(0x4, target);
1352 }
1353 
1354 
jmp(const Operand & src)1355 void Assembler::jmp(const Operand& src) {
1356   EnsureSpace ensure_space(this);
1357   // Opcode FF/4 m64.
1358   emit_optional_rex_32(src);
1359   emit(0xFF);
1360   emit_operand(0x4, src);
1361 }
1362 
1363 
lea(Register dst,const Operand & src)1364 void Assembler::lea(Register dst, const Operand& src) {
1365   EnsureSpace ensure_space(this);
1366   emit_rex_64(dst, src);
1367   emit(0x8D);
1368   emit_operand(dst, src);
1369 }
1370 
1371 
leal(Register dst,const Operand & src)1372 void Assembler::leal(Register dst, const Operand& src) {
1373   EnsureSpace ensure_space(this);
1374   emit_optional_rex_32(dst, src);
1375   emit(0x8D);
1376   emit_operand(dst, src);
1377 }
1378 
1379 
load_rax(void * value,RelocInfo::Mode mode)1380 void Assembler::load_rax(void* value, RelocInfo::Mode mode) {
1381   EnsureSpace ensure_space(this);
1382   emit(0x48);  // REX.W
1383   emit(0xA1);
1384   emitq(reinterpret_cast<uintptr_t>(value), mode);
1385 }
1386 
1387 
load_rax(ExternalReference ref)1388 void Assembler::load_rax(ExternalReference ref) {
1389   load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1390 }
1391 
1392 
leave()1393 void Assembler::leave() {
1394   EnsureSpace ensure_space(this);
1395   emit(0xC9);
1396 }
1397 
1398 
movb(Register dst,const Operand & src)1399 void Assembler::movb(Register dst, const Operand& src) {
1400   EnsureSpace ensure_space(this);
1401   if (dst.code() > 3) {
1402     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
1403     emit_rex_32(dst, src);
1404   } else {
1405     emit_optional_rex_32(dst, src);
1406   }
1407   emit(0x8A);
1408   emit_operand(dst, src);
1409 }
1410 
1411 
movb(Register dst,Immediate imm)1412 void Assembler::movb(Register dst, Immediate imm) {
1413   EnsureSpace ensure_space(this);
1414   if (dst.code() > 3) {
1415     emit_rex_32(dst);
1416   }
1417   emit(0xB0 + dst.low_bits());
1418   emit(imm.value_);
1419 }
1420 
1421 
movb(const Operand & dst,Register src)1422 void Assembler::movb(const Operand& dst, Register src) {
1423   EnsureSpace ensure_space(this);
1424   if (src.code() > 3) {
1425     emit_rex_32(src, dst);
1426   } else {
1427     emit_optional_rex_32(src, dst);
1428   }
1429   emit(0x88);
1430   emit_operand(src, dst);
1431 }
1432 
1433 
movw(const Operand & dst,Register src)1434 void Assembler::movw(const Operand& dst, Register src) {
1435   EnsureSpace ensure_space(this);
1436   emit(0x66);
1437   emit_optional_rex_32(src, dst);
1438   emit(0x89);
1439   emit_operand(src, dst);
1440 }
1441 
1442 
movl(Register dst,const Operand & src)1443 void Assembler::movl(Register dst, const Operand& src) {
1444   EnsureSpace ensure_space(this);
1445   emit_optional_rex_32(dst, src);
1446   emit(0x8B);
1447   emit_operand(dst, src);
1448 }
1449 
1450 
movl(Register dst,Register src)1451 void Assembler::movl(Register dst, Register src) {
1452   EnsureSpace ensure_space(this);
1453   if (src.low_bits() == 4) {
1454     emit_optional_rex_32(src, dst);
1455     emit(0x89);
1456     emit_modrm(src, dst);
1457   } else {
1458     emit_optional_rex_32(dst, src);
1459     emit(0x8B);
1460     emit_modrm(dst, src);
1461   }
1462 }
1463 
1464 
movl(const Operand & dst,Register src)1465 void Assembler::movl(const Operand& dst, Register src) {
1466   EnsureSpace ensure_space(this);
1467   emit_optional_rex_32(src, dst);
1468   emit(0x89);
1469   emit_operand(src, dst);
1470 }
1471 
1472 
movl(const Operand & dst,Immediate value)1473 void Assembler::movl(const Operand& dst, Immediate value) {
1474   EnsureSpace ensure_space(this);
1475   emit_optional_rex_32(dst);
1476   emit(0xC7);
1477   emit_operand(0x0, dst);
1478   emit(value);
1479 }
1480 
1481 
movl(Register dst,Immediate value)1482 void Assembler::movl(Register dst, Immediate value) {
1483   EnsureSpace ensure_space(this);
1484   emit_optional_rex_32(dst);
1485   emit(0xB8 + dst.low_bits());
1486   emit(value);
1487 }
1488 
1489 
movq(Register dst,const Operand & src)1490 void Assembler::movq(Register dst, const Operand& src) {
1491   EnsureSpace ensure_space(this);
1492   emit_rex_64(dst, src);
1493   emit(0x8B);
1494   emit_operand(dst, src);
1495 }
1496 
1497 
movq(Register dst,Register src)1498 void Assembler::movq(Register dst, Register src) {
1499   EnsureSpace ensure_space(this);
1500   if (src.low_bits() == 4) {
1501     emit_rex_64(src, dst);
1502     emit(0x89);
1503     emit_modrm(src, dst);
1504   } else {
1505     emit_rex_64(dst, src);
1506     emit(0x8B);
1507     emit_modrm(dst, src);
1508   }
1509 }
1510 
1511 
movq(Register dst,Immediate value)1512 void Assembler::movq(Register dst, Immediate value) {
1513   EnsureSpace ensure_space(this);
1514   emit_rex_64(dst);
1515   emit(0xC7);
1516   emit_modrm(0x0, dst);
1517   emit(value);  // Only 32-bit immediates are possible, not 8-bit immediates.
1518 }
1519 
1520 
movq(const Operand & dst,Register src)1521 void Assembler::movq(const Operand& dst, Register src) {
1522   EnsureSpace ensure_space(this);
1523   emit_rex_64(src, dst);
1524   emit(0x89);
1525   emit_operand(src, dst);
1526 }
1527 
1528 
movq(Register dst,void * value,RelocInfo::Mode rmode)1529 void Assembler::movq(Register dst, void* value, RelocInfo::Mode rmode) {
1530   // This method must not be used with heap object references. The stored
1531   // address is not GC safe. Use the handle version instead.
1532   ASSERT(rmode > RelocInfo::LAST_GCED_ENUM);
1533   EnsureSpace ensure_space(this);
1534   emit_rex_64(dst);
1535   emit(0xB8 | dst.low_bits());
1536   emitq(reinterpret_cast<uintptr_t>(value), rmode);
1537 }
1538 
1539 
movq(Register dst,int64_t value,RelocInfo::Mode rmode)1540 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) {
1541   // Non-relocatable values might not need a 64-bit representation.
1542   if (rmode == RelocInfo::NONE) {
1543     // Sadly, there is no zero or sign extending move for 8-bit immediates.
1544     if (is_int32(value)) {
1545       movq(dst, Immediate(static_cast<int32_t>(value)));
1546       return;
1547     } else if (is_uint32(value)) {
1548       movl(dst, Immediate(static_cast<int32_t>(value)));
1549       return;
1550     }
1551     // Value cannot be represented by 32 bits, so do a full 64 bit immediate
1552     // value.
1553   }
1554   EnsureSpace ensure_space(this);
1555   emit_rex_64(dst);
1556   emit(0xB8 | dst.low_bits());
1557   emitq(value, rmode);
1558 }
1559 
1560 
movq(Register dst,ExternalReference ref)1561 void Assembler::movq(Register dst, ExternalReference ref) {
1562   int64_t value = reinterpret_cast<int64_t>(ref.address());
1563   movq(dst, value, RelocInfo::EXTERNAL_REFERENCE);
1564 }
1565 
1566 
movq(const Operand & dst,Immediate value)1567 void Assembler::movq(const Operand& dst, Immediate value) {
1568   EnsureSpace ensure_space(this);
1569   emit_rex_64(dst);
1570   emit(0xC7);
1571   emit_operand(0, dst);
1572   emit(value);
1573 }
1574 
1575 
1576 // Loads the ip-relative location of the src label into the target location
1577 // (as a 32-bit offset sign extended to 64-bit).
movl(const Operand & dst,Label * src)1578 void Assembler::movl(const Operand& dst, Label* src) {
1579   EnsureSpace ensure_space(this);
1580   emit_optional_rex_32(dst);
1581   emit(0xC7);
1582   emit_operand(0, dst);
1583   if (src->is_bound()) {
1584     int offset = src->pos() - pc_offset() - sizeof(int32_t);
1585     ASSERT(offset <= 0);
1586     emitl(offset);
1587   } else if (src->is_linked()) {
1588     emitl(src->pos());
1589     src->link_to(pc_offset() - sizeof(int32_t));
1590   } else {
1591     ASSERT(src->is_unused());
1592     int32_t current = pc_offset();
1593     emitl(current);
1594     src->link_to(current);
1595   }
1596 }
1597 
1598 
movq(Register dst,Handle<Object> value,RelocInfo::Mode mode)1599 void Assembler::movq(Register dst, Handle<Object> value, RelocInfo::Mode mode) {
1600   // If there is no relocation info, emit the value of the handle efficiently
1601   // (possibly using less that 8 bytes for the value).
1602   if (mode == RelocInfo::NONE) {
1603     // There is no possible reason to store a heap pointer without relocation
1604     // info, so it must be a smi.
1605     ASSERT(value->IsSmi());
1606     movq(dst, reinterpret_cast<int64_t>(*value), RelocInfo::NONE);
1607   } else {
1608     EnsureSpace ensure_space(this);
1609     ASSERT(value->IsHeapObject());
1610     ASSERT(!HEAP->InNewSpace(*value));
1611     emit_rex_64(dst);
1612     emit(0xB8 | dst.low_bits());
1613     emitq(reinterpret_cast<uintptr_t>(value.location()), mode);
1614   }
1615 }
1616 
1617 
movsxbq(Register dst,const Operand & src)1618 void Assembler::movsxbq(Register dst, const Operand& src) {
1619   EnsureSpace ensure_space(this);
1620   emit_rex_64(dst, src);
1621   emit(0x0F);
1622   emit(0xBE);
1623   emit_operand(dst, src);
1624 }
1625 
1626 
movsxwq(Register dst,const Operand & src)1627 void Assembler::movsxwq(Register dst, const Operand& src) {
1628   EnsureSpace ensure_space(this);
1629   emit_rex_64(dst, src);
1630   emit(0x0F);
1631   emit(0xBF);
1632   emit_operand(dst, src);
1633 }
1634 
1635 
movsxlq(Register dst,Register src)1636 void Assembler::movsxlq(Register dst, Register src) {
1637   EnsureSpace ensure_space(this);
1638   emit_rex_64(dst, src);
1639   emit(0x63);
1640   emit_modrm(dst, src);
1641 }
1642 
1643 
movsxlq(Register dst,const Operand & src)1644 void Assembler::movsxlq(Register dst, const Operand& src) {
1645   EnsureSpace ensure_space(this);
1646   emit_rex_64(dst, src);
1647   emit(0x63);
1648   emit_operand(dst, src);
1649 }
1650 
1651 
movzxbq(Register dst,const Operand & src)1652 void Assembler::movzxbq(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 
movzxbl(Register dst,const Operand & src)1661 void Assembler::movzxbl(Register dst, const Operand& src) {
1662   EnsureSpace ensure_space(this);
1663   emit_optional_rex_32(dst, src);
1664   emit(0x0F);
1665   emit(0xB6);
1666   emit_operand(dst, src);
1667 }
1668 
1669 
movzxwq(Register dst,const Operand & src)1670 void Assembler::movzxwq(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 
movzxwl(Register dst,const Operand & src)1679 void Assembler::movzxwl(Register dst, const Operand& src) {
1680   EnsureSpace ensure_space(this);
1681   emit_optional_rex_32(dst, src);
1682   emit(0x0F);
1683   emit(0xB7);
1684   emit_operand(dst, src);
1685 }
1686 
1687 
repmovsb()1688 void Assembler::repmovsb() {
1689   EnsureSpace ensure_space(this);
1690   emit(0xF3);
1691   emit(0xA4);
1692 }
1693 
1694 
repmovsw()1695 void Assembler::repmovsw() {
1696   EnsureSpace ensure_space(this);
1697   emit(0x66);  // Operand size override.
1698   emit(0xF3);
1699   emit(0xA4);
1700 }
1701 
1702 
repmovsl()1703 void Assembler::repmovsl() {
1704   EnsureSpace ensure_space(this);
1705   emit(0xF3);
1706   emit(0xA5);
1707 }
1708 
1709 
repmovsq()1710 void Assembler::repmovsq() {
1711   EnsureSpace ensure_space(this);
1712   emit(0xF3);
1713   emit_rex_64();
1714   emit(0xA5);
1715 }
1716 
1717 
mul(Register src)1718 void Assembler::mul(Register src) {
1719   EnsureSpace ensure_space(this);
1720   emit_rex_64(src);
1721   emit(0xF7);
1722   emit_modrm(0x4, src);
1723 }
1724 
1725 
neg(Register dst)1726 void Assembler::neg(Register dst) {
1727   EnsureSpace ensure_space(this);
1728   emit_rex_64(dst);
1729   emit(0xF7);
1730   emit_modrm(0x3, dst);
1731 }
1732 
1733 
negl(Register dst)1734 void Assembler::negl(Register dst) {
1735   EnsureSpace ensure_space(this);
1736   emit_optional_rex_32(dst);
1737   emit(0xF7);
1738   emit_modrm(0x3, dst);
1739 }
1740 
1741 
neg(const Operand & dst)1742 void Assembler::neg(const Operand& dst) {
1743   EnsureSpace ensure_space(this);
1744   emit_rex_64(dst);
1745   emit(0xF7);
1746   emit_operand(3, dst);
1747 }
1748 
1749 
nop()1750 void Assembler::nop() {
1751   EnsureSpace ensure_space(this);
1752   emit(0x90);
1753 }
1754 
1755 
not_(Register dst)1756 void Assembler::not_(Register dst) {
1757   EnsureSpace ensure_space(this);
1758   emit_rex_64(dst);
1759   emit(0xF7);
1760   emit_modrm(0x2, dst);
1761 }
1762 
1763 
not_(const Operand & dst)1764 void Assembler::not_(const Operand& dst) {
1765   EnsureSpace ensure_space(this);
1766   emit_rex_64(dst);
1767   emit(0xF7);
1768   emit_operand(2, dst);
1769 }
1770 
1771 
notl(Register dst)1772 void Assembler::notl(Register dst) {
1773   EnsureSpace ensure_space(this);
1774   emit_optional_rex_32(dst);
1775   emit(0xF7);
1776   emit_modrm(0x2, dst);
1777 }
1778 
1779 
nop(int n)1780 void Assembler::nop(int n) {
1781   // The recommended muti-byte sequences of NOP instructions from the Intel 64
1782   // and IA-32 Architectures Software Developer's Manual.
1783   //
1784   // Length   Assembly                                Byte Sequence
1785   // 2 bytes  66 NOP                                  66 90H
1786   // 3 bytes  NOP DWORD ptr [EAX]                     0F 1F 00H
1787   // 4 bytes  NOP DWORD ptr [EAX + 00H]               0F 1F 40 00H
1788   // 5 bytes  NOP DWORD ptr [EAX + EAX*1 + 00H]       0F 1F 44 00 00H
1789   // 6 bytes  66 NOP DWORD ptr [EAX + EAX*1 + 00H]    66 0F 1F 44 00 00H
1790   // 7 bytes  NOP DWORD ptr [EAX + 00000000H]         0F 1F 80 00 00 00 00H
1791   // 8 bytes  NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H
1792   // 9 bytes  66 NOP DWORD ptr [EAX + EAX*1 +         66 0F 1F 84 00 00 00 00
1793   //          00000000H]                              00H
1794 
1795   ASSERT(1 <= n);
1796   ASSERT(n <= 9);
1797   EnsureSpace ensure_space(this);
1798   switch (n) {
1799   case 1:
1800     emit(0x90);
1801     return;
1802   case 2:
1803     emit(0x66);
1804     emit(0x90);
1805     return;
1806   case 3:
1807     emit(0x0f);
1808     emit(0x1f);
1809     emit(0x00);
1810     return;
1811   case 4:
1812     emit(0x0f);
1813     emit(0x1f);
1814     emit(0x40);
1815     emit(0x00);
1816     return;
1817   case 5:
1818     emit(0x0f);
1819     emit(0x1f);
1820     emit(0x44);
1821     emit(0x00);
1822     emit(0x00);
1823     return;
1824   case 6:
1825     emit(0x66);
1826     emit(0x0f);
1827     emit(0x1f);
1828     emit(0x44);
1829     emit(0x00);
1830     emit(0x00);
1831     return;
1832   case 7:
1833     emit(0x0f);
1834     emit(0x1f);
1835     emit(0x80);
1836     emit(0x00);
1837     emit(0x00);
1838     emit(0x00);
1839     emit(0x00);
1840     return;
1841   case 8:
1842     emit(0x0f);
1843     emit(0x1f);
1844     emit(0x84);
1845     emit(0x00);
1846     emit(0x00);
1847     emit(0x00);
1848     emit(0x00);
1849     emit(0x00);
1850     return;
1851   case 9:
1852     emit(0x66);
1853     emit(0x0f);
1854     emit(0x1f);
1855     emit(0x84);
1856     emit(0x00);
1857     emit(0x00);
1858     emit(0x00);
1859     emit(0x00);
1860     emit(0x00);
1861     return;
1862   }
1863 }
1864 
1865 
pop(Register dst)1866 void Assembler::pop(Register dst) {
1867   EnsureSpace ensure_space(this);
1868   emit_optional_rex_32(dst);
1869   emit(0x58 | dst.low_bits());
1870 }
1871 
1872 
pop(const Operand & dst)1873 void Assembler::pop(const Operand& dst) {
1874   EnsureSpace ensure_space(this);
1875   emit_optional_rex_32(dst);
1876   emit(0x8F);
1877   emit_operand(0, dst);
1878 }
1879 
1880 
popfq()1881 void Assembler::popfq() {
1882   EnsureSpace ensure_space(this);
1883   emit(0x9D);
1884 }
1885 
1886 
push(Register src)1887 void Assembler::push(Register src) {
1888   EnsureSpace ensure_space(this);
1889   emit_optional_rex_32(src);
1890   emit(0x50 | src.low_bits());
1891 }
1892 
1893 
push(const Operand & src)1894 void Assembler::push(const Operand& src) {
1895   EnsureSpace ensure_space(this);
1896   emit_optional_rex_32(src);
1897   emit(0xFF);
1898   emit_operand(6, src);
1899 }
1900 
1901 
push(Immediate value)1902 void Assembler::push(Immediate value) {
1903   EnsureSpace ensure_space(this);
1904   if (is_int8(value.value_)) {
1905     emit(0x6A);
1906     emit(value.value_);  // Emit low byte of value.
1907   } else {
1908     emit(0x68);
1909     emitl(value.value_);
1910   }
1911 }
1912 
1913 
push_imm32(int32_t imm32)1914 void Assembler::push_imm32(int32_t imm32) {
1915   EnsureSpace ensure_space(this);
1916   emit(0x68);
1917   emitl(imm32);
1918 }
1919 
1920 
pushfq()1921 void Assembler::pushfq() {
1922   EnsureSpace ensure_space(this);
1923   emit(0x9C);
1924 }
1925 
1926 
rdtsc()1927 void Assembler::rdtsc() {
1928   EnsureSpace ensure_space(this);
1929   emit(0x0F);
1930   emit(0x31);
1931 }
1932 
1933 
ret(int imm16)1934 void Assembler::ret(int imm16) {
1935   EnsureSpace ensure_space(this);
1936   ASSERT(is_uint16(imm16));
1937   if (imm16 == 0) {
1938     emit(0xC3);
1939   } else {
1940     emit(0xC2);
1941     emit(imm16 & 0xFF);
1942     emit((imm16 >> 8) & 0xFF);
1943   }
1944 }
1945 
1946 
setcc(Condition cc,Register reg)1947 void Assembler::setcc(Condition cc, Register reg) {
1948   if (cc > last_condition) {
1949     movb(reg, Immediate(cc == always ? 1 : 0));
1950     return;
1951   }
1952   EnsureSpace ensure_space(this);
1953   ASSERT(is_uint4(cc));
1954   if (reg.code() > 3) {  // Use x64 byte registers, where different.
1955     emit_rex_32(reg);
1956   }
1957   emit(0x0F);
1958   emit(0x90 | cc);
1959   emit_modrm(0x0, reg);
1960 }
1961 
1962 
shld(Register dst,Register src)1963 void Assembler::shld(Register dst, Register src) {
1964   EnsureSpace ensure_space(this);
1965   emit_rex_64(src, dst);
1966   emit(0x0F);
1967   emit(0xA5);
1968   emit_modrm(src, dst);
1969 }
1970 
1971 
shrd(Register dst,Register src)1972 void Assembler::shrd(Register dst, Register src) {
1973   EnsureSpace ensure_space(this);
1974   emit_rex_64(src, dst);
1975   emit(0x0F);
1976   emit(0xAD);
1977   emit_modrm(src, dst);
1978 }
1979 
1980 
xchg(Register dst,Register src)1981 void Assembler::xchg(Register dst, Register src) {
1982   EnsureSpace ensure_space(this);
1983   if (src.is(rax) || dst.is(rax)) {  // Single-byte encoding
1984     Register other = src.is(rax) ? dst : src;
1985     emit_rex_64(other);
1986     emit(0x90 | other.low_bits());
1987   } else if (dst.low_bits() == 4) {
1988     emit_rex_64(dst, src);
1989     emit(0x87);
1990     emit_modrm(dst, src);
1991   } else {
1992     emit_rex_64(src, dst);
1993     emit(0x87);
1994     emit_modrm(src, dst);
1995   }
1996 }
1997 
1998 
store_rax(void * dst,RelocInfo::Mode mode)1999 void Assembler::store_rax(void* dst, RelocInfo::Mode mode) {
2000   EnsureSpace ensure_space(this);
2001   emit(0x48);  // REX.W
2002   emit(0xA3);
2003   emitq(reinterpret_cast<uintptr_t>(dst), mode);
2004 }
2005 
2006 
store_rax(ExternalReference ref)2007 void Assembler::store_rax(ExternalReference ref) {
2008   store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
2009 }
2010 
2011 
testb(Register dst,Register src)2012 void Assembler::testb(Register dst, Register src) {
2013   EnsureSpace ensure_space(this);
2014   if (src.low_bits() == 4) {
2015     emit_rex_32(src, dst);
2016     emit(0x84);
2017     emit_modrm(src, dst);
2018   } else {
2019     if (dst.code() > 3 || src.code() > 3) {
2020       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
2021       emit_rex_32(dst, src);
2022     }
2023     emit(0x84);
2024     emit_modrm(dst, src);
2025   }
2026 }
2027 
2028 
testb(Register reg,Immediate mask)2029 void Assembler::testb(Register reg, Immediate mask) {
2030   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
2031   EnsureSpace ensure_space(this);
2032   if (reg.is(rax)) {
2033     emit(0xA8);
2034     emit(mask.value_);  // Low byte emitted.
2035   } else {
2036     if (reg.code() > 3) {
2037       // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
2038       emit_rex_32(reg);
2039     }
2040     emit(0xF6);
2041     emit_modrm(0x0, reg);
2042     emit(mask.value_);  // Low byte emitted.
2043   }
2044 }
2045 
2046 
testb(const Operand & op,Immediate mask)2047 void Assembler::testb(const Operand& op, Immediate mask) {
2048   ASSERT(is_int8(mask.value_) || is_uint8(mask.value_));
2049   EnsureSpace ensure_space(this);
2050   emit_optional_rex_32(rax, op);
2051   emit(0xF6);
2052   emit_operand(rax, op);  // Operation code 0
2053   emit(mask.value_);  // Low byte emitted.
2054 }
2055 
2056 
testb(const Operand & op,Register reg)2057 void Assembler::testb(const Operand& op, Register reg) {
2058   EnsureSpace ensure_space(this);
2059   if (reg.code() > 3) {
2060     // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
2061     emit_rex_32(reg, op);
2062   } else {
2063     emit_optional_rex_32(reg, op);
2064   }
2065   emit(0x84);
2066   emit_operand(reg, op);
2067 }
2068 
2069 
testl(Register dst,Register src)2070 void Assembler::testl(Register dst, Register src) {
2071   EnsureSpace ensure_space(this);
2072   if (src.low_bits() == 4) {
2073     emit_optional_rex_32(src, dst);
2074     emit(0x85);
2075     emit_modrm(src, dst);
2076   } else {
2077     emit_optional_rex_32(dst, src);
2078     emit(0x85);
2079     emit_modrm(dst, src);
2080   }
2081 }
2082 
2083 
testl(Register reg,Immediate mask)2084 void Assembler::testl(Register reg, Immediate mask) {
2085   // testl with a mask that fits in the low byte is exactly testb.
2086   if (is_uint8(mask.value_)) {
2087     testb(reg, mask);
2088     return;
2089   }
2090   EnsureSpace ensure_space(this);
2091   if (reg.is(rax)) {
2092     emit(0xA9);
2093     emit(mask);
2094   } else {
2095     emit_optional_rex_32(rax, reg);
2096     emit(0xF7);
2097     emit_modrm(0x0, reg);
2098     emit(mask);
2099   }
2100 }
2101 
2102 
testl(const Operand & op,Immediate mask)2103 void Assembler::testl(const Operand& op, Immediate mask) {
2104   // testl with a mask that fits in the low byte is exactly testb.
2105   if (is_uint8(mask.value_)) {
2106     testb(op, mask);
2107     return;
2108   }
2109   EnsureSpace ensure_space(this);
2110   emit_optional_rex_32(rax, op);
2111   emit(0xF7);
2112   emit_operand(rax, op);  // Operation code 0
2113   emit(mask);
2114 }
2115 
2116 
testq(const Operand & op,Register reg)2117 void Assembler::testq(const Operand& op, Register reg) {
2118   EnsureSpace ensure_space(this);
2119   emit_rex_64(reg, op);
2120   emit(0x85);
2121   emit_operand(reg, op);
2122 }
2123 
2124 
testq(Register dst,Register src)2125 void Assembler::testq(Register dst, Register src) {
2126   EnsureSpace ensure_space(this);
2127   if (src.low_bits() == 4) {
2128     emit_rex_64(src, dst);
2129     emit(0x85);
2130     emit_modrm(src, dst);
2131   } else {
2132     emit_rex_64(dst, src);
2133     emit(0x85);
2134     emit_modrm(dst, src);
2135   }
2136 }
2137 
2138 
testq(Register dst,Immediate mask)2139 void Assembler::testq(Register dst, Immediate mask) {
2140   EnsureSpace ensure_space(this);
2141   if (dst.is(rax)) {
2142     emit_rex_64();
2143     emit(0xA9);
2144     emit(mask);
2145   } else {
2146     emit_rex_64(dst);
2147     emit(0xF7);
2148     emit_modrm(0, dst);
2149     emit(mask);
2150   }
2151 }
2152 
2153 
2154 // FPU instructions.
2155 
2156 
fld(int i)2157 void Assembler::fld(int i) {
2158   EnsureSpace ensure_space(this);
2159   emit_farith(0xD9, 0xC0, i);
2160 }
2161 
2162 
fld1()2163 void Assembler::fld1() {
2164   EnsureSpace ensure_space(this);
2165   emit(0xD9);
2166   emit(0xE8);
2167 }
2168 
2169 
fldz()2170 void Assembler::fldz() {
2171   EnsureSpace ensure_space(this);
2172   emit(0xD9);
2173   emit(0xEE);
2174 }
2175 
2176 
fldpi()2177 void Assembler::fldpi() {
2178   EnsureSpace ensure_space(this);
2179   emit(0xD9);
2180   emit(0xEB);
2181 }
2182 
2183 
fldln2()2184 void Assembler::fldln2() {
2185   EnsureSpace ensure_space(this);
2186   emit(0xD9);
2187   emit(0xED);
2188 }
2189 
2190 
fld_s(const Operand & adr)2191 void Assembler::fld_s(const Operand& adr) {
2192   EnsureSpace ensure_space(this);
2193   emit_optional_rex_32(adr);
2194   emit(0xD9);
2195   emit_operand(0, adr);
2196 }
2197 
2198 
fld_d(const Operand & adr)2199 void Assembler::fld_d(const Operand& adr) {
2200   EnsureSpace ensure_space(this);
2201   emit_optional_rex_32(adr);
2202   emit(0xDD);
2203   emit_operand(0, adr);
2204 }
2205 
2206 
fstp_s(const Operand & adr)2207 void Assembler::fstp_s(const Operand& adr) {
2208   EnsureSpace ensure_space(this);
2209   emit_optional_rex_32(adr);
2210   emit(0xD9);
2211   emit_operand(3, adr);
2212 }
2213 
2214 
fstp_d(const Operand & adr)2215 void Assembler::fstp_d(const Operand& adr) {
2216   EnsureSpace ensure_space(this);
2217   emit_optional_rex_32(adr);
2218   emit(0xDD);
2219   emit_operand(3, adr);
2220 }
2221 
2222 
fstp(int index)2223 void Assembler::fstp(int index) {
2224   ASSERT(is_uint3(index));
2225   EnsureSpace ensure_space(this);
2226   emit_farith(0xDD, 0xD8, index);
2227 }
2228 
2229 
fild_s(const Operand & adr)2230 void Assembler::fild_s(const Operand& adr) {
2231   EnsureSpace ensure_space(this);
2232   emit_optional_rex_32(adr);
2233   emit(0xDB);
2234   emit_operand(0, adr);
2235 }
2236 
2237 
fild_d(const Operand & adr)2238 void Assembler::fild_d(const Operand& adr) {
2239   EnsureSpace ensure_space(this);
2240   emit_optional_rex_32(adr);
2241   emit(0xDF);
2242   emit_operand(5, adr);
2243 }
2244 
2245 
fistp_s(const Operand & adr)2246 void Assembler::fistp_s(const Operand& adr) {
2247   EnsureSpace ensure_space(this);
2248   emit_optional_rex_32(adr);
2249   emit(0xDB);
2250   emit_operand(3, adr);
2251 }
2252 
2253 
fisttp_s(const Operand & adr)2254 void Assembler::fisttp_s(const Operand& adr) {
2255   ASSERT(CpuFeatures::IsEnabled(SSE3));
2256   EnsureSpace ensure_space(this);
2257   emit_optional_rex_32(adr);
2258   emit(0xDB);
2259   emit_operand(1, adr);
2260 }
2261 
2262 
fisttp_d(const Operand & adr)2263 void Assembler::fisttp_d(const Operand& adr) {
2264   ASSERT(CpuFeatures::IsEnabled(SSE3));
2265   EnsureSpace ensure_space(this);
2266   emit_optional_rex_32(adr);
2267   emit(0xDD);
2268   emit_operand(1, adr);
2269 }
2270 
2271 
fist_s(const Operand & adr)2272 void Assembler::fist_s(const Operand& adr) {
2273   EnsureSpace ensure_space(this);
2274   emit_optional_rex_32(adr);
2275   emit(0xDB);
2276   emit_operand(2, adr);
2277 }
2278 
2279 
fistp_d(const Operand & adr)2280 void Assembler::fistp_d(const Operand& adr) {
2281   EnsureSpace ensure_space(this);
2282   emit_optional_rex_32(adr);
2283   emit(0xDF);
2284   emit_operand(7, adr);
2285 }
2286 
2287 
fabs()2288 void Assembler::fabs() {
2289   EnsureSpace ensure_space(this);
2290   emit(0xD9);
2291   emit(0xE1);
2292 }
2293 
2294 
fchs()2295 void Assembler::fchs() {
2296   EnsureSpace ensure_space(this);
2297   emit(0xD9);
2298   emit(0xE0);
2299 }
2300 
2301 
fcos()2302 void Assembler::fcos() {
2303   EnsureSpace ensure_space(this);
2304   emit(0xD9);
2305   emit(0xFF);
2306 }
2307 
2308 
fsin()2309 void Assembler::fsin() {
2310   EnsureSpace ensure_space(this);
2311   emit(0xD9);
2312   emit(0xFE);
2313 }
2314 
2315 
fyl2x()2316 void Assembler::fyl2x() {
2317   EnsureSpace ensure_space(this);
2318   emit(0xD9);
2319   emit(0xF1);
2320 }
2321 
2322 
fadd(int i)2323 void Assembler::fadd(int i) {
2324   EnsureSpace ensure_space(this);
2325   emit_farith(0xDC, 0xC0, i);
2326 }
2327 
2328 
fsub(int i)2329 void Assembler::fsub(int i) {
2330   EnsureSpace ensure_space(this);
2331   emit_farith(0xDC, 0xE8, i);
2332 }
2333 
2334 
fisub_s(const Operand & adr)2335 void Assembler::fisub_s(const Operand& adr) {
2336   EnsureSpace ensure_space(this);
2337   emit_optional_rex_32(adr);
2338   emit(0xDA);
2339   emit_operand(4, adr);
2340 }
2341 
2342 
fmul(int i)2343 void Assembler::fmul(int i) {
2344   EnsureSpace ensure_space(this);
2345   emit_farith(0xDC, 0xC8, i);
2346 }
2347 
2348 
fdiv(int i)2349 void Assembler::fdiv(int i) {
2350   EnsureSpace ensure_space(this);
2351   emit_farith(0xDC, 0xF8, i);
2352 }
2353 
2354 
faddp(int i)2355 void Assembler::faddp(int i) {
2356   EnsureSpace ensure_space(this);
2357   emit_farith(0xDE, 0xC0, i);
2358 }
2359 
2360 
fsubp(int i)2361 void Assembler::fsubp(int i) {
2362   EnsureSpace ensure_space(this);
2363   emit_farith(0xDE, 0xE8, i);
2364 }
2365 
2366 
fsubrp(int i)2367 void Assembler::fsubrp(int i) {
2368   EnsureSpace ensure_space(this);
2369   emit_farith(0xDE, 0xE0, i);
2370 }
2371 
2372 
fmulp(int i)2373 void Assembler::fmulp(int i) {
2374   EnsureSpace ensure_space(this);
2375   emit_farith(0xDE, 0xC8, i);
2376 }
2377 
2378 
fdivp(int i)2379 void Assembler::fdivp(int i) {
2380   EnsureSpace ensure_space(this);
2381   emit_farith(0xDE, 0xF8, i);
2382 }
2383 
2384 
fprem()2385 void Assembler::fprem() {
2386   EnsureSpace ensure_space(this);
2387   emit(0xD9);
2388   emit(0xF8);
2389 }
2390 
2391 
fprem1()2392 void Assembler::fprem1() {
2393   EnsureSpace ensure_space(this);
2394   emit(0xD9);
2395   emit(0xF5);
2396 }
2397 
2398 
fxch(int i)2399 void Assembler::fxch(int i) {
2400   EnsureSpace ensure_space(this);
2401   emit_farith(0xD9, 0xC8, i);
2402 }
2403 
2404 
fincstp()2405 void Assembler::fincstp() {
2406   EnsureSpace ensure_space(this);
2407   emit(0xD9);
2408   emit(0xF7);
2409 }
2410 
2411 
ffree(int i)2412 void Assembler::ffree(int i) {
2413   EnsureSpace ensure_space(this);
2414   emit_farith(0xDD, 0xC0, i);
2415 }
2416 
2417 
ftst()2418 void Assembler::ftst() {
2419   EnsureSpace ensure_space(this);
2420   emit(0xD9);
2421   emit(0xE4);
2422 }
2423 
2424 
fucomp(int i)2425 void Assembler::fucomp(int i) {
2426   EnsureSpace ensure_space(this);
2427   emit_farith(0xDD, 0xE8, i);
2428 }
2429 
2430 
fucompp()2431 void Assembler::fucompp() {
2432   EnsureSpace ensure_space(this);
2433   emit(0xDA);
2434   emit(0xE9);
2435 }
2436 
2437 
fucomi(int i)2438 void Assembler::fucomi(int i) {
2439   EnsureSpace ensure_space(this);
2440   emit(0xDB);
2441   emit(0xE8 + i);
2442 }
2443 
2444 
fucomip()2445 void Assembler::fucomip() {
2446   EnsureSpace ensure_space(this);
2447   emit(0xDF);
2448   emit(0xE9);
2449 }
2450 
2451 
fcompp()2452 void Assembler::fcompp() {
2453   EnsureSpace ensure_space(this);
2454   emit(0xDE);
2455   emit(0xD9);
2456 }
2457 
2458 
fnstsw_ax()2459 void Assembler::fnstsw_ax() {
2460   EnsureSpace ensure_space(this);
2461   emit(0xDF);
2462   emit(0xE0);
2463 }
2464 
2465 
fwait()2466 void Assembler::fwait() {
2467   EnsureSpace ensure_space(this);
2468   emit(0x9B);
2469 }
2470 
2471 
frndint()2472 void Assembler::frndint() {
2473   EnsureSpace ensure_space(this);
2474   emit(0xD9);
2475   emit(0xFC);
2476 }
2477 
2478 
fnclex()2479 void Assembler::fnclex() {
2480   EnsureSpace ensure_space(this);
2481   emit(0xDB);
2482   emit(0xE2);
2483 }
2484 
2485 
sahf()2486 void Assembler::sahf() {
2487   // TODO(X64): Test for presence. Not all 64-bit intel CPU's have sahf
2488   // in 64-bit mode. Test CpuID.
2489   EnsureSpace ensure_space(this);
2490   emit(0x9E);
2491 }
2492 
2493 
emit_farith(int b1,int b2,int i)2494 void Assembler::emit_farith(int b1, int b2, int i) {
2495   ASSERT(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2496   ASSERT(is_uint3(i));  // illegal stack offset
2497   emit(b1);
2498   emit(b2 + i);
2499 }
2500 
2501 // SSE 2 operations.
2502 
movd(XMMRegister dst,Register src)2503 void Assembler::movd(XMMRegister dst, Register src) {
2504   EnsureSpace ensure_space(this);
2505   emit(0x66);
2506   emit_optional_rex_32(dst, src);
2507   emit(0x0F);
2508   emit(0x6E);
2509   emit_sse_operand(dst, src);
2510 }
2511 
2512 
movd(Register dst,XMMRegister src)2513 void Assembler::movd(Register dst, XMMRegister src) {
2514   EnsureSpace ensure_space(this);
2515   emit(0x66);
2516   emit_optional_rex_32(src, dst);
2517   emit(0x0F);
2518   emit(0x7E);
2519   emit_sse_operand(src, dst);
2520 }
2521 
2522 
movq(XMMRegister dst,Register src)2523 void Assembler::movq(XMMRegister dst, Register src) {
2524   EnsureSpace ensure_space(this);
2525   emit(0x66);
2526   emit_rex_64(dst, src);
2527   emit(0x0F);
2528   emit(0x6E);
2529   emit_sse_operand(dst, src);
2530 }
2531 
2532 
movq(Register dst,XMMRegister src)2533 void Assembler::movq(Register dst, XMMRegister src) {
2534   EnsureSpace ensure_space(this);
2535   emit(0x66);
2536   emit_rex_64(src, dst);
2537   emit(0x0F);
2538   emit(0x7E);
2539   emit_sse_operand(src, dst);
2540 }
2541 
2542 
movdqa(const Operand & dst,XMMRegister src)2543 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2544   EnsureSpace ensure_space(this);
2545   emit(0x66);
2546   emit_rex_64(src, dst);
2547   emit(0x0F);
2548   emit(0x7F);
2549   emit_sse_operand(src, dst);
2550 }
2551 
2552 
movdqa(XMMRegister dst,const Operand & src)2553 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2554   EnsureSpace ensure_space(this);
2555   emit(0x66);
2556   emit_rex_64(dst, src);
2557   emit(0x0F);
2558   emit(0x6F);
2559   emit_sse_operand(dst, src);
2560 }
2561 
2562 
extractps(Register dst,XMMRegister src,byte imm8)2563 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2564   ASSERT(is_uint2(imm8));
2565   EnsureSpace ensure_space(this);
2566   emit(0x66);
2567   emit_optional_rex_32(dst, src);
2568   emit(0x0F);
2569   emit(0x3A);
2570   emit(0x17);
2571   emit_sse_operand(dst, src);
2572   emit(imm8);
2573 }
2574 
2575 
movsd(const Operand & dst,XMMRegister src)2576 void Assembler::movsd(const Operand& dst, XMMRegister src) {
2577   EnsureSpace ensure_space(this);
2578   emit(0xF2);  // double
2579   emit_optional_rex_32(src, dst);
2580   emit(0x0F);
2581   emit(0x11);  // store
2582   emit_sse_operand(src, dst);
2583 }
2584 
2585 
movsd(XMMRegister dst,XMMRegister src)2586 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
2587   EnsureSpace ensure_space(this);
2588   emit(0xF2);  // double
2589   emit_optional_rex_32(dst, src);
2590   emit(0x0F);
2591   emit(0x10);  // load
2592   emit_sse_operand(dst, src);
2593 }
2594 
2595 
movsd(XMMRegister dst,const Operand & src)2596 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2597   EnsureSpace ensure_space(this);
2598   emit(0xF2);  // double
2599   emit_optional_rex_32(dst, src);
2600   emit(0x0F);
2601   emit(0x10);  // load
2602   emit_sse_operand(dst, src);
2603 }
2604 
2605 
movss(XMMRegister dst,const Operand & src)2606 void Assembler::movss(XMMRegister dst, const Operand& src) {
2607   EnsureSpace ensure_space(this);
2608   emit(0xF3);  // single
2609   emit_optional_rex_32(dst, src);
2610   emit(0x0F);
2611   emit(0x10);  // load
2612   emit_sse_operand(dst, src);
2613 }
2614 
2615 
movss(const Operand & src,XMMRegister dst)2616 void Assembler::movss(const Operand& src, XMMRegister dst) {
2617   EnsureSpace ensure_space(this);
2618   emit(0xF3);  // single
2619   emit_optional_rex_32(dst, src);
2620   emit(0x0F);
2621   emit(0x11);  // store
2622   emit_sse_operand(dst, src);
2623 }
2624 
2625 
cvttss2si(Register dst,const Operand & src)2626 void Assembler::cvttss2si(Register dst, const Operand& src) {
2627   EnsureSpace ensure_space(this);
2628   emit(0xF3);
2629   emit_optional_rex_32(dst, src);
2630   emit(0x0F);
2631   emit(0x2C);
2632   emit_operand(dst, src);
2633 }
2634 
2635 
cvttss2si(Register dst,XMMRegister src)2636 void Assembler::cvttss2si(Register dst, XMMRegister src) {
2637   EnsureSpace ensure_space(this);
2638   emit(0xF3);
2639   emit_optional_rex_32(dst, src);
2640   emit(0x0F);
2641   emit(0x2C);
2642   emit_sse_operand(dst, src);
2643 }
2644 
2645 
cvttsd2si(Register dst,const Operand & src)2646 void Assembler::cvttsd2si(Register dst, const Operand& src) {
2647   EnsureSpace ensure_space(this);
2648   emit(0xF2);
2649   emit_optional_rex_32(dst, src);
2650   emit(0x0F);
2651   emit(0x2C);
2652   emit_operand(dst, src);
2653 }
2654 
2655 
cvttsd2si(Register dst,XMMRegister src)2656 void Assembler::cvttsd2si(Register dst, XMMRegister src) {
2657   EnsureSpace ensure_space(this);
2658   emit(0xF2);
2659   emit_optional_rex_32(dst, src);
2660   emit(0x0F);
2661   emit(0x2C);
2662   emit_sse_operand(dst, src);
2663 }
2664 
2665 
cvttsd2siq(Register dst,XMMRegister src)2666 void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
2667   EnsureSpace ensure_space(this);
2668   emit(0xF2);
2669   emit_rex_64(dst, src);
2670   emit(0x0F);
2671   emit(0x2C);
2672   emit_sse_operand(dst, src);
2673 }
2674 
2675 
cvtlsi2sd(XMMRegister dst,const Operand & src)2676 void Assembler::cvtlsi2sd(XMMRegister dst, const Operand& src) {
2677   EnsureSpace ensure_space(this);
2678   emit(0xF2);
2679   emit_optional_rex_32(dst, src);
2680   emit(0x0F);
2681   emit(0x2A);
2682   emit_sse_operand(dst, src);
2683 }
2684 
2685 
cvtlsi2sd(XMMRegister dst,Register src)2686 void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
2687   EnsureSpace ensure_space(this);
2688   emit(0xF2);
2689   emit_optional_rex_32(dst, src);
2690   emit(0x0F);
2691   emit(0x2A);
2692   emit_sse_operand(dst, src);
2693 }
2694 
2695 
cvtlsi2ss(XMMRegister dst,Register src)2696 void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
2697   EnsureSpace ensure_space(this);
2698   emit(0xF3);
2699   emit_optional_rex_32(dst, src);
2700   emit(0x0F);
2701   emit(0x2A);
2702   emit_sse_operand(dst, src);
2703 }
2704 
2705 
cvtqsi2sd(XMMRegister dst,Register src)2706 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
2707   EnsureSpace ensure_space(this);
2708   emit(0xF2);
2709   emit_rex_64(dst, src);
2710   emit(0x0F);
2711   emit(0x2A);
2712   emit_sse_operand(dst, src);
2713 }
2714 
2715 
cvtss2sd(XMMRegister dst,XMMRegister src)2716 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
2717   EnsureSpace ensure_space(this);
2718   emit(0xF3);
2719   emit_optional_rex_32(dst, src);
2720   emit(0x0F);
2721   emit(0x5A);
2722   emit_sse_operand(dst, src);
2723 }
2724 
2725 
cvtss2sd(XMMRegister dst,const Operand & src)2726 void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
2727   EnsureSpace ensure_space(this);
2728   emit(0xF3);
2729   emit_optional_rex_32(dst, src);
2730   emit(0x0F);
2731   emit(0x5A);
2732   emit_sse_operand(dst, src);
2733 }
2734 
2735 
cvtsd2ss(XMMRegister dst,XMMRegister src)2736 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
2737   EnsureSpace ensure_space(this);
2738   emit(0xF2);
2739   emit_optional_rex_32(dst, src);
2740   emit(0x0F);
2741   emit(0x5A);
2742   emit_sse_operand(dst, src);
2743 }
2744 
2745 
cvtsd2si(Register dst,XMMRegister src)2746 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2747   EnsureSpace ensure_space(this);
2748   emit(0xF2);
2749   emit_optional_rex_32(dst, src);
2750   emit(0x0F);
2751   emit(0x2D);
2752   emit_sse_operand(dst, src);
2753 }
2754 
2755 
cvtsd2siq(Register dst,XMMRegister src)2756 void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
2757   EnsureSpace ensure_space(this);
2758   emit(0xF2);
2759   emit_rex_64(dst, src);
2760   emit(0x0F);
2761   emit(0x2D);
2762   emit_sse_operand(dst, src);
2763 }
2764 
2765 
addsd(XMMRegister dst,XMMRegister src)2766 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
2767   EnsureSpace ensure_space(this);
2768   emit(0xF2);
2769   emit_optional_rex_32(dst, src);
2770   emit(0x0F);
2771   emit(0x58);
2772   emit_sse_operand(dst, src);
2773 }
2774 
2775 
mulsd(XMMRegister dst,XMMRegister src)2776 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
2777   EnsureSpace ensure_space(this);
2778   emit(0xF2);
2779   emit_optional_rex_32(dst, src);
2780   emit(0x0F);
2781   emit(0x59);
2782   emit_sse_operand(dst, src);
2783 }
2784 
2785 
subsd(XMMRegister dst,XMMRegister src)2786 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
2787   EnsureSpace ensure_space(this);
2788   emit(0xF2);
2789   emit_optional_rex_32(dst, src);
2790   emit(0x0F);
2791   emit(0x5C);
2792   emit_sse_operand(dst, src);
2793 }
2794 
2795 
divsd(XMMRegister dst,XMMRegister src)2796 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
2797   EnsureSpace ensure_space(this);
2798   emit(0xF2);
2799   emit_optional_rex_32(dst, src);
2800   emit(0x0F);
2801   emit(0x5E);
2802   emit_sse_operand(dst, src);
2803 }
2804 
2805 
andpd(XMMRegister dst,XMMRegister src)2806 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2807   EnsureSpace ensure_space(this);
2808   emit(0x66);
2809   emit_optional_rex_32(dst, src);
2810   emit(0x0F);
2811   emit(0x54);
2812   emit_sse_operand(dst, src);
2813 }
2814 
2815 
orpd(XMMRegister dst,XMMRegister src)2816 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2817   EnsureSpace ensure_space(this);
2818   emit(0x66);
2819   emit_optional_rex_32(dst, src);
2820   emit(0x0F);
2821   emit(0x56);
2822   emit_sse_operand(dst, src);
2823 }
2824 
2825 
xorpd(XMMRegister dst,XMMRegister src)2826 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2827   EnsureSpace ensure_space(this);
2828   emit(0x66);
2829   emit_optional_rex_32(dst, src);
2830   emit(0x0F);
2831   emit(0x57);
2832   emit_sse_operand(dst, src);
2833 }
2834 
2835 
sqrtsd(XMMRegister dst,XMMRegister src)2836 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
2837   EnsureSpace ensure_space(this);
2838   emit(0xF2);
2839   emit_optional_rex_32(dst, src);
2840   emit(0x0F);
2841   emit(0x51);
2842   emit_sse_operand(dst, src);
2843 }
2844 
2845 
ucomisd(XMMRegister dst,XMMRegister src)2846 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
2847   EnsureSpace ensure_space(this);
2848   emit(0x66);
2849   emit_optional_rex_32(dst, src);
2850   emit(0x0f);
2851   emit(0x2e);
2852   emit_sse_operand(dst, src);
2853 }
2854 
2855 
ucomisd(XMMRegister dst,const Operand & src)2856 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2857   EnsureSpace ensure_space(this);
2858   emit(0x66);
2859   emit_optional_rex_32(dst, src);
2860   emit(0x0f);
2861   emit(0x2e);
2862   emit_sse_operand(dst, src);
2863 }
2864 
2865 
movmskpd(Register dst,XMMRegister src)2866 void Assembler::movmskpd(Register dst, XMMRegister src) {
2867   EnsureSpace ensure_space(this);
2868   emit(0x66);
2869   emit_optional_rex_32(dst, src);
2870   emit(0x0f);
2871   emit(0x50);
2872   emit_sse_operand(dst, src);
2873 }
2874 
2875 
emit_sse_operand(XMMRegister reg,const Operand & adr)2876 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2877   Register ireg = { reg.code() };
2878   emit_operand(ireg, adr);
2879 }
2880 
2881 
emit_sse_operand(XMMRegister dst,XMMRegister src)2882 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2883   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2884 }
2885 
emit_sse_operand(XMMRegister dst,Register src)2886 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2887   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2888 }
2889 
emit_sse_operand(Register dst,XMMRegister src)2890 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2891   emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2892 }
2893 
2894 
db(uint8_t data)2895 void Assembler::db(uint8_t data) {
2896   EnsureSpace ensure_space(this);
2897   emit(data);
2898 }
2899 
2900 
dd(uint32_t data)2901 void Assembler::dd(uint32_t data) {
2902   EnsureSpace ensure_space(this);
2903   emitl(data);
2904 }
2905 
2906 
2907 // Relocation information implementations.
2908 
RecordRelocInfo(RelocInfo::Mode rmode,intptr_t data)2909 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2910   ASSERT(rmode != RelocInfo::NONE);
2911   // Don't record external references unless the heap will be serialized.
2912   if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2913 #ifdef DEBUG
2914     if (!Serializer::enabled()) {
2915       Serializer::TooLateToEnableNow();
2916     }
2917 #endif
2918     if (!Serializer::enabled() && !emit_debug_code()) {
2919       return;
2920     }
2921   }
2922   RelocInfo rinfo(pc_, rmode, data);
2923   reloc_info_writer.Write(&rinfo);
2924 }
2925 
RecordJSReturn()2926 void Assembler::RecordJSReturn() {
2927   positions_recorder()->WriteRecordedPositions();
2928   EnsureSpace ensure_space(this);
2929   RecordRelocInfo(RelocInfo::JS_RETURN);
2930 }
2931 
2932 
RecordDebugBreakSlot()2933 void Assembler::RecordDebugBreakSlot() {
2934   positions_recorder()->WriteRecordedPositions();
2935   EnsureSpace ensure_space(this);
2936   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2937 }
2938 
2939 
RecordComment(const char * msg,bool force)2940 void Assembler::RecordComment(const char* msg, bool force) {
2941   if (FLAG_code_comments || force) {
2942     EnsureSpace ensure_space(this);
2943     RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2944   }
2945 }
2946 
2947 
2948 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
2949                                   1 << RelocInfo::INTERNAL_REFERENCE;
2950 
2951 
IsCodedSpecially()2952 bool RelocInfo::IsCodedSpecially() {
2953   // The deserializer needs to know whether a pointer is specially coded.  Being
2954   // specially coded on x64 means that it is a relative 32 bit address, as used
2955   // by branch instructions.
2956   return (1 << rmode_) & kApplyMask;
2957 }
2958 
2959 
2960 
2961 } }  // namespace v8::internal
2962 
2963 #endif  // V8_TARGET_ARCH_X64
2964