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