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