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