• 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 are
6 // 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 distribution.
14 //
15 // - Neither the name of Sun Microsystems or the names of contributors may
16 // be used to endorse or promote products derived from this software without
17 // specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // The original source code covered by the above license above has been
32 // modified significantly by Google Inc.
33 // Copyright 2011 the V8 project authors. All rights reserved.
34 
35 // A light-weight IA32 Assembler.
36 
37 #ifndef V8_IA32_ASSEMBLER_IA32_H_
38 #define V8_IA32_ASSEMBLER_IA32_H_
39 
40 #include <deque>
41 
42 #include "src/assembler.h"
43 #include "src/ia32/constants-ia32.h"
44 #include "src/ia32/sse-instr.h"
45 #include "src/isolate.h"
46 #include "src/utils.h"
47 
48 namespace v8 {
49 namespace internal {
50 
51 #define GENERAL_REGISTERS(V) \
52   V(eax)                     \
53   V(ecx)                     \
54   V(edx)                     \
55   V(ebx)                     \
56   V(esp)                     \
57   V(ebp)                     \
58   V(esi)                     \
59   V(edi)
60 
61 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
62   V(eax)                                 \
63   V(ecx)                                 \
64   V(edx)                                 \
65   V(ebx)                                 \
66   V(esi)                                 \
67   V(edi)
68 
69 #define DOUBLE_REGISTERS(V) \
70   V(xmm0)                   \
71   V(xmm1)                   \
72   V(xmm2)                   \
73   V(xmm3)                   \
74   V(xmm4)                   \
75   V(xmm5)                   \
76   V(xmm6)                   \
77   V(xmm7)
78 
79 #define FLOAT_REGISTERS DOUBLE_REGISTERS
80 #define SIMD128_REGISTERS DOUBLE_REGISTERS
81 
82 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
83   V(xmm1)                               \
84   V(xmm2)                               \
85   V(xmm3)                               \
86   V(xmm4)                               \
87   V(xmm5)                               \
88   V(xmm6)                               \
89   V(xmm7)
90 
91 enum RegisterCode {
92 #define REGISTER_CODE(R) kRegCode_##R,
93   GENERAL_REGISTERS(REGISTER_CODE)
94 #undef REGISTER_CODE
95       kRegAfterLast
96 };
97 
98 class Register : public RegisterBase<Register, kRegAfterLast> {
99  public:
is_byte_register()100   bool is_byte_register() const { return reg_code_ <= 3; }
101 
102  private:
103   friend class RegisterBase<Register, kRegAfterLast>;
Register(int code)104   explicit constexpr Register(int code) : RegisterBase(code) {}
105 };
106 
107 ASSERT_TRIVIALLY_COPYABLE(Register);
108 static_assert(sizeof(Register) == sizeof(int),
109               "Register can efficiently be passed by value");
110 
111 #define DEFINE_REGISTER(R) \
112   constexpr Register R = Register::from_code<kRegCode_##R>();
113 GENERAL_REGISTERS(DEFINE_REGISTER)
114 #undef DEFINE_REGISTER
115 constexpr Register no_reg = Register::no_reg();
116 
117 constexpr bool kPadArguments = false;
118 constexpr bool kSimpleFPAliasing = true;
119 constexpr bool kSimdMaskRegisters = false;
120 
121 enum DoubleCode {
122 #define REGISTER_CODE(R) kDoubleCode_##R,
123   DOUBLE_REGISTERS(REGISTER_CODE)
124 #undef REGISTER_CODE
125       kDoubleAfterLast
126 };
127 
128 class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
129   friend class RegisterBase<XMMRegister, kDoubleAfterLast>;
XMMRegister(int code)130   explicit constexpr XMMRegister(int code) : RegisterBase(code) {}
131 };
132 
133 typedef XMMRegister FloatRegister;
134 
135 typedef XMMRegister DoubleRegister;
136 
137 typedef XMMRegister Simd128Register;
138 
139 #define DEFINE_REGISTER(R) \
140   constexpr DoubleRegister R = DoubleRegister::from_code<kDoubleCode_##R>();
141 DOUBLE_REGISTERS(DEFINE_REGISTER)
142 #undef DEFINE_REGISTER
143 constexpr DoubleRegister no_double_reg = DoubleRegister::no_reg();
144 constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
145 
146 // Note that the bit values must match those used in actual instruction encoding
147 constexpr int kNumRegs = 8;
148 
149 // Caller-saved registers
150 constexpr RegList kJSCallerSaved =
151     Register::ListOf<eax, ecx, edx,
152                      ebx,  // used as a caller-saved register in JavaScript code
153                      edi   // callee function
154                      >();
155 
156 constexpr int kNumJSCallerSaved = 5;
157 
158 // Number of registers for which space is reserved in safepoints.
159 constexpr int kNumSafepointRegisters = 8;
160 
161 enum Condition {
162   // any value < 0 is considered no_condition
163   no_condition  = -1,
164 
165   overflow      =  0,
166   no_overflow   =  1,
167   below         =  2,
168   above_equal   =  3,
169   equal         =  4,
170   not_equal     =  5,
171   below_equal   =  6,
172   above         =  7,
173   negative      =  8,
174   positive      =  9,
175   parity_even   = 10,
176   parity_odd    = 11,
177   less          = 12,
178   greater_equal = 13,
179   less_equal    = 14,
180   greater       = 15,
181 
182   // aliases
183   carry         = below,
184   not_carry     = above_equal,
185   zero          = equal,
186   not_zero      = not_equal,
187   sign          = negative,
188   not_sign      = positive
189 };
190 
191 
192 // Returns the equivalent of !cc.
193 // Negation of the default no_condition (-1) results in a non-default
194 // no_condition value (-2). As long as tests for no_condition check
195 // for condition < 0, this will work as expected.
NegateCondition(Condition cc)196 inline Condition NegateCondition(Condition cc) {
197   return static_cast<Condition>(cc ^ 1);
198 }
199 
200 
201 enum RoundingMode {
202   kRoundToNearest = 0x0,
203   kRoundDown = 0x1,
204   kRoundUp = 0x2,
205   kRoundToZero = 0x3
206 };
207 
208 // -----------------------------------------------------------------------------
209 // Machine instruction Immediates
210 
211 class Immediate BASE_EMBEDDED {
212  public:
213   // Calls where x is an Address (uintptr_t) resolve to this overload.
214   inline explicit Immediate(int x, RelocInfo::Mode rmode = RelocInfo::NONE) {
215     value_.immediate = x;
216     rmode_ = rmode;
217   }
Immediate(const ExternalReference & ext)218   inline explicit Immediate(const ExternalReference& ext)
219       : Immediate(ext.address(), RelocInfo::EXTERNAL_REFERENCE) {}
Immediate(Handle<HeapObject> handle)220   inline explicit Immediate(Handle<HeapObject> handle)
221       : Immediate(handle.address(), RelocInfo::EMBEDDED_OBJECT) {}
Immediate(Smi * value)222   inline explicit Immediate(Smi* value)
223       : Immediate(reinterpret_cast<intptr_t>(value)) {}
224 
225   static Immediate EmbeddedNumber(double number);  // Smi or HeapNumber.
226   static Immediate EmbeddedCode(CodeStub* code);
227 
CodeRelativeOffset(Label * label)228   static Immediate CodeRelativeOffset(Label* label) {
229     return Immediate(label);
230   }
231 
is_heap_object_request()232   bool is_heap_object_request() const {
233     DCHECK_IMPLIES(is_heap_object_request_,
234                    rmode_ == RelocInfo::EMBEDDED_OBJECT ||
235                        rmode_ == RelocInfo::CODE_TARGET);
236     return is_heap_object_request_;
237   }
238 
heap_object_request()239   HeapObjectRequest heap_object_request() const {
240     DCHECK(is_heap_object_request());
241     return value_.heap_object_request;
242   }
243 
immediate()244   int immediate() const {
245     DCHECK(!is_heap_object_request());
246     return value_.immediate;
247   }
248 
is_external_reference()249   bool is_external_reference() const {
250     return rmode() == RelocInfo::EXTERNAL_REFERENCE;
251   }
252 
external_reference()253   ExternalReference external_reference() const {
254     DCHECK(is_external_reference());
255     return bit_cast<ExternalReference>(immediate());
256   }
257 
is_zero()258   bool is_zero() const { return RelocInfo::IsNone(rmode_) && immediate() == 0; }
is_int8()259   bool is_int8() const {
260     return RelocInfo::IsNone(rmode_) && i::is_int8(immediate());
261   }
is_uint8()262   bool is_uint8() const {
263     return RelocInfo::IsNone(rmode_) && i::is_uint8(immediate());
264   }
is_int16()265   bool is_int16() const {
266     return RelocInfo::IsNone(rmode_) && i::is_int16(immediate());
267   }
268 
is_uint16()269   bool is_uint16() const {
270     return RelocInfo::IsNone(rmode_) && i::is_uint16(immediate());
271   }
272 
rmode()273   RelocInfo::Mode rmode() const { return rmode_; }
274 
275  private:
Immediate(Label * value)276   inline explicit Immediate(Label* value) {
277     value_.immediate = reinterpret_cast<int32_t>(value);
278     rmode_ = RelocInfo::INTERNAL_REFERENCE;
279   }
280 
281   union Value {
Value()282     Value() {}
283     HeapObjectRequest heap_object_request;
284     int immediate;
285   } value_;
286   bool is_heap_object_request_ = false;
287   RelocInfo::Mode rmode_;
288 
289   friend class Operand;
290   friend class Assembler;
291   friend class MacroAssembler;
292 };
293 
294 
295 // -----------------------------------------------------------------------------
296 // Machine instruction Operands
297 
298 enum ScaleFactor {
299   times_1 = 0,
300   times_2 = 1,
301   times_4 = 2,
302   times_8 = 3,
303   times_int_size = times_4,
304   times_half_pointer_size = times_2,
305   times_pointer_size = times_4,
306   times_twice_pointer_size = times_8
307 };
308 
309 class V8_EXPORT_PRIVATE Operand {
310  public:
311   // reg
Operand(Register reg)312   V8_INLINE explicit Operand(Register reg) { set_modrm(3, reg); }
313 
314   // XMM reg
Operand(XMMRegister xmm_reg)315   V8_INLINE explicit Operand(XMMRegister xmm_reg) {
316     Register reg = Register::from_code(xmm_reg.code());
317     set_modrm(3, reg);
318   }
319 
320   // [disp/r]
Operand(int32_t disp,RelocInfo::Mode rmode)321   V8_INLINE explicit Operand(int32_t disp, RelocInfo::Mode rmode) {
322     set_modrm(0, ebp);
323     set_dispr(disp, rmode);
324   }
325 
326   // [disp/r]
Operand(Immediate imm)327   V8_INLINE explicit Operand(Immediate imm) {
328     set_modrm(0, ebp);
329     set_dispr(imm.immediate(), imm.rmode_);
330   }
331 
332   // [base + disp/r]
333   explicit Operand(Register base, int32_t disp,
334                    RelocInfo::Mode rmode = RelocInfo::NONE);
335 
336   // [base + index*scale + disp/r]
337   explicit Operand(Register base, Register index, ScaleFactor scale,
338                    int32_t disp, RelocInfo::Mode rmode = RelocInfo::NONE);
339 
340   // [index*scale + disp/r]
341   explicit Operand(Register index, ScaleFactor scale, int32_t disp,
342                    RelocInfo::Mode rmode = RelocInfo::NONE);
343 
JumpTable(Register index,ScaleFactor scale,Label * table)344   static Operand JumpTable(Register index, ScaleFactor scale, Label* table) {
345     return Operand(index, scale, reinterpret_cast<int32_t>(table),
346                    RelocInfo::INTERNAL_REFERENCE);
347   }
348 
ForRegisterPlusImmediate(Register base,Immediate imm)349   static Operand ForRegisterPlusImmediate(Register base, Immediate imm) {
350     return Operand(base, imm.value_.immediate, imm.rmode_);
351   }
352 
353   // Returns true if this Operand is a wrapper for the specified register.
is_reg(Register reg)354   bool is_reg(Register reg) const { return is_reg(reg.code()); }
is_reg(XMMRegister reg)355   bool is_reg(XMMRegister reg) const { return is_reg(reg.code()); }
356 
357   // Returns true if this Operand is a wrapper for one register.
358   bool is_reg_only() const;
359 
360   // Asserts that this Operand is a wrapper for one register and returns the
361   // register.
362   Register reg() const;
363 
364  private:
365   // Set the ModRM byte without an encoded 'reg' register. The
366   // register is encoded later as part of the emit_operand operation.
set_modrm(int mod,Register rm)367   inline void set_modrm(int mod, Register rm) {
368     DCHECK_EQ(mod & -4, 0);
369     buf_[0] = mod << 6 | rm.code();
370     len_ = 1;
371   }
372 
373   inline void set_sib(ScaleFactor scale, Register index, Register base);
374   inline void set_disp8(int8_t disp);
set_dispr(int32_t disp,RelocInfo::Mode rmode)375   inline void set_dispr(int32_t disp, RelocInfo::Mode rmode) {
376     DCHECK(len_ == 1 || len_ == 2);
377     int32_t* p = reinterpret_cast<int32_t*>(&buf_[len_]);
378     *p = disp;
379     len_ += sizeof(int32_t);
380     rmode_ = rmode;
381   }
382 
is_reg(int reg_code)383   inline bool is_reg(int reg_code) const {
384     return ((buf_[0] & 0xF8) == 0xC0)  // addressing mode is register only.
385            && ((buf_[0] & 0x07) == reg_code);  // register codes match.
386   }
387 
388   byte buf_[6];
389   // The number of bytes in buf_.
390   uint8_t len_ = 0;
391   // Only valid if len_ > 4.
392   RelocInfo::Mode rmode_ = RelocInfo::NONE;
393 
394   // TODO(clemensh): Get rid of this friendship, or make Operand immutable.
395   friend class Assembler;
396 };
397 ASSERT_TRIVIALLY_COPYABLE(Operand);
398 static_assert(sizeof(Operand) <= 2 * kPointerSize,
399               "Operand must be small enough to pass it by value");
400 
401 // -----------------------------------------------------------------------------
402 // A Displacement describes the 32bit immediate field of an instruction which
403 // may be used together with a Label in order to refer to a yet unknown code
404 // position. Displacements stored in the instruction stream are used to describe
405 // the instruction and to chain a list of instructions using the same Label.
406 // A Displacement contains 2 different fields:
407 //
408 // next field: position of next displacement in the chain (0 = end of list)
409 // type field: instruction type
410 //
411 // A next value of null (0) indicates the end of a chain (note that there can
412 // be no displacement at position zero, because there is always at least one
413 // instruction byte before the displacement).
414 //
415 // Displacement _data field layout
416 //
417 // |31.....2|1......0|
418 // [  next  |  type  |
419 
420 class Displacement BASE_EMBEDDED {
421  public:
422   enum Type { UNCONDITIONAL_JUMP, CODE_RELATIVE, OTHER, CODE_ABSOLUTE };
423 
data()424   int data() const { return data_; }
type()425   Type type() const { return TypeField::decode(data_); }
next(Label * L)426   void next(Label* L) const {
427     int n = NextField::decode(data_);
428     n > 0 ? L->link_to(n) : L->Unuse();
429   }
link_to(Label * L)430   void link_to(Label* L) { init(L, type()); }
431 
Displacement(int data)432   explicit Displacement(int data) { data_ = data; }
433 
Displacement(Label * L,Type type)434   Displacement(Label* L, Type type) { init(L, type); }
435 
print()436   void print() {
437     PrintF("%s (%x) ", (type() == UNCONDITIONAL_JUMP ? "jmp" : "[other]"),
438                        NextField::decode(data_));
439   }
440 
441  private:
442   int data_;
443 
444   class TypeField: public BitField<Type, 0, 2> {};
445   class NextField: public BitField<int,  2, 32-2> {};
446 
447   void init(Label* L, Type type);
448 };
449 
450 class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
451  private:
452   // We check before assembling an instruction that there is sufficient
453   // space to write an instruction and its relocation information.
454   // The relocation writer's position must be kGap bytes above the end of
455   // the generated instructions. This leaves enough space for the
456   // longest possible ia32 instruction, 15 bytes, and the longest possible
457   // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
458   // (There is a 15 byte limit on ia32 instruction length that rules out some
459   // otherwise valid instructions.)
460   // This allows for a single, fast space check per instruction.
461   static constexpr int kGap = 32;
462 
463  public:
464   // Create an assembler. Instructions and relocation information are emitted
465   // into a buffer, with the instructions starting from the beginning and the
466   // relocation information starting from the end of the buffer. See CodeDesc
467   // for a detailed comment on the layout (globals.h).
468   //
469   // If the provided buffer is nullptr, the assembler allocates and grows its
470   // own buffer, and buffer_size determines the initial buffer size. The buffer
471   // is owned by the assembler and deallocated upon destruction of the
472   // assembler.
473   //
474   // If the provided buffer is not nullptr, the assembler uses the provided
475   // buffer for code generation and assumes its size to be buffer_size. If the
476   // buffer is too small, a fatal error occurs. No deallocation of the buffer is
477   // done upon destruction of the assembler.
478   Assembler(const AssemblerOptions& options, void* buffer, int buffer_size);
~Assembler()479   virtual ~Assembler() {}
480 
481   // GetCode emits any pending (non-emitted) code and fills the descriptor
482   // desc. GetCode() is idempotent; it returns the same result if no other
483   // Assembler functions are invoked in between GetCode() calls.
484   void GetCode(Isolate* isolate, CodeDesc* desc);
485 
486   // Read/Modify the code target in the branch/call instruction at pc.
487   // The isolate argument is unused (and may be nullptr) when skipping flushing.
488   inline static Address target_address_at(Address pc, Address constant_pool);
489   inline static void set_target_address_at(
490       Address pc, Address constant_pool, Address target,
491       ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
492 
493   // Return the code target address at a call site from the return address
494   // of that call in the instruction stream.
495   inline static Address target_address_from_return_address(Address pc);
496 
497   // This sets the branch destination (which is in the instruction on x86).
498   // This is for calls and branches within generated code.
499   inline static void deserialization_set_special_target_at(
500       Address instruction_payload, Code* code, Address target);
501 
502   // Get the size of the special target encoded at 'instruction_payload'.
503   inline static int deserialization_special_target_size(
504       Address instruction_payload);
505 
506   // This sets the internal reference at the pc.
507   inline static void deserialization_set_target_internal_reference_at(
508       Address pc, Address target,
509       RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
510 
511   static constexpr int kSpecialTargetSize = kPointerSize;
512 
513   // Distance between the address of the code target in the call instruction
514   // and the return address
515   static constexpr int kCallTargetAddressOffset = kPointerSize;
516 
517   static constexpr int kCallInstructionLength = 5;
518 
519   // One byte opcode for test al, 0xXX.
520   static constexpr byte kTestAlByte = 0xA8;
521   // One byte opcode for nop.
522   static constexpr byte kNopByte = 0x90;
523 
524   // One byte opcode for a short unconditional jump.
525   static constexpr byte kJmpShortOpcode = 0xEB;
526   // One byte prefix for a short conditional jump.
527   static constexpr byte kJccShortPrefix = 0x70;
528   static constexpr byte kJncShortOpcode = kJccShortPrefix | not_carry;
529   static constexpr byte kJcShortOpcode = kJccShortPrefix | carry;
530   static constexpr byte kJnzShortOpcode = kJccShortPrefix | not_zero;
531   static constexpr byte kJzShortOpcode = kJccShortPrefix | zero;
532 
533   // ---------------------------------------------------------------------------
534   // Code generation
535   //
536   // - function names correspond one-to-one to ia32 instruction mnemonics
537   // - unless specified otherwise, instructions operate on 32bit operands
538   // - instructions on 8bit (byte) operands/registers have a trailing '_b'
539   // - instructions on 16bit (word) operands/registers have a trailing '_w'
540   // - naming conflicts with C++ keywords are resolved via a trailing '_'
541 
542   // NOTE ON INTERFACE: Currently, the interface is not very consistent
543   // in the sense that some operations (e.g. mov()) can be called in more
544   // the one way to generate the same instruction: The Register argument
545   // can in some cases be replaced with an Operand(Register) argument.
546   // This should be cleaned up and made more orthogonal. The questions
547   // is: should we always use Operands instead of Registers where an
548   // Operand is possible, or should we have a Register (overloaded) form
549   // instead? We must be careful to make sure that the selected instruction
550   // is obvious from the parameters to avoid hard-to-find code generation
551   // bugs.
552 
553   // Insert the smallest number of nop instructions
554   // possible to align the pc offset to a multiple
555   // of m. m must be a power of 2.
556   void Align(int m);
557   // Insert the smallest number of zero bytes possible to align the pc offset
558   // to a mulitple of m. m must be a power of 2 (>= 2).
559   void DataAlign(int m);
560   void Nop(int bytes = 1);
561   // Aligns code to something that's optimal for a jump target for the platform.
562   void CodeTargetAlign();
563 
564   // Stack
565   void pushad();
566   void popad();
567 
568   void pushfd();
569   void popfd();
570 
571   void push(const Immediate& x);
572   void push_imm32(int32_t imm32);
573   void push(Register src);
574   void push(Operand src);
575 
576   void pop(Register dst);
577   void pop(Operand dst);
578 
579   void enter(const Immediate& size);
580   void leave();
581 
582   // Moves
mov_b(Register dst,Register src)583   void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
584   void mov_b(Register dst, Operand src);
mov_b(Register dst,int8_t imm8)585   void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
mov_b(Operand dst,int8_t src)586   void mov_b(Operand dst, int8_t src) { mov_b(dst, Immediate(src)); }
587   void mov_b(Operand dst, const Immediate& src);
588   void mov_b(Operand dst, Register src);
589 
590   void mov_w(Register dst, Operand src);
mov_w(Operand dst,int16_t src)591   void mov_w(Operand dst, int16_t src) { mov_w(dst, Immediate(src)); }
592   void mov_w(Operand dst, const Immediate& src);
593   void mov_w(Operand dst, Register src);
594 
595   void mov(Register dst, int32_t imm32);
596   void mov(Register dst, const Immediate& x);
597   void mov(Register dst, Handle<HeapObject> handle);
598   void mov(Register dst, Operand src);
599   void mov(Register dst, Register src);
600   void mov(Operand dst, const Immediate& x);
601   void mov(Operand dst, Handle<HeapObject> handle);
602   void mov(Operand dst, Register src);
603   void mov(Operand dst, Address src, RelocInfo::Mode);
604 
movsx_b(Register dst,Register src)605   void movsx_b(Register dst, Register src) { movsx_b(dst, Operand(src)); }
606   void movsx_b(Register dst, Operand src);
607 
movsx_w(Register dst,Register src)608   void movsx_w(Register dst, Register src) { movsx_w(dst, Operand(src)); }
609   void movsx_w(Register dst, Operand src);
610 
movzx_b(Register dst,Register src)611   void movzx_b(Register dst, Register src) { movzx_b(dst, Operand(src)); }
612   void movzx_b(Register dst, Operand src);
613 
movzx_w(Register dst,Register src)614   void movzx_w(Register dst, Register src) { movzx_w(dst, Operand(src)); }
615   void movzx_w(Register dst, Operand src);
616 
617   void movq(XMMRegister dst, Operand src);
618   // Conditional moves
cmov(Condition cc,Register dst,Register src)619   void cmov(Condition cc, Register dst, Register src) {
620     cmov(cc, dst, Operand(src));
621   }
622   void cmov(Condition cc, Register dst, Operand src);
623 
624   // Flag management.
625   void cld();
626 
627   // Repetitive string instructions.
628   void rep_movs();
629   void rep_stos();
630   void stos();
631 
632   // Exchange
633   void xchg(Register dst, Register src);
634   void xchg(Register dst, Operand src);
635   void xchg_b(Register reg, Operand op);
636   void xchg_w(Register reg, Operand op);
637 
638   // Lock prefix
639   void lock();
640 
641   // CompareExchange
642   void cmpxchg(Operand dst, Register src);
643   void cmpxchg_b(Operand dst, Register src);
644   void cmpxchg_w(Operand dst, Register src);
645   void cmpxchg8b(Operand dst);
646 
647   // Memory Fence
648   void lfence();
649 
650   void pause();
651 
652   // Arithmetics
653   void adc(Register dst, int32_t imm32);
adc(Register dst,Register src)654   void adc(Register dst, Register src) { adc(dst, Operand(src)); }
655   void adc(Register dst, Operand src);
656 
add(Register dst,Register src)657   void add(Register dst, Register src) { add(dst, Operand(src)); }
658   void add(Register dst, Operand src);
659   void add(Operand dst, Register src);
add(Register dst,const Immediate & imm)660   void add(Register dst, const Immediate& imm) { add(Operand(dst), imm); }
661   void add(Operand dst, const Immediate& x);
662 
663   void and_(Register dst, int32_t imm32);
664   void and_(Register dst, const Immediate& x);
and_(Register dst,Register src)665   void and_(Register dst, Register src) { and_(dst, Operand(src)); }
666   void and_(Register dst, Operand src);
667   void and_(Operand dst, Register src);
668   void and_(Operand dst, const Immediate& x);
669 
cmpb(Register reg,Immediate imm8)670   void cmpb(Register reg, Immediate imm8) { cmpb(Operand(reg), imm8); }
671   void cmpb(Operand op, Immediate imm8);
672   void cmpb(Register reg, Operand op);
673   void cmpb(Operand op, Register reg);
cmpb(Register dst,Register src)674   void cmpb(Register dst, Register src) { cmpb(Operand(dst), src); }
675   void cmpb_al(Operand op);
676   void cmpw_ax(Operand op);
677   void cmpw(Operand dst, Immediate src);
cmpw(Register dst,Immediate src)678   void cmpw(Register dst, Immediate src) { cmpw(Operand(dst), src); }
679   void cmpw(Register dst, Operand src);
cmpw(Register dst,Register src)680   void cmpw(Register dst, Register src) { cmpw(Operand(dst), src); }
681   void cmpw(Operand dst, Register src);
682   void cmp(Register reg, int32_t imm32);
683   void cmp(Register reg, Handle<HeapObject> handle);
cmp(Register reg0,Register reg1)684   void cmp(Register reg0, Register reg1) { cmp(reg0, Operand(reg1)); }
685   void cmp(Register reg, Operand op);
cmp(Register reg,const Immediate & imm)686   void cmp(Register reg, const Immediate& imm) { cmp(Operand(reg), imm); }
687   void cmp(Operand op, Register reg);
688   void cmp(Operand op, const Immediate& imm);
689   void cmp(Operand op, Handle<HeapObject> handle);
690 
691   void dec_b(Register dst);
692   void dec_b(Operand dst);
693 
694   void dec(Register dst);
695   void dec(Operand dst);
696 
697   void cdq();
698 
idiv(Register src)699   void idiv(Register src) { idiv(Operand(src)); }
700   void idiv(Operand src);
div(Register src)701   void div(Register src) { div(Operand(src)); }
702   void div(Operand src);
703 
704   // Signed multiply instructions.
705   void imul(Register src);                               // edx:eax = eax * src.
imul(Register dst,Register src)706   void imul(Register dst, Register src) { imul(dst, Operand(src)); }
707   void imul(Register dst, Operand src);                  // dst = dst * src.
708   void imul(Register dst, Register src, int32_t imm32);  // dst = src * imm32.
709   void imul(Register dst, Operand src, int32_t imm32);
710 
711   void inc(Register dst);
712   void inc(Operand dst);
713 
714   void lea(Register dst, Operand src);
715 
716   // Unsigned multiply instruction.
717   void mul(Register src);                                // edx:eax = eax * reg.
718 
719   void neg(Register dst);
720   void neg(Operand dst);
721 
722   void not_(Register dst);
723   void not_(Operand dst);
724 
725   void or_(Register dst, int32_t imm32);
or_(Register dst,Register src)726   void or_(Register dst, Register src) { or_(dst, Operand(src)); }
727   void or_(Register dst, Operand src);
728   void or_(Operand dst, Register src);
or_(Register dst,const Immediate & imm)729   void or_(Register dst, const Immediate& imm) { or_(Operand(dst), imm); }
730   void or_(Operand dst, const Immediate& x);
731 
732   void rcl(Register dst, uint8_t imm8);
733   void rcr(Register dst, uint8_t imm8);
734 
ror(Register dst,uint8_t imm8)735   void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
736   void ror(Operand dst, uint8_t imm8);
ror_cl(Register dst)737   void ror_cl(Register dst) { ror_cl(Operand(dst)); }
738   void ror_cl(Operand dst);
739 
sar(Register dst,uint8_t imm8)740   void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
741   void sar(Operand dst, uint8_t imm8);
sar_cl(Register dst)742   void sar_cl(Register dst) { sar_cl(Operand(dst)); }
743   void sar_cl(Operand dst);
744 
sbb(Register dst,Register src)745   void sbb(Register dst, Register src) { sbb(dst, Operand(src)); }
746   void sbb(Register dst, Operand src);
747 
shl(Register dst,uint8_t imm8)748   void shl(Register dst, uint8_t imm8) { shl(Operand(dst), imm8); }
749   void shl(Operand dst, uint8_t imm8);
shl_cl(Register dst)750   void shl_cl(Register dst) { shl_cl(Operand(dst)); }
751   void shl_cl(Operand dst);
752   void shld(Register dst, Register src, uint8_t shift);
753   void shld_cl(Register dst, Register src);
754 
shr(Register dst,uint8_t imm8)755   void shr(Register dst, uint8_t imm8) { shr(Operand(dst), imm8); }
756   void shr(Operand dst, uint8_t imm8);
shr_cl(Register dst)757   void shr_cl(Register dst) { shr_cl(Operand(dst)); }
758   void shr_cl(Operand dst);
759   void shrd(Register dst, Register src, uint8_t shift);
shrd_cl(Register dst,Register src)760   void shrd_cl(Register dst, Register src) { shrd_cl(Operand(dst), src); }
761   void shrd_cl(Operand dst, Register src);
762 
sub(Register dst,const Immediate & imm)763   void sub(Register dst, const Immediate& imm) { sub(Operand(dst), imm); }
764   void sub(Operand dst, const Immediate& x);
sub(Register dst,Register src)765   void sub(Register dst, Register src) { sub(dst, Operand(src)); }
766   void sub(Register dst, Operand src);
767   void sub(Operand dst, Register src);
768   void sub_sp_32(uint32_t imm);
769 
770   void test(Register reg, const Immediate& imm);
test(Register reg0,Register reg1)771   void test(Register reg0, Register reg1) { test(reg0, Operand(reg1)); }
772   void test(Register reg, Operand op);
773   void test(Operand op, const Immediate& imm);
test(Operand op,Register reg)774   void test(Operand op, Register reg) { test(reg, op); }
775   void test_b(Register reg, Operand op);
776   void test_b(Register reg, Immediate imm8);
777   void test_b(Operand op, Immediate imm8);
test_b(Operand op,Register reg)778   void test_b(Operand op, Register reg) { test_b(reg, op); }
test_b(Register dst,Register src)779   void test_b(Register dst, Register src) { test_b(dst, Operand(src)); }
780   void test_w(Register reg, Operand op);
781   void test_w(Register reg, Immediate imm16);
782   void test_w(Operand op, Immediate imm16);
test_w(Operand op,Register reg)783   void test_w(Operand op, Register reg) { test_w(reg, op); }
test_w(Register dst,Register src)784   void test_w(Register dst, Register src) { test_w(dst, Operand(src)); }
785 
786   void xor_(Register dst, int32_t imm32);
xor_(Register dst,Register src)787   void xor_(Register dst, Register src) { xor_(dst, Operand(src)); }
788   void xor_(Register dst, Operand src);
789   void xor_(Operand dst, Register src);
xor_(Register dst,const Immediate & imm)790   void xor_(Register dst, const Immediate& imm) { xor_(Operand(dst), imm); }
791   void xor_(Operand dst, const Immediate& x);
792 
793   // Bit operations.
794   void bswap(Register dst);
795   void bt(Operand dst, Register src);
bts(Register dst,Register src)796   void bts(Register dst, Register src) { bts(Operand(dst), src); }
797   void bts(Operand dst, Register src);
bsr(Register dst,Register src)798   void bsr(Register dst, Register src) { bsr(dst, Operand(src)); }
799   void bsr(Register dst, Operand src);
bsf(Register dst,Register src)800   void bsf(Register dst, Register src) { bsf(dst, Operand(src)); }
801   void bsf(Register dst, Operand src);
802 
803   // Miscellaneous
804   void hlt();
805   void int3();
806   void nop();
807   void ret(int imm16);
808   void ud2();
809 
810   // Label operations & relative jumps (PPUM Appendix D)
811   //
812   // Takes a branch opcode (cc) and a label (L) and generates
813   // either a backward branch or a forward branch and links it
814   // to the label fixup chain. Usage:
815   //
816   // Label L;    // unbound label
817   // j(cc, &L);  // forward branch to unbound label
818   // bind(&L);   // bind label to the current pc
819   // j(cc, &L);  // backward branch to bound label
820   // bind(&L);   // illegal: a label may be bound only once
821   //
822   // Note: The same Label can be used for forward and backward branches
823   // but it may be bound only once.
824 
825   void bind(Label* L);  // binds an unbound label L to the current code position
826 
827   // Calls
828   void call(Label* L);
829   void call(Address entry, RelocInfo::Mode rmode);
call(Register reg)830   void call(Register reg) { call(Operand(reg)); }
831   void call(Operand adr);
832   void call(Handle<Code> code, RelocInfo::Mode rmode);
833   void call(CodeStub* stub);
834   void wasm_call(Address address, RelocInfo::Mode rmode);
835 
836   // Jumps
837   // unconditional jump to L
838   void jmp(Label* L, Label::Distance distance = Label::kFar);
839   void jmp(Address entry, RelocInfo::Mode rmode);
jmp(Register reg)840   void jmp(Register reg) { jmp(Operand(reg)); }
841   void jmp(Operand adr);
842   void jmp(Handle<Code> code, RelocInfo::Mode rmode);
843   // unconditionoal jump relative to the current address. Low-level rountine,
844   // use with caution!
845   void jmp_rel(int offset);
846 
847   // Conditional jumps
848   void j(Condition cc,
849          Label* L,
850          Label::Distance distance = Label::kFar);
851   void j(Condition cc, byte* entry, RelocInfo::Mode rmode);
852   void j(Condition cc, Handle<Code> code,
853          RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
854 
855   // Floating-point operations
856   void fld(int i);
857   void fstp(int i);
858 
859   void fld1();
860   void fldz();
861   void fldpi();
862   void fldln2();
863 
864   void fld_s(Operand adr);
865   void fld_d(Operand adr);
866 
867   void fstp_s(Operand adr);
868   void fst_s(Operand adr);
869   void fstp_d(Operand adr);
870   void fst_d(Operand adr);
871 
872   void fild_s(Operand adr);
873   void fild_d(Operand adr);
874 
875   void fist_s(Operand adr);
876 
877   void fistp_s(Operand adr);
878   void fistp_d(Operand adr);
879 
880   // The fisttp instructions require SSE3.
881   void fisttp_s(Operand adr);
882   void fisttp_d(Operand adr);
883 
884   void fabs();
885   void fchs();
886   void fcos();
887   void fsin();
888   void fptan();
889   void fyl2x();
890   void f2xm1();
891   void fscale();
892   void fninit();
893 
894   void fadd(int i);
895   void fadd_i(int i);
896   void fsub(int i);
897   void fsub_i(int i);
898   void fmul(int i);
899   void fmul_i(int i);
900   void fdiv(int i);
901   void fdiv_i(int i);
902 
903   void fisub_s(Operand adr);
904 
905   void faddp(int i = 1);
906   void fsubp(int i = 1);
907   void fsubrp(int i = 1);
908   void fmulp(int i = 1);
909   void fdivp(int i = 1);
910   void fprem();
911   void fprem1();
912 
913   void fxch(int i = 1);
914   void fincstp();
915   void ffree(int i = 0);
916 
917   void ftst();
918   void fucomp(int i);
919   void fucompp();
920   void fucomi(int i);
921   void fucomip();
922   void fcompp();
923   void fnstsw_ax();
924   void fwait();
925   void fnclex();
926 
927   void frndint();
928 
929   void sahf();
930   void setcc(Condition cc, Register reg);
931 
932   void cpuid();
933 
934   // SSE instructions
addss(XMMRegister dst,XMMRegister src)935   void addss(XMMRegister dst, XMMRegister src) { addss(dst, Operand(src)); }
936   void addss(XMMRegister dst, Operand src);
subss(XMMRegister dst,XMMRegister src)937   void subss(XMMRegister dst, XMMRegister src) { subss(dst, Operand(src)); }
938   void subss(XMMRegister dst, Operand src);
mulss(XMMRegister dst,XMMRegister src)939   void mulss(XMMRegister dst, XMMRegister src) { mulss(dst, Operand(src)); }
940   void mulss(XMMRegister dst, Operand src);
divss(XMMRegister dst,XMMRegister src)941   void divss(XMMRegister dst, XMMRegister src) { divss(dst, Operand(src)); }
942   void divss(XMMRegister dst, Operand src);
sqrtss(XMMRegister dst,XMMRegister src)943   void sqrtss(XMMRegister dst, XMMRegister src) { sqrtss(dst, Operand(src)); }
944   void sqrtss(XMMRegister dst, Operand src);
945 
ucomiss(XMMRegister dst,XMMRegister src)946   void ucomiss(XMMRegister dst, XMMRegister src) { ucomiss(dst, Operand(src)); }
947   void ucomiss(XMMRegister dst, Operand src);
948   void movaps(XMMRegister dst, XMMRegister src);
949   void movups(XMMRegister dst, XMMRegister src);
950   void movups(XMMRegister dst, Operand src);
951   void movups(Operand dst, XMMRegister src);
952   void shufps(XMMRegister dst, XMMRegister src, byte imm8);
953 
maxss(XMMRegister dst,XMMRegister src)954   void maxss(XMMRegister dst, XMMRegister src) { maxss(dst, Operand(src)); }
955   void maxss(XMMRegister dst, Operand src);
minss(XMMRegister dst,XMMRegister src)956   void minss(XMMRegister dst, XMMRegister src) { minss(dst, Operand(src)); }
957   void minss(XMMRegister dst, Operand src);
958 
959   void andps(XMMRegister dst, Operand src);
andps(XMMRegister dst,XMMRegister src)960   void andps(XMMRegister dst, XMMRegister src) { andps(dst, Operand(src)); }
961   void xorps(XMMRegister dst, Operand src);
xorps(XMMRegister dst,XMMRegister src)962   void xorps(XMMRegister dst, XMMRegister src) { xorps(dst, Operand(src)); }
963   void orps(XMMRegister dst, Operand src);
orps(XMMRegister dst,XMMRegister src)964   void orps(XMMRegister dst, XMMRegister src) { orps(dst, Operand(src)); }
965 
966   void addps(XMMRegister dst, Operand src);
addps(XMMRegister dst,XMMRegister src)967   void addps(XMMRegister dst, XMMRegister src) { addps(dst, Operand(src)); }
968   void subps(XMMRegister dst, Operand src);
subps(XMMRegister dst,XMMRegister src)969   void subps(XMMRegister dst, XMMRegister src) { subps(dst, Operand(src)); }
970   void mulps(XMMRegister dst, Operand src);
mulps(XMMRegister dst,XMMRegister src)971   void mulps(XMMRegister dst, XMMRegister src) { mulps(dst, Operand(src)); }
972   void divps(XMMRegister dst, Operand src);
divps(XMMRegister dst,XMMRegister src)973   void divps(XMMRegister dst, XMMRegister src) { divps(dst, Operand(src)); }
974   void rcpps(XMMRegister dst, Operand src);
rcpps(XMMRegister dst,XMMRegister src)975   void rcpps(XMMRegister dst, XMMRegister src) { rcpps(dst, Operand(src)); }
976   void rsqrtps(XMMRegister dst, Operand src);
rsqrtps(XMMRegister dst,XMMRegister src)977   void rsqrtps(XMMRegister dst, XMMRegister src) { rsqrtps(dst, Operand(src)); }
978   void haddps(XMMRegister dst, Operand src);
haddps(XMMRegister dst,XMMRegister src)979   void haddps(XMMRegister dst, XMMRegister src) { haddps(dst, Operand(src)); }
980 
981   void minps(XMMRegister dst, Operand src);
minps(XMMRegister dst,XMMRegister src)982   void minps(XMMRegister dst, XMMRegister src) { minps(dst, Operand(src)); }
983   void maxps(XMMRegister dst, Operand src);
maxps(XMMRegister dst,XMMRegister src)984   void maxps(XMMRegister dst, XMMRegister src) { maxps(dst, Operand(src)); }
985 
986   void cmpps(XMMRegister dst, Operand src, int8_t cmp);
987 #define SSE_CMP_P(instr, imm8)                       \
988   void instr##ps(XMMRegister dst, XMMRegister src) { \
989     cmpps(dst, Operand(src), imm8);                  \
990   }                                                  \
991   void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); }
992 
993   SSE_CMP_P(cmpeq, 0x0);
994   SSE_CMP_P(cmplt, 0x1);
995   SSE_CMP_P(cmple, 0x2);
996   SSE_CMP_P(cmpneq, 0x4);
997 
998 #undef SSE_CMP_P
999 
1000   // SSE2 instructions
1001   void cvttss2si(Register dst, Operand src);
cvttss2si(Register dst,XMMRegister src)1002   void cvttss2si(Register dst, XMMRegister src) {
1003     cvttss2si(dst, Operand(src));
1004   }
1005   void cvttsd2si(Register dst, Operand src);
cvttsd2si(Register dst,XMMRegister src)1006   void cvttsd2si(Register dst, XMMRegister src) {
1007     cvttsd2si(dst, Operand(src));
1008   }
1009   void cvtsd2si(Register dst, XMMRegister src);
1010 
cvtsi2ss(XMMRegister dst,Register src)1011   void cvtsi2ss(XMMRegister dst, Register src) { cvtsi2ss(dst, Operand(src)); }
1012   void cvtsi2ss(XMMRegister dst, Operand src);
cvtsi2sd(XMMRegister dst,Register src)1013   void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
1014   void cvtsi2sd(XMMRegister dst, Operand src);
1015   void cvtss2sd(XMMRegister dst, Operand src);
cvtss2sd(XMMRegister dst,XMMRegister src)1016   void cvtss2sd(XMMRegister dst, XMMRegister src) {
1017     cvtss2sd(dst, Operand(src));
1018   }
1019   void cvtsd2ss(XMMRegister dst, Operand src);
cvtsd2ss(XMMRegister dst,XMMRegister src)1020   void cvtsd2ss(XMMRegister dst, XMMRegister src) {
1021     cvtsd2ss(dst, Operand(src));
1022   }
cvtdq2ps(XMMRegister dst,XMMRegister src)1023   void cvtdq2ps(XMMRegister dst, XMMRegister src) {
1024     cvtdq2ps(dst, Operand(src));
1025   }
1026   void cvtdq2ps(XMMRegister dst, Operand src);
cvttps2dq(XMMRegister dst,XMMRegister src)1027   void cvttps2dq(XMMRegister dst, XMMRegister src) {
1028     cvttps2dq(dst, Operand(src));
1029   }
1030   void cvttps2dq(XMMRegister dst, Operand src);
1031 
addsd(XMMRegister dst,XMMRegister src)1032   void addsd(XMMRegister dst, XMMRegister src) { addsd(dst, Operand(src)); }
1033   void addsd(XMMRegister dst, Operand src);
subsd(XMMRegister dst,XMMRegister src)1034   void subsd(XMMRegister dst, XMMRegister src) { subsd(dst, Operand(src)); }
1035   void subsd(XMMRegister dst, Operand src);
mulsd(XMMRegister dst,XMMRegister src)1036   void mulsd(XMMRegister dst, XMMRegister src) { mulsd(dst, Operand(src)); }
1037   void mulsd(XMMRegister dst, Operand src);
divsd(XMMRegister dst,XMMRegister src)1038   void divsd(XMMRegister dst, XMMRegister src) { divsd(dst, Operand(src)); }
1039   void divsd(XMMRegister dst, Operand src);
xorpd(XMMRegister dst,XMMRegister src)1040   void xorpd(XMMRegister dst, XMMRegister src) { xorpd(dst, Operand(src)); }
1041   void xorpd(XMMRegister dst, Operand src);
sqrtsd(XMMRegister dst,XMMRegister src)1042   void sqrtsd(XMMRegister dst, XMMRegister src) { sqrtsd(dst, Operand(src)); }
1043   void sqrtsd(XMMRegister dst, Operand src);
1044 
andpd(XMMRegister dst,XMMRegister src)1045   void andpd(XMMRegister dst, XMMRegister src) { andpd(dst, Operand(src)); }
1046   void andpd(XMMRegister dst, Operand src);
orpd(XMMRegister dst,XMMRegister src)1047   void orpd(XMMRegister dst, XMMRegister src) { orpd(dst, Operand(src)); }
1048   void orpd(XMMRegister dst, Operand src);
1049 
ucomisd(XMMRegister dst,XMMRegister src)1050   void ucomisd(XMMRegister dst, XMMRegister src) { ucomisd(dst, Operand(src)); }
1051   void ucomisd(XMMRegister dst, Operand src);
1052 
1053   void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
1054   void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1055 
1056   void movmskpd(Register dst, XMMRegister src);
1057   void movmskps(Register dst, XMMRegister src);
1058 
1059   void cmpltsd(XMMRegister dst, XMMRegister src);
1060 
maxsd(XMMRegister dst,XMMRegister src)1061   void maxsd(XMMRegister dst, XMMRegister src) { maxsd(dst, Operand(src)); }
1062   void maxsd(XMMRegister dst, Operand src);
minsd(XMMRegister dst,XMMRegister src)1063   void minsd(XMMRegister dst, XMMRegister src) { minsd(dst, Operand(src)); }
1064   void minsd(XMMRegister dst, Operand src);
1065 
1066   void movdqa(XMMRegister dst, Operand src);
1067   void movdqa(Operand dst, XMMRegister src);
1068   void movdqu(XMMRegister dst, Operand src);
1069   void movdqu(Operand dst, XMMRegister src);
movdq(bool aligned,XMMRegister dst,Operand src)1070   void movdq(bool aligned, XMMRegister dst, Operand src) {
1071     if (aligned) {
1072       movdqa(dst, src);
1073     } else {
1074       movdqu(dst, src);
1075     }
1076   }
1077 
movd(XMMRegister dst,Register src)1078   void movd(XMMRegister dst, Register src) { movd(dst, Operand(src)); }
1079   void movd(XMMRegister dst, Operand src);
movd(Register dst,XMMRegister src)1080   void movd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
1081   void movd(Operand dst, XMMRegister src);
movsd(XMMRegister dst,XMMRegister src)1082   void movsd(XMMRegister dst, XMMRegister src) { movsd(dst, Operand(src)); }
1083   void movsd(XMMRegister dst, Operand src);
1084   void movsd(Operand dst, XMMRegister src);
1085 
1086   void movss(XMMRegister dst, Operand src);
1087   void movss(Operand dst, XMMRegister src);
movss(XMMRegister dst,XMMRegister src)1088   void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); }
1089   void extractps(Register dst, XMMRegister src, byte imm8);
1090 
1091   void psllw(XMMRegister reg, int8_t shift);
1092   void pslld(XMMRegister reg, int8_t shift);
1093   void psrlw(XMMRegister reg, int8_t shift);
1094   void psrld(XMMRegister reg, int8_t shift);
1095   void psraw(XMMRegister reg, int8_t shift);
1096   void psrad(XMMRegister reg, int8_t shift);
1097   void psllq(XMMRegister reg, int8_t shift);
1098   void psllq(XMMRegister dst, XMMRegister src);
1099   void psrlq(XMMRegister reg, int8_t shift);
1100   void psrlq(XMMRegister dst, XMMRegister src);
1101 
pshufhw(XMMRegister dst,XMMRegister src,uint8_t shuffle)1102   void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1103     pshufhw(dst, Operand(src), shuffle);
1104   }
1105   void pshufhw(XMMRegister dst, Operand src, uint8_t shuffle);
pshuflw(XMMRegister dst,XMMRegister src,uint8_t shuffle)1106   void pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1107     pshuflw(dst, Operand(src), shuffle);
1108   }
1109   void pshuflw(XMMRegister dst, Operand src, uint8_t shuffle);
pshufd(XMMRegister dst,XMMRegister src,uint8_t shuffle)1110   void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1111     pshufd(dst, Operand(src), shuffle);
1112   }
1113   void pshufd(XMMRegister dst, Operand src, uint8_t shuffle);
1114 
pblendw(XMMRegister dst,XMMRegister src,uint8_t mask)1115   void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask) {
1116     pblendw(dst, Operand(src), mask);
1117   }
1118   void pblendw(XMMRegister dst, Operand src, uint8_t mask);
1119 
palignr(XMMRegister dst,XMMRegister src,uint8_t mask)1120   void palignr(XMMRegister dst, XMMRegister src, uint8_t mask) {
1121     palignr(dst, Operand(src), mask);
1122   }
1123   void palignr(XMMRegister dst, Operand src, uint8_t mask);
1124 
pextrb(Register dst,XMMRegister src,int8_t offset)1125   void pextrb(Register dst, XMMRegister src, int8_t offset) {
1126     pextrb(Operand(dst), src, offset);
1127   }
1128   void pextrb(Operand dst, XMMRegister src, int8_t offset);
1129   // Use SSE4_1 encoding for pextrw reg, xmm, imm8 for consistency
pextrw(Register dst,XMMRegister src,int8_t offset)1130   void pextrw(Register dst, XMMRegister src, int8_t offset) {
1131     pextrw(Operand(dst), src, offset);
1132   }
1133   void pextrw(Operand dst, XMMRegister src, int8_t offset);
pextrd(Register dst,XMMRegister src,int8_t offset)1134   void pextrd(Register dst, XMMRegister src, int8_t offset) {
1135     pextrd(Operand(dst), src, offset);
1136   }
1137   void pextrd(Operand dst, XMMRegister src, int8_t offset);
1138 
insertps(XMMRegister dst,XMMRegister src,int8_t offset)1139   void insertps(XMMRegister dst, XMMRegister src, int8_t offset) {
1140     insertps(dst, Operand(src), offset);
1141   }
1142   void insertps(XMMRegister dst, Operand src, int8_t offset);
pinsrb(XMMRegister dst,Register src,int8_t offset)1143   void pinsrb(XMMRegister dst, Register src, int8_t offset) {
1144     pinsrb(dst, Operand(src), offset);
1145   }
1146   void pinsrb(XMMRegister dst, Operand src, int8_t offset);
pinsrw(XMMRegister dst,Register src,int8_t offset)1147   void pinsrw(XMMRegister dst, Register src, int8_t offset) {
1148     pinsrw(dst, Operand(src), offset);
1149   }
1150   void pinsrw(XMMRegister dst, Operand src, int8_t offset);
pinsrd(XMMRegister dst,Register src,int8_t offset)1151   void pinsrd(XMMRegister dst, Register src, int8_t offset) {
1152     pinsrd(dst, Operand(src), offset);
1153   }
1154   void pinsrd(XMMRegister dst, Operand src, int8_t offset);
1155 
1156   // AVX instructions
vfmadd132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1157   void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1158     vfmadd132sd(dst, src1, Operand(src2));
1159   }
vfmadd213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1160   void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1161     vfmadd213sd(dst, src1, Operand(src2));
1162   }
vfmadd231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1163   void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1164     vfmadd231sd(dst, src1, Operand(src2));
1165   }
vfmadd132sd(XMMRegister dst,XMMRegister src1,Operand src2)1166   void vfmadd132sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1167     vfmasd(0x99, dst, src1, src2);
1168   }
vfmadd213sd(XMMRegister dst,XMMRegister src1,Operand src2)1169   void vfmadd213sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1170     vfmasd(0xa9, dst, src1, src2);
1171   }
vfmadd231sd(XMMRegister dst,XMMRegister src1,Operand src2)1172   void vfmadd231sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1173     vfmasd(0xb9, dst, src1, src2);
1174   }
vfmsub132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1175   void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1176     vfmsub132sd(dst, src1, Operand(src2));
1177   }
vfmsub213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1178   void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1179     vfmsub213sd(dst, src1, Operand(src2));
1180   }
vfmsub231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1181   void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1182     vfmsub231sd(dst, src1, Operand(src2));
1183   }
vfmsub132sd(XMMRegister dst,XMMRegister src1,Operand src2)1184   void vfmsub132sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1185     vfmasd(0x9b, dst, src1, src2);
1186   }
vfmsub213sd(XMMRegister dst,XMMRegister src1,Operand src2)1187   void vfmsub213sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1188     vfmasd(0xab, dst, src1, src2);
1189   }
vfmsub231sd(XMMRegister dst,XMMRegister src1,Operand src2)1190   void vfmsub231sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1191     vfmasd(0xbb, dst, src1, src2);
1192   }
vfnmadd132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1193   void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1194     vfnmadd132sd(dst, src1, Operand(src2));
1195   }
vfnmadd213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1196   void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1197     vfnmadd213sd(dst, src1, Operand(src2));
1198   }
vfnmadd231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1199   void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1200     vfnmadd231sd(dst, src1, Operand(src2));
1201   }
vfnmadd132sd(XMMRegister dst,XMMRegister src1,Operand src2)1202   void vfnmadd132sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1203     vfmasd(0x9d, dst, src1, src2);
1204   }
vfnmadd213sd(XMMRegister dst,XMMRegister src1,Operand src2)1205   void vfnmadd213sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1206     vfmasd(0xad, dst, src1, src2);
1207   }
vfnmadd231sd(XMMRegister dst,XMMRegister src1,Operand src2)1208   void vfnmadd231sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1209     vfmasd(0xbd, dst, src1, src2);
1210   }
vfnmsub132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1211   void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1212     vfnmsub132sd(dst, src1, Operand(src2));
1213   }
vfnmsub213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1214   void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1215     vfnmsub213sd(dst, src1, Operand(src2));
1216   }
vfnmsub231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1217   void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1218     vfnmsub231sd(dst, src1, Operand(src2));
1219   }
vfnmsub132sd(XMMRegister dst,XMMRegister src1,Operand src2)1220   void vfnmsub132sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1221     vfmasd(0x9f, dst, src1, src2);
1222   }
vfnmsub213sd(XMMRegister dst,XMMRegister src1,Operand src2)1223   void vfnmsub213sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1224     vfmasd(0xaf, dst, src1, src2);
1225   }
vfnmsub231sd(XMMRegister dst,XMMRegister src1,Operand src2)1226   void vfnmsub231sd(XMMRegister dst, XMMRegister src1, Operand src2) {
1227     vfmasd(0xbf, dst, src1, src2);
1228   }
1229   void vfmasd(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1230 
vfmadd132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1231   void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1232     vfmadd132ss(dst, src1, Operand(src2));
1233   }
vfmadd213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1234   void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1235     vfmadd213ss(dst, src1, Operand(src2));
1236   }
vfmadd231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1237   void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1238     vfmadd231ss(dst, src1, Operand(src2));
1239   }
vfmadd132ss(XMMRegister dst,XMMRegister src1,Operand src2)1240   void vfmadd132ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1241     vfmass(0x99, dst, src1, src2);
1242   }
vfmadd213ss(XMMRegister dst,XMMRegister src1,Operand src2)1243   void vfmadd213ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1244     vfmass(0xa9, dst, src1, src2);
1245   }
vfmadd231ss(XMMRegister dst,XMMRegister src1,Operand src2)1246   void vfmadd231ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1247     vfmass(0xb9, dst, src1, src2);
1248   }
vfmsub132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1249   void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1250     vfmsub132ss(dst, src1, Operand(src2));
1251   }
vfmsub213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1252   void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1253     vfmsub213ss(dst, src1, Operand(src2));
1254   }
vfmsub231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1255   void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1256     vfmsub231ss(dst, src1, Operand(src2));
1257   }
vfmsub132ss(XMMRegister dst,XMMRegister src1,Operand src2)1258   void vfmsub132ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1259     vfmass(0x9b, dst, src1, src2);
1260   }
vfmsub213ss(XMMRegister dst,XMMRegister src1,Operand src2)1261   void vfmsub213ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1262     vfmass(0xab, dst, src1, src2);
1263   }
vfmsub231ss(XMMRegister dst,XMMRegister src1,Operand src2)1264   void vfmsub231ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1265     vfmass(0xbb, dst, src1, src2);
1266   }
vfnmadd132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1267   void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1268     vfnmadd132ss(dst, src1, Operand(src2));
1269   }
vfnmadd213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1270   void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1271     vfnmadd213ss(dst, src1, Operand(src2));
1272   }
vfnmadd231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1273   void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1274     vfnmadd231ss(dst, src1, Operand(src2));
1275   }
vfnmadd132ss(XMMRegister dst,XMMRegister src1,Operand src2)1276   void vfnmadd132ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1277     vfmass(0x9d, dst, src1, src2);
1278   }
vfnmadd213ss(XMMRegister dst,XMMRegister src1,Operand src2)1279   void vfnmadd213ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1280     vfmass(0xad, dst, src1, src2);
1281   }
vfnmadd231ss(XMMRegister dst,XMMRegister src1,Operand src2)1282   void vfnmadd231ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1283     vfmass(0xbd, dst, src1, src2);
1284   }
vfnmsub132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1285   void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1286     vfnmsub132ss(dst, src1, Operand(src2));
1287   }
vfnmsub213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1288   void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1289     vfnmsub213ss(dst, src1, Operand(src2));
1290   }
vfnmsub231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1291   void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1292     vfnmsub231ss(dst, src1, Operand(src2));
1293   }
vfnmsub132ss(XMMRegister dst,XMMRegister src1,Operand src2)1294   void vfnmsub132ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1295     vfmass(0x9f, dst, src1, src2);
1296   }
vfnmsub213ss(XMMRegister dst,XMMRegister src1,Operand src2)1297   void vfnmsub213ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1298     vfmass(0xaf, dst, src1, src2);
1299   }
vfnmsub231ss(XMMRegister dst,XMMRegister src1,Operand src2)1300   void vfnmsub231ss(XMMRegister dst, XMMRegister src1, Operand src2) {
1301     vfmass(0xbf, dst, src1, src2);
1302   }
1303   void vfmass(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1304 
vaddsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1305   void vaddsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1306     vaddsd(dst, src1, Operand(src2));
1307   }
vaddsd(XMMRegister dst,XMMRegister src1,Operand src2)1308   void vaddsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1309     vsd(0x58, dst, src1, src2);
1310   }
vsubsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1311   void vsubsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1312     vsubsd(dst, src1, Operand(src2));
1313   }
vsubsd(XMMRegister dst,XMMRegister src1,Operand src2)1314   void vsubsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1315     vsd(0x5c, dst, src1, src2);
1316   }
vmulsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1317   void vmulsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1318     vmulsd(dst, src1, Operand(src2));
1319   }
vmulsd(XMMRegister dst,XMMRegister src1,Operand src2)1320   void vmulsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1321     vsd(0x59, dst, src1, src2);
1322   }
vdivsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1323   void vdivsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1324     vdivsd(dst, src1, Operand(src2));
1325   }
vdivsd(XMMRegister dst,XMMRegister src1,Operand src2)1326   void vdivsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1327     vsd(0x5e, dst, src1, src2);
1328   }
vmaxsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1329   void vmaxsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1330     vmaxsd(dst, src1, Operand(src2));
1331   }
vmaxsd(XMMRegister dst,XMMRegister src1,Operand src2)1332   void vmaxsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1333     vsd(0x5f, dst, src1, src2);
1334   }
vminsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1335   void vminsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1336     vminsd(dst, src1, Operand(src2));
1337   }
vminsd(XMMRegister dst,XMMRegister src1,Operand src2)1338   void vminsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1339     vsd(0x5d, dst, src1, src2);
1340   }
vsqrtsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1341   void vsqrtsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1342     vsqrtsd(dst, src1, Operand(src2));
1343   }
vsqrtsd(XMMRegister dst,XMMRegister src1,Operand src2)1344   void vsqrtsd(XMMRegister dst, XMMRegister src1, Operand src2) {
1345     vsd(0x51, dst, src1, src2);
1346   }
1347   void vsd(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1348 
vaddss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1349   void vaddss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1350     vaddss(dst, src1, Operand(src2));
1351   }
vaddss(XMMRegister dst,XMMRegister src1,Operand src2)1352   void vaddss(XMMRegister dst, XMMRegister src1, Operand src2) {
1353     vss(0x58, dst, src1, src2);
1354   }
vsubss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1355   void vsubss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1356     vsubss(dst, src1, Operand(src2));
1357   }
vsubss(XMMRegister dst,XMMRegister src1,Operand src2)1358   void vsubss(XMMRegister dst, XMMRegister src1, Operand src2) {
1359     vss(0x5c, dst, src1, src2);
1360   }
vmulss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1361   void vmulss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1362     vmulss(dst, src1, Operand(src2));
1363   }
vmulss(XMMRegister dst,XMMRegister src1,Operand src2)1364   void vmulss(XMMRegister dst, XMMRegister src1, Operand src2) {
1365     vss(0x59, dst, src1, src2);
1366   }
vdivss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1367   void vdivss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1368     vdivss(dst, src1, Operand(src2));
1369   }
vdivss(XMMRegister dst,XMMRegister src1,Operand src2)1370   void vdivss(XMMRegister dst, XMMRegister src1, Operand src2) {
1371     vss(0x5e, dst, src1, src2);
1372   }
vmaxss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1373   void vmaxss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1374     vmaxss(dst, src1, Operand(src2));
1375   }
vmaxss(XMMRegister dst,XMMRegister src1,Operand src2)1376   void vmaxss(XMMRegister dst, XMMRegister src1, Operand src2) {
1377     vss(0x5f, dst, src1, src2);
1378   }
vminss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1379   void vminss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1380     vminss(dst, src1, Operand(src2));
1381   }
vminss(XMMRegister dst,XMMRegister src1,Operand src2)1382   void vminss(XMMRegister dst, XMMRegister src1, Operand src2) {
1383     vss(0x5d, dst, src1, src2);
1384   }
vsqrtss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1385   void vsqrtss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1386     vsqrtss(dst, src1, Operand(src2));
1387   }
vsqrtss(XMMRegister dst,XMMRegister src1,Operand src2)1388   void vsqrtss(XMMRegister dst, XMMRegister src1, Operand src2) {
1389     vss(0x51, dst, src1, src2);
1390   }
1391   void vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1392 
vrcpps(XMMRegister dst,XMMRegister src)1393   void vrcpps(XMMRegister dst, XMMRegister src) { vrcpps(dst, Operand(src)); }
vrcpps(XMMRegister dst,Operand src)1394   void vrcpps(XMMRegister dst, Operand src) {
1395     vinstr(0x53, dst, xmm0, src, kNone, k0F, kWIG);
1396   }
vrsqrtps(XMMRegister dst,XMMRegister src)1397   void vrsqrtps(XMMRegister dst, XMMRegister src) {
1398     vrsqrtps(dst, Operand(src));
1399   }
vrsqrtps(XMMRegister dst,Operand src)1400   void vrsqrtps(XMMRegister dst, Operand src) {
1401     vinstr(0x52, dst, xmm0, src, kNone, k0F, kWIG);
1402   }
vhaddps(XMMRegister dst,XMMRegister src1,XMMRegister src2)1403   void vhaddps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1404     vhaddps(dst, src1, Operand(src2));
1405   }
vhaddps(XMMRegister dst,XMMRegister src1,Operand src2)1406   void vhaddps(XMMRegister dst, XMMRegister src1, Operand src2) {
1407     vinstr(0x7C, dst, src1, src2, kF2, k0F, kWIG);
1408   }
vmovaps(XMMRegister dst,XMMRegister src)1409   void vmovaps(XMMRegister dst, XMMRegister src) {
1410     vps(0x28, dst, xmm0, Operand(src));
1411   }
vshufps(XMMRegister dst,XMMRegister src1,XMMRegister src2,byte imm8)1412   void vshufps(XMMRegister dst, XMMRegister src1, XMMRegister src2, byte imm8) {
1413     vshufps(dst, src1, Operand(src2), imm8);
1414   }
1415   void vshufps(XMMRegister dst, XMMRegister src1, Operand src2, byte imm8);
1416 
1417   void vpsllw(XMMRegister dst, XMMRegister src, int8_t imm8);
1418   void vpslld(XMMRegister dst, XMMRegister src, int8_t imm8);
1419   void vpsrlw(XMMRegister dst, XMMRegister src, int8_t imm8);
1420   void vpsrld(XMMRegister dst, XMMRegister src, int8_t imm8);
1421   void vpsraw(XMMRegister dst, XMMRegister src, int8_t imm8);
1422   void vpsrad(XMMRegister dst, XMMRegister src, int8_t imm8);
1423 
vpshufhw(XMMRegister dst,XMMRegister src,uint8_t shuffle)1424   void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1425     vpshufhw(dst, Operand(src), shuffle);
1426   }
1427   void vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle);
vpshuflw(XMMRegister dst,XMMRegister src,uint8_t shuffle)1428   void vpshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1429     vpshuflw(dst, Operand(src), shuffle);
1430   }
1431   void vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle);
vpshufd(XMMRegister dst,XMMRegister src,uint8_t shuffle)1432   void vpshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
1433     vpshufd(dst, Operand(src), shuffle);
1434   }
1435   void vpshufd(XMMRegister dst, Operand src, uint8_t shuffle);
1436 
vpblendw(XMMRegister dst,XMMRegister src1,XMMRegister src2,uint8_t mask)1437   void vpblendw(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1438                 uint8_t mask) {
1439     vpblendw(dst, src1, Operand(src2), mask);
1440   }
1441   void vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask);
1442 
vpalignr(XMMRegister dst,XMMRegister src1,XMMRegister src2,uint8_t mask)1443   void vpalignr(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1444                 uint8_t mask) {
1445     vpalignr(dst, src1, Operand(src2), mask);
1446   }
1447   void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask);
1448 
vpextrb(Register dst,XMMRegister src,int8_t offset)1449   void vpextrb(Register dst, XMMRegister src, int8_t offset) {
1450     vpextrb(Operand(dst), src, offset);
1451   }
1452   void vpextrb(Operand dst, XMMRegister src, int8_t offset);
vpextrw(Register dst,XMMRegister src,int8_t offset)1453   void vpextrw(Register dst, XMMRegister src, int8_t offset) {
1454     vpextrw(Operand(dst), src, offset);
1455   }
1456   void vpextrw(Operand dst, XMMRegister src, int8_t offset);
vpextrd(Register dst,XMMRegister src,int8_t offset)1457   void vpextrd(Register dst, XMMRegister src, int8_t offset) {
1458     vpextrd(Operand(dst), src, offset);
1459   }
1460   void vpextrd(Operand dst, XMMRegister src, int8_t offset);
1461 
vinsertps(XMMRegister dst,XMMRegister src1,XMMRegister src2,int8_t offset)1462   void vinsertps(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1463                  int8_t offset) {
1464     vinsertps(dst, src1, Operand(src2), offset);
1465   }
1466   void vinsertps(XMMRegister dst, XMMRegister src1, Operand src2,
1467                  int8_t offset);
vpinsrb(XMMRegister dst,XMMRegister src1,Register src2,int8_t offset)1468   void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2,
1469                int8_t offset) {
1470     vpinsrb(dst, src1, Operand(src2), offset);
1471   }
1472   void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset);
vpinsrw(XMMRegister dst,XMMRegister src1,Register src2,int8_t offset)1473   void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2,
1474                int8_t offset) {
1475     vpinsrw(dst, src1, Operand(src2), offset);
1476   }
1477   void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset);
vpinsrd(XMMRegister dst,XMMRegister src1,Register src2,int8_t offset)1478   void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2,
1479                int8_t offset) {
1480     vpinsrd(dst, src1, Operand(src2), offset);
1481   }
1482   void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, int8_t offset);
1483 
vcvtdq2ps(XMMRegister dst,XMMRegister src)1484   void vcvtdq2ps(XMMRegister dst, XMMRegister src) {
1485     vcvtdq2ps(dst, Operand(src));
1486   }
vcvtdq2ps(XMMRegister dst,Operand src)1487   void vcvtdq2ps(XMMRegister dst, Operand src) {
1488     vinstr(0x5B, dst, xmm0, src, kNone, k0F, kWIG);
1489   }
vcvttps2dq(XMMRegister dst,XMMRegister src)1490   void vcvttps2dq(XMMRegister dst, XMMRegister src) {
1491     vcvttps2dq(dst, Operand(src));
1492   }
vcvttps2dq(XMMRegister dst,Operand src)1493   void vcvttps2dq(XMMRegister dst, Operand src) {
1494     vinstr(0x5B, dst, xmm0, src, kF3, k0F, kWIG);
1495   }
1496 
vmovdqu(XMMRegister dst,Operand src)1497   void vmovdqu(XMMRegister dst, Operand src) {
1498     vinstr(0x6F, dst, xmm0, src, kF3, k0F, kWIG);
1499   }
vmovdqu(Operand dst,XMMRegister src)1500   void vmovdqu(Operand dst, XMMRegister src) {
1501     vinstr(0x7F, src, xmm0, dst, kF3, k0F, kWIG);
1502   }
vmovd(XMMRegister dst,Register src)1503   void vmovd(XMMRegister dst, Register src) { vmovd(dst, Operand(src)); }
vmovd(XMMRegister dst,Operand src)1504   void vmovd(XMMRegister dst, Operand src) {
1505     vinstr(0x6E, dst, xmm0, src, k66, k0F, kWIG);
1506   }
vmovd(Register dst,XMMRegister src)1507   void vmovd(Register dst, XMMRegister src) { movd(Operand(dst), src); }
vmovd(Operand dst,XMMRegister src)1508   void vmovd(Operand dst, XMMRegister src) {
1509     vinstr(0x7E, src, xmm0, dst, k66, k0F, kWIG);
1510   }
1511 
1512   // BMI instruction
andn(Register dst,Register src1,Register src2)1513   void andn(Register dst, Register src1, Register src2) {
1514     andn(dst, src1, Operand(src2));
1515   }
andn(Register dst,Register src1,Operand src2)1516   void andn(Register dst, Register src1, Operand src2) {
1517     bmi1(0xf2, dst, src1, src2);
1518   }
bextr(Register dst,Register src1,Register src2)1519   void bextr(Register dst, Register src1, Register src2) {
1520     bextr(dst, Operand(src1), src2);
1521   }
bextr(Register dst,Operand src1,Register src2)1522   void bextr(Register dst, Operand src1, Register src2) {
1523     bmi1(0xf7, dst, src2, src1);
1524   }
blsi(Register dst,Register src)1525   void blsi(Register dst, Register src) { blsi(dst, Operand(src)); }
blsi(Register dst,Operand src)1526   void blsi(Register dst, Operand src) { bmi1(0xf3, ebx, dst, src); }
blsmsk(Register dst,Register src)1527   void blsmsk(Register dst, Register src) { blsmsk(dst, Operand(src)); }
blsmsk(Register dst,Operand src)1528   void blsmsk(Register dst, Operand src) { bmi1(0xf3, edx, dst, src); }
blsr(Register dst,Register src)1529   void blsr(Register dst, Register src) { blsr(dst, Operand(src)); }
blsr(Register dst,Operand src)1530   void blsr(Register dst, Operand src) { bmi1(0xf3, ecx, dst, src); }
tzcnt(Register dst,Register src)1531   void tzcnt(Register dst, Register src) { tzcnt(dst, Operand(src)); }
1532   void tzcnt(Register dst, Operand src);
1533 
lzcnt(Register dst,Register src)1534   void lzcnt(Register dst, Register src) { lzcnt(dst, Operand(src)); }
1535   void lzcnt(Register dst, Operand src);
1536 
popcnt(Register dst,Register src)1537   void popcnt(Register dst, Register src) { popcnt(dst, Operand(src)); }
1538   void popcnt(Register dst, Operand src);
1539 
bzhi(Register dst,Register src1,Register src2)1540   void bzhi(Register dst, Register src1, Register src2) {
1541     bzhi(dst, Operand(src1), src2);
1542   }
bzhi(Register dst,Operand src1,Register src2)1543   void bzhi(Register dst, Operand src1, Register src2) {
1544     bmi2(kNone, 0xf5, dst, src2, src1);
1545   }
mulx(Register dst1,Register dst2,Register src)1546   void mulx(Register dst1, Register dst2, Register src) {
1547     mulx(dst1, dst2, Operand(src));
1548   }
mulx(Register dst1,Register dst2,Operand src)1549   void mulx(Register dst1, Register dst2, Operand src) {
1550     bmi2(kF2, 0xf6, dst1, dst2, src);
1551   }
pdep(Register dst,Register src1,Register src2)1552   void pdep(Register dst, Register src1, Register src2) {
1553     pdep(dst, src1, Operand(src2));
1554   }
pdep(Register dst,Register src1,Operand src2)1555   void pdep(Register dst, Register src1, Operand src2) {
1556     bmi2(kF2, 0xf5, dst, src1, src2);
1557   }
pext(Register dst,Register src1,Register src2)1558   void pext(Register dst, Register src1, Register src2) {
1559     pext(dst, src1, Operand(src2));
1560   }
pext(Register dst,Register src1,Operand src2)1561   void pext(Register dst, Register src1, Operand src2) {
1562     bmi2(kF3, 0xf5, dst, src1, src2);
1563   }
sarx(Register dst,Register src1,Register src2)1564   void sarx(Register dst, Register src1, Register src2) {
1565     sarx(dst, Operand(src1), src2);
1566   }
sarx(Register dst,Operand src1,Register src2)1567   void sarx(Register dst, Operand src1, Register src2) {
1568     bmi2(kF3, 0xf7, dst, src2, src1);
1569   }
shlx(Register dst,Register src1,Register src2)1570   void shlx(Register dst, Register src1, Register src2) {
1571     shlx(dst, Operand(src1), src2);
1572   }
shlx(Register dst,Operand src1,Register src2)1573   void shlx(Register dst, Operand src1, Register src2) {
1574     bmi2(k66, 0xf7, dst, src2, src1);
1575   }
shrx(Register dst,Register src1,Register src2)1576   void shrx(Register dst, Register src1, Register src2) {
1577     shrx(dst, Operand(src1), src2);
1578   }
shrx(Register dst,Operand src1,Register src2)1579   void shrx(Register dst, Operand src1, Register src2) {
1580     bmi2(kF2, 0xf7, dst, src2, src1);
1581   }
rorx(Register dst,Register src,byte imm8)1582   void rorx(Register dst, Register src, byte imm8) {
1583     rorx(dst, Operand(src), imm8);
1584   }
1585   void rorx(Register dst, Operand src, byte imm8);
1586 
1587 #define PACKED_OP_LIST(V) \
1588   V(and, 0x54)            \
1589   V(xor, 0x57)            \
1590   V(add, 0x58)            \
1591   V(mul, 0x59)            \
1592   V(sub, 0x5c)            \
1593   V(min, 0x5d)            \
1594   V(div, 0x5e)            \
1595   V(max, 0x5f)
1596 
1597 #define AVX_PACKED_OP_DECLARE(name, opcode)                               \
1598   void v##name##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1599     vps(opcode, dst, src1, Operand(src2));                                \
1600   }                                                                       \
1601   void v##name##ps(XMMRegister dst, XMMRegister src1, Operand src2) {     \
1602     vps(opcode, dst, src1, src2);                                         \
1603   }                                                                       \
1604   void v##name##pd(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1605     vpd(opcode, dst, src1, Operand(src2));                                \
1606   }                                                                       \
1607   void v##name##pd(XMMRegister dst, XMMRegister src1, Operand src2) {     \
1608     vpd(opcode, dst, src1, src2);                                         \
1609   }
1610 
1611   PACKED_OP_LIST(AVX_PACKED_OP_DECLARE);
1612   void vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1613   void vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2);
1614 
1615   void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp);
1616 #define AVX_CMP_P(instr, imm8)                                          \
1617   void instr##ps(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1618     vcmpps(dst, src1, Operand(src2), imm8);                             \
1619   }                                                                     \
1620   void instr##ps(XMMRegister dst, XMMRegister src1, Operand src2) {     \
1621     vcmpps(dst, src1, src2, imm8);                                      \
1622   }
1623 
1624   AVX_CMP_P(vcmpeq, 0x0);
1625   AVX_CMP_P(vcmplt, 0x1);
1626   AVX_CMP_P(vcmple, 0x2);
1627   AVX_CMP_P(vcmpneq, 0x4);
1628 
1629 #undef AVX_CMP_P
1630 
1631 // Other SSE and AVX instructions
1632 #define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \
1633   void instruction(XMMRegister dst, XMMRegister src) {                \
1634     instruction(dst, Operand(src));                                   \
1635   }                                                                   \
1636   void instruction(XMMRegister dst, Operand src) {                    \
1637     sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode);         \
1638   }
1639 
1640   SSE2_INSTRUCTION_LIST(DECLARE_SSE2_INSTRUCTION)
1641 #undef DECLARE_SSE2_INSTRUCTION
1642 
1643 #define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode)    \
1644   void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1645     v##instruction(dst, src1, Operand(src2));                                \
1646   }                                                                          \
1647   void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) {     \
1648     vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0);          \
1649   }
1650 
1651   SSE2_INSTRUCTION_LIST(DECLARE_SSE2_AVX_INSTRUCTION)
1652 #undef DECLARE_SSE2_AVX_INSTRUCTION
1653 
1654 #define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2,     \
1655                                   opcode)                                    \
1656   void instruction(XMMRegister dst, XMMRegister src) {                       \
1657     instruction(dst, Operand(src));                                          \
1658   }                                                                          \
1659   void instruction(XMMRegister dst, Operand src) {                           \
1660     ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1661   }
1662 
1663   SSSE3_INSTRUCTION_LIST(DECLARE_SSSE3_INSTRUCTION)
1664 #undef DECLARE_SSSE3_INSTRUCTION
1665 
1666 #define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2,     \
1667                                  opcode)                                    \
1668   void instruction(XMMRegister dst, XMMRegister src) {                      \
1669     instruction(dst, Operand(src));                                         \
1670   }                                                                         \
1671   void instruction(XMMRegister dst, Operand src) {                          \
1672     sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1673   }
1674 
1675   SSE4_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION)
1676   SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE4_INSTRUCTION)
1677 #undef DECLARE_SSE4_INSTRUCTION
1678 
1679 #define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2,  \
1680                                       opcode)                                 \
1681   void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) {  \
1682     v##instruction(dst, src1, Operand(src2));                                 \
1683   }                                                                           \
1684   void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) {      \
1685     vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
1686   }
1687 
1688   SSSE3_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
1689   SSE4_INSTRUCTION_LIST(DECLARE_SSE34_AVX_INSTRUCTION)
1690 #undef DECLARE_SSE34_AVX_INSTRUCTION
1691 
1692 #define DECLARE_SSE4_AVX_RM_INSTRUCTION(instruction, prefix, escape1, escape2, \
1693                                         opcode)                                \
1694   void v##instruction(XMMRegister dst, XMMRegister src) {                      \
1695     v##instruction(dst, Operand(src));                                         \
1696   }                                                                            \
1697   void v##instruction(XMMRegister dst, Operand src) {                          \
1698     vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0);   \
1699   }
1700 
1701   SSE4_RM_INSTRUCTION_LIST(DECLARE_SSE4_AVX_RM_INSTRUCTION)
1702 #undef DECLARE_SSE4_AVX_RM_INSTRUCTION
1703 
1704   // Prefetch src position into cache level.
1705   // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
1706   // non-temporal
1707   void prefetch(Operand src, int level);
1708   // TODO(lrn): Need SFENCE for movnt?
1709 
1710   // Check the code size generated from label to here.
SizeOfCodeGeneratedSince(Label * label)1711   int SizeOfCodeGeneratedSince(Label* label) {
1712     return pc_offset() - label->pos();
1713   }
1714 
1715   // Use --code-comments to enable.
1716   void RecordComment(const char* msg);
1717 
1718   // Record a deoptimization reason that can be used by a log or cpu profiler.
1719   // Use --trace-deopt to enable.
1720   void RecordDeoptReason(DeoptimizeReason reason, SourcePosition position,
1721                          int id);
1722 
1723   // Writes a single byte or word of data in the code stream.  Used for
1724   // inline tables, e.g., jump-tables.
1725   void db(uint8_t data);
1726   void dd(uint32_t data);
1727   void dq(uint64_t data);
dp(uintptr_t data)1728   void dp(uintptr_t data) { dd(data); }
1729   void dd(Label* label);
1730 
1731   // Check if there is less than kGap bytes available in the buffer.
1732   // If this is the case, we need to grow the buffer before emitting
1733   // an instruction or relocation information.
buffer_overflow()1734   inline bool buffer_overflow() const {
1735     return pc_ >= reloc_info_writer.pos() - kGap;
1736   }
1737 
1738   // Get the number of bytes available in the buffer.
available_space()1739   inline int available_space() const { return reloc_info_writer.pos() - pc_; }
1740 
1741   static bool IsNop(Address addr);
1742 
relocation_writer_size()1743   int relocation_writer_size() {
1744     return (buffer_ + buffer_size_) - reloc_info_writer.pos();
1745   }
1746 
1747   // Avoid overflows for displacements etc.
1748   static constexpr int kMaximalBufferSize = 512 * MB;
1749 
byte_at(int pos)1750   byte byte_at(int pos) { return buffer_[pos]; }
set_byte_at(int pos,byte value)1751   void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1752 
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1753   void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1754                                           ConstantPoolEntry::Access access,
1755                                           ConstantPoolEntry::Type type) {
1756     // No embedded constant pool support.
1757     UNREACHABLE();
1758   }
1759 
1760  protected:
1761   void emit_sse_operand(XMMRegister reg, Operand adr);
1762   void emit_sse_operand(XMMRegister dst, XMMRegister src);
1763   void emit_sse_operand(Register dst, XMMRegister src);
1764   void emit_sse_operand(XMMRegister dst, Register src);
1765 
addr_at(int pos)1766   byte* addr_at(int pos) { return buffer_ + pos; }
1767 
1768 
1769  private:
long_at(int pos)1770   uint32_t long_at(int pos)  {
1771     return *reinterpret_cast<uint32_t*>(addr_at(pos));
1772   }
long_at_put(int pos,uint32_t x)1773   void long_at_put(int pos, uint32_t x)  {
1774     *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1775   }
1776 
1777   // code emission
1778   void GrowBuffer();
1779   inline void emit(uint32_t x);
1780   inline void emit(Handle<HeapObject> handle);
1781   inline void emit(uint32_t x, RelocInfo::Mode rmode);
1782   inline void emit(Handle<Code> code, RelocInfo::Mode rmode);
1783   inline void emit(const Immediate& x);
1784   inline void emit_b(Immediate x);
1785   inline void emit_w(const Immediate& x);
1786   inline void emit_q(uint64_t x);
1787 
1788   // Emit the code-object-relative offset of the label's position
1789   inline void emit_code_relative_offset(Label* label);
1790 
1791   // instruction generation
1792   void emit_arith_b(int op1, int op2, Register dst, int imm8);
1793 
1794   // Emit a basic arithmetic instruction (i.e. first byte of the family is 0x81)
1795   // with a given destination expression and an immediate operand.  It attempts
1796   // to use the shortest encoding possible.
1797   // sel specifies the /n in the modrm byte (see the Intel PRM).
1798   void emit_arith(int sel, Operand dst, const Immediate& x);
1799 
1800   void emit_operand(int code, Operand adr);
1801   void emit_operand(Register reg, Operand adr);
1802   void emit_operand(XMMRegister reg, Operand adr);
1803 
1804   void emit_label(Label* label);
1805 
1806   void emit_farith(int b1, int b2, int i);
1807 
1808   // Emit vex prefix
1809   enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
1810   enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
1811   enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
1812   enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
1813   inline void emit_vex_prefix(XMMRegister v, VectorLength l, SIMDPrefix pp,
1814                               LeadingOpcode m, VexW w);
1815   inline void emit_vex_prefix(Register v, VectorLength l, SIMDPrefix pp,
1816                               LeadingOpcode m, VexW w);
1817 
1818   // labels
1819   void print(const Label* L);
1820   void bind_to(Label* L, int pos);
1821 
1822   // displacements
1823   inline Displacement disp_at(Label* L);
1824   inline void disp_at_put(Label* L, Displacement disp);
1825   inline void emit_disp(Label* L, Displacement::Type type);
1826   inline void emit_near_disp(Label* L);
1827 
1828   void sse2_instr(XMMRegister dst, Operand src, byte prefix, byte escape,
1829                   byte opcode);
1830   void ssse3_instr(XMMRegister dst, Operand src, byte prefix, byte escape1,
1831                    byte escape2, byte opcode);
1832   void sse4_instr(XMMRegister dst, Operand src, byte prefix, byte escape1,
1833                   byte escape2, byte opcode);
1834   void vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
1835               SIMDPrefix pp, LeadingOpcode m, VexW w);
1836   // Most BMI instructions are similar.
1837   void bmi1(byte op, Register reg, Register vreg, Operand rm);
1838   void bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg, Operand rm);
1839 
1840   // record reloc info for current pc_
1841   void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1842 
1843   // record the position of jmp/jcc instruction
1844   void record_farjmp_position(Label* L, int pos);
1845 
1846   bool is_optimizable_farjmp(int idx);
1847 
1848   void AllocateAndInstallRequestedHeapObjects(Isolate* isolate);
1849 
1850   friend class EnsureSpace;
1851 
1852   // Internal reference positions, required for (potential) patching in
1853   // GrowBuffer(); contains only those internal references whose labels
1854   // are already bound.
1855   std::deque<int> internal_reference_positions_;
1856 
1857   // code generation
1858   RelocInfoWriter reloc_info_writer;
1859 
1860   // Variables for this instance of assembler
1861   int farjmp_num_ = 0;
1862   std::deque<int> farjmp_positions_;
1863   std::map<Label*, std::vector<int>> label_farjmp_maps_;
1864 };
1865 
1866 
1867 // Helper class that ensures that there is enough space for generating
1868 // instructions and relocation information.  The constructor makes
1869 // sure that there is enough space and (in debug mode) the destructor
1870 // checks that we did not generate too much.
1871 class EnsureSpace BASE_EMBEDDED {
1872  public:
EnsureSpace(Assembler * assembler)1873   explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
1874     if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
1875 #ifdef DEBUG
1876     space_before_ = assembler_->available_space();
1877 #endif
1878   }
1879 
1880 #ifdef DEBUG
~EnsureSpace()1881   ~EnsureSpace() {
1882     int bytes_generated = space_before_ - assembler_->available_space();
1883     DCHECK(bytes_generated < assembler_->kGap);
1884   }
1885 #endif
1886 
1887  private:
1888   Assembler* assembler_;
1889 #ifdef DEBUG
1890   int space_before_;
1891 #endif
1892 };
1893 
1894 }  // namespace internal
1895 }  // namespace v8
1896 
1897 #endif  // V8_IA32_ASSEMBLER_IA32_H_
1898