Upstream version 11.40.271.0
[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(const Operand& 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_operand(ecx, dst);
1037   } else {
1038     EMIT(0xC1);
1039     emit_operand(ecx, dst);
1040     EMIT(imm8);
1041   }
1042 }
1043
1044
1045 void Assembler::ror_cl(const Operand& dst) {
1046   EnsureSpace ensure_space(this);
1047   EMIT(0xD3);
1048   emit_operand(ecx, dst);
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, const Operand& 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, const Operand& 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, const Operand& 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::mulsd(XMMRegister dst, const Operand& src) {
2028   EnsureSpace ensure_space(this);
2029   EMIT(0xF2);
2030   EMIT(0x0F);
2031   EMIT(0x59);
2032   emit_sse_operand(dst, src);
2033 }
2034
2035
2036 void Assembler::subsd(XMMRegister dst, const Operand& src) {
2037   EnsureSpace ensure_space(this);
2038   EMIT(0xF2);
2039   EMIT(0x0F);
2040   EMIT(0x5C);
2041   emit_sse_operand(dst, src);
2042 }
2043
2044
2045 void Assembler::divsd(XMMRegister dst, const Operand& src) {
2046   EnsureSpace ensure_space(this);
2047   EMIT(0xF2);
2048   EMIT(0x0F);
2049   EMIT(0x5E);
2050   emit_sse_operand(dst, src);
2051 }
2052
2053
2054 void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
2055   EnsureSpace ensure_space(this);
2056   EMIT(0x66);
2057   EMIT(0x0F);
2058   EMIT(0x57);
2059   emit_sse_operand(dst, src);
2060 }
2061
2062
2063 void Assembler::xorpd(XMMRegister dst, const Operand& src) {
2064   EnsureSpace ensure_space(this);
2065   EMIT(0x66);
2066   EMIT(0x0F);
2067   EMIT(0x57);
2068   emit_sse_operand(dst, src);
2069 }
2070
2071
2072 void Assembler::andps(XMMRegister dst, const Operand& src) {
2073   EnsureSpace ensure_space(this);
2074   EMIT(0x0F);
2075   EMIT(0x54);
2076   emit_sse_operand(dst, src);
2077 }
2078
2079
2080 void Assembler::orps(XMMRegister dst, const Operand& src) {
2081   EnsureSpace ensure_space(this);
2082   EMIT(0x0F);
2083   EMIT(0x56);
2084   emit_sse_operand(dst, src);
2085 }
2086
2087
2088 void Assembler::xorps(XMMRegister dst, const Operand& src) {
2089   EnsureSpace ensure_space(this);
2090   EMIT(0x0F);
2091   EMIT(0x57);
2092   emit_sse_operand(dst, src);
2093 }
2094
2095
2096 void Assembler::addps(XMMRegister dst, const Operand& src) {
2097   EnsureSpace ensure_space(this);
2098   EMIT(0x0F);
2099   EMIT(0x58);
2100   emit_sse_operand(dst, src);
2101 }
2102
2103
2104 void Assembler::subps(XMMRegister dst, const Operand& src) {
2105   EnsureSpace ensure_space(this);
2106   EMIT(0x0F);
2107   EMIT(0x5C);
2108   emit_sse_operand(dst, src);
2109 }
2110
2111
2112 void Assembler::mulps(XMMRegister dst, const Operand& src) {
2113   EnsureSpace ensure_space(this);
2114   EMIT(0x0F);
2115   EMIT(0x59);
2116   emit_sse_operand(dst, src);
2117 }
2118
2119
2120 void Assembler::divps(XMMRegister dst, const Operand& src) {
2121   EnsureSpace ensure_space(this);
2122   EMIT(0x0F);
2123   EMIT(0x5E);
2124   emit_sse_operand(dst, src);
2125 }
2126
2127
2128 void Assembler::addpd(XMMRegister dst, const Operand& src) {
2129   EnsureSpace ensure_space(this);
2130   EMIT(0x66);
2131   EMIT(0x0F);
2132   EMIT(0x58);
2133   emit_sse_operand(dst, src);
2134 }
2135
2136
2137 void Assembler::subpd(XMMRegister dst, const Operand& src) {
2138   EnsureSpace ensure_space(this);
2139   EMIT(0x66);
2140   EMIT(0x0F);
2141   EMIT(0x5C);
2142   emit_sse_operand(dst, src);
2143 }
2144
2145
2146 void Assembler::mulpd(XMMRegister dst, const Operand& src) {
2147   EnsureSpace ensure_space(this);
2148   EMIT(0x66);
2149   EMIT(0x0F);
2150   EMIT(0x59);
2151   emit_sse_operand(dst, src);
2152 }
2153
2154
2155 void Assembler::divpd(XMMRegister dst, const Operand& src) {
2156   EnsureSpace ensure_space(this);
2157   EMIT(0x66);
2158   EMIT(0x0F);
2159   EMIT(0x5E);
2160   emit_sse_operand(dst, src);
2161 }
2162
2163
2164 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
2165   EnsureSpace ensure_space(this);
2166   EMIT(0xF2);
2167   EMIT(0x0F);
2168   EMIT(0x51);
2169   emit_sse_operand(dst, src);
2170 }
2171
2172
2173 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
2174   EnsureSpace ensure_space(this);
2175   EMIT(0x66);
2176   EMIT(0x0F);
2177   EMIT(0x54);
2178   emit_sse_operand(dst, src);
2179 }
2180
2181
2182 void Assembler::andpd(XMMRegister dst, const Operand& src) {
2183   EnsureSpace ensure_space(this);
2184   EMIT(0x66);
2185   EMIT(0x0F);
2186   EMIT(0x54);
2187   emit_sse_operand(dst, src);
2188 }
2189
2190
2191 void Assembler::orpd(XMMRegister dst, XMMRegister src) {
2192   EnsureSpace ensure_space(this);
2193   EMIT(0x66);
2194   EMIT(0x0F);
2195   EMIT(0x56);
2196   emit_sse_operand(dst, src);
2197 }
2198
2199
2200 void Assembler::ucomisd(XMMRegister dst, const Operand& src) {
2201   EnsureSpace ensure_space(this);
2202   EMIT(0x66);
2203   EMIT(0x0F);
2204   EMIT(0x2E);
2205   emit_sse_operand(dst, src);
2206 }
2207
2208
2209 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2210   DCHECK(IsEnabled(SSE4_1));
2211   EnsureSpace ensure_space(this);
2212   EMIT(0x66);
2213   EMIT(0x0F);
2214   EMIT(0x3A);
2215   EMIT(0x0B);
2216   emit_sse_operand(dst, src);
2217   // Mask precision exeption.
2218   EMIT(static_cast<byte>(mode) | 0x8);
2219 }
2220
2221
2222 void Assembler::movmskpd(Register dst, XMMRegister src) {
2223   EnsureSpace ensure_space(this);
2224   EMIT(0x66);
2225   EMIT(0x0F);
2226   EMIT(0x50);
2227   emit_sse_operand(dst, src);
2228 }
2229
2230
2231 void Assembler::movmskps(Register dst, XMMRegister src) {
2232   EnsureSpace ensure_space(this);
2233   EMIT(0x0F);
2234   EMIT(0x50);
2235   emit_sse_operand(dst, src);
2236 }
2237
2238
2239 void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
2240   EnsureSpace ensure_space(this);
2241   EMIT(0x66);
2242   EMIT(0x0F);
2243   EMIT(0x76);
2244   emit_sse_operand(dst, src);
2245 }
2246
2247
2248 void Assembler::pcmpgtd(XMMRegister dst, XMMRegister src) {
2249   EnsureSpace ensure_space(this);
2250   EMIT(0x66);
2251   EMIT(0x0F);
2252   EMIT(0x66);
2253   emit_sse_operand(dst, src);
2254 }
2255
2256
2257 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2258   EnsureSpace ensure_space(this);
2259   EMIT(0xF2);
2260   EMIT(0x0F);
2261   EMIT(0xC2);
2262   emit_sse_operand(dst, src);
2263   EMIT(1);  // LT == 1
2264 }
2265
2266
2267 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2268   EnsureSpace ensure_space(this);
2269   EMIT(0x0F);
2270   EMIT(0x28);
2271   emit_sse_operand(dst, src);
2272 }
2273
2274
2275 void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
2276   EnsureSpace ensure_space(this);
2277   EMIT(0x0F);
2278   EMIT(0x16);
2279   emit_sse_operand(dst, src);
2280 }
2281
2282
2283 void Assembler::movhlps(XMMRegister dst, XMMRegister src) {
2284   EnsureSpace ensure_space(this);
2285   EMIT(0x0F);
2286   EMIT(0x12);
2287   emit_sse_operand(dst, src);
2288 }
2289
2290
2291 void Assembler::movups(XMMRegister dst, const Operand& src) {
2292   EnsureSpace ensure_space(this);
2293   EMIT(0x0F);
2294   EMIT(0x10);
2295   emit_sse_operand(dst, src);
2296 }
2297
2298
2299 void Assembler::movups(const Operand& dst, XMMRegister src) {
2300   EnsureSpace ensure_space(this);
2301   EMIT(0x0F);
2302   EMIT(0x11);
2303   emit_sse_operand(src, dst);
2304 }
2305
2306
2307 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2308   DCHECK(is_uint8(imm8));
2309   EnsureSpace ensure_space(this);
2310   EMIT(0x0F);
2311   EMIT(0xC6);
2312   emit_sse_operand(dst, src);
2313   EMIT(imm8);
2314 }
2315
2316
2317 void Assembler::shufpd(XMMRegister dst, XMMRegister src, byte imm8) {
2318     DCHECK(is_uint8(imm8));
2319   EnsureSpace ensure_space(this);
2320   EMIT(0x66);
2321   EMIT(0x0F);
2322   EMIT(0xC6);
2323   emit_sse_operand(dst, src);
2324   EMIT(imm8);
2325 }
2326
2327
2328 void Assembler::movdqa(const Operand& dst, XMMRegister src) {
2329   EnsureSpace ensure_space(this);
2330   EMIT(0x66);
2331   EMIT(0x0F);
2332   EMIT(0x7F);
2333   emit_sse_operand(src, dst);
2334 }
2335
2336
2337 void Assembler::movdqa(XMMRegister dst, const Operand& src) {
2338   EnsureSpace ensure_space(this);
2339   EMIT(0x66);
2340   EMIT(0x0F);
2341   EMIT(0x6F);
2342   emit_sse_operand(dst, src);
2343 }
2344
2345
2346 void Assembler::movdqu(const Operand& dst, XMMRegister src ) {
2347   EnsureSpace ensure_space(this);
2348   EMIT(0xF3);
2349   EMIT(0x0F);
2350   EMIT(0x7F);
2351   emit_sse_operand(src, dst);
2352 }
2353
2354
2355 void Assembler::movdqu(XMMRegister dst, const Operand& src) {
2356   EnsureSpace ensure_space(this);
2357   EMIT(0xF3);
2358   EMIT(0x0F);
2359   EMIT(0x6F);
2360   emit_sse_operand(dst, src);
2361 }
2362
2363
2364 void Assembler::movntdqa(XMMRegister dst, const Operand& src) {
2365   DCHECK(IsEnabled(SSE4_1));
2366   EnsureSpace ensure_space(this);
2367   EMIT(0x66);
2368   EMIT(0x0F);
2369   EMIT(0x38);
2370   EMIT(0x2A);
2371   emit_sse_operand(dst, src);
2372 }
2373
2374
2375 void Assembler::movntdq(const Operand& dst, XMMRegister src) {
2376   EnsureSpace ensure_space(this);
2377   EMIT(0x66);
2378   EMIT(0x0F);
2379   EMIT(0xE7);
2380   emit_sse_operand(src, dst);
2381 }
2382
2383
2384 void Assembler::prefetch(const Operand& src, int level) {
2385   DCHECK(is_uint2(level));
2386   EnsureSpace ensure_space(this);
2387   EMIT(0x0F);
2388   EMIT(0x18);
2389   // Emit hint number in Reg position of RegR/M.
2390   XMMRegister code = XMMRegister::from_code(level);
2391   emit_sse_operand(code, src);
2392 }
2393
2394
2395 void Assembler::movsd(const Operand& dst, XMMRegister src ) {
2396   EnsureSpace ensure_space(this);
2397   EMIT(0xF2);  // double
2398   EMIT(0x0F);
2399   EMIT(0x11);  // store
2400   emit_sse_operand(src, dst);
2401 }
2402
2403
2404 void Assembler::movsd(XMMRegister dst, const Operand& src) {
2405   EnsureSpace ensure_space(this);
2406   EMIT(0xF2);  // double
2407   EMIT(0x0F);
2408   EMIT(0x10);  // load
2409   emit_sse_operand(dst, src);
2410 }
2411
2412
2413 void Assembler::movss(const Operand& dst, XMMRegister src ) {
2414   EnsureSpace ensure_space(this);
2415   EMIT(0xF3);  // float
2416   EMIT(0x0F);
2417   EMIT(0x11);  // store
2418   emit_sse_operand(src, dst);
2419 }
2420
2421
2422 void Assembler::movss(XMMRegister dst, const Operand& src) {
2423   EnsureSpace ensure_space(this);
2424   EMIT(0xF3);  // float
2425   EMIT(0x0F);
2426   EMIT(0x10);  // load
2427   emit_sse_operand(dst, src);
2428 }
2429
2430
2431 void Assembler::movq(const Operand& dst, XMMRegister src ) {
2432   EnsureSpace ensure_space(this);
2433   EMIT(0x66);
2434   EMIT(0x0F);
2435   EMIT(0xD6);  // store
2436   emit_sse_operand(src, dst);
2437 }
2438
2439
2440 void Assembler::movq(XMMRegister dst, const Operand& src) {
2441   EnsureSpace ensure_space(this);
2442   EMIT(0xF3);
2443   EMIT(0x0F);
2444   EMIT(0x7E);  // load
2445   emit_sse_operand(dst, src);
2446 }
2447
2448
2449 void Assembler::movd(XMMRegister dst, const Operand& src) {
2450   EnsureSpace ensure_space(this);
2451   EMIT(0x66);
2452   EMIT(0x0F);
2453   EMIT(0x6E);
2454   emit_sse_operand(dst, src);
2455 }
2456
2457
2458 void Assembler::movd(const Operand& dst, XMMRegister src) {
2459   EnsureSpace ensure_space(this);
2460   EMIT(0x66);
2461   EMIT(0x0F);
2462   EMIT(0x7E);
2463   emit_sse_operand(src, dst);
2464 }
2465
2466
2467 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2468   DCHECK(IsEnabled(SSE4_1));
2469   DCHECK(is_uint8(imm8));
2470   EnsureSpace ensure_space(this);
2471   EMIT(0x66);
2472   EMIT(0x0F);
2473   EMIT(0x3A);
2474   EMIT(0x17);
2475   emit_sse_operand(src, dst);
2476   EMIT(imm8);
2477 }
2478
2479
2480 void Assembler::pand(XMMRegister dst, XMMRegister src) {
2481   EnsureSpace ensure_space(this);
2482   EMIT(0x66);
2483   EMIT(0x0F);
2484   EMIT(0xDB);
2485   emit_sse_operand(dst, src);
2486 }
2487
2488
2489 void Assembler::pxor(XMMRegister dst, XMMRegister src) {
2490   EnsureSpace ensure_space(this);
2491   EMIT(0x66);
2492   EMIT(0x0F);
2493   EMIT(0xEF);
2494   emit_sse_operand(dst, src);
2495 }
2496
2497
2498 void Assembler::por(XMMRegister dst, XMMRegister src) {
2499   EnsureSpace ensure_space(this);
2500   EMIT(0x66);
2501   EMIT(0x0F);
2502   EMIT(0xEB);
2503   emit_sse_operand(dst, src);
2504 }
2505
2506
2507 void Assembler::ptest(XMMRegister dst, XMMRegister src) {
2508   DCHECK(IsEnabled(SSE4_1));
2509   EnsureSpace ensure_space(this);
2510   EMIT(0x66);
2511   EMIT(0x0F);
2512   EMIT(0x38);
2513   EMIT(0x17);
2514   emit_sse_operand(dst, src);
2515 }
2516
2517
2518 void Assembler::pslld(XMMRegister reg, int8_t shift) {
2519   EnsureSpace ensure_space(this);
2520   EMIT(0x66);
2521   EMIT(0x0F);
2522   EMIT(0x72);
2523   emit_sse_operand(esi, reg);  // esi == 6
2524   EMIT(shift);
2525 }
2526
2527
2528 void Assembler::psrld(XMMRegister reg, int8_t shift) {
2529   EnsureSpace ensure_space(this);
2530   EMIT(0x66);
2531   EMIT(0x0F);
2532   EMIT(0x72);
2533   emit_sse_operand(edx, reg);  // edx == 2
2534   EMIT(shift);
2535 }
2536
2537
2538 void Assembler::psllq(XMMRegister reg, int8_t shift) {
2539   EnsureSpace ensure_space(this);
2540   EMIT(0x66);
2541   EMIT(0x0F);
2542   EMIT(0x73);
2543   emit_sse_operand(esi, reg);  // esi == 6
2544   EMIT(shift);
2545 }
2546
2547
2548 void Assembler::psllq(XMMRegister dst, XMMRegister src) {
2549   EnsureSpace ensure_space(this);
2550   EMIT(0x66);
2551   EMIT(0x0F);
2552   EMIT(0xF3);
2553   emit_sse_operand(dst, src);
2554 }
2555
2556
2557 void Assembler::pslld(XMMRegister dst, XMMRegister src) {
2558   EnsureSpace ensure_space(this);
2559   EMIT(0x66);
2560   EMIT(0x0F);
2561   EMIT(0xF2);
2562   emit_sse_operand(dst, src);
2563 }
2564
2565
2566 void Assembler::psrld(XMMRegister dst, XMMRegister src) {
2567   EnsureSpace ensure_space(this);
2568   EMIT(0x66);
2569   EMIT(0x0F);
2570   EMIT(0xD2);
2571   emit_sse_operand(dst, src);
2572 }
2573
2574
2575 void Assembler::psrad(XMMRegister reg, int8_t shift) {
2576   EnsureSpace ensure_space(this);
2577   EMIT(0x66);
2578   EMIT(0x0F);
2579   EMIT(0x72);
2580   emit_sse_operand(esp, reg);  // esp == 4
2581   EMIT(shift);
2582 }
2583
2584
2585 void Assembler::psrad(XMMRegister dst, XMMRegister src) {
2586   EnsureSpace ensure_space(this);
2587   EMIT(0x66);
2588   EMIT(0x0F);
2589   EMIT(0xE2);
2590   emit_sse_operand(dst, src);
2591 }
2592
2593
2594 void Assembler::psrlq(XMMRegister reg, int8_t shift) {
2595   EnsureSpace ensure_space(this);
2596   EMIT(0x66);
2597   EMIT(0x0F);
2598   EMIT(0x73);
2599   emit_sse_operand(edx, reg);  // edx == 2
2600   EMIT(shift);
2601 }
2602
2603
2604 void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
2605   EnsureSpace ensure_space(this);
2606   EMIT(0x66);
2607   EMIT(0x0F);
2608   EMIT(0xD3);
2609   emit_sse_operand(dst, src);
2610 }
2611
2612
2613 void Assembler::psrldq(XMMRegister dst, int8_t shift) {
2614   EnsureSpace ensure_space(this);
2615   EMIT(0x66);
2616   EMIT(0x0F);
2617   EMIT(0x73);
2618   emit_sse_operand(ebx, dst);   // ebx == 3
2619   EMIT(shift);
2620 }
2621
2622
2623 void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
2624   EnsureSpace ensure_space(this);
2625   EMIT(0x66);
2626   EMIT(0x0F);
2627   EMIT(0x70);
2628   emit_sse_operand(dst, src);
2629   EMIT(shuffle);
2630 }
2631
2632
2633 void Assembler::pextrd(const Operand& dst, XMMRegister src, int8_t offset) {
2634   DCHECK(IsEnabled(SSE4_1));
2635   EnsureSpace ensure_space(this);
2636   EMIT(0x66);
2637   EMIT(0x0F);
2638   EMIT(0x3A);
2639   EMIT(0x16);
2640   emit_sse_operand(src, dst);
2641   EMIT(offset);
2642 }
2643
2644
2645 void Assembler::pinsrd(XMMRegister dst, const Operand& src, int8_t offset) {
2646   DCHECK(IsEnabled(SSE4_1));
2647   EnsureSpace ensure_space(this);
2648   EMIT(0x66);
2649   EMIT(0x0F);
2650   EMIT(0x3A);
2651   EMIT(0x22);
2652   emit_sse_operand(dst, src);
2653   EMIT(offset);
2654 }
2655
2656
2657 void Assembler::minps(XMMRegister dst, const Operand& src) {
2658   EnsureSpace ensure_space(this);
2659   EMIT(0x0F);
2660   EMIT(0x5D);
2661   emit_sse_operand(dst, src);
2662 }
2663
2664
2665 void Assembler::maxps(XMMRegister dst, const Operand& src) {
2666   EnsureSpace ensure_space(this);
2667   EMIT(0x0F);
2668   EMIT(0x5F);
2669   emit_sse_operand(dst, src);
2670 }
2671
2672
2673 void Assembler::minpd(XMMRegister dst, const Operand& src) {
2674   EnsureSpace ensure_space(this);
2675   EMIT(0x66);
2676   EMIT(0x0F);
2677   EMIT(0x5D);
2678   emit_sse_operand(dst, src);
2679 }
2680
2681
2682 void Assembler::maxpd(XMMRegister dst, const Operand& src) {
2683   EnsureSpace ensure_space(this);
2684   EMIT(0x66);
2685   EMIT(0x0F);
2686   EMIT(0x5F);
2687   emit_sse_operand(dst, src);
2688 }
2689
2690
2691 void Assembler::rcpps(XMMRegister dst, const Operand& src) {
2692   EnsureSpace ensure_space(this);
2693   EMIT(0x0F);
2694   EMIT(0x53);
2695   emit_sse_operand(dst, src);
2696 }
2697
2698
2699 void Assembler::rsqrtps(XMMRegister dst, const Operand& src) {
2700   EnsureSpace ensure_space(this);
2701   EMIT(0x0F);
2702   EMIT(0x52);
2703   emit_sse_operand(dst, src);
2704 }
2705
2706
2707 void Assembler::sqrtps(XMMRegister dst, const Operand& src) {
2708   EnsureSpace ensure_space(this);
2709   EMIT(0x0F);
2710   EMIT(0x51);
2711   emit_sse_operand(dst, src);
2712 }
2713
2714
2715 void Assembler::sqrtpd(XMMRegister dst, const Operand& src) {
2716   EnsureSpace ensure_space(this);
2717   EMIT(0x66);
2718   EMIT(0x0F);
2719   EMIT(0x51);
2720   emit_sse_operand(dst, src);
2721 }
2722
2723
2724 void Assembler::cvtdq2ps(XMMRegister dst, const Operand& src) {
2725   EnsureSpace ensure_space(this);
2726   EMIT(0x0F);
2727   EMIT(0x5B);
2728   emit_sse_operand(dst, src);
2729 }
2730
2731
2732 void Assembler::paddd(XMMRegister dst, const Operand& src) {
2733   EnsureSpace ensure_space(this);
2734   EMIT(0x66);
2735   EMIT(0x0F);
2736   EMIT(0xFE);
2737   emit_sse_operand(dst, src);
2738 }
2739
2740
2741 void Assembler::psubd(XMMRegister dst, const Operand& src) {
2742   EnsureSpace ensure_space(this);
2743   EMIT(0x66);
2744   EMIT(0x0F);
2745   EMIT(0xFA);
2746   emit_sse_operand(dst, src);
2747 }
2748
2749
2750 void Assembler::pmulld(XMMRegister dst, const Operand& src) {
2751   DCHECK(IsEnabled(SSE4_1));
2752   EnsureSpace ensure_space(this);
2753   EMIT(0x66);
2754   EMIT(0x0F);
2755   EMIT(0x38);
2756   EMIT(0x40);
2757   emit_sse_operand(dst, src);
2758 }
2759
2760
2761 void Assembler::pmuludq(XMMRegister dst, const Operand& src) {
2762   EnsureSpace ensure_space(this);
2763   EMIT(0x66);
2764   EMIT(0x0F);
2765   EMIT(0xF4);
2766   emit_sse_operand(dst, src);
2767 }
2768
2769
2770 void Assembler::punpackldq(XMMRegister dst, const Operand& src) {
2771   EnsureSpace ensure_space(this);
2772   EMIT(0x66);
2773   EMIT(0x0F);
2774   EMIT(0x62);
2775   emit_sse_operand(dst, src);
2776 }
2777
2778
2779 void Assembler::cvtps2dq(XMMRegister dst, const Operand& src) {
2780   EnsureSpace ensure_space(this);
2781   EMIT(0x66);
2782   EMIT(0x0F);
2783   EMIT(0x5B);
2784   emit_sse_operand(dst, src);
2785 }
2786
2787
2788 void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
2789   EnsureSpace ensure_space(this);
2790   EMIT(0x0F);
2791   EMIT(0xC2);
2792   emit_sse_operand(dst, src);
2793   EMIT(cmp);
2794 }
2795
2796
2797 void Assembler::cmpeqps(XMMRegister dst, XMMRegister src) {
2798   cmpps(dst, src, 0x0);
2799 }
2800
2801
2802 void Assembler::cmpltps(XMMRegister dst, XMMRegister src) {
2803   cmpps(dst, src, 0x1);
2804 }
2805
2806
2807 void Assembler::cmpleps(XMMRegister dst, XMMRegister src) {
2808   cmpps(dst, src, 0x2);
2809 }
2810
2811
2812 void Assembler::cmpneqps(XMMRegister dst, XMMRegister src) {
2813   cmpps(dst, src, 0x4);
2814 }
2815
2816
2817 void Assembler::cmpnltps(XMMRegister dst, XMMRegister src) {
2818   cmpps(dst, src, 0x5);
2819 }
2820
2821
2822 void Assembler::cmpnleps(XMMRegister dst, XMMRegister src) {
2823   cmpps(dst, src, 0x6);
2824 }
2825
2826
2827 void Assembler::insertps(XMMRegister dst, XMMRegister src, byte imm8) {
2828   DCHECK(CpuFeatures::IsSupported(SSE4_1));
2829   DCHECK(is_uint8(imm8));
2830   EnsureSpace ensure_space(this);
2831   EMIT(0x66);
2832   EMIT(0x0F);
2833   EMIT(0x3A);
2834   EMIT(0x21);
2835   emit_sse_operand(dst, src);
2836   EMIT(imm8);
2837 }
2838
2839
2840 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
2841   Register ireg = { reg.code() };
2842   emit_operand(ireg, adr);
2843 }
2844
2845
2846 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
2847   EMIT(0xC0 | dst.code() << 3 | src.code());
2848 }
2849
2850
2851 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
2852   EMIT(0xC0 | dst.code() << 3 | src.code());
2853 }
2854
2855
2856 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
2857   EMIT(0xC0 | (dst.code() << 3) | src.code());
2858 }
2859
2860
2861 void Assembler::RecordJSReturn() {
2862   positions_recorder()->WriteRecordedPositions();
2863   EnsureSpace ensure_space(this);
2864   RecordRelocInfo(RelocInfo::JS_RETURN);
2865 }
2866
2867
2868 void Assembler::RecordDebugBreakSlot() {
2869   positions_recorder()->WriteRecordedPositions();
2870   EnsureSpace ensure_space(this);
2871   RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2872 }
2873
2874
2875 void Assembler::RecordComment(const char* msg, bool force) {
2876   if (FLAG_code_comments || force) {
2877   EnsureSpace ensure_space(this);
2878     RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
2879   }
2880 }
2881
2882
2883 void Assembler::GrowBuffer() {
2884   DCHECK(buffer_overflow());
2885   if (!own_buffer_) FATAL("external code buffer is too small");
2886
2887   // Compute new buffer size.
2888   CodeDesc desc;  // the new buffer
2889   desc.buffer_size = 2 * buffer_size_;
2890
2891   // Some internal data structures overflow for very large buffers,
2892   // they must ensure that kMaximalBufferSize is not too large.
2893   if ((desc.buffer_size > kMaximalBufferSize) ||
2894       (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
2895     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
2896   }
2897
2898   // Set up new buffer.
2899   desc.buffer = NewArray<byte>(desc.buffer_size);
2900   desc.instr_size = pc_offset();
2901   desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
2902
2903   // Clear the buffer in debug mode. Use 'int3' instructions to make
2904   // sure to get into problems if we ever run uninitialized code.
2905 #ifdef DEBUG
2906   memset(desc.buffer, 0xCC, desc.buffer_size);
2907 #endif
2908
2909   // Copy the data.
2910   int pc_delta = desc.buffer - buffer_;
2911   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2912   MemMove(desc.buffer, buffer_, desc.instr_size);
2913   MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
2914           desc.reloc_size);
2915
2916   // Switch buffers.
2917   DeleteArray(buffer_);
2918   buffer_ = desc.buffer;
2919   buffer_size_ = desc.buffer_size;
2920   pc_ += pc_delta;
2921   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2922                                reloc_info_writer.last_pc() + pc_delta);
2923
2924   // Relocate runtime entries.
2925   for (RelocIterator it(desc); !it.done(); it.next()) {
2926     RelocInfo::Mode rmode = it.rinfo()->rmode();
2927     if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2928       int32_t* p = reinterpret_cast<int32_t*>(it.rinfo()->pc());
2929       if (*p != 0) {  // 0 means uninitialized.
2930         *p += pc_delta;
2931       }
2932     }
2933   }
2934
2935   DCHECK(!buffer_overflow());
2936 }
2937
2938
2939 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
2940   DCHECK(is_uint8(op1) && is_uint8(op2));  // wrong opcode
2941   DCHECK(is_uint8(imm8));
2942   DCHECK((op1 & 0x01) == 0);  // should be 8bit operation
2943   EMIT(op1);
2944   EMIT(op2 | dst.code());
2945   EMIT(imm8);
2946 }
2947
2948
2949 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
2950   DCHECK((0 <= sel) && (sel <= 7));
2951   Register ireg = { sel };
2952   if (x.is_int8()) {
2953     EMIT(0x83);  // using a sign-extended 8-bit immediate.
2954     emit_operand(ireg, dst);
2955     EMIT(x.x_ & 0xFF);
2956   } else if (dst.is_reg(eax)) {
2957     EMIT((sel << 3) | 0x05);  // short form if the destination is eax.
2958     emit(x);
2959   } else {
2960     EMIT(0x81);  // using a literal 32-bit immediate.
2961     emit_operand(ireg, dst);
2962     emit(x);
2963   }
2964 }
2965
2966
2967 void Assembler::emit_operand(Register reg, const Operand& adr) {
2968   const unsigned length = adr.len_;
2969   DCHECK(length > 0);
2970
2971   // Emit updated ModRM byte containing the given register.
2972   pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2973
2974   // Emit the rest of the encoded operand.
2975   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
2976   pc_ += length;
2977
2978   // Emit relocation information if necessary.
2979   if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
2980     pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
2981     RecordRelocInfo(adr.rmode_);
2982     pc_ += sizeof(int32_t);
2983   }
2984 }
2985
2986
2987 void Assembler::emit_farith(int b1, int b2, int i) {
2988   DCHECK(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2989   DCHECK(0 <= i &&  i < 8);  // illegal stack offset
2990   EMIT(b1);
2991   EMIT(b2 + i);
2992 }
2993
2994
2995 void Assembler::db(uint8_t data) {
2996   EnsureSpace ensure_space(this);
2997   EMIT(data);
2998 }
2999
3000
3001 void Assembler::dd(uint32_t data) {
3002   EnsureSpace ensure_space(this);
3003   emit(data);
3004 }
3005
3006
3007 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3008   DCHECK(!RelocInfo::IsNone(rmode));
3009   // Don't record external references unless the heap will be serialized.
3010   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
3011       !serializer_enabled() && !emit_debug_code()) {
3012     return;
3013   }
3014   RelocInfo rinfo(pc_, rmode, data, NULL);
3015   reloc_info_writer.Write(&rinfo);
3016 }
3017
3018
3019 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
3020   // No out-of-line constant pool support.
3021   DCHECK(!FLAG_enable_ool_constant_pool);
3022   return isolate->factory()->empty_constant_pool_array();
3023 }
3024
3025
3026 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
3027   // No out-of-line constant pool support.
3028   DCHECK(!FLAG_enable_ool_constant_pool);
3029   return;
3030 }
3031
3032
3033 #ifdef GENERATED_CODE_COVERAGE
3034 static FILE* coverage_log = NULL;
3035
3036
3037 static void InitCoverageLog() {
3038   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
3039   if (file_name != NULL) {
3040     coverage_log = fopen(file_name, "aw+");
3041   }
3042 }
3043
3044
3045 void LogGeneratedCodeCoverage(const char* file_line) {
3046   const char* return_address = (&file_line)[-1];
3047   char* push_insn = const_cast<char*>(return_address - 12);
3048   push_insn[0] = 0xeb;  // Relative branch insn.
3049   push_insn[1] = 13;    // Skip over coverage insns.
3050   if (coverage_log != NULL) {
3051     fprintf(coverage_log, "%s\n", file_line);
3052     fflush(coverage_log);
3053   }
3054 }
3055
3056 #endif
3057
3058 } }  // namespace v8::internal
3059
3060 #endif  // V8_TARGET_ARCH_IA32