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