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