v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
assembler-x64.cc
Go to the documentation of this file.
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 
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.
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.
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 
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 
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 
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 
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 
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 
313 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 
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 
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 
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 
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 
434  Align(16); // Preferred alignment of jump targets on x64.
435 }
436 
437 
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 
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 
482 void Assembler::bind(Label* L) {
483  bind_to(L, pc_offset());
484 }
485 
486 
487 void Assembler::GrowBuffer() {
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 
551 }
552 
553 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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.
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 
923 void Assembler::clc() {
924  EnsureSpace ensure_space(this);
925  emit(0xF8);
926 }
927 
928 void Assembler::cld() {
929  EnsureSpace ensure_space(this);
930  emit(0xFC);
931 }
932 
933 void Assembler::cdq() {
934  EnsureSpace ensure_space(this);
935  emit(0x99);
936 }
937 
938 
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 
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 
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 
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 
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 
1013 void Assembler::cpuid() {
1014  ASSERT(CpuFeatures::IsEnabled(CPUID));
1015  EnsureSpace ensure_space(this);
1016  emit(0x0F);
1017  emit(0xA2);
1018 }
1019 
1020 
1021 void Assembler::cqo() {
1022  EnsureSpace ensure_space(this);
1023  emit_rex_64();
1024  emit(0x99);
1025 }
1026 
1027 
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 
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 
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 
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 
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 
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 
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 
1087 void Assembler::hlt() {
1088  EnsureSpace ensure_space(this);
1089  emit(0xF4);
1090 }
1091 
1092 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1215 void Assembler::int3() {
1216  EnsureSpace ensure_space(this);
1217  emit(0xCC);
1218 }
1219 
1220 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1377 void Assembler::load_rax(ExternalReference ref) {
1378  load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1379 }
1380 
1381 
1382 void Assembler::leave() {
1383  EnsureSpace ensure_space(this);
1384  emit(0xC9);
1385 }
1386 
1387 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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).
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1679 void Assembler::repmovsb() {
1680  EnsureSpace ensure_space(this);
1681  emit(0xF3);
1682  emit(0xA4);
1683 }
1684 
1685 
1686 void Assembler::repmovsw() {
1687  EnsureSpace ensure_space(this);
1688  emit(0x66); // Operand size override.
1689  emit(0xF3);
1690  emit(0xA4);
1691 }
1692 
1693 
1694 void Assembler::repmovsl() {
1695  EnsureSpace ensure_space(this);
1696  emit(0xF3);
1697  emit(0xA5);
1698 }
1699 
1700 
1701 void Assembler::repmovsq() {
1702  EnsureSpace ensure_space(this);
1703  emit(0xF3);
1704  emit_rex_64();
1705  emit(0xA5);
1706 }
1707 
1708 
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 
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 
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 
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 
1741 void Assembler::nop() {
1742  EnsureSpace ensure_space(this);
1743  emit(0x90);
1744 }
1745 
1746 
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 
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 
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 
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 
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 
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 
1863 void Assembler::popfq() {
1864  EnsureSpace ensure_space(this);
1865  emit(0x9D);
1866 }
1867 
1868 
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 
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 
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 
1896 void Assembler::push_imm32(int32_t imm32) {
1897  EnsureSpace ensure_space(this);
1898  emit(0x68);
1899  emitl(imm32);
1900 }
1901 
1902 
1903 void Assembler::pushfq() {
1904  EnsureSpace ensure_space(this);
1905  emit(0x9C);
1906 }
1907 
1908 
1909 void Assembler::rdtsc() {
1910  EnsureSpace ensure_space(this);
1911  emit(0x0F);
1912  emit(0x31);
1913 }
1914 
1915 
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 
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 
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 
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 
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 
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 
1989 void Assembler::store_rax(ExternalReference ref) {
1990  store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1991 }
1992 
1993 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
2139 void Assembler::fld(int i) {
2140  EnsureSpace ensure_space(this);
2141  emit_farith(0xD9, 0xC0, i);
2142 }
2143 
2144 
2145 void Assembler::fld1() {
2146  EnsureSpace ensure_space(this);
2147  emit(0xD9);
2148  emit(0xE8);
2149 }
2150 
2151 
2152 void Assembler::fldz() {
2153  EnsureSpace ensure_space(this);
2154  emit(0xD9);
2155  emit(0xEE);
2156 }
2157 
2158 
2159 void Assembler::fldpi() {
2160  EnsureSpace ensure_space(this);
2161  emit(0xD9);
2162  emit(0xEB);
2163 }
2164 
2165 
2166 void Assembler::fldln2() {
2167  EnsureSpace ensure_space(this);
2168  emit(0xD9);
2169  emit(0xED);
2170 }
2171 
2172 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
2270 void Assembler::fabs() {
2271  EnsureSpace ensure_space(this);
2272  emit(0xD9);
2273  emit(0xE1);
2274 }
2275 
2276 
2277 void Assembler::fchs() {
2278  EnsureSpace ensure_space(this);
2279  emit(0xD9);
2280  emit(0xE0);
2281 }
2282 
2283 
2284 void Assembler::fcos() {
2285  EnsureSpace ensure_space(this);
2286  emit(0xD9);
2287  emit(0xFF);
2288 }
2289 
2290 
2291 void Assembler::fsin() {
2292  EnsureSpace ensure_space(this);
2293  emit(0xD9);
2294  emit(0xFE);
2295 }
2296 
2297 
2298 void Assembler::fptan() {
2299  EnsureSpace ensure_space(this);
2300  emit(0xD9);
2301  emit(0xF2);
2302 }
2303 
2304 
2305 void Assembler::fyl2x() {
2306  EnsureSpace ensure_space(this);
2307  emit(0xD9);
2308  emit(0xF1);
2309 }
2310 
2311 
2312 void Assembler::f2xm1() {
2313  EnsureSpace ensure_space(this);
2314  emit(0xD9);
2315  emit(0xF0);
2316 }
2317 
2318 
2319 void Assembler::fscale() {
2320  EnsureSpace ensure_space(this);
2321  emit(0xD9);
2322  emit(0xFD);
2323 }
2324 
2325 
2326 void Assembler::fninit() {
2327  EnsureSpace ensure_space(this);
2328  emit(0xDB);
2329  emit(0xE3);
2330 }
2331 
2332 
2333 void Assembler::fadd(int i) {
2334  EnsureSpace ensure_space(this);
2335  emit_farith(0xDC, 0xC0, i);
2336 }
2337 
2338 
2339 void Assembler::fsub(int i) {
2340  EnsureSpace ensure_space(this);
2341  emit_farith(0xDC, 0xE8, i);
2342 }
2343 
2344 
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 
2353 void Assembler::fmul(int i) {
2354  EnsureSpace ensure_space(this);
2355  emit_farith(0xDC, 0xC8, i);
2356 }
2357 
2358 
2359 void Assembler::fdiv(int i) {
2360  EnsureSpace ensure_space(this);
2361  emit_farith(0xDC, 0xF8, i);
2362 }
2363 
2364 
2365 void Assembler::faddp(int i) {
2366  EnsureSpace ensure_space(this);
2367  emit_farith(0xDE, 0xC0, i);
2368 }
2369 
2370 
2371 void Assembler::fsubp(int i) {
2372  EnsureSpace ensure_space(this);
2373  emit_farith(0xDE, 0xE8, i);
2374 }
2375 
2376 
2377 void Assembler::fsubrp(int i) {
2378  EnsureSpace ensure_space(this);
2379  emit_farith(0xDE, 0xE0, i);
2380 }
2381 
2382 
2383 void Assembler::fmulp(int i) {
2384  EnsureSpace ensure_space(this);
2385  emit_farith(0xDE, 0xC8, i);
2386 }
2387 
2388 
2389 void Assembler::fdivp(int i) {
2390  EnsureSpace ensure_space(this);
2391  emit_farith(0xDE, 0xF8, i);
2392 }
2393 
2394 
2395 void Assembler::fprem() {
2396  EnsureSpace ensure_space(this);
2397  emit(0xD9);
2398  emit(0xF8);
2399 }
2400 
2401 
2402 void Assembler::fprem1() {
2403  EnsureSpace ensure_space(this);
2404  emit(0xD9);
2405  emit(0xF5);
2406 }
2407 
2408 
2409 void Assembler::fxch(int i) {
2410  EnsureSpace ensure_space(this);
2411  emit_farith(0xD9, 0xC8, i);
2412 }
2413 
2414 
2415 void Assembler::fincstp() {
2416  EnsureSpace ensure_space(this);
2417  emit(0xD9);
2418  emit(0xF7);
2419 }
2420 
2421 
2422 void Assembler::ffree(int i) {
2423  EnsureSpace ensure_space(this);
2424  emit_farith(0xDD, 0xC0, i);
2425 }
2426 
2427 
2428 void Assembler::ftst() {
2429  EnsureSpace ensure_space(this);
2430  emit(0xD9);
2431  emit(0xE4);
2432 }
2433 
2434 
2435 void Assembler::fucomp(int i) {
2436  EnsureSpace ensure_space(this);
2437  emit_farith(0xDD, 0xE8, i);
2438 }
2439 
2440 
2441 void Assembler::fucompp() {
2442  EnsureSpace ensure_space(this);
2443  emit(0xDA);
2444  emit(0xE9);
2445 }
2446 
2447 
2448 void Assembler::fucomi(int i) {
2449  EnsureSpace ensure_space(this);
2450  emit(0xDB);
2451  emit(0xE8 + i);
2452 }
2453 
2454 
2455 void Assembler::fucomip() {
2456  EnsureSpace ensure_space(this);
2457  emit(0xDF);
2458  emit(0xE9);
2459 }
2460 
2461 
2462 void Assembler::fcompp() {
2463  EnsureSpace ensure_space(this);
2464  emit(0xDE);
2465  emit(0xD9);
2466 }
2467 
2468 
2469 void Assembler::fnstsw_ax() {
2470  EnsureSpace ensure_space(this);
2471  emit(0xDF);
2472  emit(0xE0);
2473 }
2474 
2475 
2476 void Assembler::fwait() {
2477  EnsureSpace ensure_space(this);
2478  emit(0x9B);
2479 }
2480 
2481 
2482 void Assembler::frndint() {
2483  EnsureSpace ensure_space(this);
2484  emit(0xD9);
2485  emit(0xFC);
2486 }
2487 
2488 
2489 void Assembler::fnclex() {
2490  EnsureSpace ensure_space(this);
2491  emit(0xDB);
2492  emit(0xE2);
2493 }
2494 
2495 
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 
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 
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 
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 
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 
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 
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 
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 
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 
2591 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
2965 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2966  Register ireg = { reg.code() };
2967  emit_operand(ireg, adr);
2968 }
2969 
2970 
2971 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2972  emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2973 }
2974 
2975 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2976  emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2977 }
2978 
2979 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2980  emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
2981 }
2982 
2983 
2984 void Assembler::db(uint8_t data) {
2985  EnsureSpace ensure_space(this);
2986  emit(data);
2987 }
2988 
2989 
2990 void Assembler::dd(uint32_t data) {
2991  EnsureSpace ensure_space(this);
2992  emitl(data);
2993 }
2994 
2995 
2996 // Relocation information implementations.
2997 
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()) {
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 
3016  positions_recorder()->WriteRecordedPositions();
3017  EnsureSpace ensure_space(this);
3018  RecordRelocInfo(RelocInfo::JS_RETURN);
3019 }
3020 
3021 
3023  positions_recorder()->WriteRecordedPositions();
3024  EnsureSpace ensure_space(this);
3025  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
3026 }
3027 
3028 
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 
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
byte * Address
Definition: globals.h:172
const Register rdx
void cvtlsi2ss(XMMRegister dst, Register src)
void movapd(XMMRegister dst, XMMRegister src)
static const int kMaximalBufferSize
Isolate * isolate() const
Definition: assembler.h:62
void db(uint8_t data)
void load_rax(void *ptr, RelocInfo::Mode rmode)
void ucomisd(XMMRegister dst, XMMRegister src)
void cvttss2si(Register dst, const Operand &src)
void movzxbl(Register dst, const Operand &src)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
#define FATAL(msg)
Definition: checks.h:46
bool buffer_overflow() const
const int kNumRegisters
Definition: constants-arm.h:95
void mulsd(XMMRegister dst, XMMRegister src)
const Register rbp
const int KB
Definition: globals.h:221
void cvtsd2si(Register dst, XMMRegister src)
void idivq(Register src)
void orpd(XMMRegister dst, XMMRegister src)
void dd(uint32_t data)
void push(Register src, Condition cond=al)
void cvtss2sd(XMMRegister dst, XMMRegister src)
void sqrtsd(XMMRegister dst, XMMRegister src)
int int32_t
Definition: unicode.cc:47
static bool IsSupported(CpuFeature f)
static bool enabled()
Definition: serialize.h:480
bool is_uint3(int x)
Definition: assembler.h:840
void andpd(XMMRegister dst, XMMRegister src)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
bool is_int8(int x)
Definition: assembler.h:830
Address address() const
Definition: ic-inl.h:41
static const int kMinimalBufferSize
#define ASSERT(condition)
Definition: checks.h:270
void cvtlsi2sd(XMMRegister dst, const Operand &src)
bool is_uint6(int x)
Definition: assembler.h:843
void movsxlq(Register dst, Register src)
void xorpd(XMMRegister dst, XMMRegister src)
void ret(int imm16)
void bt(const Operand &dst, Register src)
bool is_uint32(int64_t x)
Definition: assembler-x64.h:48
void incl(Register dst)
void cmovl(Condition cc, Register dst, Register src)
void testb(Register dst, Register src)
void fistp_s(const Operand &adr)
void imul(Register src)
void addsd(XMMRegister dst, XMMRegister src)
void fld_d(const Operand &adr)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 instructions(ARM only)") DEFINE_bool(enable_armv7
void imull(Register dst, Register src)
void cmpb_al(const Operand &op)
void xchg(Register dst, Register src)
void fild_s(const Operand &adr)
void decl(Register dst)
void idivl(Register src)
uint8_t byte
Definition: globals.h:171
void enter(const Immediate &size)
void testl(Register dst, Register src)
void movzxbq(Register dst, const Operand &src)
void shld(Register dst, Register src)
void fisttp_d(const Operand &adr)
void movss(XMMRegister dst, const Operand &src)
void movb(Register dst, const Operand &src)
void set_byte_at(int pos, byte value)
void cvtsd2ss(XMMRegister dst, XMMRegister src)
void negl(Register dst)
void movsd(XMMRegister dst, XMMRegister src)
void GetCode(CodeDesc *desc)
void movdqa(XMMRegister dst, const Operand &src)
void movsxbq(Register dst, const Operand &src)
static void TooLateToEnableNow()
Definition: serialize.h:479
void movmskpd(Register dst, XMMRegister src)
int(* F0)()
void fisttp_s(const Operand &adr)
void movzxwq(Register dst, const Operand &src)
bool is_uint5(int x)
Definition: assembler.h:842
const Register rbx
bool is_uint16(int x)
Definition: assembler.h:847
const Register rsp
static int32_t & int32_at(Address addr)
Definition: v8memory.h:51
void movzxwl(Register dst, const Operand &src)
#define __
const Register r12
void not_(Register dst)
const Register rax
void emit_sse_operand(XMMRegister reg, const Operand &adr)
const Register r13
const Register rdi
void cvtqsi2sd(XMMRegister dst, const Operand &src)
bool IsPowerOf2(T x)
Definition: utils.h:50
void xorps(XMMRegister dst, XMMRegister src)
void Nop(int bytes=1)
void neg(Register dst)
void setcc(Condition cc, Register reg)
void fld_s(const Operand &adr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
bool is_int32(int64_t x)
Definition: assembler-x64.h:53
void decq(Register dst)
void fstp_d(const Operand &adr)
void movw(Register reg, uint32_t immediate, Condition cond=al)
void store_rax(void *dst, RelocInfo::Mode mode)
void push_imm32(int32_t imm32)
void fistp_d(const Operand &adr)
void cvtsd2siq(Register dst, XMMRegister src)
void shrd(Register dst, Register src)
void movaps(XMMRegister dst, XMMRegister src)
void RecordComment(const char *msg)
void fstp_s(const Operand &adr)
void divsd(XMMRegister dst, XMMRegister src)
void lea(Register dst, const Operand &src)
void fild_d(const Operand &adr)
const Register rcx
Assembler(Isolate *isolate, void *buffer, int buffer_size)
#define HEAP
Definition: isolate.h:1408
void movl(Register dst, Register src)
#define ASSERT_EQ(v1, v2)
Definition: checks.h:271
void decb(Register dst)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
void notl(Register dst)
void testq(const Operand &op, Register reg)
void movd(XMMRegister dst, Register src)
PositionsRecorder * positions_recorder()
void fisub_s(const Operand &adr)
const Register r10
void extractps(Register dst, XMMRegister src, byte imm8)
static uint64_t CpuFeaturesImpliedByPlatform()
bool is_uint8(int x)
Definition: assembler.h:844
static void FlushICache(void *start, size_t size)
void fist_s(const Operand &adr)
void movsxwq(Register dst, const Operand &src)
void DeleteArray(T *array)
Definition: allocation.h:91
void bts(Register dst, Register src)
void cmovq(Condition cc, Register dst, Register src)
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
bool emit_debug_code() const
void subsd(XMMRegister dst, XMMRegister src)
void cvttsd2siq(Register dst, XMMRegister src)
void movq(const Operand &dst, Register src)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
void cvttsd2si(Register dst, const Operand &src)
void incq(Register dst)
void leal(Register dst, const Operand &src)
bool is_uint4(int x)
Definition: assembler.h:841