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