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