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