• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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