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