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 2012 the V8 project authors. All rights reserved.
34
35 // A lightweight X64 Assembler.
36
37 #ifndef V8_X64_ASSEMBLER_X64_H_
38 #define V8_X64_ASSEMBLER_X64_H_
39
40 #include <deque>
41
42 #include "src/assembler.h"
43
44 namespace v8 {
45 namespace internal {
46
47 // Utility functions
48
49 #define GENERAL_REGISTERS(V) \
50 V(rax) \
51 V(rcx) \
52 V(rdx) \
53 V(rbx) \
54 V(rsp) \
55 V(rbp) \
56 V(rsi) \
57 V(rdi) \
58 V(r8) \
59 V(r9) \
60 V(r10) \
61 V(r11) \
62 V(r12) \
63 V(r13) \
64 V(r14) \
65 V(r15)
66
67 #define ALLOCATABLE_GENERAL_REGISTERS(V) \
68 V(rax) \
69 V(rbx) \
70 V(rdx) \
71 V(rcx) \
72 V(rsi) \
73 V(rdi) \
74 V(r8) \
75 V(r9) \
76 V(r11) \
77 V(r12) \
78 V(r14) \
79 V(r15)
80
81
82 // CPU Registers.
83 //
84 // 1) We would prefer to use an enum, but enum values are assignment-
85 // compatible with int, which has caused code-generation bugs.
86 //
87 // 2) We would prefer to use a class instead of a struct but we don't like
88 // the register initialization to depend on the particular initialization
89 // order (which appears to be different on OS X, Linux, and Windows for the
90 // installed versions of C++ we tried). Using a struct permits C-style
91 // "initialization". Also, the Register objects cannot be const as this
92 // forces initialization stubs in MSVC, making us dependent on initialization
93 // order.
94 //
95 // 3) By not using an enum, we are possibly preventing the compiler from
96 // doing certain constant folds, which may significantly reduce the
97 // code generated for some assembly instructions (because they boil down
98 // to a few constants). If this is a problem, we could change the code
99 // such that we use an enum in optimized mode, and the struct in debug
100 // mode. This way we get the compile-time error checking in debug mode
101 // and best performance in optimized code.
102 //
103 struct Register {
104 enum Code {
105 #define REGISTER_CODE(R) kCode_##R,
106 GENERAL_REGISTERS(REGISTER_CODE)
107 #undef REGISTER_CODE
108 kAfterLast,
109 kCode_no_reg = -1
110 };
111
112 static const int kNumRegisters = Code::kAfterLast;
113
from_codeRegister114 static Register from_code(int code) {
115 DCHECK(code >= 0);
116 DCHECK(code < kNumRegisters);
117 Register r = {code};
118 return r;
119 }
120 const char* ToString();
121 bool IsAllocatable() const;
is_validRegister122 bool is_valid() const { return 0 <= reg_code && reg_code < kNumRegisters; }
isRegister123 bool is(Register reg) const { return reg_code == reg.reg_code; }
codeRegister124 int code() const {
125 DCHECK(is_valid());
126 return reg_code;
127 }
bitRegister128 int bit() const {
129 DCHECK(is_valid());
130 return 1 << reg_code;
131 }
132
is_byte_registerRegister133 bool is_byte_register() const { return reg_code <= 3; }
134 // Return the high bit of the register code as a 0 or 1. Used often
135 // when constructing the REX prefix byte.
high_bitRegister136 int high_bit() const { return reg_code >> 3; }
137 // Return the 3 low bits of the register code. Used when encoding registers
138 // in modR/M, SIB, and opcode bytes.
low_bitsRegister139 int low_bits() const { return reg_code & 0x7; }
140
141 // Unfortunately we can't make this private in a struct when initializing
142 // by assignment.
143 int reg_code;
144 };
145
146
147 #define DECLARE_REGISTER(R) const Register R = {Register::kCode_##R};
148 GENERAL_REGISTERS(DECLARE_REGISTER)
149 #undef DECLARE_REGISTER
150 const Register no_reg = {Register::kCode_no_reg};
151
152
153 #ifdef _WIN64
154 // Windows calling convention
155 const Register arg_reg_1 = {Register::kCode_rcx};
156 const Register arg_reg_2 = {Register::kCode_rdx};
157 const Register arg_reg_3 = {Register::kCode_r8};
158 const Register arg_reg_4 = {Register::kCode_r9};
159 #else
160 // AMD64 calling convention
161 const Register arg_reg_1 = {Register::kCode_rdi};
162 const Register arg_reg_2 = {Register::kCode_rsi};
163 const Register arg_reg_3 = {Register::kCode_rdx};
164 const Register arg_reg_4 = {Register::kCode_rcx};
165 #endif // _WIN64
166
167
168 #define DOUBLE_REGISTERS(V) \
169 V(xmm0) \
170 V(xmm1) \
171 V(xmm2) \
172 V(xmm3) \
173 V(xmm4) \
174 V(xmm5) \
175 V(xmm6) \
176 V(xmm7) \
177 V(xmm8) \
178 V(xmm9) \
179 V(xmm10) \
180 V(xmm11) \
181 V(xmm12) \
182 V(xmm13) \
183 V(xmm14) \
184 V(xmm15)
185
186 #define ALLOCATABLE_DOUBLE_REGISTERS(V) \
187 V(xmm1) \
188 V(xmm2) \
189 V(xmm3) \
190 V(xmm4) \
191 V(xmm5) \
192 V(xmm6) \
193 V(xmm7) \
194 V(xmm8) \
195 V(xmm9) \
196 V(xmm10) \
197 V(xmm11) \
198 V(xmm12) \
199 V(xmm13) \
200 V(xmm14) \
201 V(xmm15)
202
203
204 struct DoubleRegister {
205 enum Code {
206 #define REGISTER_CODE(R) kCode_##R,
207 DOUBLE_REGISTERS(REGISTER_CODE)
208 #undef REGISTER_CODE
209 kAfterLast,
210 kCode_no_reg = -1
211 };
212
213 static const int kMaxNumRegisters = Code::kAfterLast;
214
from_codeDoubleRegister215 static DoubleRegister from_code(int code) {
216 DoubleRegister result = {code};
217 return result;
218 }
219
220 const char* ToString();
221 bool IsAllocatable() const;
is_validDoubleRegister222 bool is_valid() const { return 0 <= reg_code && reg_code < kMaxNumRegisters; }
isDoubleRegister223 bool is(DoubleRegister reg) const { return reg_code == reg.reg_code; }
codeDoubleRegister224 int code() const {
225 DCHECK(is_valid());
226 return reg_code;
227 }
228
229 // Return the high bit of the register code as a 0 or 1. Used often
230 // when constructing the REX prefix byte.
high_bitDoubleRegister231 int high_bit() const { return reg_code >> 3; }
232 // Return the 3 low bits of the register code. Used when encoding registers
233 // in modR/M, SIB, and opcode bytes.
low_bitsDoubleRegister234 int low_bits() const { return reg_code & 0x7; }
235
236 // Unfortunately we can't make this private in a struct when initializing
237 // by assignment.
238 int reg_code;
239 };
240
241
242 #define DECLARE_REGISTER(R) \
243 const DoubleRegister R = {DoubleRegister::kCode_##R};
244 DOUBLE_REGISTERS(DECLARE_REGISTER)
245 #undef DECLARE_REGISTER
246 const DoubleRegister no_double_reg = {DoubleRegister::kCode_no_reg};
247
248
249 typedef DoubleRegister XMMRegister;
250
251 enum Condition {
252 // any value < 0 is considered no_condition
253 no_condition = -1,
254
255 overflow = 0,
256 no_overflow = 1,
257 below = 2,
258 above_equal = 3,
259 equal = 4,
260 not_equal = 5,
261 below_equal = 6,
262 above = 7,
263 negative = 8,
264 positive = 9,
265 parity_even = 10,
266 parity_odd = 11,
267 less = 12,
268 greater_equal = 13,
269 less_equal = 14,
270 greater = 15,
271
272 // Fake conditions that are handled by the
273 // opcodes using them.
274 always = 16,
275 never = 17,
276 // aliases
277 carry = below,
278 not_carry = above_equal,
279 zero = equal,
280 not_zero = not_equal,
281 sign = negative,
282 not_sign = positive,
283 last_condition = greater
284 };
285
286
287 // Returns the equivalent of !cc.
288 // Negation of the default no_condition (-1) results in a non-default
289 // no_condition value (-2). As long as tests for no_condition check
290 // for condition < 0, this will work as expected.
NegateCondition(Condition cc)291 inline Condition NegateCondition(Condition cc) {
292 return static_cast<Condition>(cc ^ 1);
293 }
294
295
296 // Commute a condition such that {a cond b == b cond' a}.
CommuteCondition(Condition cc)297 inline Condition CommuteCondition(Condition cc) {
298 switch (cc) {
299 case below:
300 return above;
301 case above:
302 return below;
303 case above_equal:
304 return below_equal;
305 case below_equal:
306 return above_equal;
307 case less:
308 return greater;
309 case greater:
310 return less;
311 case greater_equal:
312 return less_equal;
313 case less_equal:
314 return greater_equal;
315 default:
316 return cc;
317 }
318 }
319
320
321 enum RoundingMode {
322 kRoundToNearest = 0x0,
323 kRoundDown = 0x1,
324 kRoundUp = 0x2,
325 kRoundToZero = 0x3
326 };
327
328
329 // -----------------------------------------------------------------------------
330 // Machine instruction Immediates
331
332 class Immediate BASE_EMBEDDED {
333 public:
Immediate(int32_t value)334 explicit Immediate(int32_t value) : value_(value) {}
Immediate(Smi * value)335 explicit Immediate(Smi* value) {
336 DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
337 value_ = static_cast<int32_t>(reinterpret_cast<intptr_t>(value));
338 }
339
340 private:
341 int32_t value_;
342
343 friend class Assembler;
344 };
345
346
347 // -----------------------------------------------------------------------------
348 // Machine instruction Operands
349
350 enum ScaleFactor {
351 times_1 = 0,
352 times_2 = 1,
353 times_4 = 2,
354 times_8 = 3,
355 times_int_size = times_4,
356 times_pointer_size = (kPointerSize == 8) ? times_8 : times_4
357 };
358
359
360 class Operand BASE_EMBEDDED {
361 public:
362 // [base + disp/r]
363 Operand(Register base, int32_t disp);
364
365 // [base + index*scale + disp/r]
366 Operand(Register base,
367 Register index,
368 ScaleFactor scale,
369 int32_t disp);
370
371 // [index*scale + disp/r]
372 Operand(Register index,
373 ScaleFactor scale,
374 int32_t disp);
375
376 // Offset from existing memory operand.
377 // Offset is added to existing displacement as 32-bit signed values and
378 // this must not overflow.
379 Operand(const Operand& base, int32_t offset);
380
381 // [rip + disp/r]
382 explicit Operand(Label* label);
383
384 // Checks whether either base or index register is the given register.
385 // Does not check the "reg" part of the Operand.
386 bool AddressUsesRegister(Register reg) const;
387
388 // Queries related to the size of the generated instruction.
389 // Whether the generated instruction will have a REX prefix.
requires_rex()390 bool requires_rex() const { return rex_ != 0; }
391 // Size of the ModR/M, SIB and displacement parts of the generated
392 // instruction.
operand_size()393 int operand_size() const { return len_; }
394
395 private:
396 byte rex_;
397 byte buf_[9];
398 // The number of bytes of buf_ in use.
399 byte len_;
400
401 // Set the ModR/M byte without an encoded 'reg' register. The
402 // register is encoded later as part of the emit_operand operation.
403 // set_modrm can be called before or after set_sib and set_disp*.
404 inline void set_modrm(int mod, Register rm);
405
406 // Set the SIB byte if one is needed. Sets the length to 2 rather than 1.
407 inline void set_sib(ScaleFactor scale, Register index, Register base);
408
409 // Adds operand displacement fields (offsets added to the memory address).
410 // Needs to be called after set_sib, not before it.
411 inline void set_disp8(int disp);
412 inline void set_disp32(int disp);
413 inline void set_disp64(int64_t disp); // for labels.
414
415 friend class Assembler;
416 };
417
418
419 #define ASSEMBLER_INSTRUCTION_LIST(V) \
420 V(add) \
421 V(and) \
422 V(cmp) \
423 V(dec) \
424 V(idiv) \
425 V(div) \
426 V(imul) \
427 V(inc) \
428 V(lea) \
429 V(mov) \
430 V(movzxb) \
431 V(movzxw) \
432 V(neg) \
433 V(not) \
434 V(or) \
435 V(repmovs) \
436 V(sbb) \
437 V(sub) \
438 V(test) \
439 V(xchg) \
440 V(xor)
441
442
443 // Shift instructions on operands/registers with kPointerSize, kInt32Size and
444 // kInt64Size.
445 #define SHIFT_INSTRUCTION_LIST(V) \
446 V(rol, 0x0) \
447 V(ror, 0x1) \
448 V(rcl, 0x2) \
449 V(rcr, 0x3) \
450 V(shl, 0x4) \
451 V(shr, 0x5) \
452 V(sar, 0x7) \
453
454
455 class Assembler : public AssemblerBase {
456 private:
457 // We check before assembling an instruction that there is sufficient
458 // space to write an instruction and its relocation information.
459 // The relocation writer's position must be kGap bytes above the end of
460 // the generated instructions. This leaves enough space for the
461 // longest possible x64 instruction, 15 bytes, and the longest possible
462 // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
463 // (There is a 15 byte limit on x64 instruction length that rules out some
464 // otherwise valid instructions.)
465 // This allows for a single, fast space check per instruction.
466 static const int kGap = 32;
467
468 public:
469 // Create an assembler. Instructions and relocation information are emitted
470 // into a buffer, with the instructions starting from the beginning and the
471 // relocation information starting from the end of the buffer. See CodeDesc
472 // for a detailed comment on the layout (globals.h).
473 //
474 // If the provided buffer is NULL, the assembler allocates and grows its own
475 // buffer, and buffer_size determines the initial buffer size. The buffer is
476 // owned by the assembler and deallocated upon destruction of the assembler.
477 //
478 // If the provided buffer is not NULL, the assembler uses the provided buffer
479 // for code generation and assumes its size to be buffer_size. If the buffer
480 // is too small, a fatal error occurs. No deallocation of the buffer is done
481 // upon destruction of the assembler.
482 Assembler(Isolate* isolate, void* buffer, int buffer_size);
~Assembler()483 virtual ~Assembler() { }
484
485 // GetCode emits any pending (non-emitted) code and fills the descriptor
486 // desc. GetCode() is idempotent; it returns the same result if no other
487 // Assembler functions are invoked in between GetCode() calls.
488 void GetCode(CodeDesc* desc);
489
490 // Read/Modify the code target in the relative branch/call instruction at pc.
491 // On the x64 architecture, we use relative jumps with a 32-bit displacement
492 // to jump to other Code objects in the Code space in the heap.
493 // Jumps to C functions are done indirectly through a 64-bit register holding
494 // the absolute address of the target.
495 // These functions convert between absolute Addresses of Code objects and
496 // the relative displacements stored in the code.
497 static inline Address target_address_at(Address pc, Address constant_pool);
498 static inline void set_target_address_at(
499 Isolate* isolate, Address pc, Address constant_pool, Address target,
500 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
target_address_at(Address pc,Code * code)501 static inline Address target_address_at(Address pc, Code* code) {
502 Address constant_pool = code ? code->constant_pool() : NULL;
503 return target_address_at(pc, constant_pool);
504 }
505 static inline void set_target_address_at(
506 Isolate* isolate, Address pc, Code* code, Address target,
507 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED) {
508 Address constant_pool = code ? code->constant_pool() : NULL;
509 set_target_address_at(isolate, pc, constant_pool, target,
510 icache_flush_mode);
511 }
512
513 // Return the code target address at a call site from the return address
514 // of that call in the instruction stream.
515 static inline Address target_address_from_return_address(Address pc);
516
517 // This sets the branch destination (which is in the instruction on x64).
518 // This is for calls and branches within generated code.
deserialization_set_special_target_at(Isolate * isolate,Address instruction_payload,Code * code,Address target)519 inline static void deserialization_set_special_target_at(
520 Isolate* isolate, Address instruction_payload, Code* code,
521 Address target) {
522 set_target_address_at(isolate, instruction_payload, code, target);
523 }
524
525 // This sets the internal reference at the pc.
526 inline static void deserialization_set_target_internal_reference_at(
527 Isolate* isolate, Address pc, Address target,
528 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
529
RelocInfoNone()530 static inline RelocInfo::Mode RelocInfoNone() {
531 if (kPointerSize == kInt64Size) {
532 return RelocInfo::NONE64;
533 } else {
534 DCHECK(kPointerSize == kInt32Size);
535 return RelocInfo::NONE32;
536 }
537 }
538
539 inline Handle<Object> code_target_object_handle_at(Address pc);
540 inline Address runtime_entry_at(Address pc);
541 // Number of bytes taken up by the branch target in the code.
542 static const int kSpecialTargetSize = 4; // Use 32-bit displacement.
543 // Distance between the address of the code target in the call instruction
544 // and the return address pushed on the stack.
545 static const int kCallTargetAddressOffset = 4; // Use 32-bit displacement.
546 // The length of call(kScratchRegister).
547 static const int kCallScratchRegisterInstructionLength = 3;
548 // The length of call(Immediate32).
549 static const int kShortCallInstructionLength = 5;
550 // The length of movq(kScratchRegister, address).
551 static const int kMoveAddressIntoScratchRegisterInstructionLength =
552 2 + kPointerSize;
553 // The length of movq(kScratchRegister, address) and call(kScratchRegister).
554 static const int kCallSequenceLength =
555 kMoveAddressIntoScratchRegisterInstructionLength +
556 kCallScratchRegisterInstructionLength;
557
558 // The debug break slot must be able to contain an indirect call sequence.
559 static const int kDebugBreakSlotLength = kCallSequenceLength;
560 // Distance between start of patched debug break slot and the emitted address
561 // to jump to.
562 static const int kPatchDebugBreakSlotAddressOffset =
563 kMoveAddressIntoScratchRegisterInstructionLength - kPointerSize;
564
565 // One byte opcode for test eax,0xXXXXXXXX.
566 static const byte kTestEaxByte = 0xA9;
567 // One byte opcode for test al, 0xXX.
568 static const byte kTestAlByte = 0xA8;
569 // One byte opcode for nop.
570 static const byte kNopByte = 0x90;
571
572 // One byte prefix for a short conditional jump.
573 static const byte kJccShortPrefix = 0x70;
574 static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
575 static const byte kJcShortOpcode = kJccShortPrefix | carry;
576 static const byte kJnzShortOpcode = kJccShortPrefix | not_zero;
577 static const byte kJzShortOpcode = kJccShortPrefix | zero;
578
579 // VEX prefix encodings.
580 enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
581 enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
582 enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
583 enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
584
585 // ---------------------------------------------------------------------------
586 // Code generation
587 //
588 // Function names correspond one-to-one to x64 instruction mnemonics.
589 // Unless specified otherwise, instructions operate on 64-bit operands.
590 //
591 // If we need versions of an assembly instruction that operate on different
592 // width arguments, we add a single-letter suffix specifying the width.
593 // This is done for the following instructions: mov, cmp, inc, dec,
594 // add, sub, and test.
595 // There are no versions of these instructions without the suffix.
596 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
597 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
598 // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
599 // - Instructions on 64-bit (quadword) operands/registers use 'q'.
600 // - Instructions on operands/registers with pointer size use 'p'.
601
602 STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
603
604 #define DECLARE_INSTRUCTION(instruction) \
605 template<class P1> \
606 void instruction##p(P1 p1) { \
607 emit_##instruction(p1, kPointerSize); \
608 } \
609 \
610 template<class P1> \
611 void instruction##l(P1 p1) { \
612 emit_##instruction(p1, kInt32Size); \
613 } \
614 \
615 template<class P1> \
616 void instruction##q(P1 p1) { \
617 emit_##instruction(p1, kInt64Size); \
618 } \
619 \
620 template<class P1, class P2> \
621 void instruction##p(P1 p1, P2 p2) { \
622 emit_##instruction(p1, p2, kPointerSize); \
623 } \
624 \
625 template<class P1, class P2> \
626 void instruction##l(P1 p1, P2 p2) { \
627 emit_##instruction(p1, p2, kInt32Size); \
628 } \
629 \
630 template<class P1, class P2> \
631 void instruction##q(P1 p1, P2 p2) { \
632 emit_##instruction(p1, p2, kInt64Size); \
633 } \
634 \
635 template<class P1, class P2, class P3> \
636 void instruction##p(P1 p1, P2 p2, P3 p3) { \
637 emit_##instruction(p1, p2, p3, kPointerSize); \
638 } \
639 \
640 template<class P1, class P2, class P3> \
641 void instruction##l(P1 p1, P2 p2, P3 p3) { \
642 emit_##instruction(p1, p2, p3, kInt32Size); \
643 } \
644 \
645 template<class P1, class P2, class P3> \
646 void instruction##q(P1 p1, P2 p2, P3 p3) { \
647 emit_##instruction(p1, p2, p3, kInt64Size); \
648 }
649 ASSEMBLER_INSTRUCTION_LIST(DECLARE_INSTRUCTION)
650 #undef DECLARE_INSTRUCTION
651
652 // Insert the smallest number of nop instructions
653 // possible to align the pc offset to a multiple
654 // of m, where m must be a power of 2.
655 void Align(int m);
656 // Insert the smallest number of zero bytes possible to align the pc offset
657 // to a mulitple of m. m must be a power of 2 (>= 2).
658 void DataAlign(int m);
659 void Nop(int bytes = 1);
660 // Aligns code to something that's optimal for a jump target for the platform.
661 void CodeTargetAlign();
662
663 // Stack
664 void pushfq();
665 void popfq();
666
667 void pushq(Immediate value);
668 // Push a 32 bit integer, and guarantee that it is actually pushed as a
669 // 32 bit value, the normal push will optimize the 8 bit case.
670 void pushq_imm32(int32_t imm32);
671 void pushq(Register src);
672 void pushq(const Operand& src);
673
674 void popq(Register dst);
675 void popq(const Operand& dst);
676
677 void enter(Immediate size);
678 void leave();
679
680 // Moves
681 void movb(Register dst, const Operand& src);
682 void movb(Register dst, Immediate imm);
683 void movb(const Operand& dst, Register src);
684 void movb(const Operand& dst, Immediate imm);
685
686 // Move the low 16 bits of a 64-bit register value to a 16-bit
687 // memory location.
688 void movw(Register dst, const Operand& src);
689 void movw(const Operand& dst, Register src);
690 void movw(const Operand& dst, Immediate imm);
691
692 // Move the offset of the label location relative to the current
693 // position (after the move) to the destination.
694 void movl(const Operand& dst, Label* src);
695
696 // Loads a pointer into a register with a relocation mode.
697 void movp(Register dst, void* ptr, RelocInfo::Mode rmode);
698
699 // Loads a 64-bit immediate into a register.
700 void movq(Register dst, int64_t value);
701 void movq(Register dst, uint64_t value);
702
703 void movsxbl(Register dst, Register src);
704 void movsxbl(Register dst, const Operand& src);
705 void movsxbq(Register dst, const Operand& src);
706 void movsxwl(Register dst, Register src);
707 void movsxwl(Register dst, const Operand& src);
708 void movsxwq(Register dst, const Operand& src);
709 void movsxlq(Register dst, Register src);
710 void movsxlq(Register dst, const Operand& src);
711
712 // Repeated moves.
713
714 void repmovsb();
715 void repmovsw();
repmovsp()716 void repmovsp() { emit_repmovs(kPointerSize); }
repmovsl()717 void repmovsl() { emit_repmovs(kInt32Size); }
repmovsq()718 void repmovsq() { emit_repmovs(kInt64Size); }
719
720 // Instruction to load from an immediate 64-bit pointer into RAX.
721 void load_rax(void* ptr, RelocInfo::Mode rmode);
722 void load_rax(ExternalReference ext);
723
724 // Conditional moves.
725 void cmovq(Condition cc, Register dst, Register src);
726 void cmovq(Condition cc, Register dst, const Operand& src);
727 void cmovl(Condition cc, Register dst, Register src);
728 void cmovl(Condition cc, Register dst, const Operand& src);
729
cmpb(Register dst,Immediate src)730 void cmpb(Register dst, Immediate src) {
731 immediate_arithmetic_op_8(0x7, dst, src);
732 }
733
734 void cmpb_al(Immediate src);
735
cmpb(Register dst,Register src)736 void cmpb(Register dst, Register src) {
737 arithmetic_op_8(0x3A, dst, src);
738 }
739
cmpb(Register dst,const Operand & src)740 void cmpb(Register dst, const Operand& src) {
741 arithmetic_op_8(0x3A, dst, src);
742 }
743
cmpb(const Operand & dst,Register src)744 void cmpb(const Operand& dst, Register src) {
745 arithmetic_op_8(0x38, src, dst);
746 }
747
cmpb(const Operand & dst,Immediate src)748 void cmpb(const Operand& dst, Immediate src) {
749 immediate_arithmetic_op_8(0x7, dst, src);
750 }
751
cmpw(const Operand & dst,Immediate src)752 void cmpw(const Operand& dst, Immediate src) {
753 immediate_arithmetic_op_16(0x7, dst, src);
754 }
755
cmpw(Register dst,Immediate src)756 void cmpw(Register dst, Immediate src) {
757 immediate_arithmetic_op_16(0x7, dst, src);
758 }
759
cmpw(Register dst,const Operand & src)760 void cmpw(Register dst, const Operand& src) {
761 arithmetic_op_16(0x3B, dst, src);
762 }
763
cmpw(Register dst,Register src)764 void cmpw(Register dst, Register src) {
765 arithmetic_op_16(0x3B, dst, src);
766 }
767
cmpw(const Operand & dst,Register src)768 void cmpw(const Operand& dst, Register src) {
769 arithmetic_op_16(0x39, src, dst);
770 }
771
andb(Register dst,Immediate src)772 void andb(Register dst, Immediate src) {
773 immediate_arithmetic_op_8(0x4, dst, src);
774 }
775
776 void decb(Register dst);
777 void decb(const Operand& dst);
778
779 // Sign-extends rax into rdx:rax.
780 void cqo();
781 // Sign-extends eax into edx:eax.
782 void cdq();
783
784 // Multiply eax by src, put the result in edx:eax.
785 void mull(Register src);
786 void mull(const Operand& src);
787 // Multiply rax by src, put the result in rdx:rax.
788 void mulq(Register src);
789
790 #define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
791 void instruction##p(Register dst, Immediate imm8) { \
792 shift(dst, imm8, subcode, kPointerSize); \
793 } \
794 \
795 void instruction##l(Register dst, Immediate imm8) { \
796 shift(dst, imm8, subcode, kInt32Size); \
797 } \
798 \
799 void instruction##q(Register dst, Immediate imm8) { \
800 shift(dst, imm8, subcode, kInt64Size); \
801 } \
802 \
803 void instruction##p(Operand dst, Immediate imm8) { \
804 shift(dst, imm8, subcode, kPointerSize); \
805 } \
806 \
807 void instruction##l(Operand dst, Immediate imm8) { \
808 shift(dst, imm8, subcode, kInt32Size); \
809 } \
810 \
811 void instruction##q(Operand dst, Immediate imm8) { \
812 shift(dst, imm8, subcode, kInt64Size); \
813 } \
814 \
815 void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
816 \
817 void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \
818 \
819 void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \
820 \
821 void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); } \
822 \
823 void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \
824 \
825 void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
826 SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
827 #undef DECLARE_SHIFT_INSTRUCTION
828
829 // Shifts dst:src left by cl bits, affecting only dst.
830 void shld(Register dst, Register src);
831
832 // Shifts src:dst right by cl bits, affecting only dst.
833 void shrd(Register dst, Register src);
834
835 void store_rax(void* dst, RelocInfo::Mode mode);
836 void store_rax(ExternalReference ref);
837
subb(Register dst,Immediate src)838 void subb(Register dst, Immediate src) {
839 immediate_arithmetic_op_8(0x5, dst, src);
840 }
841
842 void testb(Register dst, Register src);
843 void testb(Register reg, Immediate mask);
844 void testb(const Operand& op, Immediate mask);
845 void testb(const Operand& op, Register reg);
846
847 // Bit operations.
848 void bt(const Operand& dst, Register src);
849 void bts(const Operand& dst, Register src);
850 void bsrq(Register dst, Register src);
851 void bsrq(Register dst, const Operand& src);
852 void bsrl(Register dst, Register src);
853 void bsrl(Register dst, const Operand& src);
854 void bsfq(Register dst, Register src);
855 void bsfq(Register dst, const Operand& src);
856 void bsfl(Register dst, Register src);
857 void bsfl(Register dst, const Operand& src);
858
859 // Miscellaneous
860 void clc();
861 void cld();
862 void cpuid();
863 void hlt();
864 void int3();
865 void nop();
866 void ret(int imm16);
867 void ud2();
868 void setcc(Condition cc, Register reg);
869
870 // Label operations & relative jumps (PPUM Appendix D)
871 //
872 // Takes a branch opcode (cc) and a label (L) and generates
873 // either a backward branch or a forward branch and links it
874 // to the label fixup chain. Usage:
875 //
876 // Label L; // unbound label
877 // j(cc, &L); // forward branch to unbound label
878 // bind(&L); // bind label to the current pc
879 // j(cc, &L); // backward branch to bound label
880 // bind(&L); // illegal: a label may be bound only once
881 //
882 // Note: The same Label can be used for forward and backward branches
883 // but it may be bound only once.
884
885 void bind(Label* L); // binds an unbound label L to the current code position
886
887 // Calls
888 // Call near relative 32-bit displacement, relative to next instruction.
889 void call(Label* L);
890 void call(Address entry, RelocInfo::Mode rmode);
891 void call(Handle<Code> target,
892 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
893 TypeFeedbackId ast_id = TypeFeedbackId::None());
894
895 // Calls directly to the given address using a relative offset.
896 // Should only ever be used in Code objects for calls within the
897 // same Code object. Should not be used when generating new code (use labels),
898 // but only when patching existing code.
899 void call(Address target);
900
901 // Call near absolute indirect, address in register
902 void call(Register adr);
903
904 // Jumps
905 // Jump short or near relative.
906 // Use a 32-bit signed displacement.
907 // Unconditional jump to L
908 void jmp(Label* L, Label::Distance distance = Label::kFar);
909 void jmp(Address entry, RelocInfo::Mode rmode);
910 void jmp(Handle<Code> target, RelocInfo::Mode rmode);
911
912 // Jump near absolute indirect (r64)
913 void jmp(Register adr);
914 void jmp(const Operand& src);
915
916 // Conditional jumps
917 void j(Condition cc,
918 Label* L,
919 Label::Distance distance = Label::kFar);
920 void j(Condition cc, Address entry, RelocInfo::Mode rmode);
921 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
922
923 // Floating-point operations
924 void fld(int i);
925
926 void fld1();
927 void fldz();
928 void fldpi();
929 void fldln2();
930
931 void fld_s(const Operand& adr);
932 void fld_d(const Operand& adr);
933
934 void fstp_s(const Operand& adr);
935 void fstp_d(const Operand& adr);
936 void fstp(int index);
937
938 void fild_s(const Operand& adr);
939 void fild_d(const Operand& adr);
940
941 void fist_s(const Operand& adr);
942
943 void fistp_s(const Operand& adr);
944 void fistp_d(const Operand& adr);
945
946 void fisttp_s(const Operand& adr);
947 void fisttp_d(const Operand& adr);
948
949 void fabs();
950 void fchs();
951
952 void fadd(int i);
953 void fsub(int i);
954 void fmul(int i);
955 void fdiv(int i);
956
957 void fisub_s(const Operand& adr);
958
959 void faddp(int i = 1);
960 void fsubp(int i = 1);
961 void fsubrp(int i = 1);
962 void fmulp(int i = 1);
963 void fdivp(int i = 1);
964 void fprem();
965 void fprem1();
966
967 void fxch(int i = 1);
968 void fincstp();
969 void ffree(int i = 0);
970
971 void ftst();
972 void fucomp(int i);
973 void fucompp();
974 void fucomi(int i);
975 void fucomip();
976
977 void fcompp();
978 void fnstsw_ax();
979 void fwait();
980 void fnclex();
981
982 void fsin();
983 void fcos();
984 void fptan();
985 void fyl2x();
986 void f2xm1();
987 void fscale();
988 void fninit();
989
990 void frndint();
991
992 void sahf();
993
994 // SSE instructions
995 void addss(XMMRegister dst, XMMRegister src);
996 void addss(XMMRegister dst, const Operand& src);
997 void subss(XMMRegister dst, XMMRegister src);
998 void subss(XMMRegister dst, const Operand& src);
999 void mulss(XMMRegister dst, XMMRegister src);
1000 void mulss(XMMRegister dst, const Operand& src);
1001 void divss(XMMRegister dst, XMMRegister src);
1002 void divss(XMMRegister dst, const Operand& src);
1003
1004 void maxss(XMMRegister dst, XMMRegister src);
1005 void maxss(XMMRegister dst, const Operand& src);
1006 void minss(XMMRegister dst, XMMRegister src);
1007 void minss(XMMRegister dst, const Operand& src);
1008
1009 void sqrtss(XMMRegister dst, XMMRegister src);
1010 void sqrtss(XMMRegister dst, const Operand& src);
1011
1012 void ucomiss(XMMRegister dst, XMMRegister src);
1013 void ucomiss(XMMRegister dst, const Operand& src);
1014 void movaps(XMMRegister dst, XMMRegister src);
1015
1016 // Don't use this unless it's important to keep the
1017 // top half of the destination register unchanged.
1018 // Use movaps when moving float values and movd for integer
1019 // values in xmm registers.
1020 void movss(XMMRegister dst, XMMRegister src);
1021
1022 void movss(XMMRegister dst, const Operand& src);
1023 void movss(const Operand& dst, XMMRegister src);
1024 void shufps(XMMRegister dst, XMMRegister src, byte imm8);
1025
1026 void cvttss2si(Register dst, const Operand& src);
1027 void cvttss2si(Register dst, XMMRegister src);
1028 void cvtlsi2ss(XMMRegister dst, Register src);
1029
1030 void andps(XMMRegister dst, XMMRegister src);
1031 void andps(XMMRegister dst, const Operand& src);
1032 void orps(XMMRegister dst, XMMRegister src);
1033 void orps(XMMRegister dst, const Operand& src);
1034 void xorps(XMMRegister dst, XMMRegister src);
1035 void xorps(XMMRegister dst, const Operand& src);
1036
1037 void addps(XMMRegister dst, XMMRegister src);
1038 void addps(XMMRegister dst, const Operand& src);
1039 void subps(XMMRegister dst, XMMRegister src);
1040 void subps(XMMRegister dst, const Operand& src);
1041 void mulps(XMMRegister dst, XMMRegister src);
1042 void mulps(XMMRegister dst, const Operand& src);
1043 void divps(XMMRegister dst, XMMRegister src);
1044 void divps(XMMRegister dst, const Operand& src);
1045
1046 void movmskps(Register dst, XMMRegister src);
1047
1048 // SSE2 instructions
1049 void movd(XMMRegister dst, Register src);
1050 void movd(XMMRegister dst, const Operand& src);
1051 void movd(Register dst, XMMRegister src);
1052 void movq(XMMRegister dst, Register src);
1053 void movq(Register dst, XMMRegister src);
1054 void movq(XMMRegister dst, XMMRegister src);
1055
1056 // Don't use this unless it's important to keep the
1057 // top half of the destination register unchanged.
1058 // Use movapd when moving double values and movq for integer
1059 // values in xmm registers.
1060 void movsd(XMMRegister dst, XMMRegister src);
1061
1062 void movsd(const Operand& dst, XMMRegister src);
1063 void movsd(XMMRegister dst, const Operand& src);
1064
1065 void movdqa(const Operand& dst, XMMRegister src);
1066 void movdqa(XMMRegister dst, const Operand& src);
1067
1068 void movdqu(const Operand& dst, XMMRegister src);
1069 void movdqu(XMMRegister dst, const Operand& src);
1070
1071 void movapd(XMMRegister dst, XMMRegister src);
1072
1073 void psllq(XMMRegister reg, byte imm8);
1074 void psrlq(XMMRegister reg, byte imm8);
1075 void pslld(XMMRegister reg, byte imm8);
1076 void psrld(XMMRegister reg, byte imm8);
1077
1078 void cvttsd2si(Register dst, const Operand& src);
1079 void cvttsd2si(Register dst, XMMRegister src);
1080 void cvttss2siq(Register dst, XMMRegister src);
1081 void cvttss2siq(Register dst, const Operand& src);
1082 void cvttsd2siq(Register dst, XMMRegister src);
1083 void cvttsd2siq(Register dst, const Operand& src);
1084
1085 void cvtlsi2sd(XMMRegister dst, const Operand& src);
1086 void cvtlsi2sd(XMMRegister dst, Register src);
1087
1088 void cvtqsi2ss(XMMRegister dst, const Operand& src);
1089 void cvtqsi2ss(XMMRegister dst, Register src);
1090
1091 void cvtqsi2sd(XMMRegister dst, const Operand& src);
1092 void cvtqsi2sd(XMMRegister dst, Register src);
1093
1094
1095 void cvtss2sd(XMMRegister dst, XMMRegister src);
1096 void cvtss2sd(XMMRegister dst, const Operand& src);
1097 void cvtsd2ss(XMMRegister dst, XMMRegister src);
1098 void cvtsd2ss(XMMRegister dst, const Operand& src);
1099
1100 void cvtsd2si(Register dst, XMMRegister src);
1101 void cvtsd2siq(Register dst, XMMRegister src);
1102
1103 void addsd(XMMRegister dst, XMMRegister src);
1104 void addsd(XMMRegister dst, const Operand& src);
1105 void subsd(XMMRegister dst, XMMRegister src);
1106 void subsd(XMMRegister dst, const Operand& src);
1107 void mulsd(XMMRegister dst, XMMRegister src);
1108 void mulsd(XMMRegister dst, const Operand& src);
1109 void divsd(XMMRegister dst, XMMRegister src);
1110 void divsd(XMMRegister dst, const Operand& src);
1111
1112 void maxsd(XMMRegister dst, XMMRegister src);
1113 void maxsd(XMMRegister dst, const Operand& src);
1114 void minsd(XMMRegister dst, XMMRegister src);
1115 void minsd(XMMRegister dst, const Operand& src);
1116
1117 void andpd(XMMRegister dst, XMMRegister src);
1118 void orpd(XMMRegister dst, XMMRegister src);
1119 void xorpd(XMMRegister dst, XMMRegister src);
1120 void sqrtsd(XMMRegister dst, XMMRegister src);
1121 void sqrtsd(XMMRegister dst, const Operand& src);
1122
1123 void ucomisd(XMMRegister dst, XMMRegister src);
1124 void ucomisd(XMMRegister dst, const Operand& src);
1125 void cmpltsd(XMMRegister dst, XMMRegister src);
1126 void pcmpeqd(XMMRegister dst, XMMRegister src);
1127
1128 void movmskpd(Register dst, XMMRegister src);
1129
1130 void punpckldq(XMMRegister dst, XMMRegister src);
1131 void punpckhdq(XMMRegister dst, XMMRegister src);
1132
1133 // SSE 4.1 instruction
1134 void extractps(Register dst, XMMRegister src, byte imm8);
1135
1136 void pextrd(Register dst, XMMRegister src, int8_t imm8);
1137
1138 void pinsrd(XMMRegister dst, Register src, int8_t imm8);
1139 void pinsrd(XMMRegister dst, const Operand& src, int8_t imm8);
1140
1141 void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode);
1142 void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
1143
1144 // AVX instruction
vfmadd132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1145 void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1146 vfmasd(0x99, dst, src1, src2);
1147 }
vfmadd213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1148 void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1149 vfmasd(0xa9, dst, src1, src2);
1150 }
vfmadd231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1151 void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1152 vfmasd(0xb9, dst, src1, src2);
1153 }
vfmadd132sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1154 void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1155 vfmasd(0x99, dst, src1, src2);
1156 }
vfmadd213sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1157 void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1158 vfmasd(0xa9, dst, src1, src2);
1159 }
vfmadd231sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1160 void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1161 vfmasd(0xb9, dst, src1, src2);
1162 }
vfmsub132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1163 void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1164 vfmasd(0x9b, dst, src1, src2);
1165 }
vfmsub213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1166 void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1167 vfmasd(0xab, dst, src1, src2);
1168 }
vfmsub231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1169 void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1170 vfmasd(0xbb, dst, src1, src2);
1171 }
vfmsub132sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1172 void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1173 vfmasd(0x9b, dst, src1, src2);
1174 }
vfmsub213sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1175 void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1176 vfmasd(0xab, dst, src1, src2);
1177 }
vfmsub231sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1178 void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1179 vfmasd(0xbb, dst, src1, src2);
1180 }
vfnmadd132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1181 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1182 vfmasd(0x9d, dst, src1, src2);
1183 }
vfnmadd213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1184 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1185 vfmasd(0xad, dst, src1, src2);
1186 }
vfnmadd231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1187 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1188 vfmasd(0xbd, dst, src1, src2);
1189 }
vfnmadd132sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1190 void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1191 vfmasd(0x9d, dst, src1, src2);
1192 }
vfnmadd213sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1193 void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1194 vfmasd(0xad, dst, src1, src2);
1195 }
vfnmadd231sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1196 void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1197 vfmasd(0xbd, dst, src1, src2);
1198 }
vfnmsub132sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1199 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1200 vfmasd(0x9f, dst, src1, src2);
1201 }
vfnmsub213sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1202 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1203 vfmasd(0xaf, dst, src1, src2);
1204 }
vfnmsub231sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1205 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1206 vfmasd(0xbf, dst, src1, src2);
1207 }
vfnmsub132sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1208 void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1209 vfmasd(0x9f, dst, src1, src2);
1210 }
vfnmsub213sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1211 void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1212 vfmasd(0xaf, dst, src1, src2);
1213 }
vfnmsub231sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1214 void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1215 vfmasd(0xbf, dst, src1, src2);
1216 }
1217 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1218 void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1219
vfmadd132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1220 void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1221 vfmass(0x99, dst, src1, src2);
1222 }
vfmadd213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1223 void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1224 vfmass(0xa9, dst, src1, src2);
1225 }
vfmadd231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1226 void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1227 vfmass(0xb9, dst, src1, src2);
1228 }
vfmadd132ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1229 void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1230 vfmass(0x99, dst, src1, src2);
1231 }
vfmadd213ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1232 void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1233 vfmass(0xa9, dst, src1, src2);
1234 }
vfmadd231ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1235 void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1236 vfmass(0xb9, dst, src1, src2);
1237 }
vfmsub132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1238 void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1239 vfmass(0x9b, dst, src1, src2);
1240 }
vfmsub213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1241 void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1242 vfmass(0xab, dst, src1, src2);
1243 }
vfmsub231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1244 void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1245 vfmass(0xbb, dst, src1, src2);
1246 }
vfmsub132ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1247 void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1248 vfmass(0x9b, dst, src1, src2);
1249 }
vfmsub213ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1250 void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1251 vfmass(0xab, dst, src1, src2);
1252 }
vfmsub231ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1253 void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1254 vfmass(0xbb, dst, src1, src2);
1255 }
vfnmadd132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1256 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1257 vfmass(0x9d, dst, src1, src2);
1258 }
vfnmadd213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1259 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1260 vfmass(0xad, dst, src1, src2);
1261 }
vfnmadd231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1262 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1263 vfmass(0xbd, dst, src1, src2);
1264 }
vfnmadd132ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1265 void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1266 vfmass(0x9d, dst, src1, src2);
1267 }
vfnmadd213ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1268 void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1269 vfmass(0xad, dst, src1, src2);
1270 }
vfnmadd231ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1271 void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1272 vfmass(0xbd, dst, src1, src2);
1273 }
vfnmsub132ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1274 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1275 vfmass(0x9f, dst, src1, src2);
1276 }
vfnmsub213ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1277 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1278 vfmass(0xaf, dst, src1, src2);
1279 }
vfnmsub231ss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1280 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1281 vfmass(0xbf, dst, src1, src2);
1282 }
vfnmsub132ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1283 void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1284 vfmass(0x9f, dst, src1, src2);
1285 }
vfnmsub213ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1286 void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1287 vfmass(0xaf, dst, src1, src2);
1288 }
vfnmsub231ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1289 void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1290 vfmass(0xbf, dst, src1, src2);
1291 }
1292 void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1293 void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1294
1295 void vmovd(XMMRegister dst, Register src);
1296 void vmovd(XMMRegister dst, const Operand& src);
1297 void vmovd(Register dst, XMMRegister src);
1298 void vmovq(XMMRegister dst, Register src);
1299 void vmovq(XMMRegister dst, const Operand& src);
1300 void vmovq(Register dst, XMMRegister src);
1301
vmovsd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1302 void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1303 vsd(0x10, dst, src1, src2);
1304 }
vmovsd(XMMRegister dst,const Operand & src)1305 void vmovsd(XMMRegister dst, const Operand& src) {
1306 vsd(0x10, dst, xmm0, src);
1307 }
vmovsd(const Operand & dst,XMMRegister src)1308 void vmovsd(const Operand& dst, XMMRegister src) {
1309 vsd(0x11, src, xmm0, dst);
1310 }
1311
1312 #define AVX_SP_3(instr, opcode) \
1313 AVX_S_3(instr, opcode) \
1314 AVX_P_3(instr, opcode)
1315
1316 #define AVX_S_3(instr, opcode) \
1317 AVX_3(instr##ss, opcode, vss) \
1318 AVX_3(instr##sd, opcode, vsd)
1319
1320 #define AVX_P_3(instr, opcode) \
1321 AVX_3(instr##ps, opcode, vps) \
1322 AVX_3(instr##pd, opcode, vpd)
1323
1324 #define AVX_3(instr, opcode, impl) \
1325 void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1326 impl(opcode, dst, src1, src2); \
1327 } \
1328 void instr(XMMRegister dst, XMMRegister src1, const Operand& src2) { \
1329 impl(opcode, dst, src1, src2); \
1330 }
1331
1332 AVX_SP_3(vsqrt, 0x51);
1333 AVX_SP_3(vadd, 0x58);
1334 AVX_SP_3(vsub, 0x5c);
1335 AVX_SP_3(vmul, 0x59);
1336 AVX_SP_3(vdiv, 0x5e);
1337 AVX_SP_3(vmin, 0x5d);
1338 AVX_SP_3(vmax, 0x5f);
1339 AVX_P_3(vand, 0x54);
1340 AVX_P_3(vor, 0x56);
1341 AVX_P_3(vxor, 0x57);
1342 AVX_3(vpcmpeqd, 0x76, vpd);
1343 AVX_3(vcvtsd2ss, 0x5a, vsd);
1344
1345 #undef AVX_3
1346 #undef AVX_S_3
1347 #undef AVX_P_3
1348 #undef AVX_SP_3
1349
vpsrlq(XMMRegister dst,XMMRegister src,byte imm8)1350 void vpsrlq(XMMRegister dst, XMMRegister src, byte imm8) {
1351 XMMRegister iop = {2};
1352 vpd(0x73, iop, dst, src);
1353 emit(imm8);
1354 }
vpsllq(XMMRegister dst,XMMRegister src,byte imm8)1355 void vpsllq(XMMRegister dst, XMMRegister src, byte imm8) {
1356 XMMRegister iop = {6};
1357 vpd(0x73, iop, dst, src);
1358 emit(imm8);
1359 }
vcvtss2sd(XMMRegister dst,XMMRegister src1,XMMRegister src2)1360 void vcvtss2sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1361 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1362 }
vcvtss2sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1363 void vcvtss2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1364 vsd(0x5a, dst, src1, src2, kF3, k0F, kWIG);
1365 }
vcvtlsi2sd(XMMRegister dst,XMMRegister src1,Register src2)1366 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1367 XMMRegister isrc2 = {src2.code()};
1368 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1369 }
vcvtlsi2sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1370 void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1371 vsd(0x2a, dst, src1, src2, kF2, k0F, kW0);
1372 }
vcvtqsi2ss(XMMRegister dst,XMMRegister src1,Register src2)1373 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2) {
1374 XMMRegister isrc2 = {src2.code()};
1375 vsd(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1376 }
vcvtqsi2ss(XMMRegister dst,XMMRegister src1,const Operand & src2)1377 void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1378 vsd(0x2a, dst, src1, src2, kF3, k0F, kW1);
1379 }
vcvtqsi2sd(XMMRegister dst,XMMRegister src1,Register src2)1380 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2) {
1381 XMMRegister isrc2 = {src2.code()};
1382 vsd(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1383 }
vcvtqsi2sd(XMMRegister dst,XMMRegister src1,const Operand & src2)1384 void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
1385 vsd(0x2a, dst, src1, src2, kF2, k0F, kW1);
1386 }
vcvttsd2si(Register dst,XMMRegister src)1387 void vcvttsd2si(Register dst, XMMRegister src) {
1388 XMMRegister idst = {dst.code()};
1389 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1390 }
vcvttsd2si(Register dst,const Operand & src)1391 void vcvttsd2si(Register dst, const Operand& src) {
1392 XMMRegister idst = {dst.code()};
1393 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1394 }
vcvttss2siq(Register dst,XMMRegister src)1395 void vcvttss2siq(Register dst, XMMRegister src) {
1396 XMMRegister idst = {dst.code()};
1397 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1398 }
vcvttss2siq(Register dst,const Operand & src)1399 void vcvttss2siq(Register dst, const Operand& src) {
1400 XMMRegister idst = {dst.code()};
1401 vsd(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1402 }
vcvttsd2siq(Register dst,XMMRegister src)1403 void vcvttsd2siq(Register dst, XMMRegister src) {
1404 XMMRegister idst = {dst.code()};
1405 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1406 }
vcvttsd2siq(Register dst,const Operand & src)1407 void vcvttsd2siq(Register dst, const Operand& src) {
1408 XMMRegister idst = {dst.code()};
1409 vsd(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1410 }
vcvtsd2si(Register dst,XMMRegister src)1411 void vcvtsd2si(Register dst, XMMRegister src) {
1412 XMMRegister idst = {dst.code()};
1413 vsd(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1414 }
vucomisd(XMMRegister dst,XMMRegister src)1415 void vucomisd(XMMRegister dst, XMMRegister src) {
1416 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1417 }
vucomisd(XMMRegister dst,const Operand & src)1418 void vucomisd(XMMRegister dst, const Operand& src) {
1419 vsd(0x2e, dst, xmm0, src, k66, k0F, kWIG);
1420 }
vroundss(XMMRegister dst,XMMRegister src1,XMMRegister src2,RoundingMode mode)1421 void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1422 RoundingMode mode) {
1423 vsd(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1424 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1425 }
vroundsd(XMMRegister dst,XMMRegister src1,XMMRegister src2,RoundingMode mode)1426 void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
1427 RoundingMode mode) {
1428 vsd(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1429 emit(static_cast<byte>(mode) | 0x8); // Mask precision exception.
1430 }
1431
vsd(byte op,XMMRegister dst,XMMRegister src1,XMMRegister src2)1432 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1433 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1434 }
vsd(byte op,XMMRegister dst,XMMRegister src1,const Operand & src2)1435 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2) {
1436 vsd(op, dst, src1, src2, kF2, k0F, kWIG);
1437 }
1438 void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1439 SIMDPrefix pp, LeadingOpcode m, VexW w);
1440 void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2,
1441 SIMDPrefix pp, LeadingOpcode m, VexW w);
1442
vmovss(XMMRegister dst,XMMRegister src1,XMMRegister src2)1443 void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
1444 vss(0x10, dst, src1, src2);
1445 }
vmovss(XMMRegister dst,const Operand & src)1446 void vmovss(XMMRegister dst, const Operand& src) {
1447 vss(0x10, dst, xmm0, src);
1448 }
vmovss(const Operand & dst,XMMRegister src)1449 void vmovss(const Operand& dst, XMMRegister src) {
1450 vss(0x11, src, xmm0, dst);
1451 }
1452 void vucomiss(XMMRegister dst, XMMRegister src);
1453 void vucomiss(XMMRegister dst, const Operand& src);
1454 void vss(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1455 void vss(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1456
vmovaps(XMMRegister dst,XMMRegister src)1457 void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
vmovapd(XMMRegister dst,XMMRegister src)1458 void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
vmovmskpd(Register dst,XMMRegister src)1459 void vmovmskpd(Register dst, XMMRegister src) {
1460 XMMRegister idst = {dst.code()};
1461 vpd(0x50, idst, xmm0, src);
1462 }
1463
1464 void vps(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1465 void vps(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1466 void vpd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
1467 void vpd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
1468
1469 // BMI instruction
andnq(Register dst,Register src1,Register src2)1470 void andnq(Register dst, Register src1, Register src2) {
1471 bmi1q(0xf2, dst, src1, src2);
1472 }
andnq(Register dst,Register src1,const Operand & src2)1473 void andnq(Register dst, Register src1, const Operand& src2) {
1474 bmi1q(0xf2, dst, src1, src2);
1475 }
andnl(Register dst,Register src1,Register src2)1476 void andnl(Register dst, Register src1, Register src2) {
1477 bmi1l(0xf2, dst, src1, src2);
1478 }
andnl(Register dst,Register src1,const Operand & src2)1479 void andnl(Register dst, Register src1, const Operand& src2) {
1480 bmi1l(0xf2, dst, src1, src2);
1481 }
bextrq(Register dst,Register src1,Register src2)1482 void bextrq(Register dst, Register src1, Register src2) {
1483 bmi1q(0xf7, dst, src2, src1);
1484 }
bextrq(Register dst,const Operand & src1,Register src2)1485 void bextrq(Register dst, const Operand& src1, Register src2) {
1486 bmi1q(0xf7, dst, src2, src1);
1487 }
bextrl(Register dst,Register src1,Register src2)1488 void bextrl(Register dst, Register src1, Register src2) {
1489 bmi1l(0xf7, dst, src2, src1);
1490 }
bextrl(Register dst,const Operand & src1,Register src2)1491 void bextrl(Register dst, const Operand& src1, Register src2) {
1492 bmi1l(0xf7, dst, src2, src1);
1493 }
blsiq(Register dst,Register src)1494 void blsiq(Register dst, Register src) {
1495 Register ireg = {3};
1496 bmi1q(0xf3, ireg, dst, src);
1497 }
blsiq(Register dst,const Operand & src)1498 void blsiq(Register dst, const Operand& src) {
1499 Register ireg = {3};
1500 bmi1q(0xf3, ireg, dst, src);
1501 }
blsil(Register dst,Register src)1502 void blsil(Register dst, Register src) {
1503 Register ireg = {3};
1504 bmi1l(0xf3, ireg, dst, src);
1505 }
blsil(Register dst,const Operand & src)1506 void blsil(Register dst, const Operand& src) {
1507 Register ireg = {3};
1508 bmi1l(0xf3, ireg, dst, src);
1509 }
blsmskq(Register dst,Register src)1510 void blsmskq(Register dst, Register src) {
1511 Register ireg = {2};
1512 bmi1q(0xf3, ireg, dst, src);
1513 }
blsmskq(Register dst,const Operand & src)1514 void blsmskq(Register dst, const Operand& src) {
1515 Register ireg = {2};
1516 bmi1q(0xf3, ireg, dst, src);
1517 }
blsmskl(Register dst,Register src)1518 void blsmskl(Register dst, Register src) {
1519 Register ireg = {2};
1520 bmi1l(0xf3, ireg, dst, src);
1521 }
blsmskl(Register dst,const Operand & src)1522 void blsmskl(Register dst, const Operand& src) {
1523 Register ireg = {2};
1524 bmi1l(0xf3, ireg, dst, src);
1525 }
blsrq(Register dst,Register src)1526 void blsrq(Register dst, Register src) {
1527 Register ireg = {1};
1528 bmi1q(0xf3, ireg, dst, src);
1529 }
blsrq(Register dst,const Operand & src)1530 void blsrq(Register dst, const Operand& src) {
1531 Register ireg = {1};
1532 bmi1q(0xf3, ireg, dst, src);
1533 }
blsrl(Register dst,Register src)1534 void blsrl(Register dst, Register src) {
1535 Register ireg = {1};
1536 bmi1l(0xf3, ireg, dst, src);
1537 }
blsrl(Register dst,const Operand & src)1538 void blsrl(Register dst, const Operand& src) {
1539 Register ireg = {1};
1540 bmi1l(0xf3, ireg, dst, src);
1541 }
1542 void tzcntq(Register dst, Register src);
1543 void tzcntq(Register dst, const Operand& src);
1544 void tzcntl(Register dst, Register src);
1545 void tzcntl(Register dst, const Operand& src);
1546
1547 void lzcntq(Register dst, Register src);
1548 void lzcntq(Register dst, const Operand& src);
1549 void lzcntl(Register dst, Register src);
1550 void lzcntl(Register dst, const Operand& src);
1551
1552 void popcntq(Register dst, Register src);
1553 void popcntq(Register dst, const Operand& src);
1554 void popcntl(Register dst, Register src);
1555 void popcntl(Register dst, const Operand& src);
1556
bzhiq(Register dst,Register src1,Register src2)1557 void bzhiq(Register dst, Register src1, Register src2) {
1558 bmi2q(kNone, 0xf5, dst, src2, src1);
1559 }
bzhiq(Register dst,const Operand & src1,Register src2)1560 void bzhiq(Register dst, const Operand& src1, Register src2) {
1561 bmi2q(kNone, 0xf5, dst, src2, src1);
1562 }
bzhil(Register dst,Register src1,Register src2)1563 void bzhil(Register dst, Register src1, Register src2) {
1564 bmi2l(kNone, 0xf5, dst, src2, src1);
1565 }
bzhil(Register dst,const Operand & src1,Register src2)1566 void bzhil(Register dst, const Operand& src1, Register src2) {
1567 bmi2l(kNone, 0xf5, dst, src2, src1);
1568 }
mulxq(Register dst1,Register dst2,Register src)1569 void mulxq(Register dst1, Register dst2, Register src) {
1570 bmi2q(kF2, 0xf6, dst1, dst2, src);
1571 }
mulxq(Register dst1,Register dst2,const Operand & src)1572 void mulxq(Register dst1, Register dst2, const Operand& src) {
1573 bmi2q(kF2, 0xf6, dst1, dst2, src);
1574 }
mulxl(Register dst1,Register dst2,Register src)1575 void mulxl(Register dst1, Register dst2, Register src) {
1576 bmi2l(kF2, 0xf6, dst1, dst2, src);
1577 }
mulxl(Register dst1,Register dst2,const Operand & src)1578 void mulxl(Register dst1, Register dst2, const Operand& src) {
1579 bmi2l(kF2, 0xf6, dst1, dst2, src);
1580 }
pdepq(Register dst,Register src1,Register src2)1581 void pdepq(Register dst, Register src1, Register src2) {
1582 bmi2q(kF2, 0xf5, dst, src1, src2);
1583 }
pdepq(Register dst,Register src1,const Operand & src2)1584 void pdepq(Register dst, Register src1, const Operand& src2) {
1585 bmi2q(kF2, 0xf5, dst, src1, src2);
1586 }
pdepl(Register dst,Register src1,Register src2)1587 void pdepl(Register dst, Register src1, Register src2) {
1588 bmi2l(kF2, 0xf5, dst, src1, src2);
1589 }
pdepl(Register dst,Register src1,const Operand & src2)1590 void pdepl(Register dst, Register src1, const Operand& src2) {
1591 bmi2l(kF2, 0xf5, dst, src1, src2);
1592 }
pextq(Register dst,Register src1,Register src2)1593 void pextq(Register dst, Register src1, Register src2) {
1594 bmi2q(kF3, 0xf5, dst, src1, src2);
1595 }
pextq(Register dst,Register src1,const Operand & src2)1596 void pextq(Register dst, Register src1, const Operand& src2) {
1597 bmi2q(kF3, 0xf5, dst, src1, src2);
1598 }
pextl(Register dst,Register src1,Register src2)1599 void pextl(Register dst, Register src1, Register src2) {
1600 bmi2l(kF3, 0xf5, dst, src1, src2);
1601 }
pextl(Register dst,Register src1,const Operand & src2)1602 void pextl(Register dst, Register src1, const Operand& src2) {
1603 bmi2l(kF3, 0xf5, dst, src1, src2);
1604 }
sarxq(Register dst,Register src1,Register src2)1605 void sarxq(Register dst, Register src1, Register src2) {
1606 bmi2q(kF3, 0xf7, dst, src2, src1);
1607 }
sarxq(Register dst,const Operand & src1,Register src2)1608 void sarxq(Register dst, const Operand& src1, Register src2) {
1609 bmi2q(kF3, 0xf7, dst, src2, src1);
1610 }
sarxl(Register dst,Register src1,Register src2)1611 void sarxl(Register dst, Register src1, Register src2) {
1612 bmi2l(kF3, 0xf7, dst, src2, src1);
1613 }
sarxl(Register dst,const Operand & src1,Register src2)1614 void sarxl(Register dst, const Operand& src1, Register src2) {
1615 bmi2l(kF3, 0xf7, dst, src2, src1);
1616 }
shlxq(Register dst,Register src1,Register src2)1617 void shlxq(Register dst, Register src1, Register src2) {
1618 bmi2q(k66, 0xf7, dst, src2, src1);
1619 }
shlxq(Register dst,const Operand & src1,Register src2)1620 void shlxq(Register dst, const Operand& src1, Register src2) {
1621 bmi2q(k66, 0xf7, dst, src2, src1);
1622 }
shlxl(Register dst,Register src1,Register src2)1623 void shlxl(Register dst, Register src1, Register src2) {
1624 bmi2l(k66, 0xf7, dst, src2, src1);
1625 }
shlxl(Register dst,const Operand & src1,Register src2)1626 void shlxl(Register dst, const Operand& src1, Register src2) {
1627 bmi2l(k66, 0xf7, dst, src2, src1);
1628 }
shrxq(Register dst,Register src1,Register src2)1629 void shrxq(Register dst, Register src1, Register src2) {
1630 bmi2q(kF2, 0xf7, dst, src2, src1);
1631 }
shrxq(Register dst,const Operand & src1,Register src2)1632 void shrxq(Register dst, const Operand& src1, Register src2) {
1633 bmi2q(kF2, 0xf7, dst, src2, src1);
1634 }
shrxl(Register dst,Register src1,Register src2)1635 void shrxl(Register dst, Register src1, Register src2) {
1636 bmi2l(kF2, 0xf7, dst, src2, src1);
1637 }
shrxl(Register dst,const Operand & src1,Register src2)1638 void shrxl(Register dst, const Operand& src1, Register src2) {
1639 bmi2l(kF2, 0xf7, dst, src2, src1);
1640 }
1641 void rorxq(Register dst, Register src, byte imm8);
1642 void rorxq(Register dst, const Operand& src, byte imm8);
1643 void rorxl(Register dst, Register src, byte imm8);
1644 void rorxl(Register dst, const Operand& src, byte imm8);
1645
1646 // Check the code size generated from label to here.
SizeOfCodeGeneratedSince(Label * label)1647 int SizeOfCodeGeneratedSince(Label* label) {
1648 return pc_offset() - label->pos();
1649 }
1650
1651 // Mark generator continuation.
1652 void RecordGeneratorContinuation();
1653
1654 // Mark address of a debug break slot.
1655 void RecordDebugBreakSlot(RelocInfo::Mode mode);
1656
1657 // Record a comment relocation entry that can be used by a disassembler.
1658 // Use --code-comments to enable.
1659 void RecordComment(const char* msg);
1660
1661 // Record a deoptimization reason that can be used by a log or cpu profiler.
1662 // Use --trace-deopt to enable.
1663 void RecordDeoptReason(const int reason, const SourcePosition position);
1664
PatchConstantPoolAccessInstruction(int pc_offset,int offset,ConstantPoolEntry::Access access,ConstantPoolEntry::Type type)1665 void PatchConstantPoolAccessInstruction(int pc_offset, int offset,
1666 ConstantPoolEntry::Access access,
1667 ConstantPoolEntry::Type type) {
1668 // No embedded constant pool support.
1669 UNREACHABLE();
1670 }
1671
1672 // Writes a single word of data in the code stream.
1673 // Used for inline tables, e.g., jump-tables.
1674 void db(uint8_t data);
1675 void dd(uint32_t data);
1676 void dq(uint64_t data);
dp(uintptr_t data)1677 void dp(uintptr_t data) { dq(data); }
1678 void dq(Label* label);
1679
positions_recorder()1680 PositionsRecorder* positions_recorder() { return &positions_recorder_; }
1681
1682 // Check if there is less than kGap bytes available in the buffer.
1683 // If this is the case, we need to grow the buffer before emitting
1684 // an instruction or relocation information.
buffer_overflow()1685 inline bool buffer_overflow() const {
1686 return pc_ >= reloc_info_writer.pos() - kGap;
1687 }
1688
1689 // Get the number of bytes available in the buffer.
available_space()1690 inline int available_space() const {
1691 return static_cast<int>(reloc_info_writer.pos() - pc_);
1692 }
1693
1694 static bool IsNop(Address addr);
1695
1696 // Avoid overflows for displacements etc.
1697 static const int kMaximalBufferSize = 512*MB;
1698
byte_at(int pos)1699 byte byte_at(int pos) { return buffer_[pos]; }
set_byte_at(int pos,byte value)1700 void set_byte_at(int pos, byte value) { buffer_[pos] = value; }
1701
1702 protected:
1703 // Call near indirect
1704 void call(const Operand& operand);
1705
1706 private:
addr_at(int pos)1707 byte* addr_at(int pos) { return buffer_ + pos; }
long_at(int pos)1708 uint32_t long_at(int pos) {
1709 return *reinterpret_cast<uint32_t*>(addr_at(pos));
1710 }
long_at_put(int pos,uint32_t x)1711 void long_at_put(int pos, uint32_t x) {
1712 *reinterpret_cast<uint32_t*>(addr_at(pos)) = x;
1713 }
1714
1715 // code emission
1716 void GrowBuffer();
1717
emit(byte x)1718 void emit(byte x) { *pc_++ = x; }
1719 inline void emitl(uint32_t x);
1720 inline void emitp(void* x, RelocInfo::Mode rmode);
1721 inline void emitq(uint64_t x);
1722 inline void emitw(uint16_t x);
1723 inline void emit_code_target(Handle<Code> target,
1724 RelocInfo::Mode rmode,
1725 TypeFeedbackId ast_id = TypeFeedbackId::None());
1726 inline void emit_runtime_entry(Address entry, RelocInfo::Mode rmode);
emit(Immediate x)1727 void emit(Immediate x) { emitl(x.value_); }
1728
1729 // Emits a REX prefix that encodes a 64-bit operand size and
1730 // the top bit of both register codes.
1731 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1732 // REX.W is set.
1733 inline void emit_rex_64(XMMRegister reg, Register rm_reg);
1734 inline void emit_rex_64(Register reg, XMMRegister rm_reg);
1735 inline void emit_rex_64(Register reg, Register rm_reg);
1736
1737 // Emits a REX prefix that encodes a 64-bit operand size and
1738 // the top bit of the destination, index, and base register codes.
1739 // The high bit of reg is used for REX.R, the high bit of op's base
1740 // register is used for REX.B, and the high bit of op's index register
1741 // is used for REX.X. REX.W is set.
1742 inline void emit_rex_64(Register reg, const Operand& op);
1743 inline void emit_rex_64(XMMRegister reg, const Operand& op);
1744
1745 // Emits a REX prefix that encodes a 64-bit operand size and
1746 // the top bit of the register code.
1747 // The high bit of register is used for REX.B.
1748 // REX.W is set and REX.R and REX.X are clear.
1749 inline void emit_rex_64(Register rm_reg);
1750
1751 // Emits a REX prefix that encodes a 64-bit operand size and
1752 // the top bit of the index and base register codes.
1753 // The high bit of op's base register is used for REX.B, and the high
1754 // bit of op's index register is used for REX.X.
1755 // REX.W is set and REX.R clear.
1756 inline void emit_rex_64(const Operand& op);
1757
1758 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
emit_rex_64()1759 void emit_rex_64() { emit(0x48); }
1760
1761 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1762 // REX.W is clear.
1763 inline void emit_rex_32(Register reg, Register rm_reg);
1764
1765 // The high bit of reg is used for REX.R, the high bit of op's base
1766 // register is used for REX.B, and the high bit of op's index register
1767 // is used for REX.X. REX.W is cleared.
1768 inline void emit_rex_32(Register reg, const Operand& op);
1769
1770 // High bit of rm_reg goes to REX.B.
1771 // REX.W, REX.R and REX.X are clear.
1772 inline void emit_rex_32(Register rm_reg);
1773
1774 // High bit of base goes to REX.B and high bit of index to REX.X.
1775 // REX.W and REX.R are clear.
1776 inline void emit_rex_32(const Operand& op);
1777
1778 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
1779 // REX.W is cleared. If no REX bits are set, no byte is emitted.
1780 inline void emit_optional_rex_32(Register reg, Register rm_reg);
1781
1782 // The high bit of reg is used for REX.R, the high bit of op's base
1783 // register is used for REX.B, and the high bit of op's index register
1784 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
1785 // is emitted.
1786 inline void emit_optional_rex_32(Register reg, const Operand& op);
1787
1788 // As for emit_optional_rex_32(Register, Register), except that
1789 // the registers are XMM registers.
1790 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
1791
1792 // As for emit_optional_rex_32(Register, Register), except that
1793 // one of the registers is an XMM registers.
1794 inline void emit_optional_rex_32(XMMRegister reg, Register base);
1795
1796 // As for emit_optional_rex_32(Register, Register), except that
1797 // one of the registers is an XMM registers.
1798 inline void emit_optional_rex_32(Register reg, XMMRegister base);
1799
1800 // As for emit_optional_rex_32(Register, const Operand&), except that
1801 // the register is an XMM register.
1802 inline void emit_optional_rex_32(XMMRegister reg, const Operand& op);
1803
1804 // Optionally do as emit_rex_32(Register) if the register number has
1805 // the high bit set.
1806 inline void emit_optional_rex_32(Register rm_reg);
1807 inline void emit_optional_rex_32(XMMRegister rm_reg);
1808
1809 // Optionally do as emit_rex_32(const Operand&) if the operand register
1810 // numbers have a high bit set.
1811 inline void emit_optional_rex_32(const Operand& op);
1812
emit_rex(int size)1813 void emit_rex(int size) {
1814 if (size == kInt64Size) {
1815 emit_rex_64();
1816 } else {
1817 DCHECK(size == kInt32Size);
1818 }
1819 }
1820
1821 template<class P1>
emit_rex(P1 p1,int size)1822 void emit_rex(P1 p1, int size) {
1823 if (size == kInt64Size) {
1824 emit_rex_64(p1);
1825 } else {
1826 DCHECK(size == kInt32Size);
1827 emit_optional_rex_32(p1);
1828 }
1829 }
1830
1831 template<class P1, class P2>
emit_rex(P1 p1,P2 p2,int size)1832 void emit_rex(P1 p1, P2 p2, int size) {
1833 if (size == kInt64Size) {
1834 emit_rex_64(p1, p2);
1835 } else {
1836 DCHECK(size == kInt32Size);
1837 emit_optional_rex_32(p1, p2);
1838 }
1839 }
1840
1841 // Emit vex prefix
emit_vex2_byte0()1842 void emit_vex2_byte0() { emit(0xc5); }
1843 inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
1844 SIMDPrefix pp);
emit_vex3_byte0()1845 void emit_vex3_byte0() { emit(0xc4); }
1846 inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
1847 inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
1848 LeadingOpcode m);
1849 inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
1850 SIMDPrefix pp);
1851 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
1852 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1853 VexW w);
1854 inline void emit_vex_prefix(Register reg, Register v, Register rm,
1855 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1856 VexW w);
1857 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
1858 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1859 VexW w);
1860 inline void emit_vex_prefix(Register reg, Register v, const Operand& rm,
1861 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
1862 VexW w);
1863
1864 // Emit the ModR/M byte, and optionally the SIB byte and
1865 // 1- or 4-byte offset for a memory operand. Also encodes
1866 // the second operand of the operation, a register or operation
1867 // subcode, into the reg field of the ModR/M byte.
emit_operand(Register reg,const Operand & adr)1868 void emit_operand(Register reg, const Operand& adr) {
1869 emit_operand(reg.low_bits(), adr);
1870 }
1871
1872 // Emit the ModR/M byte, and optionally the SIB byte and
1873 // 1- or 4-byte offset for a memory operand. Also used to encode
1874 // a three-bit opcode extension into the ModR/M byte.
1875 void emit_operand(int rm, const Operand& adr);
1876
1877 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
emit_modrm(Register reg,Register rm_reg)1878 void emit_modrm(Register reg, Register rm_reg) {
1879 emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
1880 }
1881
1882 // Emit a ModR/M byte with an operation subcode in the reg field and
1883 // a register in the rm_reg field.
emit_modrm(int code,Register rm_reg)1884 void emit_modrm(int code, Register rm_reg) {
1885 DCHECK(is_uint3(code));
1886 emit(0xC0 | code << 3 | rm_reg.low_bits());
1887 }
1888
1889 // Emit the code-object-relative offset of the label's position
1890 inline void emit_code_relative_offset(Label* label);
1891
1892 // The first argument is the reg field, the second argument is the r/m field.
1893 void emit_sse_operand(XMMRegister dst, XMMRegister src);
1894 void emit_sse_operand(XMMRegister reg, const Operand& adr);
1895 void emit_sse_operand(Register reg, const Operand& adr);
1896 void emit_sse_operand(XMMRegister dst, Register src);
1897 void emit_sse_operand(Register dst, XMMRegister src);
1898
1899 // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
1900 // AND, OR, XOR, or CMP. The encodings of these operations are all
1901 // similar, differing just in the opcode or in the reg field of the
1902 // ModR/M byte.
1903 void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
1904 void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
1905 void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
1906 void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
1907 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1908 void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
1909 void arithmetic_op(byte opcode,
1910 Register reg,
1911 const Operand& rm_reg,
1912 int size);
1913 // Operate on a byte in memory or register.
1914 void immediate_arithmetic_op_8(byte subcode,
1915 Register dst,
1916 Immediate src);
1917 void immediate_arithmetic_op_8(byte subcode,
1918 const Operand& dst,
1919 Immediate src);
1920 // Operate on a word in memory or register.
1921 void immediate_arithmetic_op_16(byte subcode,
1922 Register dst,
1923 Immediate src);
1924 void immediate_arithmetic_op_16(byte subcode,
1925 const Operand& dst,
1926 Immediate src);
1927 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
1928 void immediate_arithmetic_op(byte subcode,
1929 Register dst,
1930 Immediate src,
1931 int size);
1932 void immediate_arithmetic_op(byte subcode,
1933 const Operand& dst,
1934 Immediate src,
1935 int size);
1936
1937 // Emit machine code for a shift operation.
1938 void shift(Operand dst, Immediate shift_amount, int subcode, int size);
1939 void shift(Register dst, Immediate shift_amount, int subcode, int size);
1940 // Shift dst by cl % 64 bits.
1941 void shift(Register dst, int subcode, int size);
1942 void shift(Operand dst, int subcode, int size);
1943
1944 void emit_farith(int b1, int b2, int i);
1945
1946 // labels
1947 // void print(Label* L);
1948 void bind_to(Label* L, int pos);
1949
1950 // record reloc info for current pc_
1951 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
1952
1953 // Arithmetics
emit_add(Register dst,Register src,int size)1954 void emit_add(Register dst, Register src, int size) {
1955 arithmetic_op(0x03, dst, src, size);
1956 }
1957
emit_add(Register dst,Immediate src,int size)1958 void emit_add(Register dst, Immediate src, int size) {
1959 immediate_arithmetic_op(0x0, dst, src, size);
1960 }
1961
emit_add(Register dst,const Operand & src,int size)1962 void emit_add(Register dst, const Operand& src, int size) {
1963 arithmetic_op(0x03, dst, src, size);
1964 }
1965
emit_add(const Operand & dst,Register src,int size)1966 void emit_add(const Operand& dst, Register src, int size) {
1967 arithmetic_op(0x1, src, dst, size);
1968 }
1969
emit_add(const Operand & dst,Immediate src,int size)1970 void emit_add(const Operand& dst, Immediate src, int size) {
1971 immediate_arithmetic_op(0x0, dst, src, size);
1972 }
1973
emit_and(Register dst,Register src,int size)1974 void emit_and(Register dst, Register src, int size) {
1975 arithmetic_op(0x23, dst, src, size);
1976 }
1977
emit_and(Register dst,const Operand & src,int size)1978 void emit_and(Register dst, const Operand& src, int size) {
1979 arithmetic_op(0x23, dst, src, size);
1980 }
1981
emit_and(const Operand & dst,Register src,int size)1982 void emit_and(const Operand& dst, Register src, int size) {
1983 arithmetic_op(0x21, src, dst, size);
1984 }
1985
emit_and(Register dst,Immediate src,int size)1986 void emit_and(Register dst, Immediate src, int size) {
1987 immediate_arithmetic_op(0x4, dst, src, size);
1988 }
1989
emit_and(const Operand & dst,Immediate src,int size)1990 void emit_and(const Operand& dst, Immediate src, int size) {
1991 immediate_arithmetic_op(0x4, dst, src, size);
1992 }
1993
emit_cmp(Register dst,Register src,int size)1994 void emit_cmp(Register dst, Register src, int size) {
1995 arithmetic_op(0x3B, dst, src, size);
1996 }
1997
emit_cmp(Register dst,const Operand & src,int size)1998 void emit_cmp(Register dst, const Operand& src, int size) {
1999 arithmetic_op(0x3B, dst, src, size);
2000 }
2001
emit_cmp(const Operand & dst,Register src,int size)2002 void emit_cmp(const Operand& dst, Register src, int size) {
2003 arithmetic_op(0x39, src, dst, size);
2004 }
2005
emit_cmp(Register dst,Immediate src,int size)2006 void emit_cmp(Register dst, Immediate src, int size) {
2007 immediate_arithmetic_op(0x7, dst, src, size);
2008 }
2009
emit_cmp(const Operand & dst,Immediate src,int size)2010 void emit_cmp(const Operand& dst, Immediate src, int size) {
2011 immediate_arithmetic_op(0x7, dst, src, size);
2012 }
2013
2014 void emit_dec(Register dst, int size);
2015 void emit_dec(const Operand& dst, int size);
2016
2017 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64.
2018 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx
2019 // when size is 32.
2020 void emit_idiv(Register src, int size);
2021 void emit_div(Register src, int size);
2022
2023 // Signed multiply instructions.
2024 // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2025 void emit_imul(Register src, int size);
2026 void emit_imul(const Operand& src, int size);
2027 void emit_imul(Register dst, Register src, int size);
2028 void emit_imul(Register dst, const Operand& src, int size);
2029 void emit_imul(Register dst, Register src, Immediate imm, int size);
2030 void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
2031
2032 void emit_inc(Register dst, int size);
2033 void emit_inc(const Operand& dst, int size);
2034
2035 void emit_lea(Register dst, const Operand& src, int size);
2036
2037 void emit_mov(Register dst, const Operand& src, int size);
2038 void emit_mov(Register dst, Register src, int size);
2039 void emit_mov(const Operand& dst, Register src, int size);
2040 void emit_mov(Register dst, Immediate value, int size);
2041 void emit_mov(const Operand& dst, Immediate value, int size);
2042
2043 void emit_movzxb(Register dst, const Operand& src, int size);
2044 void emit_movzxb(Register dst, Register src, int size);
2045 void emit_movzxw(Register dst, const Operand& src, int size);
2046 void emit_movzxw(Register dst, Register src, int size);
2047
2048 void emit_neg(Register dst, int size);
2049 void emit_neg(const Operand& dst, int size);
2050
2051 void emit_not(Register dst, int size);
2052 void emit_not(const Operand& dst, int size);
2053
emit_or(Register dst,Register src,int size)2054 void emit_or(Register dst, Register src, int size) {
2055 arithmetic_op(0x0B, dst, src, size);
2056 }
2057
emit_or(Register dst,const Operand & src,int size)2058 void emit_or(Register dst, const Operand& src, int size) {
2059 arithmetic_op(0x0B, dst, src, size);
2060 }
2061
emit_or(const Operand & dst,Register src,int size)2062 void emit_or(const Operand& dst, Register src, int size) {
2063 arithmetic_op(0x9, src, dst, size);
2064 }
2065
emit_or(Register dst,Immediate src,int size)2066 void emit_or(Register dst, Immediate src, int size) {
2067 immediate_arithmetic_op(0x1, dst, src, size);
2068 }
2069
emit_or(const Operand & dst,Immediate src,int size)2070 void emit_or(const Operand& dst, Immediate src, int size) {
2071 immediate_arithmetic_op(0x1, dst, src, size);
2072 }
2073
2074 void emit_repmovs(int size);
2075
emit_sbb(Register dst,Register src,int size)2076 void emit_sbb(Register dst, Register src, int size) {
2077 arithmetic_op(0x1b, dst, src, size);
2078 }
2079
emit_sub(Register dst,Register src,int size)2080 void emit_sub(Register dst, Register src, int size) {
2081 arithmetic_op(0x2B, dst, src, size);
2082 }
2083
emit_sub(Register dst,Immediate src,int size)2084 void emit_sub(Register dst, Immediate src, int size) {
2085 immediate_arithmetic_op(0x5, dst, src, size);
2086 }
2087
emit_sub(Register dst,const Operand & src,int size)2088 void emit_sub(Register dst, const Operand& src, int size) {
2089 arithmetic_op(0x2B, dst, src, size);
2090 }
2091
emit_sub(const Operand & dst,Register src,int size)2092 void emit_sub(const Operand& dst, Register src, int size) {
2093 arithmetic_op(0x29, src, dst, size);
2094 }
2095
emit_sub(const Operand & dst,Immediate src,int size)2096 void emit_sub(const Operand& dst, Immediate src, int size) {
2097 immediate_arithmetic_op(0x5, dst, src, size);
2098 }
2099
2100 void emit_test(Register dst, Register src, int size);
2101 void emit_test(Register reg, Immediate mask, int size);
2102 void emit_test(const Operand& op, Register reg, int size);
2103 void emit_test(const Operand& op, Immediate mask, int size);
emit_test(Register reg,const Operand & op,int size)2104 void emit_test(Register reg, const Operand& op, int size) {
2105 return emit_test(op, reg, size);
2106 }
2107
2108 void emit_xchg(Register dst, Register src, int size);
2109 void emit_xchg(Register dst, const Operand& src, int size);
2110
emit_xor(Register dst,Register src,int size)2111 void emit_xor(Register dst, Register src, int size) {
2112 if (size == kInt64Size && dst.code() == src.code()) {
2113 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
2114 // there is no need to make this a 64 bit operation.
2115 arithmetic_op(0x33, dst, src, kInt32Size);
2116 } else {
2117 arithmetic_op(0x33, dst, src, size);
2118 }
2119 }
2120
emit_xor(Register dst,const Operand & src,int size)2121 void emit_xor(Register dst, const Operand& src, int size) {
2122 arithmetic_op(0x33, dst, src, size);
2123 }
2124
emit_xor(Register dst,Immediate src,int size)2125 void emit_xor(Register dst, Immediate src, int size) {
2126 immediate_arithmetic_op(0x6, dst, src, size);
2127 }
2128
emit_xor(const Operand & dst,Immediate src,int size)2129 void emit_xor(const Operand& dst, Immediate src, int size) {
2130 immediate_arithmetic_op(0x6, dst, src, size);
2131 }
2132
emit_xor(const Operand & dst,Register src,int size)2133 void emit_xor(const Operand& dst, Register src, int size) {
2134 arithmetic_op(0x31, src, dst, size);
2135 }
2136
2137 // Most BMI instructions are similiar.
2138 void bmi1q(byte op, Register reg, Register vreg, Register rm);
2139 void bmi1q(byte op, Register reg, Register vreg, const Operand& rm);
2140 void bmi1l(byte op, Register reg, Register vreg, Register rm);
2141 void bmi1l(byte op, Register reg, Register vreg, const Operand& rm);
2142 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2143 void bmi2q(SIMDPrefix pp, byte op, Register reg, Register vreg,
2144 const Operand& rm);
2145 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg, Register rm);
2146 void bmi2l(SIMDPrefix pp, byte op, Register reg, Register vreg,
2147 const Operand& rm);
2148
2149 friend class CodePatcher;
2150 friend class EnsureSpace;
2151 friend class RegExpMacroAssemblerX64;
2152
2153 // code generation
2154 RelocInfoWriter reloc_info_writer;
2155
2156 // Internal reference positions, required for (potential) patching in
2157 // GrowBuffer(); contains only those internal references whose labels
2158 // are already bound.
2159 std::deque<int> internal_reference_positions_;
2160
2161 List< Handle<Code> > code_targets_;
2162
2163 PositionsRecorder positions_recorder_;
2164 friend class PositionsRecorder;
2165 };
2166
2167
2168 // Helper class that ensures that there is enough space for generating
2169 // instructions and relocation information. The constructor makes
2170 // sure that there is enough space and (in debug mode) the destructor
2171 // checks that we did not generate too much.
2172 class EnsureSpace BASE_EMBEDDED {
2173 public:
EnsureSpace(Assembler * assembler)2174 explicit EnsureSpace(Assembler* assembler) : assembler_(assembler) {
2175 if (assembler_->buffer_overflow()) assembler_->GrowBuffer();
2176 #ifdef DEBUG
2177 space_before_ = assembler_->available_space();
2178 #endif
2179 }
2180
2181 #ifdef DEBUG
~EnsureSpace()2182 ~EnsureSpace() {
2183 int bytes_generated = space_before_ - assembler_->available_space();
2184 DCHECK(bytes_generated < assembler_->kGap);
2185 }
2186 #endif
2187
2188 private:
2189 Assembler* assembler_;
2190 #ifdef DEBUG
2191 int space_before_;
2192 #endif
2193 };
2194
2195 } // namespace internal
2196 } // namespace v8
2197
2198 #endif // V8_X64_ASSEMBLER_X64_H_
2199