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