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