f2db021b69dba779676100807790a57f15003880
[platform/upstream/nodejs.git] / deps / v8 / src / x87 / assembler-x87.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_X87
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
56   // Only use statically determined features for cross compile (snapshot).
57   if (cross_compile) return;
58 }
59
60
61 void CpuFeatures::PrintTarget() { }
62 void CpuFeatures::PrintFeatures() { }
63
64
65 // -----------------------------------------------------------------------------
66 // Implementation of Displacement
67
68 void Displacement::init(Label* L, Type type) {
69   DCHECK(!L->is_bound());
70   int next = 0;
71   if (L->is_linked()) {
72     next = L->pos();
73     DCHECK(next > 0);  // Displacements must be at positions > 0
74   }
75   // Ensure that we _never_ overflow the next field.
76   DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
77   data_ = NextField::encode(next) | TypeField::encode(type);
78 }
79
80
81 // -----------------------------------------------------------------------------
82 // Implementation of RelocInfo
83
84
85 const int RelocInfo::kApplyMask =
86   RelocInfo::kCodeTargetMask | 1 << RelocInfo::RUNTIME_ENTRY |
87     1 << RelocInfo::JS_RETURN | 1 << RelocInfo::INTERNAL_REFERENCE |
88     1 << RelocInfo::DEBUG_BREAK_SLOT | 1 << RelocInfo::CODE_AGE_SEQUENCE;
89
90
91 bool RelocInfo::IsCodedSpecially() {
92   // The deserializer needs to know whether a pointer is specially coded.  Being
93   // specially coded on IA32 means that it is a relative address, as used by
94   // branch instructions.  These are also the ones that need changing when a
95   // code object moves.
96   return (1 << rmode_) & kApplyMask;
97 }
98
99
100 bool RelocInfo::IsInConstantPool() {
101   return false;
102 }
103
104
105 void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
106   // Patch the code at the current address with the supplied instructions.
107   for (int i = 0; i < instruction_count; i++) {
108     *(pc_ + i) = *(instructions + i);
109   }
110
111   // Indicate that code has changed.
112   CpuFeatures::FlushICache(pc_, instruction_count);
113 }
114
115
116 // Patch the code at the current PC with a call to the target address.
117 // Additional guard int3 instructions can be added if required.
118 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
119   // Call instruction takes up 5 bytes and int3 takes up one byte.
120   static const int kCallCodeSize = 5;
121   int code_size = kCallCodeSize + guard_bytes;
122
123   // Create a code patcher.
124   CodePatcher patcher(pc_, code_size);
125
126   // Add a label for checking the size of the code used for returning.
127 #ifdef DEBUG
128   Label check_codesize;
129   patcher.masm()->bind(&check_codesize);
130 #endif
131
132   // Patch the code.
133   patcher.masm()->call(target, RelocInfo::NONE32);
134
135   // Check that the size of the code generated is as expected.
136   DCHECK_EQ(kCallCodeSize,
137             patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
138
139   // Add the requested number of int3 instructions after the call.
140   DCHECK_GE(guard_bytes, 0);
141   for (int i = 0; i < guard_bytes; i++) {
142     patcher.masm()->int3();
143   }
144 }
145
146
147 // -----------------------------------------------------------------------------
148 // Implementation of Operand
149
150 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
151   // [base + disp/r]
152   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
153     // [base]
154     set_modrm(0, base);
155     if (base.is(esp)) set_sib(times_1, esp, base);
156   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
157     // [base + disp8]
158     set_modrm(1, base);
159     if (base.is(esp)) set_sib(times_1, esp, base);
160     set_disp8(disp);
161   } else {
162     // [base + disp/r]
163     set_modrm(2, base);
164     if (base.is(esp)) set_sib(times_1, esp, base);
165     set_dispr(disp, rmode);
166   }
167 }
168
169
170 Operand::Operand(Register base,
171                  Register index,
172                  ScaleFactor scale,
173                  int32_t disp,
174                  RelocInfo::Mode rmode) {
175   DCHECK(!index.is(esp));  // illegal addressing mode
176   // [base + index*scale + disp/r]
177   if (disp == 0 && RelocInfo::IsNone(rmode) && !base.is(ebp)) {
178     // [base + index*scale]
179     set_modrm(0, esp);
180     set_sib(scale, index, base);
181   } else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
182     // [base + index*scale + disp8]
183     set_modrm(1, esp);
184     set_sib(scale, index, base);
185     set_disp8(disp);
186   } else {
187     // [base + index*scale + disp/r]
188     set_modrm(2, esp);
189     set_sib(scale, index, base);
190     set_dispr(disp, rmode);
191   }
192 }
193
194
195 Operand::Operand(Register index,
196                  ScaleFactor scale,
197                  int32_t disp,
198                  RelocInfo::Mode rmode) {
199   DCHECK(!index.is(esp));  // illegal addressing mode
200   // [index*scale + disp/r]
201   set_modrm(0, esp);
202   set_sib(scale, index, ebp);
203   set_dispr(disp, rmode);
204 }
205
206
207 bool Operand::is_reg(Register reg) const {
208   return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
209       && ((buf_[0] & 0x07) == reg.code());  // register codes match.
210 }
211
212
213 bool Operand::is_reg_only() const {
214   return (buf_[0] & 0xF8) == 0xC0;  // Addressing mode is register only.
215 }
216
217
218 Register Operand::reg() const {
219   DCHECK(is_reg_only());
220   return Register::from_code(buf_[0] & 0x07);
221 }
222
223
224 // -----------------------------------------------------------------------------
225 // Implementation of Assembler.
226
227 // Emit a single byte. Must always be inlined.
228 #define EMIT(x)                                 \
229   *pc_++ = (x)
230
231
232 #ifdef GENERATED_CODE_COVERAGE
233 static void InitCoverageLog();
234 #endif
235
236 Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
237     : AssemblerBase(isolate, buffer, buffer_size),
238       positions_recorder_(this) {
239   // Clear the buffer in debug mode unless it was provided by the
240   // caller in which case we can't be sure it's okay to overwrite
241   // existing code in it; see CodePatcher::CodePatcher(...).
242 #ifdef DEBUG
243   if (own_buffer_) {
244     memset(buffer_, 0xCC, buffer_size_);  // int3
245   }
246 #endif
247
248   reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
249
250 #ifdef GENERATED_CODE_COVERAGE
251   InitCoverageLog();
252 #endif
253 }
254
255
256 void Assembler::GetCode(CodeDesc* desc) {
257   // Finalize code (at this point overflow() may be true, but the gap ensures
258   // that we are still not overlapping instructions and relocation info).
259   reloc_info_writer.Finish();
260   DCHECK(pc_ <= reloc_info_writer.pos());  // No overlap.
261   // Set up code descriptor.
262   desc->buffer = buffer_;
263   desc->buffer_size = buffer_size_;
264   desc->instr_size = pc_offset();
265   desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
266   desc->origin = this;
267 }
268
269
270 void Assembler::Align(int m) {
271   DCHECK(base::bits::IsPowerOfTwo32(m));
272   int mask = m - 1;
273   int addr = pc_offset();
274   Nop((m - (addr & mask)) & mask);
275 }
276
277
278 bool Assembler::IsNop(Address addr) {
279   Address a = addr;
280   while (*a == 0x66) a++;
281   if (*a == 0x90) return true;
282   if (a[0] == 0xf && a[1] == 0x1f) return true;
283   return false;
284 }
285
286
287 void Assembler::Nop(int bytes) {
288   EnsureSpace ensure_space(this);
289
290   // Older CPUs that do not support SSE2 may not support multibyte NOP
291   // instructions.
292   for (; bytes > 0; bytes--) {
293     EMIT(0x90);
294   }
295   return;
296 }
297
298
299 void Assembler::CodeTargetAlign() {
300   Align(16);  // Preferred alignment of jump targets on ia32.
301 }
302
303
304 void Assembler::cpuid() {
305   EnsureSpace ensure_space(this);
306   EMIT(0x0F);
307   EMIT(0xA2);
308 }
309
310
311 void Assembler::pushad() {
312   EnsureSpace ensure_space(this);
313   EMIT(0x60);
314 }
315
316
317 void Assembler::popad() {
318   EnsureSpace ensure_space(this);
319   EMIT(0x61);
320 }
321
322
323 void Assembler::pushfd() {
324   EnsureSpace ensure_space(this);
325   EMIT(0x9C);
326 }
327
328
329 void Assembler::popfd() {
330   EnsureSpace ensure_space(this);
331   EMIT(0x9D);
332 }
333
334
335 void Assembler::push(const Immediate& x) {
336   EnsureSpace ensure_space(this);
337   if (x.is_int8()) {
338     EMIT(0x6a);
339     EMIT(x.x_);
340   } else {
341     EMIT(0x68);
342     emit(x);
343   }
344 }
345
346
347 void Assembler::push_imm32(int32_t imm32) {
348   EnsureSpace ensure_space(this);
349   EMIT(0x68);
350   emit(imm32);
351 }
352
353
354 void Assembler::push(Register src) {
355   EnsureSpace ensure_space(this);
356   EMIT(0x50 | src.code());
357 }
358
359
360 void Assembler::push(const Operand& src) {
361   EnsureSpace ensure_space(this);
362   EMIT(0xFF);
363   emit_operand(esi, src);
364 }
365
366
367 void Assembler::pop(Register dst) {
368   DCHECK(reloc_info_writer.last_pc() != NULL);
369   EnsureSpace ensure_space(this);
370   EMIT(0x58 | dst.code());
371 }
372
373
374 void Assembler::pop(const Operand& dst) {
375   EnsureSpace ensure_space(this);
376   EMIT(0x8F);
377   emit_operand(eax, dst);
378 }
379
380
381 void Assembler::enter(const Immediate& size) {
382   EnsureSpace ensure_space(this);
383   EMIT(0xC8);
384   emit_w(size);
385   EMIT(0);
386 }
387
388
389 void Assembler::leave() {
390   EnsureSpace ensure_space(this);
391   EMIT(0xC9);
392 }
393
394
395 void Assembler::mov_b(Register dst, const Operand& src) {
396   CHECK(dst.is_byte_register());
397   EnsureSpace ensure_space(this);
398   EMIT(0x8A);
399   emit_operand(dst, src);
400 }
401
402
403 void Assembler::mov_b(const Operand& dst, int8_t imm8) {
404   EnsureSpace ensure_space(this);
405   EMIT(0xC6);
406   emit_operand(eax, dst);
407   EMIT(imm8);
408 }
409
410
411 void Assembler::mov_b(const Operand& dst, Register src) {
412   CHECK(src.is_byte_register());
413   EnsureSpace ensure_space(this);
414   EMIT(0x88);
415   emit_operand(src, dst);
416 }
417
418
419 void Assembler::mov_w(Register dst, const Operand& src) {
420   EnsureSpace ensure_space(this);
421   EMIT(0x66);
422   EMIT(0x8B);
423   emit_operand(dst, src);
424 }
425
426
427 void Assembler::mov_w(const Operand& dst, Register src) {
428   EnsureSpace ensure_space(this);
429   EMIT(0x66);
430   EMIT(0x89);
431   emit_operand(src, dst);
432 }
433
434
435 void Assembler::mov_w(const Operand& dst, int16_t imm16) {
436   EnsureSpace ensure_space(this);
437   EMIT(0x66);
438   EMIT(0xC7);
439   emit_operand(eax, dst);
440   EMIT(static_cast<int8_t>(imm16 & 0xff));
441   EMIT(static_cast<int8_t>(imm16 >> 8));
442 }
443
444
445 void Assembler::mov(Register dst, int32_t imm32) {
446   EnsureSpace ensure_space(this);
447   EMIT(0xB8 | dst.code());
448   emit(imm32);
449 }
450
451
452 void Assembler::mov(Register dst, const Immediate& x) {
453   EnsureSpace ensure_space(this);
454   EMIT(0xB8 | dst.code());
455   emit(x);
456 }
457
458
459 void Assembler::mov(Register dst, Handle<Object> handle) {
460   EnsureSpace ensure_space(this);
461   EMIT(0xB8 | dst.code());
462   emit(handle);
463 }
464
465
466 void Assembler::mov(Register dst, const Operand& src) {
467   EnsureSpace ensure_space(this);
468   EMIT(0x8B);
469   emit_operand(dst, src);
470 }
471
472
473 void Assembler::mov(Register dst, Register src) {
474   EnsureSpace ensure_space(this);
475   EMIT(0x89);
476   EMIT(0xC0 | src.code() << 3 | dst.code());
477 }
478
479
480 void Assembler::mov(const Operand& dst, const Immediate& x) {
481   EnsureSpace ensure_space(this);
482   EMIT(0xC7);
483   emit_operand(eax, dst);
484   emit(x);
485 }
486
487
488 void Assembler::mov(const Operand& dst, Handle<Object> handle) {
489   EnsureSpace ensure_space(this);
490   EMIT(0xC7);
491   emit_operand(eax, dst);
492   emit(handle);
493 }
494
495
496 void Assembler::mov(const Operand& dst, Register src) {
497   EnsureSpace ensure_space(this);
498   EMIT(0x89);
499   emit_operand(src, dst);
500 }
501
502
503 void Assembler::movsx_b(Register dst, const Operand& src) {
504   EnsureSpace ensure_space(this);
505   EMIT(0x0F);
506   EMIT(0xBE);
507   emit_operand(dst, src);
508 }
509
510
511 void Assembler::movsx_w(Register dst, const Operand& src) {
512   EnsureSpace ensure_space(this);
513   EMIT(0x0F);
514   EMIT(0xBF);
515   emit_operand(dst, src);
516 }
517
518
519 void Assembler::movzx_b(Register dst, const Operand& src) {
520   EnsureSpace ensure_space(this);
521   EMIT(0x0F);
522   EMIT(0xB6);
523   emit_operand(dst, src);
524 }
525
526
527 void Assembler::movzx_w(Register dst, const Operand& src) {
528   EnsureSpace ensure_space(this);
529   EMIT(0x0F);
530   EMIT(0xB7);
531   emit_operand(dst, src);
532 }
533
534
535 void Assembler::cld() {
536   EnsureSpace ensure_space(this);
537   EMIT(0xFC);
538 }
539
540
541 void Assembler::rep_movs() {
542   EnsureSpace ensure_space(this);
543   EMIT(0xF3);
544   EMIT(0xA5);
545 }
546
547
548 void Assembler::rep_stos() {
549   EnsureSpace ensure_space(this);
550   EMIT(0xF3);
551   EMIT(0xAB);
552 }
553
554
555 void Assembler::stos() {
556   EnsureSpace ensure_space(this);
557   EMIT(0xAB);
558 }
559
560
561 void Assembler::xchg(Register dst, Register src) {
562   EnsureSpace ensure_space(this);
563   if (src.is(eax) || dst.is(eax)) {  // Single-byte encoding.
564     EMIT(0x90 | (src.is(eax) ? dst.code() : src.code()));
565   } else {
566     EMIT(0x87);
567     EMIT(0xC0 | src.code() << 3 | dst.code());
568   }
569 }
570
571
572 void Assembler::xchg(Register dst, const Operand& src) {
573   EnsureSpace ensure_space(this);
574   EMIT(0x87);
575   emit_operand(dst, src);
576 }
577
578
579 void Assembler::adc(Register dst, int32_t imm32) {
580   EnsureSpace ensure_space(this);
581   emit_arith(2, Operand(dst), Immediate(imm32));
582 }
583
584
585 void Assembler::adc(Register dst, const Operand& src) {
586   EnsureSpace ensure_space(this);
587   EMIT(0x13);
588   emit_operand(dst, src);
589 }
590
591
592 void Assembler::add(Register dst, const Operand& src) {
593   EnsureSpace ensure_space(this);
594   EMIT(0x03);
595   emit_operand(dst, src);
596 }
597
598
599 void Assembler::add(const Operand& dst, Register src) {
600   EnsureSpace ensure_space(this);
601   EMIT(0x01);
602   emit_operand(src, dst);
603 }
604
605
606 void Assembler::add(const Operand& dst, const Immediate& x) {
607   DCHECK(reloc_info_writer.last_pc() != NULL);
608   EnsureSpace ensure_space(this);
609   emit_arith(0, dst, x);
610 }
611
612
613 void Assembler::and_(Register dst, int32_t imm32) {
614   and_(dst, Immediate(imm32));
615 }
616
617
618 void Assembler::and_(Register dst, const Immediate& x) {
619   EnsureSpace ensure_space(this);
620   emit_arith(4, Operand(dst), x);
621 }
622
623
624 void Assembler::and_(Register dst, const Operand& src) {
625   EnsureSpace ensure_space(this);
626   EMIT(0x23);
627   emit_operand(dst, src);
628 }
629
630
631 void Assembler::and_(const Operand& dst, const Immediate& x) {
632   EnsureSpace ensure_space(this);
633   emit_arith(4, dst, x);
634 }
635
636
637 void Assembler::and_(const Operand& dst, Register src) {
638   EnsureSpace ensure_space(this);
639   EMIT(0x21);
640   emit_operand(src, dst);
641 }
642
643
644 void Assembler::cmpb(const Operand& op, int8_t imm8) {
645   EnsureSpace ensure_space(this);
646   if (op.is_reg(eax)) {
647     EMIT(0x3C);
648   } else {
649     EMIT(0x80);
650     emit_operand(edi, op);  // edi == 7
651   }
652   EMIT(imm8);
653 }
654
655
656 void Assembler::cmpb(const Operand& op, Register reg) {
657   CHECK(reg.is_byte_register());
658   EnsureSpace ensure_space(this);
659   EMIT(0x38);
660   emit_operand(reg, op);
661 }
662
663
664 void Assembler::cmpb(Register reg, const Operand& op) {
665   CHECK(reg.is_byte_register());
666   EnsureSpace ensure_space(this);
667   EMIT(0x3A);
668   emit_operand(reg, op);
669 }
670
671
672 void Assembler::cmpw(const Operand& op, Immediate imm16) {
673   DCHECK(imm16.is_int16());
674   EnsureSpace ensure_space(this);
675   EMIT(0x66);
676   EMIT(0x81);
677   emit_operand(edi, op);
678   emit_w(imm16);
679 }
680
681
682 void Assembler::cmp(Register reg, int32_t imm32) {
683   EnsureSpace ensure_space(this);
684   emit_arith(7, Operand(reg), Immediate(imm32));
685 }
686
687
688 void Assembler::cmp(Register reg, Handle<Object> handle) {
689   EnsureSpace ensure_space(this);
690   emit_arith(7, Operand(reg), Immediate(handle));
691 }
692
693
694 void Assembler::cmp(Register reg, const Operand& op) {
695   EnsureSpace ensure_space(this);
696   EMIT(0x3B);
697   emit_operand(reg, op);
698 }
699
700
701 void Assembler::cmp(const Operand& op, const Immediate& imm) {
702   EnsureSpace ensure_space(this);
703   emit_arith(7, op, imm);
704 }
705
706
707 void Assembler::cmp(const Operand& op, Handle<Object> handle) {
708   EnsureSpace ensure_space(this);
709   emit_arith(7, op, Immediate(handle));
710 }
711
712
713 void Assembler::cmpb_al(const Operand& op) {
714   EnsureSpace ensure_space(this);
715   EMIT(0x38);  // CMP r/m8, r8
716   emit_operand(eax, op);  // eax has same code as register al.
717 }
718
719
720 void Assembler::cmpw_ax(const Operand& op) {
721   EnsureSpace ensure_space(this);
722   EMIT(0x66);
723   EMIT(0x39);  // CMP r/m16, r16
724   emit_operand(eax, op);  // eax has same code as register ax.
725 }
726
727
728 void Assembler::dec_b(Register dst) {
729   CHECK(dst.is_byte_register());
730   EnsureSpace ensure_space(this);
731   EMIT(0xFE);
732   EMIT(0xC8 | dst.code());
733 }
734
735
736 void Assembler::dec_b(const Operand& dst) {
737   EnsureSpace ensure_space(this);
738   EMIT(0xFE);
739   emit_operand(ecx, dst);
740 }
741
742
743 void Assembler::dec(Register dst) {
744   EnsureSpace ensure_space(this);
745   EMIT(0x48 | dst.code());
746 }
747
748
749 void Assembler::dec(const Operand& dst) {
750   EnsureSpace ensure_space(this);
751   EMIT(0xFF);
752   emit_operand(ecx, dst);
753 }
754
755
756 void Assembler::cdq() {
757   EnsureSpace ensure_space(this);
758   EMIT(0x99);
759 }
760
761
762 void Assembler::idiv(const Operand& src) {
763   EnsureSpace ensure_space(this);
764   EMIT(0xF7);
765   emit_operand(edi, src);
766 }
767
768
769 void Assembler::div(const Operand& src) {
770   EnsureSpace ensure_space(this);
771   EMIT(0xF7);
772   emit_operand(esi, src);
773 }
774
775
776 void Assembler::imul(Register reg) {
777   EnsureSpace ensure_space(this);
778   EMIT(0xF7);
779   EMIT(0xE8 | reg.code());
780 }
781
782
783 void Assembler::imul(Register dst, const Operand& src) {
784   EnsureSpace ensure_space(this);
785   EMIT(0x0F);
786   EMIT(0xAF);
787   emit_operand(dst, src);
788 }
789
790
791 void Assembler::imul(Register dst, Register src, int32_t imm32) {
792   imul(dst, Operand(src), imm32);
793 }
794
795
796 void Assembler::imul(Register dst, const Operand& src, int32_t imm32) {
797   EnsureSpace ensure_space(this);
798   if (is_int8(imm32)) {
799     EMIT(0x6B);
800     emit_operand(dst, src);
801     EMIT(imm32);
802   } else {
803     EMIT(0x69);
804     emit_operand(dst, src);
805     emit(imm32);
806   }
807 }
808
809
810 void Assembler::inc(Register dst) {
811   EnsureSpace ensure_space(this);
812   EMIT(0x40 | dst.code());
813 }
814
815
816 void Assembler::inc(const Operand& dst) {
817   EnsureSpace ensure_space(this);
818   EMIT(0xFF);
819   emit_operand(eax, dst);
820 }
821
822
823 void Assembler::lea(Register dst, const Operand& src) {
824   EnsureSpace ensure_space(this);
825   EMIT(0x8D);
826   emit_operand(dst, src);
827 }
828
829
830 void Assembler::mul(Register src) {
831   EnsureSpace ensure_space(this);
832   EMIT(0xF7);
833   EMIT(0xE0 | src.code());
834 }
835
836
837 void Assembler::neg(Register dst) {
838   EnsureSpace ensure_space(this);
839   EMIT(0xF7);
840   EMIT(0xD8 | dst.code());
841 }
842
843
844 void Assembler::neg(const Operand& dst) {
845   EnsureSpace ensure_space(this);
846   EMIT(0xF7);
847   emit_operand(ebx, dst);
848 }
849
850
851 void Assembler::not_(Register dst) {
852   EnsureSpace ensure_space(this);
853   EMIT(0xF7);
854   EMIT(0xD0 | dst.code());
855 }
856
857
858 void Assembler::not_(const Operand& dst) {
859   EnsureSpace ensure_space(this);
860   EMIT(0xF7);
861   emit_operand(edx, dst);
862 }
863
864
865 void Assembler::or_(Register dst, int32_t imm32) {
866   EnsureSpace ensure_space(this);
867   emit_arith(1, Operand(dst), Immediate(imm32));
868 }
869
870
871 void Assembler::or_(Register dst, const Operand& src) {
872   EnsureSpace ensure_space(this);
873   EMIT(0x0B);
874   emit_operand(dst, src);
875 }
876
877
878 void Assembler::or_(const Operand& dst, const Immediate& x) {
879   EnsureSpace ensure_space(this);
880   emit_arith(1, dst, x);
881 }
882
883
884 void Assembler::or_(const Operand& dst, Register src) {
885   EnsureSpace ensure_space(this);
886   EMIT(0x09);
887   emit_operand(src, dst);
888 }
889
890
891 void Assembler::rcl(Register dst, uint8_t imm8) {
892   EnsureSpace ensure_space(this);
893   DCHECK(is_uint5(imm8));  // illegal shift count
894   if (imm8 == 1) {
895     EMIT(0xD1);
896     EMIT(0xD0 | dst.code());
897   } else {
898     EMIT(0xC1);
899     EMIT(0xD0 | dst.code());
900     EMIT(imm8);
901   }
902 }
903
904
905 void Assembler::rcr(Register dst, uint8_t imm8) {
906   EnsureSpace ensure_space(this);
907   DCHECK(is_uint5(imm8));  // illegal shift count
908   if (imm8 == 1) {
909     EMIT(0xD1);
910     EMIT(0xD8 | dst.code());
911   } else {
912     EMIT(0xC1);
913     EMIT(0xD8 | dst.code());
914     EMIT(imm8);
915   }
916 }
917
918
919 void Assembler::ror(const Operand& dst, uint8_t imm8) {
920   EnsureSpace ensure_space(this);
921   DCHECK(is_uint5(imm8));  // illegal shift count
922   if (imm8 == 1) {
923     EMIT(0xD1);
924     emit_operand(ecx, dst);
925   } else {
926     EMIT(0xC1);
927     emit_operand(ecx, dst);
928     EMIT(imm8);
929   }
930 }
931
932
933 void Assembler::ror_cl(const Operand& dst) {
934   EnsureSpace ensure_space(this);
935   EMIT(0xD3);
936   emit_operand(ecx, dst);
937 }
938
939
940 void Assembler::sar(const Operand& dst, uint8_t imm8) {
941   EnsureSpace ensure_space(this);
942   DCHECK(is_uint5(imm8));  // illegal shift count
943   if (imm8 == 1) {
944     EMIT(0xD1);
945     emit_operand(edi, dst);
946   } else {
947     EMIT(0xC1);
948     emit_operand(edi, dst);
949     EMIT(imm8);
950   }
951 }
952
953
954 void Assembler::sar_cl(const Operand& dst) {
955   EnsureSpace ensure_space(this);
956   EMIT(0xD3);
957   emit_operand(edi, dst);
958 }
959
960
961 void Assembler::sbb(Register dst, const Operand& src) {
962   EnsureSpace ensure_space(this);
963   EMIT(0x1B);
964   emit_operand(dst, src);
965 }
966
967
968 void Assembler::shld(Register dst, const Operand& src) {
969   EnsureSpace ensure_space(this);
970   EMIT(0x0F);
971   EMIT(0xA5);
972   emit_operand(dst, src);
973 }
974
975
976 void Assembler::shl(const Operand& dst, uint8_t imm8) {
977   EnsureSpace ensure_space(this);
978   DCHECK(is_uint5(imm8));  // illegal shift count
979   if (imm8 == 1) {
980     EMIT(0xD1);
981     emit_operand(esp, dst);
982   } else {
983     EMIT(0xC1);
984     emit_operand(esp, dst);
985     EMIT(imm8);
986   }
987 }
988
989
990 void Assembler::shl_cl(const Operand& dst) {
991   EnsureSpace ensure_space(this);
992   EMIT(0xD3);
993   emit_operand(esp, dst);
994 }
995
996
997 void Assembler::shrd(Register dst, const Operand& src) {
998   EnsureSpace ensure_space(this);
999   EMIT(0x0F);
1000   EMIT(0xAD);
1001   emit_operand(dst, src);
1002 }
1003
1004
1005 void Assembler::shr(const Operand& dst, uint8_t imm8) {
1006   EnsureSpace ensure_space(this);
1007   DCHECK(is_uint5(imm8));  // illegal shift count
1008   if (imm8 == 1) {
1009     EMIT(0xD1);
1010     emit_operand(ebp, dst);
1011   } else {
1012     EMIT(0xC1);
1013     emit_operand(ebp, dst);
1014     EMIT(imm8);
1015   }
1016 }
1017
1018
1019 void Assembler::shr_cl(const Operand& dst) {
1020   EnsureSpace ensure_space(this);
1021   EMIT(0xD3);
1022   emit_operand(ebp, dst);
1023 }
1024
1025
1026 void Assembler::sub(const Operand& dst, const Immediate& x) {
1027   EnsureSpace ensure_space(this);
1028   emit_arith(5, dst, x);
1029 }
1030
1031
1032 void Assembler::sub(Register dst, const Operand& src) {
1033   EnsureSpace ensure_space(this);
1034   EMIT(0x2B);
1035   emit_operand(dst, src);
1036 }
1037
1038
1039 void Assembler::sub(const Operand& dst, Register src) {
1040   EnsureSpace ensure_space(this);
1041   EMIT(0x29);
1042   emit_operand(src, dst);
1043 }
1044
1045
1046 void Assembler::test(Register reg, const Immediate& imm) {
1047   if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1048     test_b(reg, imm.x_);
1049     return;
1050   }
1051
1052   EnsureSpace ensure_space(this);
1053   // This is not using emit_arith because test doesn't support
1054   // sign-extension of 8-bit operands.
1055   if (reg.is(eax)) {
1056     EMIT(0xA9);
1057   } else {
1058     EMIT(0xF7);
1059     EMIT(0xC0 | reg.code());
1060   }
1061   emit(imm);
1062 }
1063
1064
1065 void Assembler::test(Register reg, const Operand& op) {
1066   EnsureSpace ensure_space(this);
1067   EMIT(0x85);
1068   emit_operand(reg, op);
1069 }
1070
1071
1072 void Assembler::test_b(Register reg, const Operand& op) {
1073   CHECK(reg.is_byte_register());
1074   EnsureSpace ensure_space(this);
1075   EMIT(0x84);
1076   emit_operand(reg, op);
1077 }
1078
1079
1080 void Assembler::test(const Operand& op, const Immediate& imm) {
1081   if (op.is_reg_only()) {
1082     test(op.reg(), imm);
1083     return;
1084   }
1085   if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1086     return test_b(op, imm.x_);
1087   }
1088   EnsureSpace ensure_space(this);
1089   EMIT(0xF7);
1090   emit_operand(eax, op);
1091   emit(imm);
1092 }
1093
1094
1095 void Assembler::test_b(Register reg, uint8_t imm8) {
1096   EnsureSpace ensure_space(this);
1097   // Only use test against byte for registers that have a byte
1098   // variant: eax, ebx, ecx, and edx.
1099   if (reg.is(eax)) {
1100     EMIT(0xA8);
1101     EMIT(imm8);
1102   } else if (reg.is_byte_register()) {
1103     emit_arith_b(0xF6, 0xC0, reg, imm8);
1104   } else {
1105     EMIT(0xF7);
1106     EMIT(0xC0 | reg.code());
1107     emit(imm8);
1108   }
1109 }
1110
1111
1112 void Assembler::test_b(const Operand& op, uint8_t imm8) {
1113   if (op.is_reg_only()) {
1114     test_b(op.reg(), imm8);
1115     return;
1116   }
1117   EnsureSpace ensure_space(this);
1118   EMIT(0xF6);
1119   emit_operand(eax, op);
1120   EMIT(imm8);
1121 }
1122
1123
1124 void Assembler::xor_(Register dst, int32_t imm32) {
1125   EnsureSpace ensure_space(this);
1126   emit_arith(6, Operand(dst), Immediate(imm32));
1127 }
1128
1129
1130 void Assembler::xor_(Register dst, const Operand& src) {
1131   EnsureSpace ensure_space(this);
1132   EMIT(0x33);
1133   emit_operand(dst, src);
1134 }
1135
1136
1137 void Assembler::xor_(const Operand& dst, Register src) {
1138   EnsureSpace ensure_space(this);
1139   EMIT(0x31);
1140   emit_operand(src, dst);
1141 }
1142
1143
1144 void Assembler::xor_(const Operand& dst, const Immediate& x) {
1145   EnsureSpace ensure_space(this);
1146   emit_arith(6, dst, x);
1147 }
1148
1149
1150 void Assembler::bt(const Operand& dst, Register src) {
1151   EnsureSpace ensure_space(this);
1152   EMIT(0x0F);
1153   EMIT(0xA3);
1154   emit_operand(src, dst);
1155 }
1156
1157
1158 void Assembler::bts(const Operand& dst, Register src) {
1159   EnsureSpace ensure_space(this);
1160   EMIT(0x0F);
1161   EMIT(0xAB);
1162   emit_operand(src, dst);
1163 }
1164
1165
1166 void Assembler::bsr(Register dst, const Operand& src) {
1167   EnsureSpace ensure_space(this);
1168   EMIT(0x0F);
1169   EMIT(0xBD);
1170   emit_operand(dst, src);
1171 }
1172
1173
1174 void Assembler::hlt() {
1175   EnsureSpace ensure_space(this);
1176   EMIT(0xF4);
1177 }
1178
1179
1180 void Assembler::int3() {
1181   EnsureSpace ensure_space(this);
1182   EMIT(0xCC);
1183 }
1184
1185
1186 void Assembler::nop() {
1187   EnsureSpace ensure_space(this);
1188   EMIT(0x90);
1189 }
1190
1191
1192 void Assembler::ret(int imm16) {
1193   EnsureSpace ensure_space(this);
1194   DCHECK(is_uint16(imm16));
1195   if (imm16 == 0) {
1196     EMIT(0xC3);
1197   } else {
1198     EMIT(0xC2);
1199     EMIT(imm16 & 0xFF);
1200     EMIT((imm16 >> 8) & 0xFF);
1201   }
1202 }
1203
1204
1205 void Assembler::ud2() {
1206   EnsureSpace ensure_space(this);
1207   EMIT(0x0F);
1208   EMIT(0x0B);
1209 }
1210
1211
1212 // Labels refer to positions in the (to be) generated code.
1213 // There are bound, linked, and unused labels.
1214 //
1215 // Bound labels refer to known positions in the already
1216 // generated code. pos() is the position the label refers to.
1217 //
1218 // Linked labels refer to unknown positions in the code
1219 // to be generated; pos() is the position of the 32bit
1220 // Displacement of the last instruction using the label.
1221
1222
1223 void Assembler::print(Label* L) {
1224   if (L->is_unused()) {
1225     PrintF("unused label\n");
1226   } else if (L->is_bound()) {
1227     PrintF("bound label to %d\n", L->pos());
1228   } else if (L->is_linked()) {
1229     Label l = *L;
1230     PrintF("unbound label");
1231     while (l.is_linked()) {
1232       Displacement disp = disp_at(&l);
1233       PrintF("@ %d ", l.pos());
1234       disp.print();
1235       PrintF("\n");
1236       disp.next(&l);
1237     }
1238   } else {
1239     PrintF("label in inconsistent state (pos = %d)\n", L->pos_);
1240   }
1241 }
1242
1243
1244 void Assembler::bind_to(Label* L, int pos) {
1245   EnsureSpace ensure_space(this);
1246   DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
1247   while (L->is_linked()) {
1248     Displacement disp = disp_at(L);
1249     int fixup_pos = L->pos();
1250     if (disp.type() == Displacement::CODE_ABSOLUTE) {
1251       long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos));
1252       internal_reference_positions_.push_back(fixup_pos);
1253     } else if (disp.type() == Displacement::CODE_RELATIVE) {
1254       // Relative to Code* heap object pointer.
1255       long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1256     } else {
1257       if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1258         DCHECK(byte_at(fixup_pos - 1) == 0xE9);  // jmp expected
1259       }
1260       // Relative address, relative to point after address.
1261       int imm32 = pos - (fixup_pos + sizeof(int32_t));
1262       long_at_put(fixup_pos, imm32);
1263     }
1264     disp.next(L);
1265   }
1266   while (L->is_near_linked()) {
1267     int fixup_pos = L->near_link_pos();
1268     int offset_to_next =
1269         static_cast<int>(*reinterpret_cast<int8_t*>(addr_at(fixup_pos)));
1270     DCHECK(offset_to_next <= 0);
1271     // Relative address, relative to point after address.
1272     int disp = pos - fixup_pos - sizeof(int8_t);
1273     CHECK(0 <= disp && disp <= 127);
1274     set_byte_at(fixup_pos, disp);
1275     if (offset_to_next < 0) {
1276       L->link_to(fixup_pos + offset_to_next, Label::kNear);
1277     } else {
1278       L->UnuseNear();
1279     }
1280   }
1281   L->bind_to(pos);
1282 }
1283
1284
1285 void Assembler::bind(Label* L) {
1286   EnsureSpace ensure_space(this);
1287   DCHECK(!L->is_bound());  // label can only be bound once
1288   bind_to(L, pc_offset());
1289 }
1290
1291
1292 void Assembler::call(Label* L) {
1293   positions_recorder()->WriteRecordedPositions();
1294   EnsureSpace ensure_space(this);
1295   if (L->is_bound()) {
1296     const int long_size = 5;
1297     int offs = L->pos() - pc_offset();
1298     DCHECK(offs <= 0);
1299     // 1110 1000 #32-bit disp.
1300     EMIT(0xE8);
1301     emit(offs - long_size);
1302   } else {
1303     // 1110 1000 #32-bit disp.
1304     EMIT(0xE8);
1305     emit_disp(L, Displacement::OTHER);
1306   }
1307 }
1308
1309
1310 void Assembler::call(byte* entry, RelocInfo::Mode rmode) {
1311   positions_recorder()->WriteRecordedPositions();
1312   EnsureSpace ensure_space(this);
1313   DCHECK(!RelocInfo::IsCodeTarget(rmode));
1314   EMIT(0xE8);
1315   if (RelocInfo::IsRuntimeEntry(rmode)) {
1316     emit(reinterpret_cast<uint32_t>(entry), rmode);
1317   } else {
1318     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1319   }
1320 }
1321
1322
1323 int Assembler::CallSize(const Operand& adr) {
1324   // Call size is 1 (opcode) + adr.len_ (operand).
1325   return 1 + adr.len_;
1326 }
1327
1328
1329 void Assembler::call(const Operand& adr) {
1330   positions_recorder()->WriteRecordedPositions();
1331   EnsureSpace ensure_space(this);
1332   EMIT(0xFF);
1333   emit_operand(edx, adr);
1334 }
1335
1336
1337 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1338   return 1 /* EMIT */ + sizeof(uint32_t) /* emit */;
1339 }
1340
1341
1342 void Assembler::call(Handle<Code> code,
1343                      RelocInfo::Mode rmode,
1344                      TypeFeedbackId ast_id) {
1345   positions_recorder()->WriteRecordedPositions();
1346   EnsureSpace ensure_space(this);
1347   DCHECK(RelocInfo::IsCodeTarget(rmode)
1348       || rmode == RelocInfo::CODE_AGE_SEQUENCE);
1349   EMIT(0xE8);
1350   emit(code, rmode, ast_id);
1351 }
1352
1353
1354 void Assembler::jmp(Label* L, Label::Distance distance) {
1355   EnsureSpace ensure_space(this);
1356   if (L->is_bound()) {
1357     const int short_size = 2;
1358     const int long_size  = 5;
1359     int offs = L->pos() - pc_offset();
1360     DCHECK(offs <= 0);
1361     if (is_int8(offs - short_size)) {
1362       // 1110 1011 #8-bit disp.
1363       EMIT(0xEB);
1364       EMIT((offs - short_size) & 0xFF);
1365     } else {
1366       // 1110 1001 #32-bit disp.
1367       EMIT(0xE9);
1368       emit(offs - long_size);
1369     }
1370   } else if (distance == Label::kNear) {
1371     EMIT(0xEB);
1372     emit_near_disp(L);
1373   } else {
1374     // 1110 1001 #32-bit disp.
1375     EMIT(0xE9);
1376     emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1377   }
1378 }
1379
1380
1381 void Assembler::jmp(byte* entry, RelocInfo::Mode rmode) {
1382   EnsureSpace ensure_space(this);
1383   DCHECK(!RelocInfo::IsCodeTarget(rmode));
1384   EMIT(0xE9);
1385   if (RelocInfo::IsRuntimeEntry(rmode)) {
1386     emit(reinterpret_cast<uint32_t>(entry), rmode);
1387   } else {
1388     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1389   }
1390 }
1391
1392
1393 void Assembler::jmp(const Operand& adr) {
1394   EnsureSpace ensure_space(this);
1395   EMIT(0xFF);
1396   emit_operand(esp, adr);
1397 }
1398
1399
1400 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1401   EnsureSpace ensure_space(this);
1402   DCHECK(RelocInfo::IsCodeTarget(rmode));
1403   EMIT(0xE9);
1404   emit(code, rmode);
1405 }
1406
1407
1408 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1409   EnsureSpace ensure_space(this);
1410   DCHECK(0 <= cc && static_cast<int>(cc) < 16);
1411   if (L->is_bound()) {
1412     const int short_size = 2;
1413     const int long_size  = 6;
1414     int offs = L->pos() - pc_offset();
1415     DCHECK(offs <= 0);
1416     if (is_int8(offs - short_size)) {
1417       // 0111 tttn #8-bit disp
1418       EMIT(0x70 | cc);
1419       EMIT((offs - short_size) & 0xFF);
1420     } else {
1421       // 0000 1111 1000 tttn #32-bit disp
1422       EMIT(0x0F);
1423       EMIT(0x80 | cc);
1424       emit(offs - long_size);
1425     }
1426   } else if (distance == Label::kNear) {
1427     EMIT(0x70 | cc);
1428     emit_near_disp(L);
1429   } else {
1430     // 0000 1111 1000 tttn #32-bit disp
1431     // Note: could eliminate cond. jumps to this jump if condition
1432     //       is the same however, seems to be rather unlikely case.
1433     EMIT(0x0F);
1434     EMIT(0x80 | cc);
1435     emit_disp(L, Displacement::OTHER);
1436   }
1437 }
1438
1439
1440 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1441   EnsureSpace ensure_space(this);
1442   DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
1443   // 0000 1111 1000 tttn #32-bit disp.
1444   EMIT(0x0F);
1445   EMIT(0x80 | cc);
1446   if (RelocInfo::IsRuntimeEntry(rmode)) {
1447     emit(reinterpret_cast<uint32_t>(entry), rmode);
1448   } else {
1449     emit(entry - (pc_ + sizeof(int32_t)), rmode);
1450   }
1451 }
1452
1453
1454 void Assembler::j(Condition cc, Handle<Code> code) {
1455   EnsureSpace ensure_space(this);
1456   // 0000 1111 1000 tttn #32-bit disp
1457   EMIT(0x0F);
1458   EMIT(0x80 | cc);
1459   emit(code, RelocInfo::CODE_TARGET);
1460 }
1461
1462
1463 // FPU instructions.
1464
1465 void Assembler::fld(int i) {
1466   EnsureSpace ensure_space(this);
1467   emit_farith(0xD9, 0xC0, i);
1468 }
1469
1470
1471 void Assembler::fstp(int i) {
1472   EnsureSpace ensure_space(this);
1473   emit_farith(0xDD, 0xD8, i);
1474 }
1475
1476
1477 void Assembler::fld1() {
1478   EnsureSpace ensure_space(this);
1479   EMIT(0xD9);
1480   EMIT(0xE8);
1481 }
1482
1483
1484 void Assembler::fldpi() {
1485   EnsureSpace ensure_space(this);
1486   EMIT(0xD9);
1487   EMIT(0xEB);
1488 }
1489
1490
1491 void Assembler::fldz() {
1492   EnsureSpace ensure_space(this);
1493   EMIT(0xD9);
1494   EMIT(0xEE);
1495 }
1496
1497
1498 void Assembler::fldln2() {
1499   EnsureSpace ensure_space(this);
1500   EMIT(0xD9);
1501   EMIT(0xED);
1502 }
1503
1504
1505 void Assembler::fld_s(const Operand& adr) {
1506   EnsureSpace ensure_space(this);
1507   EMIT(0xD9);
1508   emit_operand(eax, adr);
1509 }
1510
1511
1512 void Assembler::fld_d(const Operand& adr) {
1513   EnsureSpace ensure_space(this);
1514   EMIT(0xDD);
1515   emit_operand(eax, adr);
1516 }
1517
1518
1519 void Assembler::fstp_s(const Operand& adr) {
1520   EnsureSpace ensure_space(this);
1521   EMIT(0xD9);
1522   emit_operand(ebx, adr);
1523 }
1524
1525
1526 void Assembler::fst_s(const Operand& adr) {
1527   EnsureSpace ensure_space(this);
1528   EMIT(0xD9);
1529   emit_operand(edx, adr);
1530 }
1531
1532
1533 void Assembler::fldcw(const Operand& adr) {
1534   EnsureSpace ensure_space(this);
1535   EMIT(0xD9);
1536   emit_operand(ebp, adr);
1537 }
1538
1539
1540 void Assembler::fnstcw(const Operand& adr) {
1541   EnsureSpace ensure_space(this);
1542   EMIT(0xD9);
1543   emit_operand(edi, adr);
1544 }
1545
1546
1547 void Assembler::fstp_d(const Operand& adr) {
1548   EnsureSpace ensure_space(this);
1549   EMIT(0xDD);
1550   emit_operand(ebx, adr);
1551 }
1552
1553
1554 void Assembler::fst_d(const Operand& adr) {
1555   EnsureSpace ensure_space(this);
1556   EMIT(0xDD);
1557   emit_operand(edx, adr);
1558 }
1559
1560
1561 void Assembler::fild_s(const Operand& adr) {
1562   EnsureSpace ensure_space(this);
1563   EMIT(0xDB);
1564   emit_operand(eax, adr);
1565 }
1566
1567
1568 void Assembler::fild_d(const Operand& adr) {
1569   EnsureSpace ensure_space(this);
1570   EMIT(0xDF);
1571   emit_operand(ebp, adr);
1572 }
1573
1574
1575 void Assembler::fistp_s(const Operand& adr) {
1576   EnsureSpace ensure_space(this);
1577   EMIT(0xDB);
1578   emit_operand(ebx, adr);
1579 }
1580
1581
1582 void Assembler::fisttp_s(const Operand& adr) {
1583   DCHECK(IsEnabled(SSE3));
1584   EnsureSpace ensure_space(this);
1585   EMIT(0xDB);
1586   emit_operand(ecx, adr);
1587 }
1588
1589
1590 void Assembler::fisttp_d(const Operand& adr) {
1591   DCHECK(IsEnabled(SSE3));
1592   EnsureSpace ensure_space(this);
1593   EMIT(0xDD);
1594   emit_operand(ecx, adr);
1595 }
1596
1597
1598 void Assembler::fist_s(const Operand& adr) {
1599   EnsureSpace ensure_space(this);
1600   EMIT(0xDB);
1601   emit_operand(edx, adr);
1602 }
1603
1604
1605 void Assembler::fistp_d(const Operand& adr) {
1606   EnsureSpace ensure_space(this);
1607   EMIT(0xDF);
1608   emit_operand(edi, adr);
1609 }
1610
1611
1612 void Assembler::fabs() {
1613   EnsureSpace ensure_space(this);
1614   EMIT(0xD9);
1615   EMIT(0xE1);
1616 }
1617
1618
1619 void Assembler::fchs() {
1620   EnsureSpace ensure_space(this);
1621   EMIT(0xD9);
1622   EMIT(0xE0);
1623 }
1624
1625
1626 void Assembler::fsqrt() {
1627   EnsureSpace ensure_space(this);
1628   EMIT(0xD9);
1629   EMIT(0xFA);
1630 }
1631
1632
1633 void Assembler::fcos() {
1634   EnsureSpace ensure_space(this);
1635   EMIT(0xD9);
1636   EMIT(0xFF);
1637 }
1638
1639
1640 void Assembler::fsin() {
1641   EnsureSpace ensure_space(this);
1642   EMIT(0xD9);
1643   EMIT(0xFE);
1644 }
1645
1646
1647 void Assembler::fptan() {
1648   EnsureSpace ensure_space(this);
1649   EMIT(0xD9);
1650   EMIT(0xF2);
1651 }
1652
1653
1654 void Assembler::fyl2x() {
1655   EnsureSpace ensure_space(this);
1656   EMIT(0xD9);
1657   EMIT(0xF1);
1658 }
1659
1660
1661 void Assembler::f2xm1() {
1662   EnsureSpace ensure_space(this);
1663   EMIT(0xD9);
1664   EMIT(0xF0);
1665 }
1666
1667
1668 void Assembler::fscale() {
1669   EnsureSpace ensure_space(this);
1670   EMIT(0xD9);
1671   EMIT(0xFD);
1672 }
1673
1674
1675 void Assembler::fninit() {
1676   EnsureSpace ensure_space(this);
1677   EMIT(0xDB);
1678   EMIT(0xE3);
1679 }
1680
1681
1682 void Assembler::fadd(int i) {
1683   EnsureSpace ensure_space(this);
1684   emit_farith(0xDC, 0xC0, i);
1685 }
1686
1687
1688 void Assembler::fadd_i(int i) {
1689   EnsureSpace ensure_space(this);
1690   emit_farith(0xD8, 0xC0, i);
1691 }
1692
1693
1694 void Assembler::fadd_d(const Operand& adr) {
1695   EnsureSpace ensure_space(this);
1696   EMIT(0xDC);
1697   emit_operand(eax, adr);
1698 }
1699
1700
1701 void Assembler::fsub(int i) {
1702   EnsureSpace ensure_space(this);
1703   emit_farith(0xDC, 0xE8, i);
1704 }
1705
1706
1707 void Assembler::fsub_i(int i) {
1708   EnsureSpace ensure_space(this);
1709   emit_farith(0xD8, 0xE0, i);
1710 }
1711
1712
1713 void Assembler::fisub_s(const Operand& adr) {
1714   EnsureSpace ensure_space(this);
1715   EMIT(0xDA);
1716   emit_operand(esp, adr);
1717 }
1718
1719
1720 void Assembler::fmul_i(int i) {
1721   EnsureSpace ensure_space(this);
1722   emit_farith(0xD8, 0xC8, i);
1723 }
1724
1725
1726 void Assembler::fmul(int i) {
1727   EnsureSpace ensure_space(this);
1728   emit_farith(0xDC, 0xC8, i);
1729 }
1730
1731
1732 void Assembler::fdiv(int i) {
1733   EnsureSpace ensure_space(this);
1734   emit_farith(0xDC, 0xF8, i);
1735 }
1736
1737
1738 void Assembler::fdiv_i(int i) {
1739   EnsureSpace ensure_space(this);
1740   emit_farith(0xD8, 0xF0, i);
1741 }
1742
1743
1744 void Assembler::faddp(int i) {
1745   EnsureSpace ensure_space(this);
1746   emit_farith(0xDE, 0xC0, i);
1747 }
1748
1749
1750 void Assembler::fsubp(int i) {
1751   EnsureSpace ensure_space(this);
1752   emit_farith(0xDE, 0xE8, i);
1753 }
1754
1755
1756 void Assembler::fsubrp(int i) {
1757   EnsureSpace ensure_space(this);
1758   emit_farith(0xDE, 0xE0, i);
1759 }
1760
1761
1762 void Assembler::fmulp(int i) {
1763   EnsureSpace ensure_space(this);
1764   emit_farith(0xDE, 0xC8, i);
1765 }
1766
1767
1768 void Assembler::fdivp(int i) {
1769   EnsureSpace ensure_space(this);
1770   emit_farith(0xDE, 0xF8, i);
1771 }
1772
1773
1774 void Assembler::fprem() {
1775   EnsureSpace ensure_space(this);
1776   EMIT(0xD9);
1777   EMIT(0xF8);
1778 }
1779
1780
1781 void Assembler::fprem1() {
1782   EnsureSpace ensure_space(this);
1783   EMIT(0xD9);
1784   EMIT(0xF5);
1785 }
1786
1787
1788 void Assembler::fxch(int i) {
1789   EnsureSpace ensure_space(this);
1790   emit_farith(0xD9, 0xC8, i);
1791 }
1792
1793
1794 void Assembler::fincstp() {
1795   EnsureSpace ensure_space(this);
1796   EMIT(0xD9);
1797   EMIT(0xF7);
1798 }
1799
1800
1801 void Assembler::ffree(int i) {
1802   EnsureSpace ensure_space(this);
1803   emit_farith(0xDD, 0xC0, i);
1804 }
1805
1806
1807 void Assembler::ftst() {
1808   EnsureSpace ensure_space(this);
1809   EMIT(0xD9);
1810   EMIT(0xE4);
1811 }
1812
1813
1814 void Assembler::fxam() {
1815   EnsureSpace ensure_space(this);
1816   EMIT(0xD9);
1817   EMIT(0xE5);
1818 }
1819
1820
1821 void Assembler::fucomp(int i) {
1822   EnsureSpace ensure_space(this);
1823   emit_farith(0xDD, 0xE8, i);
1824 }
1825
1826
1827 void Assembler::fucompp() {
1828   EnsureSpace ensure_space(this);
1829   EMIT(0xDA);
1830   EMIT(0xE9);
1831 }
1832
1833
1834 void Assembler::fucomi(int i) {
1835   EnsureSpace ensure_space(this);
1836   EMIT(0xDB);
1837   EMIT(0xE8 + i);
1838 }
1839
1840
1841 void Assembler::fucomip() {
1842   EnsureSpace ensure_space(this);
1843   EMIT(0xDF);
1844   EMIT(0xE9);
1845 }
1846
1847
1848 void Assembler::fcompp() {
1849   EnsureSpace ensure_space(this);
1850   EMIT(0xDE);
1851   EMIT(0xD9);
1852 }
1853
1854
1855 void Assembler::fnstsw_ax() {
1856   EnsureSpace ensure_space(this);
1857   EMIT(0xDF);
1858   EMIT(0xE0);
1859 }
1860
1861
1862 void Assembler::fwait() {
1863   EnsureSpace ensure_space(this);
1864   EMIT(0x9B);
1865 }
1866
1867
1868 void Assembler::frndint() {
1869   EnsureSpace ensure_space(this);
1870   EMIT(0xD9);
1871   EMIT(0xFC);
1872 }
1873
1874
1875 void Assembler::fnclex() {
1876   EnsureSpace ensure_space(this);
1877   EMIT(0xDB);
1878   EMIT(0xE2);
1879 }
1880
1881
1882 void Assembler::fnsave(const Operand& adr) {
1883   EnsureSpace ensure_space(this);
1884   EMIT(0xDD);
1885   emit_operand(esi, adr);
1886 }
1887
1888
1889 void Assembler::frstor(const Operand& adr) {
1890   EnsureSpace ensure_space(this);
1891   EMIT(0xDD);
1892   emit_operand(esp, adr);
1893 }
1894
1895
1896 void Assembler::sahf() {
1897   EnsureSpace ensure_space(this);
1898   EMIT(0x9E);
1899 }
1900
1901
1902 void Assembler::setcc(Condition cc, Register reg) {
1903   DCHECK(reg.is_byte_register());
1904   EnsureSpace ensure_space(this);
1905   EMIT(0x0F);
1906   EMIT(0x90 | cc);
1907   EMIT(0xC0 | reg.code());
1908 }
1909
1910
1911 void Assembler::GrowBuffer() {
1912   DCHECK(buffer_overflow());
1913   if (!own_buffer_) FATAL("external code buffer is too small");
1914
1915   // Compute new buffer size.
1916   CodeDesc desc;  // the new buffer
1917   desc.buffer_size = 2 * buffer_size_;
1918
1919   // Some internal data structures overflow for very large buffers,
1920   // they must ensure that kMaximalBufferSize is not too large.
1921   if ((desc.buffer_size > kMaximalBufferSize) ||
1922       (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
1923     V8::FatalProcessOutOfMemory("Assembler::GrowBuffer");
1924   }
1925
1926   // Set up new buffer.
1927   desc.buffer = NewArray<byte>(desc.buffer_size);
1928   desc.instr_size = pc_offset();
1929   desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
1930
1931   // Clear the buffer in debug mode. Use 'int3' instructions to make
1932   // sure to get into problems if we ever run uninitialized code.
1933 #ifdef DEBUG
1934   memset(desc.buffer, 0xCC, desc.buffer_size);
1935 #endif
1936
1937   // Copy the data.
1938   int pc_delta = desc.buffer - buffer_;
1939   int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
1940   MemMove(desc.buffer, buffer_, desc.instr_size);
1941   MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
1942           desc.reloc_size);
1943
1944   DeleteArray(buffer_);
1945   buffer_ = desc.buffer;
1946   buffer_size_ = desc.buffer_size;
1947   pc_ += pc_delta;
1948   reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
1949                                reloc_info_writer.last_pc() + pc_delta);
1950
1951   // Relocate internal references.
1952   for (auto pos : internal_reference_positions_) {
1953     int32_t* p = reinterpret_cast<int32_t*>(buffer_ + pos);
1954     *p += pc_delta;
1955   }
1956
1957   DCHECK(!buffer_overflow());
1958 }
1959
1960
1961 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
1962   DCHECK(is_uint8(op1) && is_uint8(op2));  // wrong opcode
1963   DCHECK(is_uint8(imm8));
1964   DCHECK((op1 & 0x01) == 0);  // should be 8bit operation
1965   EMIT(op1);
1966   EMIT(op2 | dst.code());
1967   EMIT(imm8);
1968 }
1969
1970
1971 void Assembler::emit_arith(int sel, Operand dst, const Immediate& x) {
1972   DCHECK((0 <= sel) && (sel <= 7));
1973   Register ireg = { sel };
1974   if (x.is_int8()) {
1975     EMIT(0x83);  // using a sign-extended 8-bit immediate.
1976     emit_operand(ireg, dst);
1977     EMIT(x.x_ & 0xFF);
1978   } else if (dst.is_reg(eax)) {
1979     EMIT((sel << 3) | 0x05);  // short form if the destination is eax.
1980     emit(x);
1981   } else {
1982     EMIT(0x81);  // using a literal 32-bit immediate.
1983     emit_operand(ireg, dst);
1984     emit(x);
1985   }
1986 }
1987
1988
1989 void Assembler::emit_operand(Register reg, const Operand& adr) {
1990   const unsigned length = adr.len_;
1991   DCHECK(length > 0);
1992
1993   // Emit updated ModRM byte containing the given register.
1994   pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
1995
1996   // Emit the rest of the encoded operand.
1997   for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
1998   pc_ += length;
1999
2000   // Emit relocation information if necessary.
2001   if (length >= sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
2002     pc_ -= sizeof(int32_t);  // pc_ must be *at* disp32
2003     RecordRelocInfo(adr.rmode_);
2004     if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) {  // Fixup for labels
2005       emit_label(*reinterpret_cast<Label**>(pc_));
2006     } else {
2007       pc_ += sizeof(int32_t);
2008     }
2009   }
2010 }
2011
2012
2013 void Assembler::emit_label(Label* label) {
2014   if (label->is_bound()) {
2015     internal_reference_positions_.push_back(pc_offset());
2016     emit(reinterpret_cast<uint32_t>(buffer_ + label->pos()));
2017   } else {
2018     emit_disp(label, Displacement::CODE_ABSOLUTE);
2019   }
2020 }
2021
2022
2023 void Assembler::emit_farith(int b1, int b2, int i) {
2024   DCHECK(is_uint8(b1) && is_uint8(b2));  // wrong opcode
2025   DCHECK(0 <= i &&  i < 8);  // illegal stack offset
2026   EMIT(b1);
2027   EMIT(b2 + i);
2028 }
2029
2030
2031 void Assembler::db(uint8_t data) {
2032   EnsureSpace ensure_space(this);
2033   EMIT(data);
2034 }
2035
2036
2037 void Assembler::dd(uint32_t data) {
2038   EnsureSpace ensure_space(this);
2039   emit(data);
2040 }
2041
2042
2043 void Assembler::dd(Label* label) {
2044   EnsureSpace ensure_space(this);
2045   RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2046   emit_label(label);
2047 }
2048
2049
2050 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2051   DCHECK(!RelocInfo::IsNone(rmode));
2052   // Don't record external references unless the heap will be serialized.
2053   if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2054       !serializer_enabled() && !emit_debug_code()) {
2055       return;
2056   }
2057   RelocInfo rinfo(pc_, rmode, data, NULL);
2058   reloc_info_writer.Write(&rinfo);
2059 }
2060
2061
2062 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2063   // No out-of-line constant pool support.
2064   DCHECK(!FLAG_enable_ool_constant_pool);
2065   return isolate->factory()->empty_constant_pool_array();
2066 }
2067
2068
2069 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2070   // No out-of-line constant pool support.
2071   DCHECK(!FLAG_enable_ool_constant_pool);
2072   return;
2073 }
2074
2075
2076 #ifdef GENERATED_CODE_COVERAGE
2077 static FILE* coverage_log = NULL;
2078
2079
2080 static void InitCoverageLog() {
2081   char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
2082   if (file_name != NULL) {
2083     coverage_log = fopen(file_name, "aw+");
2084   }
2085 }
2086
2087
2088 void LogGeneratedCodeCoverage(const char* file_line) {
2089   const char* return_address = (&file_line)[-1];
2090   char* push_insn = const_cast<char*>(return_address - 12);
2091   push_insn[0] = 0xeb;  // Relative branch insn.
2092   push_insn[1] = 13;    // Skip over coverage insns.
2093   if (coverage_log != NULL) {
2094     fprintf(coverage_log, "%s\n", file_line);
2095     fflush(coverage_log);
2096   }
2097 }
2098
2099 #endif
2100
2101 } }  // namespace v8::internal
2102
2103 #endif  // V8_TARGET_ARCH_X87