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