v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
assembler-x64.h
Go to the documentation of this file.
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_CODEGEN_X64_ASSEMBLER_X64_H_
38#define V8_CODEGEN_X64_ASSEMBLER_X64_H_
39
40#include <deque>
41#include <map>
42#include <memory>
43#include <vector>
44
48#include "src/codegen/label.h"
54#include "src/objects/smi.h"
55
56#if defined(V8_OS_WIN_X64)
58#endif
59
60namespace v8 {
61namespace internal {
62
63class SafepointTableBuilder;
64class MaglevSafepointTableBuilder;
65
66// Utility functions
67
68enum Condition : int {
69 overflow = 0,
70 no_overflow = 1,
71 below = 2,
72 above_equal = 3,
73 equal = 4,
74 not_equal = 5,
75 below_equal = 6,
76 above = 7,
77 negative = 8,
78 positive = 9,
79 parity_even = 10,
80 parity_odd = 11,
81 less = 12,
82 greater_equal = 13,
83 less_equal = 14,
84 greater = 15,
85
86 // aliases
87 carry = below,
89 zero = equal,
91 sign = negative,
93
94 // Unified cross-platform condition names/aliases.
95 kEqual = equal,
107 kZero = equal,
109};
110
111// Returns the equivalent of !cc.
113 return static_cast<Condition>(cc ^ 1);
114}
115
117 kRoundToNearest = 0x0,
118 kRoundDown = 0x1,
119 kRoundUp = 0x2,
120 kRoundToZero = 0x3
121};
122
123// -----------------------------------------------------------------------------
124// Machine instruction Immediates
125
127 public:
128 explicit constexpr Immediate(int32_t value) : value_(value) {}
129 explicit constexpr Immediate(int32_t value, RelocInfo::Mode rmode)
130 : value_(value), rmode_(rmode) {}
131 explicit Immediate(Tagged<Smi> value)
132 : value_(static_cast<int32_t>(static_cast<intptr_t>(value.ptr()))) {
133 DCHECK(SmiValuesAre31Bits()); // Only available for 31-bit SMI.
134 }
135
136 int32_t value() const { return value_; }
137 RelocInfo::Mode rmode() const { return rmode_; }
138
139 private:
140 const int32_t value_;
142
143 friend class Assembler;
144};
146static_assert(sizeof(Immediate) <= kSystemPointerSize,
147 "Immediate must be small enough to pass it by value");
148
150 public:
151 explicit constexpr Immediate64(int64_t value) : value_(value) {}
152 explicit constexpr Immediate64(int64_t value, RelocInfo::Mode rmode)
153 : value_(value), rmode_(rmode) {}
154 explicit constexpr Immediate64(Address value, RelocInfo::Mode rmode)
155 : value_(static_cast<int64_t>(value)), rmode_(rmode) {}
156
157 private:
158 const int64_t value_;
160
161 friend class Assembler;
162};
163
164// -----------------------------------------------------------------------------
165// Machine instruction Operands
166
179
181 public:
183 // The first two fields are shared in {LabelOperand} and {MemoryOperand},
184 // but cannot be pulled out of the union, because otherwise the compiler
185 // introduces additional padding between them and the union, increasing the
186 // size unnecessarily.
187 bool is_label_operand = true;
188 uint8_t rex = 0; // REX prefix, always zero for label operands.
189
190 int8_t addend; // Used for rip + offset + addend operands.
192 };
193
195 bool is_label_operand = false;
196 uint8_t rex = 0; // REX prefix.
197
198 // Register (1 byte) + SIB (0 or 1 byte) + displacement (0, 1, or 4 byte).
199 uint8_t buf[6] = {0};
200 // Number of bytes of buf in use.
201 // We must keep {len} and {buf} together for the compiler to elide the
202 // stack canary protection code.
203 size_t len = 1;
204 };
205
206 // Assert that the shared {is_label_operand} and {rex} fields have the same
207 // type and offset in both union variants.
208 static_assert(std::is_same<decltype(LabelOperand::is_label_operand),
209 decltype(MemoryOperand::is_label_operand)>::value);
210 static_assert(offsetof(LabelOperand, is_label_operand) ==
211 offsetof(MemoryOperand, is_label_operand));
212 static_assert(std::is_same<decltype(LabelOperand::rex),
213 decltype(MemoryOperand::rex)>::value);
214 static_assert(offsetof(LabelOperand, rex) == offsetof(MemoryOperand, rex));
215
216 static_assert(sizeof(MemoryOperand::len) == kSystemPointerSize,
217 "Length must have native word size to avoid spurious reloads "
218 "after writing it.");
219 static_assert(offsetof(MemoryOperand, len) % kSystemPointerSize == 0,
220 "Length must be aligned for fast access.");
221
222 // [base + disp/r]
223 V8_INLINE constexpr Operand(Register base, int32_t disp) {
224 if (base == rsp || base == r12) {
225 // SIB byte is needed to encode (rsp + offset) or (r12 + offset).
226 set_sib(times_1, rsp, base);
227 }
228
229 if (disp == 0 && base != rbp && base != r13) {
230 set_modrm(0, base);
231 } else if (is_int8(disp)) {
232 set_modrm(1, base);
233 set_disp8(disp);
234 } else {
235 set_modrm(2, base);
236 set_disp32(disp);
237 }
238 }
239
240 // [base + index*scale + disp/r]
242 int32_t disp) {
243 DCHECK(index != rsp);
244 set_sib(scale, index, base);
245 if (disp == 0 && base != rbp && base != r13) {
246 // This call to set_modrm doesn't overwrite the REX.B (or REX.X) bits
247 // possibly set by set_sib.
248 set_modrm(0, rsp);
249 } else if (is_int8(disp)) {
250 set_modrm(1, rsp);
251 set_disp8(disp);
252 } else {
253 set_modrm(2, rsp);
254 set_disp32(disp);
255 }
256 }
257
258 // [index*scale + disp/r]
260 // The encoding generated by this constructor is longer than the
261 // {register, displacement} constructor above. Hence only use this if the
262 // scale factor is >1.
263 // We could dynamically check this and do what the other constructor does,
264 // but that adds unnecessary checks to a very commonly used constructor in
265 // the Assembler, which should be as fast as possible.
266 DCHECK_NE(ScaleFactor::times_1, scale);
267
268 DCHECK(index != rsp);
269 set_modrm(0, rsp);
270 set_sib(scale, index, rbp);
271 set_disp32(disp);
272 }
273
274 // Offset from existing memory operand.
275 // Offset is added to existing displacement as 32-bit signed values and
276 // this must not overflow.
278
279 // [rip + disp/r]
280 V8_INLINE explicit Operand(Label* label, int addend = 0) {
282 DCHECK(addend == 0 || (is_int8(addend) && label->is_bound()));
283 label_ = {};
284 label_.label = label;
285 label_.addend = addend;
286 }
287
288 Operand(const Operand&) V8_NOEXCEPT = default;
290
291 V8_INLINE constexpr bool is_label_operand() const {
292 // Since this field is in the common initial sequence of {label_} and
293 // {memory_}, the access is valid regardless of the active union member.
294 return memory_.is_label_operand;
295 }
296
297 V8_INLINE constexpr uint8_t rex() const {
298 // Since both fields are in the common initial sequence of {label_} and
299 // {memory_}, the access is valid regardless of the active union member.
300 // Label operands always have a REX prefix of zero.
301 V8_ASSUME(!memory_.is_label_operand || memory_.rex == 0);
302 return memory_.rex;
303 }
304
306 DCHECK(!is_label_operand());
307 return memory_;
308 }
309
310 V8_INLINE const LabelOperand& label() const {
311 DCHECK(is_label_operand());
312 return label_;
313 }
314
315 // Checks whether either base or index register is the given register.
316 // Does not check the "reg" part of the Operand.
318
319 private:
320 V8_INLINE constexpr void set_modrm(int mod, Register rm_reg) {
321 DCHECK(!is_label_operand());
322 DCHECK(is_uint2(mod));
323 memory_.buf[0] = mod << 6 | rm_reg.low_bits();
324 // Set REX.B to the high bit of rm.code().
325 memory_.rex |= rm_reg.high_bit();
326 }
327
329 Register base) {
330 V8_ASSUME(memory_.len == 1);
331 DCHECK(is_uint2(scale));
332 // Use SIB with no index register only for base rsp or r12. Otherwise we
333 // would skip the SIB byte entirely.
334 DCHECK(index != rsp || base == rsp || base == r12);
335 memory_.buf[1] = (scale << 6) | (index.low_bits() << 3) | base.low_bits();
336 memory_.rex |= index.high_bit() << 1 | base.high_bit();
337 memory_.len = 2;
338 }
339
340 V8_INLINE constexpr void set_disp8(int disp) {
341 V8_ASSUME(memory_.len == 1 || memory_.len == 2);
342 DCHECK(is_int8(disp));
343 memory_.buf[memory_.len] = disp;
344 memory_.len += sizeof(int8_t);
345 }
346
347 V8_INLINE void set_disp32(int disp) {
348 V8_ASSUME(memory_.len == 1 || memory_.len == 2);
349 Address p = reinterpret_cast<Address>(&memory_.buf[memory_.len]);
350 WriteUnalignedValue(p, disp);
351 memory_.len += sizeof(int32_t);
352 }
353
354 union {
356 MemoryOperand memory_ = {};
357 };
358};
359
361 public:
362 // [base + disp/r]
363 V8_INLINE Operand256(Register base, int32_t disp) : Operand(base, disp) {}
364
365 // [base + index*scale + disp/r]
367 int32_t disp)
368 : Operand(base, index, scale, disp) {}
369
370 // [index*scale + disp/r]
372 : Operand(index, scale, disp) {}
373
376
377 private:
378 friend class Operand;
379};
380
382static_assert(sizeof(Operand) <= 2 * kSystemPointerSize,
383 "Operand must be small enough to pass it by value");
384
385// Support DCHECK_NE in shared code. On x64, an {Operand} is never an alias
386// for a register.
387inline bool operator!=(Operand op, XMMRegister r) { return true; }
388
389#define ASSEMBLER_INSTRUCTION_LIST(V) \
390 V(add) \
391 V(and) \
392 V(cmp) \
393 V(cmpxchg) \
394 V(dec) \
395 V(idiv) \
396 V(div) \
397 V(imul) \
398 V(inc) \
399 V(lea) \
400 V(mov) \
401 V(movzxb) \
402 V(movzxw) \
403 V(not ) \
404 V(or) \
405 V(repmovs) \
406 V(sbb) \
407 V(sub) \
408 V(test) \
409 V(xchg) \
410 V(xor) \
411 V(aligned_cmp) \
412 V(aligned_test)
413
414// Shift instructions on operands/registers with kInt32Size and kInt64Size.
415#define SHIFT_INSTRUCTION_LIST(V) \
416 V(rol, 0x0) \
417 V(ror, 0x1) \
418 V(rcl, 0x2) \
419 V(rcr, 0x3) \
420 V(shl, 0x4) \
421 V(shr, 0x5) \
422 V(sar, 0x7)
423
424// Partial Constant Pool
425// Different from complete constant pool (like arm does), partial constant pool
426// only takes effects for shareable constants in order to reduce code size.
427// Partial constant pool does not emit constant pool entries at the end of each
428// code object. Instead, it keeps the first shareable constant inlined in the
429// instructions and uses rip-relative memory loadings for the same constants in
430// subsequent instructions. These rip-relative memory loadings will target at
431// the position of the first inlined constant. For example:
432//
433// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes
434// …
435// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes
436// …
437//
438// turns into
439//
440// REX.W movq r10,0x7f9f75a32c20 ; 10 bytes
441// …
442// REX.W movq r10,[rip+0xffffff96] ; 7 bytes
443// …
444
446 public:
447 explicit ConstPool(Assembler* assm) : assm_(assm) {}
448 // Returns true when partial constant pool is valid for this entry.
449 bool TryRecordEntry(intptr_t data, RelocInfo::Mode mode);
450 bool IsEmpty() const { return entries_.empty(); }
451
453 // Discard any pending pool entries.
454 void Clear();
455
456 private:
457 // Adds a shared entry to entries_. Returns true if this is not the first time
458 // we add this entry, false otherwise.
459 bool AddSharedEntry(uint64_t data, int offset);
460
461 // Check if the instruction is a rip-relative move.
463
465
466 // Values, pc offsets of entries.
467 std::multimap<uint64_t, int> entries_;
468
469 // Number of bytes taken up by the displacement of rip-relative addressing.
470 static constexpr int kRipRelativeDispSize = 4; // 32-bit displacement.
471 // Distance between the address of the displacement in the rip-relative move
472 // instruction and the head address of the instruction.
473 static constexpr int kMoveRipRelativeDispOffset =
474 3; // REX Opcode ModRM Displacement
475 // Distance between the address of the imm64 in the 'movq reg, imm64'
476 // instruction and the head address of the instruction.
477 static constexpr int kMoveImm64Offset = 2; // REX Opcode imm64
478 // A mask for rip-relative move instruction.
479 static constexpr uint32_t kMoveRipRelativeMask = 0x00C7FFFB;
480 // The bits for a rip-relative move instruction after mask.
481 static constexpr uint32_t kMoveRipRelativeInstr = 0x00058B48;
482};
483
485 private:
486 // We check before assembling an instruction that there is sufficient
487 // space to write an instruction and its relocation information.
488 // The relocation writer's position must be kGap bytes above the end of
489 // the generated instructions. This leaves enough space for the
490 // longest possible x64 instruction, 15 bytes, and the longest possible
491 // relocation information encoding, RelocInfoWriter::kMaxLength == 16.
492 // (There is a 15 byte limit on x64 instruction length that rules out some
493 // otherwise valid instructions.)
494 // This allows for a single, fast space check per instruction.
495 static constexpr int kGap = 32;
496 static_assert(AssemblerBase::kMinimalBufferSize >= 2 * kGap);
497
498 public:
499 // Create an assembler. Instructions and relocation information are emitted
500 // into a buffer, with the instructions starting from the beginning and the
501 // relocation information starting from the end of the buffer. See CodeDesc
502 // for a detailed comment on the layout (globals.h).
503 //
504 // If the provided buffer is nullptr, the assembler allocates and grows its
505 // own buffer. Otherwise it takes ownership of the provided buffer.
507 std::unique_ptr<AssemblerBuffer> = {});
508 // For compatibility with assemblers that require a zone.
510 std::unique_ptr<AssemblerBuffer> buffer = {})
511 : Assembler(options, std::move(buffer)) {}
512
513 ~Assembler() override = default;
514
515 // GetCode emits any pending (non-emitted) code and fills the descriptor desc.
516 static constexpr int kNoHandlerTable = 0;
517 static constexpr SafepointTableBuilderBase* kNoSafepointTable = nullptr;
518
519 void GetCode(LocalIsolate* isolate, CodeDesc* desc,
520 SafepointTableBuilderBase* safepoint_table_builder,
521 int handler_table_offset);
522
523 // Convenience wrapper for allocating with an Isolate.
524 void GetCode(Isolate* isolate, CodeDesc* desc);
525 // Convenience wrapper for code without safepoint or handler tables.
526 void GetCode(LocalIsolate* isolate, CodeDesc* desc) {
527 GetCode(isolate, desc, kNoSafepointTable, kNoHandlerTable);
528 }
529
531
532 // Unused on this architecture.
534
535 // Read/Modify the code target in the relative branch/call instruction at pc.
536 // On the x64 architecture, we use relative jumps with a 32-bit displacement
537 // to jump to other InstructionStream objects in the InstructionStream space
538 // in the heap. Jumps to C functions are done indirectly through a 64-bit
539 // register holding the absolute address of the target. These functions
540 // convert between absolute Addresses of InstructionStream objects and the
541 // relative displacements stored in the code. The isolate argument is unused
542 // (and may be nullptr) when skipping flushing.
543 static inline Address target_address_at(Address pc, Address constant_pool);
544 static inline void set_target_address_at(
545 Address pc, Address constant_pool, Address target,
546 WritableJitAllocation* writable_jit_allocation = nullptr,
547 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
548 static inline int32_t relative_target_offset(Address target, Address pc);
549
550 // During code generation builtin targets in PC-relative call/jump
551 // instructions are temporarily encoded as builtin ID until the generated
552 // code is moved into the code space.
553 static inline Builtin target_builtin_at(Address pc);
554
555 // Get the size of the special target encoded at 'instruction_payload'.
557 Address instruction_payload);
558
559 // This sets the internal reference at the pc.
561 Address pc, Address target, WritableJitAllocation& jit_allocation,
562 RelocInfo::Mode mode = RelocInfo::INTERNAL_REFERENCE);
563
565 inline DirectHandle<HeapObject> compressed_embedded_object_handle_at(
566 Address pc);
567
568 // Read/modify the uint32 constant used at pc.
569 static inline uint32_t uint32_constant_at(Address pc, Address constant_pool);
570 static inline void set_uint32_constant_at(
571 Address pc, Address constant_pool, uint32_t new_constant,
572 WritableJitAllocation* jit_allocation = nullptr,
573 ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
574
575 // Number of bytes taken up by the branch target in the code.
576 static constexpr int kSpecialTargetSize = 4; // 32-bit displacement.
577
578 // One byte opcode for test eax,0xXXXXXXXX.
579 static constexpr uint8_t kTestEaxByte = 0xA9;
580 // One byte opcode for test al, 0xXX.
581 static constexpr uint8_t kTestAlByte = 0xA8;
582 // One byte opcode for nop.
583 static constexpr uint8_t kNopByte = 0x90;
584
585 // One byte prefix for a short conditional jump.
586 static constexpr uint8_t kJccShortPrefix = 0x70;
587 static constexpr uint8_t kJncShortOpcode = kJccShortPrefix | not_carry;
588 static constexpr uint8_t kJcShortOpcode = kJccShortPrefix | carry;
589 static constexpr uint8_t kJnzShortOpcode = kJccShortPrefix | not_zero;
590 static constexpr uint8_t kJzShortOpcode = kJccShortPrefix | zero;
591
592 // VEX prefix encodings.
593 enum SIMDPrefix { kNoPrefix = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
594 enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
595 enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
596 enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
597
598 // ---------------------------------------------------------------------------
599 // InstructionStream generation
600 //
601 // Function names correspond one-to-one to x64 instruction mnemonics.
602 // Unless specified otherwise, instructions operate on 64-bit operands.
603 //
604 // If we need versions of an assembly instruction that operate on different
605 // width arguments, we add a single-letter suffix specifying the width.
606 // This is done for the following instructions: mov, cmp, inc, dec,
607 // add, sub, and test.
608 // There are no versions of these instructions without the suffix.
609 // - Instructions on 8-bit (byte) operands/registers have a trailing 'b'.
610 // - Instructions on 16-bit (word) operands/registers have a trailing 'w'.
611 // - Instructions on 32-bit (doubleword) operands/registers use 'l'.
612 // - Instructions on 64-bit (quadword) operands/registers use 'q'.
613 // - Instructions on operands/registers with pointer size use 'p'.
614
615#define DECLARE_INSTRUCTION(instruction) \
616 template <typename... Ps> \
617 void instruction##_tagged(Ps... ps) { \
618 emit_##instruction(ps..., kTaggedSize); \
619 } \
620 \
621 template <typename... Ps> \
622 void instruction##l(Ps... ps) { \
623 emit_##instruction(ps..., kInt32Size); \
624 } \
625 \
626 template <typename... Ps> \
627 void instruction##q(Ps... ps) { \
628 emit_##instruction(ps..., kInt64Size); \
629 }
631#undef DECLARE_INSTRUCTION
632
633 // Insert the smallest number of nop instructions
634 // possible to align the pc offset to a multiple
635 // of m, where m must be a power of 2.
636 void Align(int m);
637 // Insert the smallest number of zero bytes possible to align the pc offset
638 // to a multiple of m. m must be a power of 2 (>= 2).
639 void DataAlign(int m);
640 void Nop(int bytes = 1);
641
642 // Intel CPUs with the Skylake microarchitecture suffer from a performance
643 // regression by the JCC erratum. To mitigate the performance impact, we align
644 // jcc instructions so that they will not cross or end at 32-byte boundaries.
645 // {inst_size} is the total size of the instructions which we will avoid to
646 // cross or end at the boundaries. For example, aaaabbbb is a fused jcc
647 // instructions, e.g., cmpq+jmp. In the fused case we have:
648 // ...aaaabbbbbb
649 // ^ ^
650 // | pc_offset + inst_size
651 // pc_offset
652 // And in the non-fused case:
653 // ...bbbb
654 // ^ ^
655 // | pc_offset + inst_size
656 // pc_offset
657 void AlignForJCCErratum(int inst_size);
658
660
661 // Aligns code to something that's optimal for a jump target for the platform.
664
665 // Stack
666 void pushfq();
667 void popfq();
668
669 void pushq(Immediate value);
670 // Push a 32 bit integer, and guarantee that it is actually pushed as a
671 // 32 bit value, the normal push will optimize the 8 bit case.
672 static constexpr int kPushq32InstrSize = 5;
673 void pushq_imm32(int32_t imm32);
674 void pushq(Register src);
675 void pushq(Operand src);
676
677 void popq(Register dst);
678 void popq(Operand dst);
679
680 void incsspq(Register number_of_words);
681
682 void leave();
683
684 // Moves
685 void movb(Register dst, Operand src);
686 void movb(Register dst, Immediate imm);
687 void movb(Operand dst, Register src);
688 void movb(Operand dst, Immediate imm);
689
690 // Move the low 16 bits of a 64-bit register value to a 16-bit
691 // memory location.
692 void movw(Register dst, Operand src);
693 void movw(Operand dst, Register src);
694 void movw(Operand dst, Immediate imm);
695
696 // Move the offset of the label location relative to the current
697 // position (after the move) to the destination.
698 void movl(Operand dst, Label* src);
699
700 // Load a heap number into a register.
701 // The heap number will not be allocated and embedded into the code right
702 // away. Instead, we emit the load of a dummy object. Later, when calling
703 // Assembler::GetCode, the heap number will be allocated and the code will be
704 // patched by replacing the dummy with the actual object. The RelocInfo for
705 // the embedded object gets already recorded correctly when emitting the dummy
706 // move.
707 void movq_heap_number(Register dst, double value);
708
709 // Loads a 64-bit immediate into a register, potentially using the constant
710 // pool.
711 void movq(Register dst, int64_t value) { movq(dst, Immediate64(value)); }
712 void movq(Register dst, uint64_t value) {
713 movq(dst, Immediate64(static_cast<int64_t>(value)));
714 }
715
716 // Loads a 64-bit immediate into a register without using the constant pool.
717 void movq_imm64(Register dst, int64_t value);
718
719 void movsxbl(Register dst, Register src);
720 void movsxbl(Register dst, Operand src);
721 void movsxbq(Register dst, Register src);
722 void movsxbq(Register dst, Operand src);
723 void movsxwl(Register dst, Register src);
724 void movsxwl(Register dst, Operand src);
725 void movsxwq(Register dst, Register src);
726 void movsxwq(Register dst, Operand src);
727 void movsxlq(Register dst, Register src);
728 void movsxlq(Register dst, Operand src);
729
730 // Repeated moves.
731 void repmovsb();
732 void repmovsw();
733 void repmovsl() { emit_repmovs(kInt32Size); }
734 void repmovsq() { emit_repmovs(kInt64Size); }
735
736 // Repeated store of doublewords (fill (E)CX bytes at ES:[(E)DI] with EAX).
737 void repstosl();
738 // Repeated store of quadwords (fill RCX quadwords at [RDI] with RAX).
739 void repstosq();
740
741 // Instruction to load from an immediate 64-bit pointer into RAX.
742 void load_rax(Address value, RelocInfo::Mode rmode);
744
745 // Conditional moves.
746 void cmovq(Condition cc, Register dst, Register src);
747 void cmovq(Condition cc, Register dst, Operand src);
748 void cmovl(Condition cc, Register dst, Register src);
749 void cmovl(Condition cc, Register dst, Operand src);
750
751 void cmpb(Register dst, Immediate src) {
752 immediate_arithmetic_op_8(0x7, dst, src);
753 }
754
755 // Used for JCC erratum performance mitigation.
757 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
758 // /* cmp */ 4 + /* jcc */ 6
759 const int kMaxMacroFusionLength = 10;
760 AlignForJCCErratum(kMaxMacroFusionLength);
761 cmpb(dst, src);
762 }
763
765
766 void cmpb(Register dst, Register src) { arithmetic_op_8(0x3A, dst, src); }
767
768 // Used for JCC erratum performance mitigation.
770 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
771 // /* cmp */ 3 + /* jcc */ 6
772 const int kMaxMacroFusionLength = 9;
773 AlignForJCCErratum(kMaxMacroFusionLength);
774 cmpb(dst, src);
775 }
776
777 void cmpb(Register dst, Operand src) { arithmetic_op_8(0x3A, dst, src); }
778
779 // Used for JCC erratum performance mitigation.
781 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
782 // /* cmp */ 8 + /* jcc */ 6
783 const int kMaxMacroFusionLength = 14;
784 AlignForJCCErratum(kMaxMacroFusionLength);
785 cmpb(dst, src);
786 }
787
788 void cmpb(Operand dst, Register src) { arithmetic_op_8(0x38, src, dst); }
789
790 // Used for JCC erratum performance mitigation.
792 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
793 // /* cmp */ 8 + /* jcc */ 6
794 const int kMaxMacroFusionLength = 14;
795 AlignForJCCErratum(kMaxMacroFusionLength);
796 cmpb(dst, src);
797 }
798
799 void cmpb(Operand dst, Immediate src) {
800 immediate_arithmetic_op_8(0x7, dst, src);
801 }
802
803 // Used for JCC erratum performance mitigation.
805 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
806 // cmp can not be fused when comparing MEM-IMM, so we would not align this
807 // instruction.
808 cmpb(dst, src);
809 }
810
811 void cmpw(Operand dst, Immediate src) {
812 immediate_arithmetic_op_16(0x7, dst, src);
813 }
814
815 // Used for JCC erratum performance mitigation.
817 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
818 // cmp can not be fused when comparing MEM-IMM, so we would not align this
819 // instruction.
820 cmpw(dst, src);
821 }
822
823 void cmpw(Register dst, Immediate src) {
824 immediate_arithmetic_op_16(0x7, dst, src);
825 }
826
827 // Used for JCC erratum performance mitigation.
829 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
830 // /* cmp */ 6 + /* jcc */ 6
831 const int kMaxMacroFusionLength = 12;
832 AlignForJCCErratum(kMaxMacroFusionLength);
833 cmpw(dst, src);
834 }
835
836 void cmpw(Register dst, Operand src) { arithmetic_op_16(0x3B, dst, src); }
837
838 // Used for JCC erratum performance mitigation.
840 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
841 // /* cmp */ 9 + /* jcc */ 6
842 const int kMaxMacroFusionLength = 15;
843 AlignForJCCErratum(kMaxMacroFusionLength);
844 cmpw(dst, src);
845 }
846
847 void cmpw(Register dst, Register src) { arithmetic_op_16(0x3B, dst, src); }
848
849 // Used for JCC erratum performance mitigation.
851 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
852 // /* cmp */ 4 + /* jcc */ 6
853 const int kMaxMacroFusionLength = 10;
854 AlignForJCCErratum(kMaxMacroFusionLength);
855 cmpw(dst, src);
856 }
857
858 void cmpw(Operand dst, Register src) { arithmetic_op_16(0x39, src, dst); }
859
860 // Used for JCC erratum performance mitigation.
862 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
863 // /* cmp */ 9 + /* jcc */ 6
864 const int kMaxMacroFusionLength = 15;
865 AlignForJCCErratum(kMaxMacroFusionLength);
866 cmpw(dst, src);
867 }
868
869 void testb(Register reg, Operand op) { testb(op, reg); }
870
871 // Used for JCC erratum performance mitigation.
873
874 void testw(Register reg, Operand op) { testw(op, reg); }
875
876 // Used for JCC erratum performance mitigation.
878
879 void andb(Register dst, Immediate src) {
880 immediate_arithmetic_op_8(0x4, dst, src);
881 }
882
883 void decb(Register dst);
884 void decb(Operand dst);
885
886 // Lock prefix.
887 void lock();
888
891
892 void xaddb(Operand dst, Register src);
893 void xaddw(Operand dst, Register src);
894 void xaddl(Operand dst, Register src);
895 void xaddq(Operand dst, Register src);
896
901 void negb(Operand op);
902 void negw(Operand op);
903 void negl(Operand op);
904 void negq(Operand op);
905
906 void cmpxchgb(Operand dst, Register src);
907 void cmpxchgw(Operand dst, Register src);
908
909 // Sign-extends rax into rdx:rax.
910 void cqo();
911 // Sign-extends eax into edx:eax.
912 void cdq();
913
914 // Multiply eax by src, put the result in edx:eax.
915 void mull(Register src);
916 void mull(Operand src);
917 // Multiply rax by src, put the result in rdx:rax.
918 void mulq(Register src);
919 void mulq(Operand src);
920
921#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
922 void instruction##l(Register dst, Immediate imm8) { \
923 shift(dst, imm8, subcode, kInt32Size); \
924 } \
925 \
926 void instruction##q(Register dst, Immediate imm8) { \
927 shift(dst, imm8, subcode, kInt64Size); \
928 } \
929 \
930 void instruction##l(Operand dst, Immediate imm8) { \
931 shift(dst, imm8, subcode, kInt32Size); \
932 } \
933 \
934 void instruction##q(Operand dst, Immediate imm8) { \
935 shift(dst, imm8, subcode, kInt64Size); \
936 } \
937 \
938 void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); } \
939 \
940 void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); } \
941 \
942 void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); } \
943 \
944 void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
946#undef DECLARE_SHIFT_INSTRUCTION
947
948 // Shifts dst:src left by cl bits, affecting only dst.
949 void shld(Register dst, Register src);
950
951 // Shifts src:dst right by cl bits, affecting only dst.
952 void shrd(Register dst, Register src);
953
954 void store_rax(Address dst, RelocInfo::Mode mode);
956
957 void subb(Register dst, Immediate src) {
958 immediate_arithmetic_op_8(0x5, dst, src);
959 }
960
961 void sub_sp_32(uint32_t imm);
962
963 void testb(Register dst, Register src);
964 // Used for JCC erratum performance mitigation.
966 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
967 // /* test */ 3 + /* jcc */ 6
968 const int kMaxMacroFusionLength = 9;
969 AlignForJCCErratum(kMaxMacroFusionLength);
970 testb(dst, src);
971 }
972
974 // Used for JCC erratum performance mitigation.
976 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
977 // /* test */ 4 + /* jcc */ 6
978 const int kMaxMacroFusionLength = 10;
979 AlignForJCCErratum(kMaxMacroFusionLength);
980 testb(reg, mask);
981 }
982
984 // Used for JCC erratum performance mitigation.
986 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
987 // test can not be fused when comparing MEM-IMM, so we would not align this
988 // instruction.
989 testb(op, mask);
990 }
991
993 // Used for JCC erratum performance mitigation.
995 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
996 // /* test */ 8 + /* jcc */ 6
997 const int kMaxMacroFusionLength = 14;
998 AlignForJCCErratum(kMaxMacroFusionLength);
999 testb(op, reg);
1000 }
1001
1002 void testw(Register dst, Register src);
1003 // Used for JCC erratum performance mitigation.
1005 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1006 // /* test */ 4 + /* jcc */ 6
1007 const int kMaxMacroFusionLength = 10;
1008 AlignForJCCErratum(kMaxMacroFusionLength);
1009 testw(dst, src);
1010 }
1011
1013 // Used for JCC erratum performance mitigation.
1015 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1016 // /* test */ 6 + /* jcc */ 6
1017 const int kMaxMacroFusionLength = 12;
1018 AlignForJCCErratum(kMaxMacroFusionLength);
1019 testw(reg, mask);
1020 }
1021
1023 // Used for JCC erratum performance mitigation.
1025 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1026 // test can not be fused when comparing MEM-IMM, so we would not align this
1027 // instruction.
1028 testw(op, mask);
1029 }
1030
1032 // Used for JCC erratum performance mitigation.
1034 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1035 // /* test */ 9 + /* jcc */ 6
1036 const int kMaxMacroFusionLength = 15;
1037 AlignForJCCErratum(kMaxMacroFusionLength);
1038 testw(op, reg);
1039 }
1040
1041 // Bit operations.
1042 void bswapl(Register dst);
1043 void bswapq(Register dst);
1044 void btq(Operand dst, Register src);
1045 void btsq(Operand dst, Register src);
1046 void btsq(Register dst, Immediate imm8);
1047 void btrq(Register dst, Immediate imm8);
1048 void bsrq(Register dst, Register src);
1049 void bsrq(Register dst, Operand src);
1050 void bsrl(Register dst, Register src);
1051 void bsrl(Register dst, Operand src);
1052 void bsfq(Register dst, Register src);
1053 void bsfq(Register dst, Operand src);
1054 void bsfl(Register dst, Register src);
1055 void bsfl(Register dst, Operand src);
1056
1057 // Miscellaneous
1058 void clc();
1059 void cld();
1060 void cpuid();
1061 void hlt();
1062 void int3();
1063 void nop();
1064 void ret(int imm16);
1065 void ud2();
1067 void endbr64();
1068
1069 void pblendw(XMMRegister dst, Operand src, uint8_t mask);
1070 void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask);
1071 void palignr(XMMRegister dst, Operand src, uint8_t mask);
1072 void palignr(XMMRegister dst, XMMRegister src, uint8_t mask);
1073
1074 void vpermq(YMMRegister dst, Operand src, uint8_t imm8) {
1075 vinstr(0x0, dst, ymm0, src, k66, k0F3A, kW1, AVX2);
1076 emit(imm8);
1077 }
1078 void vpermq(YMMRegister dst, YMMRegister src, uint8_t imm8) {
1079 vinstr(0x0, dst, ymm0, src, k66, k0F3A, kW1, AVX2);
1080 emit(imm8);
1081 }
1082
1083 // Label operations & relative jumps (PPUM Appendix D)
1084 //
1085 // Takes a branch opcode (cc) and a label (L) and generates
1086 // either a backward branch or a forward branch and links it
1087 // to the label fixup chain. Usage:
1088 //
1089 // Label L; // unbound label
1090 // j(cc, &L); // forward branch to unbound label
1091 // bind(&L); // bind label to the current pc
1092 // j(cc, &L); // backward branch to bound label
1093 // bind(&L); // illegal: a label may be bound only once
1094 //
1095 // Note: The same Label can be used for forward and backward branches
1096 // but it may be bound only once.
1097
1098 void bind(Label* L); // binds an unbound label L to the current code position
1099
1100 // Calls
1101 // Call near relative 32-bit displacement, relative to next instruction.
1102 void call(Label* L);
1103
1104 // Explicitly emit a near call / near jump. The displacement is relative to
1105 // the next instructions (which starts at
1106 // {pc_offset() + kIntraSegmentJmpInstrSize}).
1107 static constexpr int kIntraSegmentJmpInstrSize = 5;
1108 void near_call(intptr_t disp, RelocInfo::Mode rmode);
1109 void near_call(Builtin buitin, RelocInfo::Mode rmode);
1110 void near_jmp(intptr_t disp, RelocInfo::Mode rmode);
1111 void near_j(Condition cc, intptr_t disp, RelocInfo::Mode rmode);
1112
1113 void call(Handle<Code> target,
1114 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET);
1115
1116 // Call near absolute indirect, address in register
1117 void call(Register adr);
1118
1119 // Jumps
1120 // Jump short or near relative.
1121 // Use a 32-bit signed displacement.
1122 // Unconditional jump to L
1123 void jmp(Label* L, Label::Distance distance = Label::kFar);
1124 // Used for JCC erratum performance mitigation.
1125 void aligned_jmp(Label* L, Label::Distance distance = Label::kFar) {
1126 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1127 const int kInstLength = distance == Label::kFar ? 6 : 2;
1128 AlignForJCCErratum(kInstLength);
1129 jmp(L, distance);
1130 }
1131 void jmp(Handle<Code> target, RelocInfo::Mode rmode);
1132
1133 // Jump near absolute indirect (r64)
1134 // With notrack, add an optional prefix to disable CET IBT enforcement for
1135 // this jump.
1136 void jmp(Register adr, bool notrack = false);
1137 void jmp(Operand src, bool notrack = false);
1138
1139 // Unconditional jump relative to the current address. Low-level routine,
1140 // use with caution!
1141 void jmp_rel(int offset);
1142
1143 // Conditional jumps
1144 void j(Condition cc, Label* L, Label::Distance distance = Label::kFar);
1145 // Used for JCC erratum performance mitigation.
1147 Label::Distance distance = Label::kFar) {
1148 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
1149 const int kInstLength = distance == Label::kFar ? 6 : 2;
1150 AlignForJCCErratum(kInstLength);
1151 j(cc, L, distance);
1152 }
1153 void j(Condition cc, Address entry, RelocInfo::Mode rmode);
1154 void j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode);
1155
1156 // Floating-point operations
1157 void fld(int i);
1158
1159 void fld1();
1160 void fldz();
1161 void fldpi();
1162 void fldln2();
1163
1164 void fld_s(Operand adr);
1165 void fld_d(Operand adr);
1166
1167 void fstp_s(Operand adr);
1168 void fstp_d(Operand adr);
1169 void fstp(int index);
1170
1171 void fild_s(Operand adr);
1172 void fild_d(Operand adr);
1173
1174 void fist_s(Operand adr);
1175
1176 void fistp_s(Operand adr);
1177 void fistp_d(Operand adr);
1178
1181
1182 void fabs();
1183 void fchs();
1184
1185 void fadd(int i);
1186 void fsub(int i);
1187 void fmul(int i);
1188 void fdiv(int i);
1189
1190 void fisub_s(Operand adr);
1191
1192 void faddp(int i = 1);
1193 void fsubp(int i = 1);
1194 void fsubrp(int i = 1);
1195 void fmulp(int i = 1);
1196 void fdivp(int i = 1);
1197 void fprem();
1198 void fprem1();
1199
1200 void fxch(int i = 1);
1201 void fincstp();
1202 void ffree(int i = 0);
1203
1204 void ftst();
1205 void fucomp(int i);
1206 void fucompp();
1207 void fucomi(int i);
1208 void fucomip();
1209
1210 void fcompp();
1212 void fwait();
1213 void fnclex();
1214
1215 void fsin();
1216 void fcos();
1217 void fptan();
1218 void fyl2x();
1219 void f2xm1();
1220 void fscale();
1221 void fninit();
1222
1223 void frndint();
1224
1225 void sahf();
1226
1231
1232 // Don't use this unless it's important to keep the
1233 // top half of the destination register unchanged.
1234 // Use movaps when moving float values and movd for integer
1235 // values in xmm registers.
1237
1238 void movss(XMMRegister dst, Operand src);
1239 void movss(Operand dst, XMMRegister src);
1240
1243
1246
1247 void shufps(XMMRegister dst, XMMRegister src, uint8_t imm8);
1248
1253
1255
1256 void vinstr(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
1257 SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature = AVX);
1258 void vinstr(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2,
1259 SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature = AVX);
1260
1261 template <typename Reg1, typename Reg2, typename Op>
1262 void vinstr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, SIMDPrefix pp,
1263 LeadingOpcode m, VexW w, CpuFeature feature = AVX2);
1264
1265 // SSE instructions
1266 void sse_instr(XMMRegister dst, XMMRegister src, uint8_t escape,
1267 uint8_t opcode);
1268 void sse_instr(XMMRegister dst, Operand src, uint8_t escape, uint8_t opcode);
1269#define DECLARE_SSE_INSTRUCTION(instruction, escape, opcode) \
1270 void instruction(XMMRegister dst, XMMRegister src) { \
1271 sse_instr(dst, src, 0x##escape, 0x##opcode); \
1272 } \
1273 void instruction(XMMRegister dst, Operand src) { \
1274 sse_instr(dst, src, 0x##escape, 0x##opcode); \
1275 }
1276
1279#undef DECLARE_SSE_INSTRUCTION
1280
1281 // SSE instructions with prefix and SSE2 instructions
1282 void sse2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
1283 uint8_t escape, uint8_t opcode);
1284 void sse2_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape,
1285 uint8_t opcode);
1286#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode) \
1287 void instruction(XMMRegister dst, XMMRegister src) { \
1288 sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \
1289 } \
1290 void instruction(XMMRegister dst, Operand src) { \
1291 sse2_instr(dst, src, 0x##prefix, 0x##escape, 0x##opcode); \
1292 }
1293
1294 // These SSE instructions have the same encoding as the SSE2 instructions.
1299#undef DECLARE_SSE2_INSTRUCTION
1300
1301 void sse2_instr(XMMRegister reg, uint8_t imm8, uint8_t prefix, uint8_t escape,
1302 uint8_t opcode, int extension) {
1303 XMMRegister ext_reg = XMMRegister::from_code(extension);
1304 sse2_instr(ext_reg, reg, prefix, escape, opcode);
1305 emit(imm8);
1306 }
1307
1308#define DECLARE_SSE2_SHIFT_IMM(instruction, prefix, escape, opcode, extension) \
1309 void instruction(XMMRegister reg, uint8_t imm8) { \
1310 sse2_instr(reg, imm8, 0x##prefix, 0x##escape, 0x##opcode, 0x##extension); \
1311 }
1313#undef DECLARE_SSE2_SHIFT_IMM
1314
1315#define DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1316 void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1317 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \
1318 } \
1319 void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) { \
1320 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0); \
1321 }
1322
1323#define DECLARE_SSE2_PD_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1324 DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1325 void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \
1326 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX); \
1327 } \
1328 void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \
1329 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX); \
1330 }
1331
1333#undef DECLARE_SSE2_PD_AVX_INSTRUCTION
1334
1335#define DECLARE_SSE2_PI_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1336 DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1337 void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \
1338 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \
1339 } \
1340 void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \
1341 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \
1342 }
1343
1345#undef DECLARE_SSE2_PI_AVX_INSTRUCTION
1346
1347#define DECLARE_SSE2_SHIFT_AVX_INSTRUCTION(instruction, prefix, escape, \
1348 opcode) \
1349 DECLARE_SSE2_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1350 void v##instruction(YMMRegister dst, YMMRegister src1, XMMRegister src2) { \
1351 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \
1352 } \
1353 void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \
1354 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kW0, AVX2); \
1355 }
1356
1358#undef DECLARE_SSE2_SHIFT_AVX_INSTRUCTION
1359#undef DECLARE_SSE2_AVX_INSTRUCTION
1360
1361#define DECLARE_SSE2_UNOP_AVX_INSTRUCTION(instruction, prefix, escape, opcode) \
1362 void v##instruction(XMMRegister dst, XMMRegister src) { \
1363 vpd(0x##opcode, dst, xmm0, src); \
1364 } \
1365 void v##instruction(XMMRegister dst, Operand src) { \
1366 vpd(0x##opcode, dst, xmm0, src); \
1367 }
1368
1370#undef DECLARE_SSE2_UNOP_AVX_INSTRUCTION
1371
1372#define DECLARE_SSE2_UNOP_AVX_YMM_INSTRUCTION( \
1373 instruction, opcode, DSTRegister, SRCRegister, MemOperand) \
1374 void v##instruction(DSTRegister dst, SRCRegister src) { \
1375 vpd(0x##opcode, dst, ymm0, src); \
1376 } \
1377 void v##instruction(DSTRegister dst, MemOperand src) { \
1378 vpd(0x##opcode, dst, ymm0, src); \
1379 }
1381 Operand)
1383 Operand256)
1385 Operand)
1387 Operand256)
1388#undef DECLARE_SSE2_UNOP_AVX_YMM_INSTRUCTION
1389
1390 // SSE3
1391 void lddqu(XMMRegister dst, Operand src);
1395
1396 // SSSE3
1397 void ssse3_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
1398 uint8_t escape1, uint8_t escape2, uint8_t opcode);
1399 void ssse3_instr(XMMRegister dst, Operand src, uint8_t prefix,
1400 uint8_t escape1, uint8_t escape2, uint8_t opcode);
1401
1402#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2, \
1403 opcode) \
1404 void instruction(XMMRegister dst, XMMRegister src) { \
1405 ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1406 } \
1407 void instruction(XMMRegister dst, Operand src) { \
1408 ssse3_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1409 }
1410
1413#undef DECLARE_SSSE3_INSTRUCTION
1414
1415 // SSE4
1416 void sse4_instr(Register dst, XMMRegister src, uint8_t prefix,
1417 uint8_t escape1, uint8_t escape2, uint8_t opcode,
1418 int8_t imm8);
1419 void sse4_instr(Operand dst, XMMRegister src, uint8_t prefix, uint8_t escape1,
1420 uint8_t escape2, uint8_t opcode, int8_t imm8);
1421 void sse4_instr(XMMRegister dst, Register src, uint8_t prefix,
1422 uint8_t escape1, uint8_t escape2, uint8_t opcode,
1423 int8_t imm8);
1424 void sse4_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
1425 uint8_t escape1, uint8_t escape2, uint8_t opcode);
1426 void sse4_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape1,
1427 uint8_t escape2, uint8_t opcode);
1428#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2, \
1429 opcode) \
1430 void instruction(XMMRegister dst, XMMRegister src) { \
1431 sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1432 } \
1433 void instruction(XMMRegister dst, Operand src) { \
1434 sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1435 }
1436
1439 DECLARE_SSE4_INSTRUCTION(pblendvb, 66, 0F, 38, 10)
1440 DECLARE_SSE4_INSTRUCTION(blendvps, 66, 0F, 38, 14)
1441 DECLARE_SSE4_INSTRUCTION(blendvpd, 66, 0F, 38, 15)
1442#undef DECLARE_SSE4_INSTRUCTION
1443
1444#define DECLARE_SSE4_EXTRACT_INSTRUCTION(instruction, prefix, escape1, \
1445 escape2, opcode) \
1446 void instruction(Register dst, XMMRegister src, uint8_t imm8) { \
1447 sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode, \
1448 imm8); \
1449 } \
1450 void instruction(Operand dst, XMMRegister src, uint8_t imm8) { \
1451 sse4_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode, \
1452 imm8); \
1453 }
1454
1456#undef DECLARE_SSE4_EXTRACT_INSTRUCTION
1457
1458 // SSE4.2
1459 void sse4_2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
1460 uint8_t escape1, uint8_t escape2, uint8_t opcode);
1461 void sse4_2_instr(XMMRegister dst, Operand src, uint8_t prefix,
1462 uint8_t escape1, uint8_t escape2, uint8_t opcode);
1463#define DECLARE_SSE4_2_INSTRUCTION(instruction, prefix, escape1, escape2, \
1464 opcode) \
1465 void instruction(XMMRegister dst, XMMRegister src) { \
1466 sse4_2_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1467 } \
1468 void instruction(XMMRegister dst, Operand src) { \
1469 sse4_2_instr(dst, src, 0x##prefix, 0x##escape1, 0x##escape2, 0x##opcode); \
1470 }
1471
1473#undef DECLARE_SSE4_2_INSTRUCTION
1474
1475#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, \
1476 opcode) \
1477 void v##instruction(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1478 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
1479 } \
1480 void v##instruction(XMMRegister dst, XMMRegister src1, Operand src2) { \
1481 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0); \
1482 } \
1483 void v##instruction(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \
1484 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0, \
1485 AVX2); \
1486 } \
1487 void v##instruction(YMMRegister dst, YMMRegister src1, Operand src2) { \
1488 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape1##escape2, kW0, \
1489 AVX2); \
1490 }
1491
1495#undef DECLARE_SSE34_AVX_INSTRUCTION
1496
1497#define DECLARE_SSSE3_UNOP_AVX_INSTRUCTION(instruction, prefix, escape1, \
1498 escape2, opcode) \
1499 void v##instruction(XMMRegister dst, XMMRegister src) { \
1500 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1501 } \
1502 void v##instruction(XMMRegister dst, Operand src) { \
1503 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1504 } \
1505 void v##instruction(YMMRegister dst, YMMRegister src) { \
1506 vinstr(0x##opcode, dst, ymm0, src, k##prefix, k##escape1##escape2, kW0); \
1507 } \
1508 void v##instruction(YMMRegister dst, Operand src) { \
1509 vinstr(0x##opcode, dst, ymm0, src, k##prefix, k##escape1##escape2, kW0); \
1510 }
1511
1513#undef DECLARE_SSSE3_UNOP_AVX_INSTRUCTION
1514
1516 XMMRegister mask) {
1517 vinstr(0x4C, dst, src1, src2, k66, k0F3A, kW0);
1518 // The mask operand is encoded in bits[7:4] of the immediate byte.
1519 emit(mask.code() << 4);
1520 }
1522 YMMRegister mask) {
1523 vinstr(0x4C, dst, src1, src2, k66, k0F3A, kW0, AVX2);
1524 // The mask operand is encoded in bits[7:4] of the immediate byte.
1525 emit(mask.code() << 4);
1526 }
1527
1529 XMMRegister mask) {
1530 vinstr(0x4A, dst, src1, src2, k66, k0F3A, kW0);
1531 // The mask operand is encoded in bits[7:4] of the immediate byte.
1532 emit(mask.code() << 4);
1533 }
1535 YMMRegister mask) {
1536 vinstr(0x4A, dst, src1, src2, k66, k0F3A, kW0, AVX);
1537 // The mask operand is encoded in bits[7:4] of the immediate byte.
1538 emit(mask.code() << 4);
1539 }
1540
1542 XMMRegister mask) {
1543 vinstr(0x4B, dst, src1, src2, k66, k0F3A, kW0);
1544 // The mask operand is encoded in bits[7:4] of the immediate byte.
1545 emit(mask.code() << 4);
1546 }
1548 YMMRegister mask) {
1549 vinstr(0x4B, dst, src1, src2, k66, k0F3A, kW0, AVX);
1550 // The mask operand is encoded in bits[7:4] of the immediate byte.
1551 emit(mask.code() << 4);
1552 }
1553
1554#define DECLARE_SSE4_PMOV_AVX_INSTRUCTION(instruction, prefix, escape1, \
1555 escape2, opcode) \
1556 void v##instruction(XMMRegister dst, XMMRegister src) { \
1557 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1558 } \
1559 void v##instruction(XMMRegister dst, Operand src) { \
1560 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1561 }
1563#undef DECLARE_SSE4_PMOV_AVX_INSTRUCTION
1564
1565#define DECLARE_SSE4_PMOV_AVX2_INSTRUCTION(instruction, prefix, escape1, \
1566 escape2, opcode) \
1567 void v##instruction(YMMRegister dst, XMMRegister src) { \
1568 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1569 } \
1570 void v##instruction(YMMRegister dst, Operand src) { \
1571 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0); \
1572 }
1574#undef DECLARE_SSE4_PMOV_AVX2_INSTRUCTION
1575
1577 vinstr(0x17, dst, ymm0, src, k66, k0F38, kW0, AVX);
1578 }
1579 void vptest(YMMRegister dst, Operand src) {
1580 vinstr(0x17, dst, ymm0, src, k66, k0F38, kW0, AVX);
1581 }
1582
1583#define DECLARE_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode) \
1584 void v##instruction(Register dst, XMMRegister src, uint8_t imm8) { \
1585 XMMRegister idst = XMMRegister::from_code(dst.code()); \
1586 vinstr(0x##opcode, src, xmm0, idst, k##prefix, k##escape1##escape2, kW0); \
1587 emit(imm8); \
1588 } \
1589 void v##instruction(Operand dst, XMMRegister src, uint8_t imm8) { \
1590 vinstr(0x##opcode, src, xmm0, dst, k##prefix, k##escape1##escape2, kW0); \
1591 emit(imm8); \
1592 }
1593
1595#undef DECLARE_AVX_INSTRUCTION
1596
1597 void movd(XMMRegister dst, Register src);
1598 void movd(XMMRegister dst, Operand src);
1599 void movd(Register dst, XMMRegister src);
1600 void movq(XMMRegister dst, Register src);
1601 void movq(XMMRegister dst, Operand src);
1602 void movq(Register dst, XMMRegister src);
1604
1605 // Don't use this unless it's important to keep the
1606 // top half of the destination register unchanged.
1607 // Use movapd when moving double values and movq for integer
1608 // values in xmm registers.
1610
1611 void movsd(Operand dst, XMMRegister src);
1612 void movsd(XMMRegister dst, Operand src);
1613
1617
1621
1625
1627
1636
1639
1642
1645
1648
1651
1655
1657
1659
1660 void pinsrw(XMMRegister dst, Register src, uint8_t imm8);
1661 void pinsrw(XMMRegister dst, Operand src, uint8_t imm8);
1662
1663 // SSE 4.1 instruction
1664 void insertps(XMMRegister dst, XMMRegister src, uint8_t imm8);
1665 void insertps(XMMRegister dst, Operand src, uint8_t imm8);
1666 void pextrq(Register dst, XMMRegister src, int8_t imm8);
1667 void pinsrb(XMMRegister dst, Register src, uint8_t imm8);
1668 void pinsrb(XMMRegister dst, Operand src, uint8_t imm8);
1669 void pinsrd(XMMRegister dst, Register src, uint8_t imm8);
1670 void pinsrd(XMMRegister dst, Operand src, uint8_t imm8);
1671 void pinsrq(XMMRegister dst, Register src, uint8_t imm8);
1672 void pinsrq(XMMRegister dst, Operand src, uint8_t imm8);
1673
1680
1681 void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp);
1682 void cmpps(XMMRegister dst, Operand src, int8_t cmp);
1683 void cmppd(XMMRegister dst, XMMRegister src, int8_t cmp);
1684 void cmppd(XMMRegister dst, Operand src, int8_t cmp);
1685
1686#define SSE_CMP_P(instr, imm8) \
1687 void instr##ps(XMMRegister dst, XMMRegister src) { cmpps(dst, src, imm8); } \
1688 void instr##ps(XMMRegister dst, Operand src) { cmpps(dst, src, imm8); } \
1689 void instr##pd(XMMRegister dst, XMMRegister src) { cmppd(dst, src, imm8); } \
1690 void instr##pd(XMMRegister dst, Operand src) { cmppd(dst, src, imm8); }
1691
1692 SSE_CMP_P(cmpeq, 0x0)
1693 SSE_CMP_P(cmplt, 0x1)
1694 SSE_CMP_P(cmple, 0x2)
1695 SSE_CMP_P(cmpunord, 0x3)
1696 SSE_CMP_P(cmpneq, 0x4)
1697 SSE_CMP_P(cmpnlt, 0x5)
1698 SSE_CMP_P(cmpnle, 0x6)
1699
1700#undef SSE_CMP_P
1701
1705 void psrldq(XMMRegister dst, uint8_t shift);
1706 void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1707 void pshufd(XMMRegister dst, Operand src, uint8_t shuffle);
1708 void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1709 void pshufhw(XMMRegister dst, Operand src, uint8_t shuffle);
1710 void pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle);
1711 void pshuflw(XMMRegister dst, Operand src, uint8_t shuffle);
1712
1714 sse_instr(dst, src, 0x0F, 0x12);
1715 }
1717 sse_instr(dst, src, 0x0F, 0x16);
1718 }
1719
1720 // AVX instruction
1733
1735 uint8_t lane);
1737 uint8_t lane);
1738 void vextractf128(XMMRegister dst, YMMRegister src, uint8_t lane);
1739
1740 template <typename Reg1, typename Reg2, typename Op>
1741 void fma_instr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, VectorLength l,
1743
1744#define FMA(instr, prefix, escape1, escape2, extension, opcode) \
1745 void instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1746 fma_instr(0x##opcode, dst, src1, src2, kL128, k##prefix, \
1747 k##escape1##escape2, k##extension); \
1748 } \
1749 void instr(XMMRegister dst, XMMRegister src1, Operand src2) { \
1750 fma_instr(0x##opcode, dst, src1, src2, kL128, k##prefix, \
1751 k##escape1##escape2, k##extension); \
1752 }
1754#undef FMA
1755
1756#define DECLARE_FMA_YMM_INSTRUCTION(instr, prefix, escape1, escape2, \
1757 extension, opcode) \
1758 void instr(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \
1759 fma_instr(0x##opcode, dst, src1, src2, kL256, k##prefix, \
1760 k##escape1##escape2, k##extension); \
1761 } \
1762 void instr(YMMRegister dst, YMMRegister src1, Operand src2) { \
1763 fma_instr(0x##opcode, dst, src1, src2, kL256, k##prefix, \
1764 k##escape1##escape2, k##extension); \
1765 }
1768#undef DECLARE_FMA_YMM_INSTRUCTION
1769
1771 void vmovd(XMMRegister dst, Operand src);
1774 void vmovq(XMMRegister dst, Operand src);
1776
1778 vsd(0x10, dst, src1, src2);
1779 }
1780 void vmovsd(XMMRegister dst, Operand src) { vsd(0x10, dst, xmm0, src); }
1781 void vmovsd(Operand dst, XMMRegister src) { vsd(0x11, src, xmm0, dst); }
1792
1795
1798
1799#define AVX_SSE_UNOP(instr, escape, opcode) \
1800 void v##instr(XMMRegister dst, XMMRegister src2) { \
1801 vps(0x##opcode, dst, xmm0, src2); \
1802 } \
1803 void v##instr(XMMRegister dst, Operand src2) { \
1804 vps(0x##opcode, dst, xmm0, src2); \
1805 } \
1806 void v##instr(YMMRegister dst, YMMRegister src2) { \
1807 vps(0x##opcode, dst, ymm0, src2); \
1808 } \
1809 void v##instr(YMMRegister dst, Operand src2) { \
1810 vps(0x##opcode, dst, ymm0, src2); \
1811 }
1813#undef AVX_SSE_UNOP
1814
1815#define AVX_SSE_BINOP(instr, escape, opcode) \
1816 void v##instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1817 vps(0x##opcode, dst, src1, src2); \
1818 } \
1819 void v##instr(XMMRegister dst, XMMRegister src1, Operand src2) { \
1820 vps(0x##opcode, dst, src1, src2); \
1821 } \
1822 void v##instr(YMMRegister dst, YMMRegister src1, YMMRegister src2) { \
1823 vps(0x##opcode, dst, src1, src2); \
1824 } \
1825 void v##instr(YMMRegister dst, YMMRegister src1, Operand src2) { \
1826 vps(0x##opcode, dst, src1, src2); \
1827 }
1829#undef AVX_SSE_BINOP
1830
1831#define AVX_3(instr, opcode, impl, SIMDRegister) \
1832 void instr(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \
1833 impl(opcode, dst, src1, src2); \
1834 } \
1835 void instr(SIMDRegister dst, SIMDRegister src1, Operand src2) { \
1836 impl(opcode, dst, src1, src2); \
1837 }
1838
1839 AVX_3(vhaddps, 0x7c, vsd, XMMRegister)
1840 AVX_3(vhaddps, 0x7c, vsd, YMMRegister)
1841
1842#define AVX_SCALAR(instr, prefix, escape, opcode) \
1843 void v##instr(XMMRegister dst, XMMRegister src1, XMMRegister src2) { \
1844 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kWIG); \
1845 } \
1846 void v##instr(XMMRegister dst, XMMRegister src1, Operand src2) { \
1847 vinstr(0x##opcode, dst, src1, src2, k##prefix, k##escape, kWIG); \
1848 }
1851#undef AVX_SCALAR
1852
1853#undef AVX_3
1854
1855#define AVX_SSE2_SHIFT_IMM(instr, prefix, escape, opcode, extension) \
1856 void v##instr(XMMRegister dst, XMMRegister src, uint8_t imm8) { \
1857 XMMRegister ext_reg = XMMRegister::from_code(extension); \
1858 vinstr(0x##opcode, ext_reg, dst, src, k##prefix, k##escape, kWIG); \
1859 emit(imm8); \
1860 } \
1861 \
1862 void v##instr(YMMRegister dst, YMMRegister src, uint8_t imm8) { \
1863 YMMRegister ext_reg = YMMRegister::from_code(extension); \
1864 vinstr(0x##opcode, ext_reg, dst, src, k##prefix, k##escape, kWIG); \
1865 emit(imm8); \
1866 }
1868#undef AVX_SSE2_SHIFT_IMM
1869
1871 vinstr(0x16, dst, src1, src2, kNoPrefix, k0F, kWIG);
1872 }
1874 vinstr(0x12, dst, src1, src2, kNoPrefix, k0F, kWIG);
1875 }
1877 vinstr(0xe6, dst, xmm0, src, kF3, k0F, kWIG);
1878 }
1880 vinstr(0xe6, dst, xmm0, src, kF3, k0F, kWIG, AVX);
1881 }
1883 vinstr(0xe6, dst, xmm0, src, kF3, k0F, kWIG, AVX);
1884 }
1886 vinstr(0x5b, dst, xmm0, src, kF3, k0F, kWIG);
1887 }
1889 vinstr(0x5b, dst, ymm0, src, kF3, k0F, kWIG, AVX);
1890 }
1892 vinstr(0x5b, dst, ymm0, src, kF3, k0F, kWIG, AVX);
1893 }
1895 XMMRegister isrc2 = XMMRegister::from_code(src2.code());
1896 vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW0);
1897 }
1899 vinstr(0x2a, dst, src1, src2, kF2, k0F, kW0);
1900 }
1902 XMMRegister isrc2 = XMMRegister::from_code(src2.code());
1903 vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW0);
1904 }
1906 vinstr(0x2a, dst, src1, src2, kF3, k0F, kW0);
1907 }
1909 XMMRegister isrc2 = XMMRegister::from_code(src2.code());
1910 vinstr(0x2a, dst, src1, isrc2, kF3, k0F, kW1);
1911 }
1913 vinstr(0x2a, dst, src1, src2, kF3, k0F, kW1);
1914 }
1916 XMMRegister isrc2 = XMMRegister::from_code(src2.code());
1917 vinstr(0x2a, dst, src1, isrc2, kF2, k0F, kW1);
1918 }
1920 vinstr(0x2a, dst, src1, src2, kF2, k0F, kW1);
1921 }
1923 XMMRegister idst = XMMRegister::from_code(dst.code());
1924 vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1925 }
1926 void vcvttss2si(Register dst, Operand src) {
1927 XMMRegister idst = XMMRegister::from_code(dst.code());
1928 vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW0);
1929 }
1931 XMMRegister idst = XMMRegister::from_code(dst.code());
1932 vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1933 }
1934 void vcvttsd2si(Register dst, Operand src) {
1935 XMMRegister idst = XMMRegister::from_code(dst.code());
1936 vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW0);
1937 }
1939 XMMRegister idst = XMMRegister::from_code(dst.code());
1940 vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1941 }
1943 XMMRegister idst = XMMRegister::from_code(dst.code());
1944 vinstr(0x2c, idst, xmm0, src, kF3, k0F, kW1);
1945 }
1947 XMMRegister idst = XMMRegister::from_code(dst.code());
1948 vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1949 }
1951 XMMRegister idst = XMMRegister::from_code(dst.code());
1952 vinstr(0x2c, idst, xmm0, src, kF2, k0F, kW1);
1953 }
1955 XMMRegister idst = XMMRegister::from_code(dst.code());
1956 vinstr(0x2d, idst, xmm0, src, kF2, k0F, kW0);
1957 }
1959 RoundingMode mode) {
1960 vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1961 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1962 }
1964 RoundingMode mode) {
1965 vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
1966 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1967 }
1969 RoundingMode mode) {
1970 vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1971 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1972 }
1974 RoundingMode mode) {
1975 vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
1976 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1977 }
1979 vinstr(0x08, dst, xmm0, src, k66, k0F3A, kWIG);
1980 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1981 }
1983 vinstr(0x08, dst, ymm0, src, k66, k0F3A, kWIG, AVX);
1984 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1985 }
1987 vinstr(0x09, dst, xmm0, src, k66, k0F3A, kWIG);
1988 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1989 }
1991 vinstr(0x09, dst, ymm0, src, k66, k0F3A, kWIG, AVX);
1992 emit(static_cast<uint8_t>(mode) | 0x8); // Mask precision exception.
1993 }
1994
1995 template <typename Reg, typename Op>
1996 void vsd(uint8_t op, Reg dst, Reg src1, Op src2) {
1997 vinstr(op, dst, src1, src2, kF2, k0F, kWIG, AVX);
1998 }
1999
2001 vss(0x10, dst, src1, src2);
2002 }
2003 void vmovss(XMMRegister dst, Operand src) { vss(0x10, dst, xmm0, src); }
2004 void vmovss(Operand dst, XMMRegister src) { vss(0x11, src, xmm0, dst); }
2007 void vss(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
2008 void vss(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2);
2009
2011 uint8_t imm8) {
2012 vps(0xC6, dst, src1, src2, imm8);
2013 }
2015 uint8_t imm8) {
2016 vps(0xC6, dst, src1, src2, imm8);
2017 }
2018
2019 void vmovaps(XMMRegister dst, XMMRegister src) { vps(0x28, dst, xmm0, src); }
2020 void vmovaps(YMMRegister dst, YMMRegister src) { vps(0x28, dst, ymm0, src); }
2021 void vmovaps(XMMRegister dst, Operand src) { vps(0x28, dst, xmm0, src); }
2022 void vmovaps(YMMRegister dst, Operand src) { vps(0x28, dst, ymm0, src); }
2023 void vmovups(XMMRegister dst, XMMRegister src) { vps(0x10, dst, xmm0, src); }
2024 void vmovups(YMMRegister dst, YMMRegister src) { vps(0x10, dst, ymm0, src); }
2025 void vmovups(XMMRegister dst, Operand src) { vps(0x10, dst, xmm0, src); }
2026 void vmovups(YMMRegister dst, Operand src) { vps(0x10, dst, ymm0, src); }
2027 void vmovups(Operand dst, XMMRegister src) { vps(0x11, src, xmm0, dst); }
2028 void vmovups(Operand dst, YMMRegister src) { vps(0x11, src, ymm0, dst); }
2029 void vmovapd(XMMRegister dst, XMMRegister src) { vpd(0x28, dst, xmm0, src); }
2030 void vmovapd(YMMRegister dst, YMMRegister src) { vpd(0x28, dst, ymm0, src); }
2031 void vmovupd(XMMRegister dst, Operand src) { vpd(0x10, dst, xmm0, src); }
2032 void vmovupd(YMMRegister dst, Operand src) { vpd(0x10, dst, ymm0, src); }
2033 void vmovupd(Operand dst, XMMRegister src) { vpd(0x11, src, xmm0, dst); }
2034 void vmovupd(Operand dst, YMMRegister src) { vpd(0x11, src, ymm0, dst); }
2036 XMMRegister idst = XMMRegister::from_code(dst.code());
2037 vps(0x50, idst, xmm0, src);
2038 }
2040 XMMRegister idst = XMMRegister::from_code(dst.code());
2041 vpd(0x50, idst, xmm0, src);
2042 }
2045 vss(0xC2, dst, dst, src);
2046 emit(0x00); // EQ == 0
2047 }
2049 vsd(0xC2, dst, dst, src);
2050 emit(0x00); // EQ == 0
2051 }
2052 void vcmpps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) {
2053 vps(0xC2, dst, src1, src2);
2054 emit(cmp);
2055 }
2056 void vcmpps(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp) {
2057 vps(0xC2, dst, src1, src2);
2058 emit(cmp);
2059 }
2060 void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp) {
2061 vps(0xC2, dst, src1, src2);
2062 emit(cmp);
2063 }
2064 void vcmpps(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp) {
2065 vps(0xC2, dst, src1, src2);
2066 emit(cmp);
2067 }
2068 void vcmppd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp) {
2069 vpd(0xC2, dst, src1, src2);
2070 emit(cmp);
2071 }
2072 void vcmppd(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp) {
2073 vpd(0xC2, dst, src1, src2);
2074 emit(cmp);
2075 }
2076 void vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp) {
2077 vpd(0xC2, dst, src1, src2);
2078 emit(cmp);
2079 }
2080 void vcmppd(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp) {
2081 vpd(0xC2, dst, src1, src2);
2082 emit(cmp);
2083 }
2084#define AVX_CMP_P(instr, imm8, SIMDRegister) \
2085 void instr##ps(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \
2086 vcmpps(dst, src1, src2, imm8); \
2087 } \
2088 void instr##ps(SIMDRegister dst, SIMDRegister src1, Operand src2) { \
2089 vcmpps(dst, src1, src2, imm8); \
2090 } \
2091 void instr##pd(SIMDRegister dst, SIMDRegister src1, SIMDRegister src2) { \
2092 vcmppd(dst, src1, src2, imm8); \
2093 } \
2094 void instr##pd(SIMDRegister dst, SIMDRegister src1, Operand src2) { \
2095 vcmppd(dst, src1, src2, imm8); \
2096 }
2097
2098 AVX_CMP_P(vcmpeq, 0x0, XMMRegister)
2099 AVX_CMP_P(vcmpeq, 0x0, YMMRegister)
2100 AVX_CMP_P(vcmplt, 0x1, XMMRegister)
2101 AVX_CMP_P(vcmplt, 0x1, YMMRegister)
2102 AVX_CMP_P(vcmple, 0x2, XMMRegister)
2103 AVX_CMP_P(vcmple, 0x2, YMMRegister)
2104 AVX_CMP_P(vcmpunord, 0x3, XMMRegister)
2105 AVX_CMP_P(vcmpunord, 0x3, YMMRegister)
2106 AVX_CMP_P(vcmpneq, 0x4, XMMRegister)
2107 AVX_CMP_P(vcmpneq, 0x4, YMMRegister)
2108 AVX_CMP_P(vcmpnlt, 0x5, XMMRegister)
2109 AVX_CMP_P(vcmpnlt, 0x5, YMMRegister)
2110 AVX_CMP_P(vcmpnle, 0x6, XMMRegister)
2111 AVX_CMP_P(vcmpnle, 0x6, YMMRegister)
2112 AVX_CMP_P(vcmpge, 0xd, XMMRegister)
2113 AVX_CMP_P(vcmpge, 0xd, YMMRegister)
2114
2115#undef AVX_CMP_P
2116
2117 void vlddqu(XMMRegister dst, Operand src) {
2118 vinstr(0xF0, dst, xmm0, src, kF2, k0F, kWIG);
2119 }
2121 uint8_t imm8) {
2122 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG);
2123 emit(imm8);
2124 }
2126 uint8_t imm8) {
2127 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG);
2128 emit(imm8);
2129 }
2130 void vpextrq(Register dst, XMMRegister src, int8_t imm8) {
2131 XMMRegister idst = XMMRegister::from_code(dst.code());
2132 vinstr(0x16, src, xmm0, idst, k66, k0F3A, kW1);
2133 emit(imm8);
2134 }
2135 void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) {
2136 XMMRegister isrc = XMMRegister::from_code(src2.code());
2137 vinstr(0x20, dst, src1, isrc, k66, k0F3A, kW0);
2138 emit(imm8);
2139 }
2140 void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) {
2141 vinstr(0x20, dst, src1, src2, k66, k0F3A, kW0);
2142 emit(imm8);
2143 }
2144 void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) {
2145 XMMRegister isrc = XMMRegister::from_code(src2.code());
2146 vinstr(0xc4, dst, src1, isrc, k66, k0F, kW0);
2147 emit(imm8);
2148 }
2149 void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) {
2150 vinstr(0xc4, dst, src1, src2, k66, k0F, kW0);
2151 emit(imm8);
2152 }
2153 void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) {
2154 XMMRegister isrc = XMMRegister::from_code(src2.code());
2155 vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW0);
2156 emit(imm8);
2157 }
2158 void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) {
2159 vinstr(0x22, dst, src1, src2, k66, k0F3A, kW0);
2160 emit(imm8);
2161 }
2162 void vpinsrq(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8) {
2163 XMMRegister isrc = XMMRegister::from_code(src2.code());
2164 vinstr(0x22, dst, src1, isrc, k66, k0F3A, kW1);
2165 emit(imm8);
2166 }
2167 void vpinsrq(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) {
2168 vinstr(0x22, dst, src1, src2, k66, k0F3A, kW1);
2169 emit(imm8);
2170 }
2171
2172 void vpshufd(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2173 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
2174 emit(imm8);
2175 }
2176 void vpshufd(YMMRegister dst, YMMRegister src, uint8_t imm8) {
2177 vinstr(0x70, dst, ymm0, src, k66, k0F, kWIG);
2178 emit(imm8);
2179 }
2180 void vpshufd(XMMRegister dst, Operand src, uint8_t imm8) {
2181 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
2182 emit(imm8);
2183 }
2184 void vpshufd(YMMRegister dst, Operand src, uint8_t imm8) {
2185 vinstr(0x70, dst, ymm0, src, k66, k0F, kWIG);
2186 emit(imm8);
2187 }
2188 void vpshuflw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2189 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG);
2190 emit(imm8);
2191 }
2192 void vpshuflw(YMMRegister dst, YMMRegister src, uint8_t imm8) {
2193 vinstr(0x70, dst, ymm0, src, kF2, k0F, kWIG);
2194 emit(imm8);
2195 }
2196 void vpshuflw(XMMRegister dst, Operand src, uint8_t imm8) {
2197 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG);
2198 emit(imm8);
2199 }
2200 void vpshuflw(YMMRegister dst, Operand src, uint8_t imm8) {
2201 vinstr(0x70, dst, ymm0, src, kF2, k0F, kWIG);
2202 emit(imm8);
2203 }
2204 void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2205 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG);
2206 emit(imm8);
2207 }
2208 void vpshufhw(YMMRegister dst, YMMRegister src, uint8_t imm8) {
2209 vinstr(0x70, dst, ymm0, src, kF3, k0F, kWIG);
2210 emit(imm8);
2211 }
2212 void vpshufhw(XMMRegister dst, Operand src, uint8_t imm8) {
2213 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG);
2214 emit(imm8);
2215 }
2216 void vpshufhw(YMMRegister dst, Operand src, uint8_t imm8) {
2217 vinstr(0x70, dst, ymm0, src, kF3, k0F, kWIG);
2218 emit(imm8);
2219 }
2220
2222 uint8_t mask) {
2223 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
2224 emit(mask);
2225 }
2227 uint8_t mask) {
2228 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
2229 emit(mask);
2230 }
2231 void vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask) {
2232 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
2233 emit(mask);
2234 }
2235 void vpblendw(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t mask) {
2236 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
2237 emit(mask);
2238 }
2239
2241 uint8_t imm8) {
2242 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
2243 emit(imm8);
2244 }
2246 uint8_t imm8) {
2247 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
2248 emit(imm8);
2249 }
2250 void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8) {
2251 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
2252 emit(imm8);
2253 }
2254 void vpalignr(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t imm8) {
2255 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
2256 emit(imm8);
2257 }
2258
2259 void vps(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
2260 void vps(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2);
2261 void vps(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2);
2262 void vps(uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2);
2263 void vps(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
2264 uint8_t imm8);
2265 void vps(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2,
2266 uint8_t imm8);
2267 void vpd(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
2268 void vpd(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2);
2269 void vpd(uint8_t op, XMMRegister dst, YMMRegister src1, YMMRegister src2);
2270 void vpd(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2);
2271 void vpd(uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2);
2272 void vpd(uint8_t op, XMMRegister dst, YMMRegister src1, Operand src2);
2273
2274 // AVX2 instructions
2275#define AVX2_INSTRUCTION(instr, prefix, escape1, escape2, opcode) \
2276 template <typename Reg, typename Op> \
2277 void instr(Reg dst, Op src) { \
2278 vinstr(0x##opcode, dst, xmm0, src, k##prefix, k##escape1##escape2, kW0, \
2279 AVX2); \
2280 }
2282#undef AVX2_INSTRUCTION
2283
2284 // F16C Instructions.
2287 void vcvtps2ph(XMMRegister dst, XMMRegister src, uint8_t imm8);
2288 void vcvtps2ph(XMMRegister dst, YMMRegister src, uint8_t imm8);
2289
2290 // AVX-VNNI instruction
2292 vinstr(0x50, dst, src1, src2, k66, k0F38, kW0, AVX_VNNI);
2293 }
2295 vinstr(0x50, dst, src1, src2, k66, k0F38, kW0, AVX_VNNI);
2296 }
2297
2298 // AVX-VNNI-INT8 instruction
2300 vinstr(0x50, dst, src1, src2, kF2, k0F38, kW0, AVX_VNNI_INT8);
2301 }
2303 vinstr(0x50, dst, src1, src2, kF2, k0F38, kW0, AVX_VNNI_INT8);
2304 }
2305
2306 // BMI instruction
2307 void andnq(Register dst, Register src1, Register src2) {
2308 bmi1q(0xf2, dst, src1, src2);
2309 }
2310 void andnq(Register dst, Register src1, Operand src2) {
2311 bmi1q(0xf2, dst, src1, src2);
2312 }
2313 void andnl(Register dst, Register src1, Register src2) {
2314 bmi1l(0xf2, dst, src1, src2);
2315 }
2316 void andnl(Register dst, Register src1, Operand src2) {
2317 bmi1l(0xf2, dst, src1, src2);
2318 }
2319 void bextrq(Register dst, Register src1, Register src2) {
2320 bmi1q(0xf7, dst, src2, src1);
2321 }
2322 void bextrq(Register dst, Operand src1, Register src2) {
2323 bmi1q(0xf7, dst, src2, src1);
2324 }
2325 void bextrl(Register dst, Register src1, Register src2) {
2326 bmi1l(0xf7, dst, src2, src1);
2327 }
2328 void bextrl(Register dst, Operand src1, Register src2) {
2329 bmi1l(0xf7, dst, src2, src1);
2330 }
2331 void blsiq(Register dst, Register src) { bmi1q(0xf3, rbx, dst, src); }
2332 void blsiq(Register dst, Operand src) { bmi1q(0xf3, rbx, dst, src); }
2333 void blsil(Register dst, Register src) { bmi1l(0xf3, rbx, dst, src); }
2334 void blsil(Register dst, Operand src) { bmi1l(0xf3, rbx, dst, src); }
2335 void blsmskq(Register dst, Register src) { bmi1q(0xf3, rdx, dst, src); }
2336 void blsmskq(Register dst, Operand src) { bmi1q(0xf3, rdx, dst, src); }
2337 void blsmskl(Register dst, Register src) { bmi1l(0xf3, rdx, dst, src); }
2338 void blsmskl(Register dst, Operand src) { bmi1l(0xf3, rdx, dst, src); }
2339 void blsrq(Register dst, Register src) { bmi1q(0xf3, rcx, dst, src); }
2340 void blsrq(Register dst, Operand src) { bmi1q(0xf3, rcx, dst, src); }
2341 void blsrl(Register dst, Register src) { bmi1l(0xf3, rcx, dst, src); }
2342 void blsrl(Register dst, Operand src) { bmi1l(0xf3, rcx, dst, src); }
2343 void tzcntq(Register dst, Register src);
2344 void tzcntq(Register dst, Operand src);
2345 void tzcntl(Register dst, Register src);
2346 void tzcntl(Register dst, Operand src);
2347
2348 void lzcntq(Register dst, Register src);
2349 void lzcntq(Register dst, Operand src);
2350 void lzcntl(Register dst, Register src);
2351 void lzcntl(Register dst, Operand src);
2352
2353 void popcntq(Register dst, Register src);
2354 void popcntq(Register dst, Operand src);
2355 void popcntl(Register dst, Register src);
2356 void popcntl(Register dst, Operand src);
2357
2358 void bzhiq(Register dst, Register src1, Register src2) {
2359 bmi2q(kNoPrefix, 0xf5, dst, src2, src1);
2360 }
2361 void bzhiq(Register dst, Operand src1, Register src2) {
2362 bmi2q(kNoPrefix, 0xf5, dst, src2, src1);
2363 }
2364 void bzhil(Register dst, Register src1, Register src2) {
2365 bmi2l(kNoPrefix, 0xf5, dst, src2, src1);
2366 }
2367 void bzhil(Register dst, Operand src1, Register src2) {
2368 bmi2l(kNoPrefix, 0xf5, dst, src2, src1);
2369 }
2370 void mulxq(Register dst1, Register dst2, Register src) {
2371 bmi2q(kF2, 0xf6, dst1, dst2, src);
2372 }
2373 void mulxq(Register dst1, Register dst2, Operand src) {
2374 bmi2q(kF2, 0xf6, dst1, dst2, src);
2375 }
2376 void mulxl(Register dst1, Register dst2, Register src) {
2377 bmi2l(kF2, 0xf6, dst1, dst2, src);
2378 }
2379 void mulxl(Register dst1, Register dst2, Operand src) {
2380 bmi2l(kF2, 0xf6, dst1, dst2, src);
2381 }
2382 void pdepq(Register dst, Register src1, Register src2) {
2383 bmi2q(kF2, 0xf5, dst, src1, src2);
2384 }
2385 void pdepq(Register dst, Register src1, Operand src2) {
2386 bmi2q(kF2, 0xf5, dst, src1, src2);
2387 }
2388 void pdepl(Register dst, Register src1, Register src2) {
2389 bmi2l(kF2, 0xf5, dst, src1, src2);
2390 }
2391 void pdepl(Register dst, Register src1, Operand src2) {
2392 bmi2l(kF2, 0xf5, dst, src1, src2);
2393 }
2394 void pextq(Register dst, Register src1, Register src2) {
2395 bmi2q(kF3, 0xf5, dst, src1, src2);
2396 }
2397 void pextq(Register dst, Register src1, Operand src2) {
2398 bmi2q(kF3, 0xf5, dst, src1, src2);
2399 }
2400 void pextl(Register dst, Register src1, Register src2) {
2401 bmi2l(kF3, 0xf5, dst, src1, src2);
2402 }
2403 void pextl(Register dst, Register src1, Operand src2) {
2404 bmi2l(kF3, 0xf5, dst, src1, src2);
2405 }
2406 void sarxq(Register dst, Register src1, Register src2) {
2407 bmi2q(kF3, 0xf7, dst, src2, src1);
2408 }
2409 void sarxq(Register dst, Operand src1, Register src2) {
2410 bmi2q(kF3, 0xf7, dst, src2, src1);
2411 }
2412 void sarxl(Register dst, Register src1, Register src2) {
2413 bmi2l(kF3, 0xf7, dst, src2, src1);
2414 }
2415 void sarxl(Register dst, Operand src1, Register src2) {
2416 bmi2l(kF3, 0xf7, dst, src2, src1);
2417 }
2418 void shlxq(Register dst, Register src1, Register src2) {
2419 bmi2q(k66, 0xf7, dst, src2, src1);
2420 }
2421 void shlxq(Register dst, Operand src1, Register src2) {
2422 bmi2q(k66, 0xf7, dst, src2, src1);
2423 }
2424 void shlxl(Register dst, Register src1, Register src2) {
2425 bmi2l(k66, 0xf7, dst, src2, src1);
2426 }
2427 void shlxl(Register dst, Operand src1, Register src2) {
2428 bmi2l(k66, 0xf7, dst, src2, src1);
2429 }
2430 void shrxq(Register dst, Register src1, Register src2) {
2431 bmi2q(kF2, 0xf7, dst, src2, src1);
2432 }
2433 void shrxq(Register dst, Operand src1, Register src2) {
2434 bmi2q(kF2, 0xf7, dst, src2, src1);
2435 }
2436 void shrxl(Register dst, Register src1, Register src2) {
2437 bmi2l(kF2, 0xf7, dst, src2, src1);
2438 }
2439 void shrxl(Register dst, Operand src1, Register src2) {
2440 bmi2l(kF2, 0xf7, dst, src2, src1);
2441 }
2442 void rorxq(Register dst, Register src, uint8_t imm8);
2443 void rorxq(Register dst, Operand src, uint8_t imm8);
2444 void rorxl(Register dst, Register src, uint8_t imm8);
2445 void rorxl(Register dst, Operand src, uint8_t imm8);
2446
2447 void mfence();
2448 void lfence();
2449 void pause();
2450
2451 // Check the code size generated from label to here.
2453 return pc_offset() - label->pos();
2454 }
2455
2456 // Record a deoptimization reason that can be used by a log or cpu profiler.
2457 // Use --trace-deopt to enable.
2458 void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id,
2459 SourcePosition position, int id);
2460
2461 // Writes a single word of data in the code stream.
2462 // Used for inline tables, e.g., jump-tables.
2463 void db(uint8_t data);
2464 void dd(uint32_t data);
2465 void dq(uint64_t data);
2466 void dp(uintptr_t data) { dq(data); }
2468
2470
2471 // Patch entries for partial constant pool.
2473
2474 // Check if use partial constant pool for this rmode.
2476
2477 // Check if there is less than kGap bytes available in the buffer.
2478 // If this is the case, we need to grow the buffer before emitting
2479 // an instruction or relocation information.
2480 bool buffer_overflow() const { return available_space() < kGap; }
2481
2482 // Get the number of bytes available in the buffer.
2483 int available_space() const {
2484 DCHECK_GE(reloc_info_writer.pos(), pc_);
2485 DCHECK_GE(kMaxInt, reloc_info_writer.pos() - pc_);
2486 return static_cast<int>(reloc_info_writer.pos() - pc_);
2487 }
2488
2489 static bool IsNop(Address addr);
2490 static bool IsJmpRel(Address addr);
2491
2492 // Avoid overflows for displacements etc.
2493 static constexpr int kMaximalBufferSize = 512 * MB;
2494
2495 uint8_t byte_at(int pos) { return buffer_start_[pos]; }
2496 void set_byte_at(int pos, uint8_t value) { buffer_start_[pos] = value; }
2497
2498#if defined(V8_OS_WIN_X64)
2499 win64_unwindinfo::BuiltinUnwindInfo GetUnwindInfo() const;
2500#endif
2501
2502 protected:
2503 // Call near indirect
2504 void call(Operand operand);
2505
2506 private:
2507 Address addr_at(int pos) {
2508 DCHECK_GE(pos, 0);
2510 return reinterpret_cast<Address>(buffer_start_ + pos);
2511 }
2512 uint32_t long_at(int pos) {
2513 return ReadUnalignedValue<uint32_t>(addr_at(pos));
2514 }
2515 void long_at_put(int pos, uint32_t x) {
2516 WriteUnalignedValue(addr_at(pos), x);
2517 }
2518
2519 // InstructionStream emission.
2521
2522 template <typename T>
2523 static uint8_t* emit(uint8_t* __restrict pc, T t) {
2524 WriteUnalignedValue(reinterpret_cast<Address>(pc), t);
2525 return pc + sizeof(T);
2526 }
2527
2528 void emit(uint8_t x) { pc_ = emit(pc_, x); }
2529 void emitw(uint16_t x) { pc_ = emit(pc_, x); }
2530 void emitl(uint32_t x) { pc_ = emit(pc_, x); }
2531 void emitq(uint64_t x) { pc_ = emit(pc_, x); }
2532
2534 if (!RelocInfo::IsNoInfo(x.rmode_)) RecordRelocInfo(x.rmode_);
2535 emitl(x.value_);
2536 }
2537
2539 if (!RelocInfo::IsNoInfo(x.rmode_)) RecordRelocInfo(x.rmode_);
2540 emitq(static_cast<uint64_t>(x.value_));
2541 }
2542
2543 // Emits a REX prefix that encodes a 64-bit operand size and
2544 // the top bit of both register codes.
2545 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2546 // REX.W is set.
2547 inline void emit_rex_64(XMMRegister reg, Register rm_reg);
2548 inline void emit_rex_64(Register reg, XMMRegister rm_reg);
2549 inline void emit_rex_64(Register reg, Register rm_reg);
2550 inline void emit_rex_64(XMMRegister reg, XMMRegister rm_reg);
2551
2552 // Emits a REX prefix that encodes a 64-bit operand size and
2553 // the top bit of the destination, index, and base register codes.
2554 // The high bit of reg is used for REX.R, the high bit of op's base
2555 // register is used for REX.B, and the high bit of op's index register
2556 // is used for REX.X. REX.W is set.
2557 inline void emit_rex_64(Register reg, Operand op);
2558 inline void emit_rex_64(XMMRegister reg, Operand op);
2559
2560 // Emits a REX prefix that encodes a 64-bit operand size and
2561 // the top bit of the register code.
2562 // The high bit of register is used for REX.B.
2563 // REX.W is set and REX.R and REX.X are clear.
2564 inline void emit_rex_64(Register rm_reg);
2565
2566 // Emits a REX prefix that encodes a 64-bit operand size and
2567 // the top bit of the index and base register codes.
2568 // The high bit of op's base register is used for REX.B, and the high
2569 // bit of op's index register is used for REX.X.
2570 // REX.W is set and REX.R clear.
2571 inline void emit_rex_64(Operand op);
2572
2573 // Emit a REX prefix that only sets REX.W to choose a 64-bit operand size.
2574 void emit_rex_64() { emit(0x48); }
2575
2576 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2577 // REX.W is clear.
2578 inline void emit_rex_32(Register reg, Register rm_reg);
2579
2580 // The high bit of reg is used for REX.R, the high bit of op's base
2581 // register is used for REX.B, and the high bit of op's index register
2582 // is used for REX.X. REX.W is cleared.
2583 inline void emit_rex_32(Register reg, Operand op);
2584
2585 // High bit of rm_reg goes to REX.B.
2586 // REX.W, REX.R and REX.X are clear.
2587 inline void emit_rex_32(Register rm_reg);
2588
2589 // High bit of base goes to REX.B and high bit of index to REX.X.
2590 // REX.W and REX.R are clear.
2591 inline void emit_rex_32(Operand op);
2592
2593 // High bit of reg goes to REX.R, high bit of rm_reg goes to REX.B.
2594 // REX.W is cleared. If no REX bits are set, no byte is emitted.
2595 inline void emit_optional_rex_32(Register reg, Register rm_reg);
2596
2597 // The high bit of reg is used for REX.R, the high bit of op's base
2598 // register is used for REX.B, and the high bit of op's index register
2599 // is used for REX.X. REX.W is cleared. If no REX bits are set, nothing
2600 // is emitted.
2601 inline void emit_optional_rex_32(Register reg, Operand op);
2602
2603 // As for emit_optional_rex_32(Register, Register), except that
2604 // the registers are XMM registers.
2605 inline void emit_optional_rex_32(XMMRegister reg, XMMRegister base);
2606
2607 // As for emit_optional_rex_32(Register, Register), except that
2608 // one of the registers is an XMM registers.
2609 inline void emit_optional_rex_32(XMMRegister reg, Register base);
2610
2611 // As for emit_optional_rex_32(Register, Register), except that
2612 // one of the registers is an XMM registers.
2613 inline void emit_optional_rex_32(Register reg, XMMRegister base);
2614
2615 // As for emit_optional_rex_32(Register, Operand), except that
2616 // the register is an XMM register.
2617 inline void emit_optional_rex_32(XMMRegister reg, Operand op);
2618
2619 // Optionally do as emit_rex_32(Register) if the register number has
2620 // the high bit set.
2621 inline void emit_optional_rex_32(Register rm_reg);
2622 inline void emit_optional_rex_32(XMMRegister rm_reg);
2623
2624 // Optionally do as emit_rex_32(Operand) if the operand register
2625 // numbers have a high bit set.
2626 inline void emit_optional_rex_32(Operand op);
2627
2628 // Calls emit_rex_32(Register) for all non-byte registers.
2629 inline void emit_optional_rex_8(Register reg);
2630
2631 // Calls emit_rex_32(Register, Operand) for all non-byte registers, and
2632 // emit_optional_rex_32(Register, Operand) for byte registers.
2633 inline void emit_optional_rex_8(Register reg, Operand op);
2634
2635 void emit_rex(int size) {
2636 if (size == kInt64Size) {
2637 emit_rex_64();
2638 } else {
2639 DCHECK_EQ(size, kInt32Size);
2640 }
2641 }
2642
2643 template <class P1>
2644 void emit_rex(P1 p1, int size) {
2645 if (size == kInt64Size) {
2646 emit_rex_64(p1);
2647 } else {
2648 DCHECK_EQ(size, kInt32Size);
2649 emit_optional_rex_32(p1);
2650 }
2651 }
2652
2653 template <class P1, class P2>
2654 void emit_rex(P1 p1, P2 p2, int size) {
2655 if (size == kInt64Size) {
2656 emit_rex_64(p1, p2);
2657 } else {
2658 DCHECK_EQ(size, kInt32Size);
2659 emit_optional_rex_32(p1, p2);
2660 }
2661 }
2662
2663 // Emit vex prefix
2664 void emit_vex2_byte0() { emit(0xc5); }
2665 inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
2666 SIMDPrefix pp);
2667 void emit_vex3_byte0() { emit(0xc4); }
2668 inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
2669 inline void emit_vex3_byte1(XMMRegister reg, Operand rm, LeadingOpcode m);
2670 inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
2671 SIMDPrefix pp);
2672 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
2673 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2674 VexW w);
2675 inline void emit_vex_prefix(Register reg, Register v, Register rm,
2676 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2677 VexW w);
2678 inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, Operand rm,
2679 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2680 VexW w);
2681 inline void emit_vex_prefix(Register reg, Register v, Operand rm,
2682 VectorLength l, SIMDPrefix pp, LeadingOpcode m,
2683 VexW w);
2684
2685 // Emit the ModR/M byte, and optionally the SIB byte and
2686 // 1- or 4-byte offset for a memory operand. Also encodes
2687 // the second operand of the operation, a register or operation
2688 // subcode, into the reg field of the ModR/M byte.
2690 emit_operand(reg.low_bits(), adr);
2691 }
2692
2693 // Emit the ModR/M byte, and optionally the SIB byte and
2694 // 1- or 4-byte offset for a memory operand.
2695 // Also used to encode a three-bit opcode extension into the ModR/M byte.
2696 void emit_operand(int rm, Operand adr);
2697
2698 // Emit a RIP-relative operand.
2699 // Also used to encode a three-bit opcode extension into the ModR/M byte.
2700 V8_NOINLINE void emit_label_operand(int rm, Label* label, int addend = 0);
2701
2702 // Emit a ModR/M byte with registers coded in the reg and rm_reg fields.
2704 emit(0xC0 | reg.low_bits() << 3 | rm_reg.low_bits());
2705 }
2706
2707 // Emit a ModR/M byte with an operation subcode in the reg field and
2708 // a register in the rm_reg field.
2709 void emit_modrm(int code, Register rm_reg) {
2710 DCHECK(is_uint3(code));
2711 emit(0xC0 | code << 3 | rm_reg.low_bits());
2712 }
2713
2714 // Emit the code-object-relative offset of the label's position
2716
2717 // The first argument is the reg field, the second argument is the r/m field.
2724
2725 // Emit machine code for one of the operations ADD, ADC, SUB, SBC,
2726 // AND, OR, XOR, or CMP. The encodings of these operations are all
2727 // similar, differing just in the opcode or in the reg field of the
2728 // ModR/M byte.
2729 void arithmetic_op_8(uint8_t opcode, Register reg, Register rm_reg);
2730 void arithmetic_op_8(uint8_t opcode, Register reg, Operand rm_reg);
2731 void arithmetic_op_16(uint8_t opcode, Register reg, Register rm_reg);
2732 void arithmetic_op_16(uint8_t opcode, Register reg, Operand rm_reg);
2733 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
2734 void arithmetic_op(uint8_t opcode, Register reg, Register rm_reg, int size);
2735 void arithmetic_op(uint8_t opcode, Register reg, Operand rm_reg, int size);
2736 // Operate on a byte in memory or register.
2737 void immediate_arithmetic_op_8(uint8_t subcode, Register dst, Immediate src);
2738 void immediate_arithmetic_op_8(uint8_t subcode, Operand dst, Immediate src);
2739 // Operate on a word in memory or register.
2740 void immediate_arithmetic_op_16(uint8_t subcode, Register dst, Immediate src);
2741 void immediate_arithmetic_op_16(uint8_t subcode, Operand dst, Immediate src);
2742 // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
2743 void immediate_arithmetic_op(uint8_t subcode, Register dst, Immediate src,
2744 int size);
2745 void immediate_arithmetic_op(uint8_t subcode, Operand dst, Immediate src,
2746 int size);
2747
2748 // Emit machine code for a shift operation.
2749 void shift(Operand dst, Immediate shift_amount, int subcode, int size);
2750 void shift(Register dst, Immediate shift_amount, int subcode, int size);
2751 // Shift dst by cl % 64 bits.
2752 void shift(Register dst, int subcode, int size);
2753 void shift(Operand dst, int subcode, int size);
2754
2755 void emit_farith(int b1, int b2, int i);
2756
2757 // labels
2758 // void print(Label* L);
2759 void bind_to(Label* L, int pos);
2760
2761 // record reloc info for current pc_
2762 void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
2763
2764 // Arithmetics
2765 void emit_add(Register dst, Register src, int size) {
2766 arithmetic_op(0x03, dst, src, size);
2767 }
2768
2769 void emit_add(Register dst, Immediate src, int size) {
2770 immediate_arithmetic_op(0x0, dst, src, size);
2771 }
2772
2773 void emit_add(Register dst, Operand src, int size) {
2774 arithmetic_op(0x03, dst, src, size);
2775 }
2776
2777 void emit_add(Operand dst, Register src, int size) {
2778 arithmetic_op(0x1, src, dst, size);
2779 }
2780
2781 void emit_add(Operand dst, Immediate src, int size) {
2782 immediate_arithmetic_op(0x0, dst, src, size);
2783 }
2784
2785 void emit_and(Register dst, Register src, int size) {
2786 arithmetic_op(0x23, dst, src, size);
2787 }
2788
2789 void emit_and(Register dst, Operand src, int size) {
2790 arithmetic_op(0x23, dst, src, size);
2791 }
2792
2793 void emit_and(Operand dst, Register src, int size) {
2794 arithmetic_op(0x21, src, dst, size);
2795 }
2796
2797 void emit_and(Register dst, Immediate src, int size) {
2798 immediate_arithmetic_op(0x4, dst, src, size);
2799 }
2800
2801 void emit_and(Operand dst, Immediate src, int size) {
2802 immediate_arithmetic_op(0x4, dst, src, size);
2803 }
2804
2805 void emit_cmp(Register dst, Register src, int size) {
2806 arithmetic_op(0x3B, dst, src, size);
2807 }
2808
2809 // Used for JCC erratum performance mitigation.
2810 void emit_aligned_cmp(Register dst, Register src, int size) {
2811 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2812 // /* cmp */ 3 + /* jcc */ 6
2813 const int kMaxMacroFusionLength = 9;
2814 AlignForJCCErratum(kMaxMacroFusionLength);
2815 emit_cmp(dst, src, size);
2816 }
2817
2818 void emit_cmp(Register dst, Operand src, int size) {
2819 arithmetic_op(0x3B, dst, src, size);
2820 }
2821
2822 // Used for JCC erratum performance mitigation.
2823 void emit_aligned_cmp(Register dst, Operand src, int size) {
2824 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2825 // /* cmp */ 8 + /* jcc */ 6
2826 const int kMaxMacroFusionLength = 14;
2827 AlignForJCCErratum(kMaxMacroFusionLength);
2828 emit_cmp(dst, src, size);
2829 }
2830
2831 void emit_cmp(Operand dst, Register src, int size) {
2832 arithmetic_op(0x39, src, dst, size);
2833 }
2834
2835 // Used for JCC erratum performance mitigation.
2836 void emit_aligned_cmp(Operand dst, Register src, int size) {
2837 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2838 // /* cmp */ 8 + /* jcc */ 6
2839 const int kMaxMacroFusionLength = 14;
2840 AlignForJCCErratum(kMaxMacroFusionLength);
2841 emit_cmp(dst, src, size);
2842 }
2843
2844 void emit_cmp(Register dst, Immediate src, int size) {
2845 immediate_arithmetic_op(0x7, dst, src, size);
2846 }
2847
2848 // Used for JCC erratum performance mitigation.
2849 void emit_aligned_cmp(Register dst, Immediate src, int size) {
2850 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2851 // /* cmpl */ 7 + /* jcc */ 6
2852 // /* cmpq */ 11 + /* jcc */ 6
2853 const int kMaxMacroFusionLength = 9 + size;
2854 AlignForJCCErratum(kMaxMacroFusionLength);
2855 emit_cmp(dst, src, size);
2856 }
2857
2858 void emit_cmp(Operand dst, Immediate src, int size) {
2859 immediate_arithmetic_op(0x7, dst, src, size);
2860 }
2861
2862 // Used for JCC erratum performance mitigation.
2863 void emit_aligned_cmp(Operand dst, Immediate src, int size) {
2864 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2865 // cmp can not be fused when comparing MEM-IMM, so we would not align this
2866 // instruction.
2867 emit_cmp(dst, src, size);
2868 }
2869
2870 // Compare {al,ax,eax,rax} with src. If equal, set ZF and write dst into
2871 // src. Otherwise clear ZF and write src into {al,ax,eax,rax}. This
2872 // operation is only atomic if prefixed by the lock instruction.
2873 void emit_cmpxchg(Operand dst, Register src, int size);
2874
2875 void emit_dec(Register dst, int size);
2876 void emit_dec(Operand dst, int size);
2877
2878 // Divide rdx:rax by src. Quotient in rax, remainder in rdx when size is 64.
2879 // Divide edx:eax by lower 32 bits of src. Quotient in eax, remainder in edx
2880 // when size is 32.
2881 void emit_idiv(Register src, int size);
2882 void emit_div(Register src, int size);
2883
2884 // Signed multiply instructions.
2885 // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
2886 void emit_imul(Register src, int size);
2887 void emit_imul(Operand src, int size);
2888 void emit_imul(Register dst, Register src, int size);
2889 void emit_imul(Register dst, Operand src, int size);
2890 void emit_imul(Register dst, Register src, Immediate imm, int size);
2891 void emit_imul(Register dst, Operand src, Immediate imm, int size);
2892
2893 void emit_inc(Register dst, int size);
2894 void emit_inc(Operand dst, int size);
2895
2896 void emit_lea(Register dst, Operand src, int size);
2897
2898 void emit_mov(Register dst, Operand src, int size);
2899 void emit_mov(Register dst, Register src, int size);
2900 void emit_mov(Operand dst, Register src, int size);
2901 void emit_mov(Register dst, Immediate value, int size);
2902 void emit_mov(Operand dst, Immediate value, int size);
2903 void emit_mov(Register dst, Immediate64 value, int size);
2904
2905 void emit_movzxb(Register dst, Operand src, int size);
2906 void emit_movzxb(Register dst, Register src, int size);
2907 void emit_movzxw(Register dst, Operand src, int size);
2908 void emit_movzxw(Register dst, Register src, int size);
2909
2910 void emit_neg(Register dst, int size);
2911 void emit_neg(Operand dst, int size);
2912
2913 void emit_not(Register dst, int size);
2914 void emit_not(Operand dst, int size);
2915
2916 void emit_or(Register dst, Register src, int size) {
2917 arithmetic_op(0x0B, dst, src, size);
2918 }
2919
2920 void emit_or(Register dst, Operand src, int size) {
2921 arithmetic_op(0x0B, dst, src, size);
2922 }
2923
2924 void emit_or(Operand dst, Register src, int size) {
2925 arithmetic_op(0x9, src, dst, size);
2926 }
2927
2928 void emit_or(Register dst, Immediate src, int size) {
2929 immediate_arithmetic_op(0x1, dst, src, size);
2930 }
2931
2932 void emit_or(Operand dst, Immediate src, int size) {
2933 immediate_arithmetic_op(0x1, dst, src, size);
2934 }
2935
2936 void emit_repmovs(int size);
2937
2938 void emit_sbb(Register dst, Register src, int size) {
2939 arithmetic_op(0x1b, dst, src, size);
2940 }
2941
2942 void emit_sub(Register dst, Register src, int size) {
2943 arithmetic_op(0x2B, dst, src, size);
2944 }
2945
2946 void emit_sub(Register dst, Immediate src, int size) {
2947 immediate_arithmetic_op(0x5, dst, src, size);
2948 }
2949
2950 void emit_sub(Register dst, Operand src, int size) {
2951 arithmetic_op(0x2B, dst, src, size);
2952 }
2953
2954 void emit_sub(Operand dst, Register src, int size) {
2955 arithmetic_op(0x29, src, dst, size);
2956 }
2957
2958 void emit_sub(Operand dst, Immediate src, int size) {
2959 immediate_arithmetic_op(0x5, dst, src, size);
2960 }
2961
2962 void emit_test(Register dst, Register src, int size);
2963 // Used for JCC erratum performance mitigation.
2964 void emit_aligned_test(Register dst, Register src, int size) {
2965 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2966 // /* test */ 3 + /* jcc */ 6
2967 const int kMaxMacroFusionLength = 9;
2968 AlignForJCCErratum(kMaxMacroFusionLength);
2969 emit_test(dst, src, size);
2970 }
2971
2973 // Used for JCC erratum performance mitigation.
2975 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2976 // /* testl */ 7 + /* jcc */ 6
2977 // /* testq */ 11 + /* jcc */ 6
2978 const int kMaxMacroFusionLength = 9 + size;
2979 AlignForJCCErratum(kMaxMacroFusionLength);
2980 emit_test(reg, mask, size);
2981 }
2982
2983 void emit_test(Operand op, Register reg, int size);
2984 // Used for JCC erratum performance mitigation.
2986 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2987 // /* test */ 8 + /* jcc */ 6
2988 const int kMaxMacroFusionLength = 14;
2989 AlignForJCCErratum(kMaxMacroFusionLength);
2990 emit_test(op, reg, size);
2991 }
2992
2993 void emit_test(Operand op, Immediate mask, int size);
2994 // Used for JCC erratum performance mitigation.
2996 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
2997 // test can not be fused when comparing MEM-IMM, so we would not align this
2998 // instruction.
2999 emit_test(op, mask, size);
3000 }
3001
3002 void emit_test(Register reg, Operand op, int size) {
3003 return emit_test(op, reg, size);
3004 }
3005
3006 // Used for JCC erratum performance mitigation.
3008 return emit_aligned_test(op, reg, size);
3009 }
3010
3011 void emit_xchg(Register dst, Register src, int size);
3012 void emit_xchg(Register dst, Operand src, int size);
3013
3014 void emit_xor(Register dst, Register src, int size) {
3015 if (size == kInt64Size && dst.code() == src.code()) {
3016 // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
3017 // there is no need to make this a 64 bit operation.
3018 arithmetic_op(0x33, dst, src, kInt32Size);
3019 } else {
3020 arithmetic_op(0x33, dst, src, size);
3021 }
3022 }
3023
3024 void emit_xor(Register dst, Operand src, int size) {
3025 arithmetic_op(0x33, dst, src, size);
3026 }
3027
3028 void emit_xor(Register dst, Immediate src, int size) {
3029 immediate_arithmetic_op(0x6, dst, src, size);
3030 }
3031
3032 void emit_xor(Operand dst, Immediate src, int size) {
3033 immediate_arithmetic_op(0x6, dst, src, size);
3034 }
3035
3036 void emit_xor(Operand dst, Register src, int size) {
3037 arithmetic_op(0x31, src, dst, size);
3038 }
3039
3040 // Most BMI instructions are similar.
3041 void bmi1q(uint8_t op, Register reg, Register vreg, Register rm);
3042 void bmi1q(uint8_t op, Register reg, Register vreg, Operand rm);
3043 void bmi1l(uint8_t op, Register reg, Register vreg, Register rm);
3044 void bmi1l(uint8_t op, Register reg, Register vreg, Operand rm);
3045 void bmi2q(SIMDPrefix pp, uint8_t op, Register reg, Register vreg,
3046 Register rm);
3047 void bmi2q(SIMDPrefix pp, uint8_t op, Register reg, Register vreg,
3048 Operand rm);
3049 void bmi2l(SIMDPrefix pp, uint8_t op, Register reg, Register vreg,
3050 Register rm);
3051 void bmi2l(SIMDPrefix pp, uint8_t op, Register reg, Register vreg,
3052 Operand rm);
3053
3054 // record the position of jmp/jcc instruction
3056
3058
3060
3063
3064 void GetCode(LocalIsolate* isolate, CodeDesc* desc,
3065 int safepoint_table_offset, int handler_table_offset);
3066
3067 friend class EnsureSpace;
3069
3070 // code generation
3071 RelocInfoWriter reloc_info_writer;
3072
3073 // Internal reference positions, required for (potential) patching in
3074 // GrowBuffer(); contains only those internal references whose labels
3075 // are already bound.
3076 std::deque<int> internal_reference_positions_;
3077
3079
3080 friend class ConstPool;
3081
3083
3084#if defined(V8_OS_WIN_X64)
3085 std::unique_ptr<win64_unwindinfo::XdataEncoder> xdata_encoder_;
3086#endif
3087};
3088
3089extern template EXPORT_TEMPLATE_DECLARE(
3091 XMMRegister src1,
3092 XMMRegister src2,
3093 VectorLength l, SIMDPrefix pp,
3094 LeadingOpcode m, VexW w);
3095
3096extern template EXPORT_TEMPLATE_DECLARE(
3098 YMMRegister src1,
3099 YMMRegister src2,
3100 VectorLength l, SIMDPrefix pp,
3101 LeadingOpcode m, VexW w);
3102
3103extern template EXPORT_TEMPLATE_DECLARE(
3105 XMMRegister src1, Operand src2,
3106 VectorLength l, SIMDPrefix pp,
3107 LeadingOpcode m, VexW w);
3108
3109extern template EXPORT_TEMPLATE_DECLARE(
3111 YMMRegister src1, Operand src2,
3112 VectorLength l, SIMDPrefix pp,
3113 LeadingOpcode m, VexW w);
3114
3115extern template EXPORT_TEMPLATE_DECLARE(
3116 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3117 YMMRegister src1,
3118 YMMRegister src2, SIMDPrefix pp,
3119 LeadingOpcode m, VexW w,
3120 CpuFeature feature);
3121extern template EXPORT_TEMPLATE_DECLARE(
3122 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3123 XMMRegister src1,
3124 XMMRegister src2, SIMDPrefix pp,
3125 LeadingOpcode m, VexW w,
3126 CpuFeature feature);
3127extern template EXPORT_TEMPLATE_DECLARE(
3128 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3129 YMMRegister src1, Operand src2,
3130 SIMDPrefix pp, LeadingOpcode m,
3131 VexW w, CpuFeature feature);
3132extern template EXPORT_TEMPLATE_DECLARE(
3133 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3134 YMMRegister src1,
3135 XMMRegister src2, SIMDPrefix pp,
3136 LeadingOpcode m, VexW w,
3137 CpuFeature feature);
3138extern template EXPORT_TEMPLATE_DECLARE(
3139 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3140 XMMRegister src1, Operand src2,
3141 SIMDPrefix pp, LeadingOpcode m,
3142 VexW w, CpuFeature feature);
3143extern template EXPORT_TEMPLATE_DECLARE(
3144 V8_EXPORT_PRIVATE) void Assembler::vinstr(uint8_t op, YMMRegister dst,
3145 XMMRegister src1,
3146 YMMRegister src2, SIMDPrefix pp,
3147 LeadingOpcode m, VexW w,
3148 CpuFeature feature);
3149
3150// Helper class that ensures that there is enough space for generating
3151// instructions and relocation information. The constructor makes
3152// sure that there is enough space and (in debug mode) the destructor
3153// checks that we did not generate too much.
3155 public:
3156 explicit V8_INLINE EnsureSpace(Assembler* assembler) : assembler_(assembler) {
3157 if (V8_UNLIKELY(assembler_->buffer_overflow())) assembler_->GrowBuffer();
3158#ifdef DEBUG
3159 space_before_ = assembler_->available_space();
3160#endif
3161 }
3162
3163#ifdef DEBUG
3164 ~EnsureSpace() {
3165 int bytes_generated = space_before_ - assembler_->available_space();
3166 DCHECK(bytes_generated < assembler_->kGap);
3167 }
3168#endif
3169
3170 private:
3171 Assembler* const assembler_;
3172#ifdef DEBUG
3173 int space_before_;
3174#endif
3175};
3176
3177} // namespace internal
3178} // namespace v8
3179
3180#endif // V8_CODEGEN_X64_ASSEMBLER_X64_H_
#define AVX2_INSTRUCTION(instr, prefix, escape1, escape2, opcode)
#define SSE_CMP_P(instr, imm8)
#define AVX_CMP_P(instr, imm8)
#define FMA(instr, length, prefix, escape1, escape2, extension, opcode)
#define DECLARE_SSE34_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_SSE2_INSTRUCTION(instruction, prefix, escape, opcode)
#define DECLARE_SSSE3_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_SSE4_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_SSE4_PMOV_AVX2_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_FMA_YMM_INSTRUCTION(instr, prefix, escape1, escape2, extension, opcode)
#define DECLARE_SSE4_PMOV_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define AVX_3(instr, opcode, impl, SIMDRegister)
#define DECLARE_SSE2_SHIFT_IMM(instruction, prefix, escape, opcode, extension)
#define AVX_SSE_UNOP(instr, escape, opcode)
#define DECLARE_SSE2_PD_AVX_INSTRUCTION(instruction, prefix, escape, opcode)
#define DECLARE_SSE2_PI_AVX_INSTRUCTION(instruction, prefix, escape, opcode)
#define AVX_SCALAR(instr, prefix, escape, opcode)
#define DECLARE_SSE2_UNOP_AVX_YMM_INSTRUCTION( instruction, opcode, DSTRegister, SRCRegister, MemOperand)
#define DECLARE_SSE4_EXTRACT_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define AVX_SSE_BINOP(instr, escape, opcode)
#define AVX_SSE2_SHIFT_IMM(instr, prefix, escape, opcode, extension)
#define ASSEMBLER_INSTRUCTION_LIST(V)
#define DECLARE_SSE2_SHIFT_AVX_INSTRUCTION(instruction, prefix, escape, opcode)
#define DECLARE_SSE2_UNOP_AVX_INSTRUCTION(instruction, prefix, escape, opcode)
#define DECLARE_SSE_INSTRUCTION(instruction, escape, opcode)
#define DECLARE_SSSE3_UNOP_AVX_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)
#define DECLARE_SSE4_2_INSTRUCTION(instruction, prefix, escape1, escape2, opcode)
#define SHIFT_INSTRUCTION_LIST(V)
#define F(name, str)
#define T
interpreter::OperandScale scale
Definition builtins.cc:44
SourcePosition pos
void shrxl(Register dst, Register src1, Register src2)
void vss(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2)
void bind_to(Label *L, int pos)
void vpinsrq(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void emit_trace_instruction(Immediate markid)
void pinsrd(XMMRegister dst, Operand src, uint8_t imm8)
void cmpeqsd(XMMRegister dst, XMMRegister src)
void cmppd(XMMRegister dst, XMMRegister src, int8_t cmp)
void movdqu(XMMRegister dst, XMMRegister src)
void vpshuflw(YMMRegister dst, YMMRegister src, uint8_t imm8)
void emit_movzxb(Register dst, Operand src, int size)
void emit_neg(Operand dst, int size)
void palignr(XMMRegister dst, Operand src, uint8_t mask)
void vpblendvb(XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister mask)
Address addr_at(int pos)
void load_rax(Address value, RelocInfo::Mode rmode)
void blsmskq(Register dst, Register src)
void vroundss(XMMRegister dst, XMMRegister src1, Operand src2, RoundingMode mode)
void vmovupd(Operand dst, XMMRegister src)
void arithmetic_op_16(uint8_t opcode, Register reg, Operand rm_reg)
void store_rax(ExternalReference ref)
void vmovhps(Operand dst, XMMRegister src)
void GetCode(LocalIsolate *isolate, CodeDesc *desc)
void movb(Operand dst, Immediate imm)
void near_j(Condition cc, intptr_t disp, RelocInfo::Mode rmode)
void shrd(Register dst, Register src)
void vpblendw(YMMRegister dst, YMMRegister src1, YMMRegister src2, uint8_t mask)
void emit_sse_operand(XMMRegister dst, XMMRegister src)
void aligned_jmp(Label *L, Label::Distance distance=Label::kFar)
void vperm2f128(YMMRegister dst, YMMRegister src1, YMMRegister src2, uint8_t lane)
void bmi1q(uint8_t op, Register reg, Register vreg, Register rm)
void movsd(XMMRegister dst, Operand src)
void sse4_instr(XMMRegister dst, Register src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode, int8_t imm8)
void negl(Operand op)
void emit_imul(Register src, int size)
void Nop(int bytes=1)
void popcntl(Register dst, Operand src)
void movsxwq(Register dst, Register src)
void pinsrq(XMMRegister dst, Operand src, uint8_t imm8)
void cmpw(Register dst, Immediate src)
void vpermq(YMMRegister dst, YMMRegister src, uint8_t imm8)
void cmpb(Register dst, Register src)
void movapd(XMMRegister dst, XMMRegister src)
void bmi1l(uint8_t op, Register reg, Register vreg, Operand rm)
void vcmppd(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp)
void cvttss2si(Register dst, XMMRegister src)
void vmovapd(YMMRegister dst, YMMRegister src)
void cvtqsi2sd(XMMRegister dst, Operand src)
void emit_repmovs(int size)
void vmovd(XMMRegister dst, Operand src)
~Assembler() override=default
void emit_imul(Operand src, int size)
void vmovaps(YMMRegister dst, YMMRegister src)
void movb(Register dst, Immediate imm)
void pextl(Register dst, Register src1, Operand src2)
void emit_sse_operand(XMMRegister dst)
void arithmetic_op_8(uint8_t opcode, Register reg, Operand rm_reg)
void cvtlsi2sd(XMMRegister dst, Register src)
void emit_xor(Register dst, Immediate src, int size)
void bextrl(Register dst, Operand src1, Register src2)
void arithmetic_op(uint8_t opcode, Register reg, Operand rm_reg, int size)
void vmovlps(Operand dst, XMMRegister src)
void cmpxchgb(Operand dst, Register src)
void pextq(Register dst, Register src1, Register src2)
void movlhps(XMMRegister dst, XMMRegister src)
void pdepq(Register dst, Register src1, Register src2)
void bsrl(Register dst, Operand src)
void cmovl(Condition cc, Register dst, Operand src)
void ucomiss(XMMRegister dst, XMMRegister src)
void shlxl(Register dst, Register src1, Register src2)
void record_farjmp_position(Label *L, int pos)
void negw(Operand op)
void emit_sse_operand(Register reg, Operand adr)
void vpdpbusd(YMMRegister dst, YMMRegister src1, YMMRegister src2)
void vpblendvb(YMMRegister dst, YMMRegister src1, YMMRegister src2, YMMRegister mask)
void aligned_cmpb(Register dst, Operand src)
void vmovdqu(XMMRegister dst, XMMRegister src)
void movss(XMMRegister dst, Operand src)
void movupd(XMMRegister dst, Operand src)
void vmovss(XMMRegister dst, XMMRegister src1, XMMRegister src2)
void vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2, RoundingMode mode)
void emit_add(Register dst, Operand src, int size)
void vmovdqa(YMMRegister dst, Operand src)
void vmovshdup(XMMRegister dst, XMMRegister src)
void emit_idiv(Register src, int size)
void vblendvpd(XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister mask)
void vmovd(XMMRegister dst, Register src)
void vpshuflw(XMMRegister dst, Operand src, uint8_t imm8)
void near_call(Builtin buitin, RelocInfo::Mode rmode)
void vcvttsd2siq(Register dst, Operand src)
void roundss(XMMRegister dst, XMMRegister src, RoundingMode mode)
static bool IsJmpRel(Address addr)
void vpd(uint8_t op, XMMRegister dst, YMMRegister src1, YMMRegister src2)
void emit_sse_operand(XMMRegister dst, Register src)
void vps(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2)
void fld_d(Operand adr)
void vpshufhw(YMMRegister dst, YMMRegister src, uint8_t imm8)
void aligned_cmpw(Operand dst, Register src)
uint8_t byte_at(int pos)
void movss(Operand dst, XMMRegister src)
void vroundps(XMMRegister dst, XMMRegister src, RoundingMode mode)
void vmovq(XMMRegister dst, Register src)
void vcvtdq2pd(YMMRegister dst, XMMRegister src)
void vmovshdup(YMMRegister dst, YMMRegister src)
void jmp_rel(int offset)
void testw(Register reg, Immediate mask)
void movq(Register dst, XMMRegister src)
void vblendvpd(YMMRegister dst, YMMRegister src1, YMMRegister src2, YMMRegister mask)
void vcvtph2ps(YMMRegister dst, XMMRegister src)
void vpinsrq(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8)
void emit_inc(Register dst, int size)
void immediate_arithmetic_op(uint8_t subcode, Operand dst, Immediate src, int size)
void cmpb_al(Immediate src)
void vpshufd(XMMRegister dst, Operand src, uint8_t imm8)
void testb(Operand op, Register reg)
void blsiq(Register dst, Operand src)
void emit_movzxw(Register dst, Operand src, int size)
void vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void emit_mov(Register dst, Operand src, int size)
void vinstr(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2, SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature=AVX)
void shift(Register dst, int subcode, int size)
void emit_xor(Register dst, Register src, int size)
void fild_s(Operand adr)
void fstp_d(Operand adr)
Assembler(const MaybeAssemblerZone &, const AssemblerOptions &options, std::unique_ptr< AssemblerBuffer > buffer={})
void vpd(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2)
void palignr(XMMRegister dst, XMMRegister src, uint8_t mask)
void vmovups(XMMRegister dst, Operand src)
void cvtlsi2ss(XMMRegister dst, Register src)
void vps(uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2)
void immediate_arithmetic_op_8(uint8_t subcode, Register dst, Immediate src)
void decb(Register dst)
static int deserialization_special_target_size(Address instruction_payload)
void vcmpps(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp)
void vpinsrd(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8)
void bzhiq(Register dst, Register src1, Register src2)
void popcntq(Register dst, Operand src)
void pushq(Register src)
void emit_inc(Operand dst, int size)
void andnq(Register dst, Register src1, Operand src2)
void movmskps(Register dst, XMMRegister src)
void AllocateAndInstallRequestedHeapNumbers(LocalIsolate *isolate)
void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Register src2)
void vinstr(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2, SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature=AVX)
void mulxq(Register dst1, Register dst2, Register src)
void vmovdqa(XMMRegister dst, XMMRegister src)
void movb(Operand dst, Register src)
void shlxl(Register dst, Operand src1, Register src2)
void vmovdqu(YMMRegister dst, YMMRegister src)
void pushq(Operand src)
void aligned_testw(Register dst, Register src)
void vcmpps(YMMRegister dst, YMMRegister src1, YMMRegister src2, int8_t cmp)
void vmovlps(XMMRegister dst, XMMRegister src1, Operand src2)
void emit_code_relative_offset(Label *label)
void sse_instr(XMMRegister dst, XMMRegister src, uint8_t escape, uint8_t opcode)
void vmovsd(Operand dst, XMMRegister src)
void cmppd(XMMRegister dst, Operand src, int8_t cmp)
void emit_or(Register dst, Register src, int size)
void tzcntl(Register dst, Operand src)
void rorxq(Register dst, Register src, uint8_t imm8)
void popcntl(Register dst, Register src)
void testb(Register dst, Register src)
void pinsrd(XMMRegister dst, Register src, uint8_t imm8)
void vmovdqa(YMMRegister dst, YMMRegister src)
void bsrq(Register dst, Operand src)
void aligned_cmpw(Register dst, Immediate src)
void j(Condition cc, Address entry, RelocInfo::Mode rmode)
void set_byte_at(int pos, uint8_t value)
void vmovups(YMMRegister dst, Operand src)
void aligned_cmpw(Register dst, Register src)
void testw(Register reg, Operand op)
void aligned_cmpb(Operand dst, Register src)
static void deserialization_set_target_internal_reference_at(Address pc, Address target, WritableJitAllocation &jit_allocation, RelocInfo::Mode mode=RelocInfo::INTERNAL_REFERENCE)
void emit_aligned_cmp(Register dst, Register src, int size)
void emit_xchg(Register dst, Operand src, int size)
void vmovss(XMMRegister dst, Operand src)
void negw(Register reg)
void fstp(int index)
void store_rax(Address dst, RelocInfo::Mode mode)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void aligned_testb(Register reg, Immediate mask)
void mulxl(Register dst1, Register dst2, Operand src)
void sarxq(Register dst, Operand src1, Register src2)
void emit_not(Register dst, int size)
void xchgb(Register reg, Operand op)
void aligned_testb(Register reg, Operand op)
void lzcntq(Register dst, Operand src)
void movd(XMMRegister dst, Register src)
void vinstr(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2, SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature=AVX)
void vcvttss2siq(Register dst, XMMRegister src)
void shrxq(Register dst, Operand src1, Register src2)
void movsxwq(Register dst, Operand src)
void bmi2l(SIMDPrefix pp, uint8_t op, Register reg, Register vreg, Operand rm)
void emit_test(Operand op, Register reg, int size)
void emit_sub(Register dst, Register src, int size)
void fild_d(Operand adr)
void emit_and(Register dst, Register src, int size)
void vbroadcastss(XMMRegister dst, XMMRegister src)
void bextrl(Register dst, Register src1, Register src2)
void rorxl(Register dst, Register src, uint8_t imm8)
void emit_or(Operand dst, Register src, int size)
void movsxlq(Register dst, Operand src)
void bsfq(Register dst, Register src)
void roundss(XMMRegister dst, Operand src, RoundingMode mode)
void emit_cmp(Operand dst, Register src, int size)
void vmovups(Operand dst, XMMRegister src)
void mulxq(Register dst1, Register dst2, Operand src)
void aligned_cmpb(Register dst, Register src)
void movups(XMMRegister dst, XMMRegister src)
void testb(Register reg, Immediate mask)
void vmovdqu(YMMRegister dst, Operand src)
void pinsrq(XMMRegister dst, Register src, uint8_t imm8)
void vmovupd(YMMRegister dst, Operand src)
void cmovq(Condition cc, Register dst, Register src)
void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Register src2)
void db(uint8_t data)
void vps(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2)
void vmovups(YMMRegister dst, YMMRegister src)
void vmovhps(XMMRegister dst, XMMRegister src1, Operand src2)
void sse_instr(XMMRegister dst, Operand src, uint8_t escape, uint8_t opcode)
void vblendvps(XMMRegister dst, XMMRegister src1, XMMRegister src2, XMMRegister mask)
void cmpb(Operand dst, Register src)
void ssse3_instr(XMMRegister dst, XMMRegister src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
void decb(Operand dst)
void emit_aligned_cmp(Operand dst, Immediate src, int size)
void mulq(Operand src)
void blsrq(Register dst, Operand src)
void vmovddup(XMMRegister dst, Operand src)
void vcvtdq2pd(YMMRegister dst, Operand src)
void emit_aligned_test(Register dst, Register src, int size)
void vcmppd(YMMRegister dst, YMMRegister src1, Operand src2, int8_t cmp)
void emit_xchg(Register dst, Register src, int size)
void cmpeqss(XMMRegister dst, XMMRegister src)
void movw(Operand dst, Immediate imm)
void vcvttsd2si(Register dst, XMMRegister src)
void roundsd(XMMRegister dst, Operand src, RoundingMode mode)
void long_at_put(int pos, uint32_t x)
void pinsrw(XMMRegister dst, Operand src, uint8_t imm8)
void vmovsd(XMMRegister dst, Operand src)
void vmovmskps(Register dst, XMMRegister src)
void emit_imul(Register dst, Operand src, Immediate imm, int size)
void shufps(XMMRegister dst, XMMRegister src, uint8_t imm8)
void cmpw(Operand dst, Immediate src)
void vcmpps(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp)
void btq(Operand dst, Register src)
void negb(Register reg)
void sarxq(Register dst, Register src1, Register src2)
void emit_div(Register src, int size)
void movsxwl(Register dst, Operand src)
void roundpd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void vpmovmskb(Register dst, XMMRegister src)
void vucomiss(XMMRegister dst, Operand src)
void shlxq(Register dst, Operand src1, Register src2)
void cmpb(Register dst, Operand src)
void vpshufhw(XMMRegister dst, Operand src, uint8_t imm8)
void movdqa(XMMRegister dst, Operand src)
void bsrq(Register dst, Register src)
void testw(Operand op, Register reg)
void ucomiss(XMMRegister dst, Operand src)
void sse4_2_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
void shrxq(Register dst, Register src1, Register src2)
void tzcntl(Register dst, Register src)
void emit_modrm(int code, Register rm_reg)
void vpalignr(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t imm8)
void call(Register adr)
void cvtqsi2sd(XMMRegister dst, Register src)
void vmovupd(XMMRegister dst, Operand src)
void sarxl(Register dst, Register src1, Register src2)
void vmovapd(XMMRegister dst, XMMRegister src)
void vcvtsd2si(Register dst, XMMRegister src)
void emit_mov(Register dst, Immediate64 value, int size)
void andnq(Register dst, Register src1, Register src2)
void vpd(uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2)
void immediate_arithmetic_op_16(uint8_t subcode, Operand dst, Immediate src)
void cvttsd2si(Register dst, Operand src)
void pdepq(Register dst, Register src1, Operand src2)
void pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle)
void emit_and(Register dst, Immediate src, int size)
void bmi1l(uint8_t op, Register reg, Register vreg, Register rm)
void blsiq(Register dst, Register src)
Operand256 Operand256 void lddqu(XMMRegister dst, Operand src)
void negl(Register reg)
void pextq(Register dst, Register src1, Operand src2)
void blsrq(Register dst, Register src)
void emit_imul(Register dst, Operand src, int size)
void vpblendw(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t mask)
void vextractf128(XMMRegister dst, YMMRegister src, uint8_t lane)
void insertps(XMMRegister dst, XMMRegister src, uint8_t imm8)
V8_NOINLINE V8_PRESERVE_MOST void GrowBuffer()
void vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void vcvttss2si(Register dst, XMMRegister src)
void emit_and(Register dst, Operand src, int size)
void emit_test(Register reg, Immediate mask, int size)
void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data=0)
void negq(Operand op)
void fist_s(Operand adr)
void vpshuflw(XMMRegister dst, XMMRegister src, uint8_t imm8)
void bsfq(Register dst, Operand src)
void shift(Register dst, Immediate shift_amount, int subcode, int size)
void movddup(XMMRegister dst, XMMRegister src)
void aligned_testw(Operand op, Register reg)
void setcc(Condition cc, Register reg)
void emit_test(Register dst, Register src, int size)
void vmovss(Operand dst, XMMRegister src)
void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Operand src2)
void pushq(Immediate value)
void arithmetic_op(uint8_t opcode, Register reg, Register rm_reg, int size)
static uint32_t uint32_constant_at(Address pc, Address constant_pool)
void popq(Operand dst)
void emit_mov(Operand dst, Register src, int size)
void movddup(XMMRegister dst, Operand src)
void emit_cmp(Register dst, Immediate src, int size)
void vbroadcastsd(YMMRegister dst, Operand src)
void testb(Operand op, Immediate mask)
void blsmskl(Register dst, Register src)
void movsxbl(Register dst, Operand src)
void movb(Register dst, Operand src)
void rorxq(Register dst, Operand src, uint8_t imm8)
void sse4_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
void vroundpd(YMMRegister dst, YMMRegister src, RoundingMode mode)
void emit_aligned_test(Operand op, Register reg, int size)
void load_rax(ExternalReference ext)
void bextrq(Register dst, Register src1, Register src2)
void sse4_instr(Operand dst, XMMRegister src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode, int8_t imm8)
void emit_dec(Register dst, int size)
void pblendw(XMMRegister dst, XMMRegister src, uint8_t mask)
void cmpb(Register dst, Immediate src)
void vpd(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2)
void jmp(Handle< Code > target, RelocInfo::Mode rmode)
void pshufd(XMMRegister dst, Operand src, uint8_t shuffle)
void vroundsd(XMMRegister dst, XMMRegister src1, Operand src2, RoundingMode mode)
void vcmpeqsd(XMMRegister dst, XMMRegister src)
void emit_and(Operand dst, Register src, int size)
void bzhil(Register dst, Operand src1, Register src2)
void vmovddup(YMMRegister dst, Operand src)
void jmp(Register adr, bool notrack=false)
void vcvtqsi2ss(XMMRegister dst, XMMRegister src1, Operand src2)
void sse4_instr(XMMRegister dst, XMMRegister src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
BuiltinJumpTableInfoWriter builtin_jump_table_info_writer_
void vmovddup(YMMRegister dst, YMMRegister src)
void sse2_instr(XMMRegister reg, uint8_t imm8, uint8_t prefix, uint8_t escape, uint8_t opcode, int extension)
void movss(XMMRegister dst, XMMRegister src)
void cmpw(Register dst, Register src)
void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Register src2)
void subb(Register dst, Immediate src)
void vshufps(YMMRegister dst, YMMRegister src1, YMMRegister src2, uint8_t imm8)
void emit(Immediate x)
void blsil(Register dst, Register src)
static void set_uint32_constant_at(Address pc, Address constant_pool, uint32_t new_constant, WritableJitAllocation *jit_allocation=nullptr, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
uint32_t long_at(int pos)
void movsxwl(Register dst, Register src)
void cmpps(XMMRegister dst, Operand src, int8_t cmp)
void vcvttss2si(Register dst, Operand src)
void shift(Operand dst, Immediate shift_amount, int subcode, int size)
void vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2, RoundingMode mode)
void fstp_s(Operand adr)
void vps(uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2, uint8_t imm8)
void bswapq(Register dst)
void vinserti128(YMMRegister dst, YMMRegister src1, XMMRegister src2, uint8_t lane)
void vpshufhw(YMMRegister dst, Operand src, uint8_t imm8)
void pdepl(Register dst, Register src1, Register src2)
void rorxl(Register dst, Operand src, uint8_t imm8)
void vcvtps2ph(XMMRegister dst, YMMRegister src, uint8_t imm8)
void emit_xor(Operand dst, Register src, int size)
void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void vmovaps(YMMRegister dst, Operand src)
void emit_aligned_cmp(Register dst, Immediate src, int size)
void blsmskl(Register dst, Operand src)
void xaddl(Operand dst, Register src)
void sse2_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape, uint8_t opcode)
void vlddqu(XMMRegister dst, Operand src)
void j(Condition cc, Handle< Code > target, RelocInfo::Mode rmode)
void vucomiss(XMMRegister dst, XMMRegister src)
bool is_optimizable_farjmp(int idx)
void vinstr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, SIMDPrefix pp, LeadingOpcode m, VexW w, CpuFeature feature=AVX2)
void tzcntq(Register dst, Operand src)
void vps(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2)
void btrq(Register dst, Immediate imm8)
void vmovd(Register dst, XMMRegister src)
void vbroadcastss(YMMRegister dst, XMMRegister src)
void movdqa(Operand dst, XMMRegister src)
static uint8_t * emit(uint8_t *__restrict pc, T t)
void mulq(Register src)
void vcvtqsi2sd(XMMRegister dst, XMMRegister src1, Operand src2)
void immediate_arithmetic_op_8(uint8_t subcode, Operand dst, Immediate src)
void cmpltsd(XMMRegister dst, XMMRegister src)
void emit_xor(Operand dst, Immediate src, int size)
void emit_imul(Register dst, Register src, int size)
void psrldq(XMMRegister dst, uint8_t shift)
void vcmppd(XMMRegister dst, XMMRegister src1, XMMRegister src2, int8_t cmp)
void vblendvps(YMMRegister dst, YMMRegister src1, YMMRegister src2, YMMRegister mask)
void vmovdqu(Operand dst, XMMRegister src)
void movdqu(XMMRegister dst, Operand src)
void movsd(Operand dst, XMMRegister src)
void vpshuflw(YMMRegister dst, Operand src, uint8_t imm8)
void fisttp_d(Operand adr)
void emit_aligned_test(Operand op, Immediate mask, int size)
void aligned_testb(Operand op, Immediate mask)
void AlignForJCCErratum(int inst_size)
void movsd(XMMRegister dst, XMMRegister src)
void pushq_imm32(int32_t imm32)
void vcvtlsi2sd(XMMRegister dst, XMMRegister src1, Operand src2)
void emit_imul(Register dst, Register src, Immediate imm, int size)
void emit_rex(P1 p1, P2 p2, int size)
void movaps(XMMRegister dst, XMMRegister src)
void vcvtlsi2ss(XMMRegister dst, XMMRegister src1, Register src2)
void vpshufd(YMMRegister dst, Operand src, uint8_t imm8)
void movsxbq(Register dst, Operand src)
void btsq(Register dst, Immediate imm8)
void emit(Immediate64 x)
void jmp(Label *L, Label::Distance distance=Label::kFar)
void blsil(Register dst, Operand src)
void haddps(XMMRegister dst, XMMRegister src)
void vcmpps(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp)
void pdepl(Register dst, Register src1, Operand src2)
void GetCode(Isolate *isolate, CodeDesc *desc)
void movsxbl(Register dst, Register src)
void cvtlsi2ss(XMMRegister dst, Operand src)
void xaddb(Operand dst, Register src)
void btsq(Operand dst, Register src)
void aligned_cmpb(Register dst, Immediate src)
void vmovdqu(XMMRegister dst, Operand src)
void fisttp_s(Operand adr)
V8_NOINLINE void emit_label_operand(int rm, Label *label, int addend=0)
void arithmetic_op_16(uint8_t opcode, Register reg, Register rm_reg)
void emit_sse_operand(Register dst, XMMRegister src)
void aligned_testb(Operand op, Register reg)
void dq(Label *label)
static void set_target_address_at(Address pc, Address constant_pool, Address target, WritableJitAllocation *writable_jit_allocation=nullptr, ICacheFlushMode icache_flush_mode=FLUSH_ICACHE_IF_NEEDED)
void blsrl(Register dst, Register src)
void cvttsd2si(Register dst, XMMRegister src)
void andb(Register dst, Immediate src)
void movsxbq(Register dst, Register src)
void cvtqsi2ss(XMMRegister dst, Register src)
void emit_add(Operand dst, Immediate src, int size)
void vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void emit_test(Register reg, Operand op, int size)
void bmi2q(SIMDPrefix pp, uint8_t op, Register reg, Register vreg, Operand rm)
void emit_or(Operand dst, Immediate src, int size)
void cvttsd2siq(Register dst, Operand src)
void cmovl(Condition cc, Register dst, Register src)
void shld(Register dst, Register src)
void arithmetic_op_8(uint8_t opcode, Register reg, Register rm_reg)
void aligned_cmpw(Operand dst, Immediate src)
void xaddw(Operand dst, Register src)
void ret(int imm16)
void movq_heap_number(Register dst, double value)
void fistp_d(Operand adr)
void vmovaps(XMMRegister dst, Operand src)
void emit_sse_operand(XMMRegister reg, Operand adr)
void bsfl(Register dst, Operand src)
void emit_sub(Register dst, Immediate src, int size)
void cmpps(XMMRegister dst, XMMRegister src, int8_t cmp)
void pshufhw(XMMRegister dst, Operand src, uint8_t shuffle)
void vmovdqa(XMMRegister dst, Operand src)
void vpdpbssd(XMMRegister dst, XMMRegister src1, XMMRegister src2)
void GetCode(LocalIsolate *isolate, CodeDesc *desc, int safepoint_table_offset, int handler_table_offset)
void movshdup(XMMRegister dst, XMMRegister src)
void dq(uint64_t data)
void tzcntq(Register dst, Register src)
void andnl(Register dst, Register src1, Operand src2)
void cmovq(Condition cc, Register dst, Operand src)
void lzcntl(Register dst, Register src)
static bool IsNop(Address addr)
void pshuflw(XMMRegister dst, Operand src, uint8_t shuffle)
void pextrq(Register dst, XMMRegister src, int8_t imm8)
void emit_modrm(Register reg, Register rm_reg)
void cvtsd2si(Register dst, XMMRegister src)
void mull(Register src)
void aligned_testw(Operand op, Immediate mask)
void vpshufd(XMMRegister dst, XMMRegister src, uint8_t imm8)
void haddps(XMMRegister dst, Operand src)
void pinsrb(XMMRegister dst, Register src, uint8_t imm8)
void vmovsd(XMMRegister dst, XMMRegister src1, XMMRegister src2)
void vcvtph2ps(XMMRegister dst, XMMRegister src)
void pinsrb(XMMRegister dst, Operand src, uint8_t imm8)
void emit_and(Operand dst, Immediate src, int size)
void aligned_testw(Register reg, Immediate mask)
void negb(Operand op)
void cvttps2dq(XMMRegister dst, XMMRegister src)
void vshufps(XMMRegister dst, XMMRegister src1, XMMRegister src2, uint8_t imm8)
void movw(Operand dst, Register src)
void emit_cmpxchg(Operand dst, Register src, int size)
void aligned_j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
void negq(Register reg)
void vpd(uint8_t op, XMMRegister dst, YMMRegister src1, Operand src2)
void sse2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix, uint8_t escape, uint8_t opcode)
void vpblendw(XMMRegister dst, XMMRegister src1, XMMRegister src2, uint8_t mask)
void shift(Operand dst, int subcode, int size)
void bzhiq(Register dst, Operand src1, Register src2)
void cmpxchgw(Operand dst, Register src)
void cmpw(Operand dst, Register src)
void pextl(Register dst, Register src1, Register src2)
void emit_cmp(Register dst, Register src, int size)
void jmp(Operand src, bool notrack=false)
void emit_aligned_cmp(Register dst, Operand src, int size)
void aligned_testw(Register reg, Operand op)
void movq(Register dst, uint64_t value)
void call(Operand operand)
void emit_dec(Operand dst, int size)
void cvttss2siq(Register dst, XMMRegister src)
void sarxl(Register dst, Operand src1, Register src2)
void lzcntq(Register dst, Register src)
void emit_farith(int b1, int b2, int i)
void bsrl(Register dst, Register src)
void popq(Register dst)
void immediate_arithmetic_op_16(uint8_t subcode, Register dst, Immediate src)
void vpalignr(YMMRegister dst, YMMRegister src1, YMMRegister src2, uint8_t imm8)
void cvtsd2siq(Register dst, XMMRegister src)
void GetCode(LocalIsolate *isolate, CodeDesc *desc, SafepointTableBuilderBase *safepoint_table_builder, int handler_table_offset)
void pblendw(XMMRegister dst, Operand src, uint8_t mask)
void emit_cmp(Operand dst, Immediate src, int size)
void vinsertps(XMMRegister dst, XMMRegister src1, XMMRegister src2, uint8_t imm8)
void mulxl(Register dst1, Register dst2, Register src)
void vmovaps(XMMRegister dst, XMMRegister src)
void vptest(YMMRegister dst, YMMRegister src)
void vcvttps2dq(YMMRegister dst, Operand src)
void emit_add(Operand dst, Register src, int size)
void vcvttss2siq(Register dst, Operand src)
void emit_sub(Register dst, Operand src, int size)
void vroundps(YMMRegister dst, YMMRegister src, RoundingMode mode)
void fisub_s(Operand adr)
void incsspq(Register number_of_words)
void vmovups(Operand dst, YMMRegister src)
void vpblendw(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t mask)
void vmovq(XMMRegister dst, Operand src)
void cvttsd2siq(Register dst, XMMRegister src)
void emit_add(Register dst, Immediate src, int size)
void vps(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2, uint8_t imm8)
void vcvttsd2siq(Register dst, XMMRegister src)
void emit_sub(Operand dst, Immediate src, int size)
void dp(uintptr_t data)
void emit_aligned_test(Register reg, Operand op, int size)
void vroundpd(XMMRegister dst, XMMRegister src, RoundingMode mode)
void vpinsrw(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8)
void insertps(XMMRegister dst, Operand src, uint8_t imm8)
void emit_operand(Register reg, Operand adr)
void movdqa(XMMRegister dst, XMMRegister src)
void blsmskq(Register dst, Operand src)
void movq(Register dst, int64_t value)
void cvtqsi2ss(XMMRegister dst, Operand src)
void vcmpeqss(XMMRegister dst, XMMRegister src)
void testw(Operand op, Immediate mask)
void vpd(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2)
void fma_instr(uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2, VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w)
void vpinsrb(XMMRegister dst, XMMRegister src1, Register src2, uint8_t imm8)
void vmovmskpd(Register dst, XMMRegister src)
void emit_mov(Register dst, Register src, int size)
void movq(XMMRegister dst, Register src)
void near_jmp(intptr_t disp, RelocInfo::Mode rmode)
void vpextrq(Register dst, XMMRegister src, int8_t imm8)
void sse4_2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
void emit_or(Register dst, Immediate src, int size)
void movmskpd(Register dst, XMMRegister src)
void popcntq(Register dst, Register src)
void lzcntl(Register dst, Operand src)
void movw(Register dst, Operand src)
void fistp_s(Operand adr)
void immediate_arithmetic_op(uint8_t subcode, Register dst, Immediate src, int size)
void emit_rex(P1 p1, int size)
void emit_sbb(Register dst, Register src, int size)
void movd(Register dst, XMMRegister src)
void emit_test(Operand op, Immediate mask, int size)
void mull(Operand src)
void emit_xor(Register dst, Operand src, int size)
void fma_instr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, VectorLength l, SIMDPrefix pp, LeadingOpcode m, VexW w)
void xchgw(Register reg, Operand op)
void vinsertps(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void movsxlq(Register dst, Register src)
void sse4_instr(Register dst, XMMRegister src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode, int8_t imm8)
void movhps(XMMRegister dst, Operand src)
void pmovmskb(Register dst, XMMRegister src)
void movd(XMMRegister dst, Operand src)
void movups(XMMRegister dst, Operand src)
void emit_add(Register dst, Register src, int size)
void andnl(Register dst, Register src1, Register src2)
void dd(uint32_t data)
void movl(Operand dst, Label *src)
void vpshufd(YMMRegister dst, YMMRegister src, uint8_t imm8)
void emit_aligned_test(Register reg, Immediate mask, int size)
void shrxl(Register dst, Operand src1, Register src2)
void emit_lea(Register dst, Operand src, int size)
void bmi1q(uint8_t op, Register reg, Register vreg, Operand rm)
void vpshufhw(XMMRegister dst, XMMRegister src, uint8_t imm8)
void bmi2q(SIMDPrefix pp, uint8_t op, Register reg, Register vreg, Register rm)
void vbroadcastss(YMMRegister dst, Operand src)
void emit_aligned_cmp(Operand dst, Register src, int size)
void roundps(XMMRegister dst, XMMRegister src, RoundingMode mode)
void vpalignr(XMMRegister dst, XMMRegister src1, XMMRegister src2, uint8_t imm8)
void vmovq(Register dst, XMMRegister src)
void testb(Register reg, Operand op)
DECLARE_SSE2_UNOP_AVX_YMM_INSTRUCTION(sqrtpd, 51, YMMRegister, YMMRegister, Operand) DECLARE_SSE2_UNOP_AVX_YMM_INSTRUCTION(cvtpd2ps
void cvttps2dq(XMMRegister dst, Operand src)
void vcmppd(XMMRegister dst, XMMRegister src1, Operand src2, int8_t cmp)
void sub_sp_32(uint32_t imm)
void vcvtdq2pd(XMMRegister dst, XMMRegister src)
void movhlps(XMMRegister dst, XMMRegister src)
Assembler(const AssemblerOptions &, std::unique_ptr< AssemblerBuffer >={})
void vbroadcastsd(YMMRegister dst, XMMRegister src)
void pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle)
void cvtdq2pd(XMMRegister dst, XMMRegister src)
void emit_neg(Register dst, int size)
void cmpb(Operand dst, Immediate src)
void movdqu(Operand dst, XMMRegister src)
void pinsrw(XMMRegister dst, Register src, uint8_t imm8)
void emit_movzxb(Register dst, Register src, int size)
void movlps(Operand dst, XMMRegister src)
void vpermq(YMMRegister dst, Operand src, uint8_t imm8)
void movups(Operand dst, XMMRegister src)
void vcvtps2ph(XMMRegister dst, XMMRegister src, uint8_t imm8)
void vss(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2)
void emit_cmp(Register dst, Operand src, int size)
void xaddq(Operand dst, Register src)
void testw(Register dst, Register src)
void bmi2l(SIMDPrefix pp, uint8_t op, Register reg, Register vreg, Register rm)
void vmovups(XMMRegister dst, XMMRegister src)
void emit_operand(int rm, Operand adr)
void cvttss2siq(Register dst, Operand src)
void call(Handle< Code > target, RelocInfo::Mode rmode=RelocInfo::CODE_TARGET)
void bsfl(Register dst, Register src)
void cmpw(Register dst, Operand src)
void vmovdqu(Operand dst, YMMRegister src)
void vptest(YMMRegister dst, Operand src)
void cvttss2si(Register dst, Operand src)
void vmovhlps(XMMRegister dst, XMMRegister src1, XMMRegister src2)
void vmovlhps(XMMRegister dst, XMMRegister src1, XMMRegister src2)
void near_call(intptr_t disp, RelocInfo::Mode rmode)
void movupd(Operand dst, XMMRegister src)
void blsrl(Register dst, Operand src)
void shlxq(Register dst, Register src1, Register src2)
void aligned_cmpw(Register dst, Operand src)
void movaps(XMMRegister dst, Operand src)
int SizeOfCodeGeneratedSince(Label *label)
void movq(XMMRegister dst, XMMRegister src)
void aligned_testb(Register dst, Register src)
void fld_s(Operand adr)
DirectHandle< Code > code_target_object_handle_at(Address pc)
void vcvttps2dq(XMMRegister dst, XMMRegister src)
static bool UseConstPoolFor(RelocInfo::Mode rmode)
void vcvttps2dq(YMMRegister dst, YMMRegister src)
void vmovupd(Operand dst, YMMRegister src)
void RecordDeoptReason(DeoptimizeReason reason, uint32_t node_id, SourcePosition position, int id)
void movlps(XMMRegister dst, Operand src)
void emit_movzxw(Register dst, Register src, int size)
void vpalignr(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8)
void ssse3_instr(XMMRegister dst, Operand src, uint8_t prefix, uint8_t escape1, uint8_t escape2, uint8_t opcode)
void aligned_cmpb(Operand dst, Immediate src)
void bextrq(Register dst, Operand src1, Register src2)
void vsd(uint8_t op, Reg dst, Reg src1, Op src2)
void bzhil(Register dst, Register src1, Register src2)
void emit_sub(Operand dst, Register src, int size)
void vbroadcastss(XMMRegister dst, Operand src)
void vcvttsd2si(Register dst, Operand src)
void WriteBuiltinJumpTableEntry(Label *label, int table_pos)
void movhps(Operand dst, XMMRegister src)
void emit_mov(Register dst, Immediate value, int size)
void bswapl(Register dst)
void emit_not(Operand dst, int size)
void cvtlsi2sd(XMMRegister dst, Operand src)
void vmovddup(XMMRegister dst, XMMRegister src)
void vpdpbssd(YMMRegister dst, YMMRegister src1, YMMRegister src2)
static Builtin target_builtin_at(Address pc)
void movq(XMMRegister dst, Operand src)
void pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle)
void emit_mov(Operand dst, Immediate value, int size)
void emit_or(Register dst, Operand src, int size)
void movq_imm64(Register dst, int64_t value)
void vpdpbusd(XMMRegister dst, XMMRegister src1, XMMRegister src2)
bool IsMoveRipRelative(Address instr)
ConstPool(Assembler *assm)
static constexpr int kMoveRipRelativeDispOffset
static constexpr int kRipRelativeDispSize
static constexpr int kMoveImm64Offset
static constexpr uint32_t kMoveRipRelativeMask
bool AddSharedEntry(uint64_t data, int offset)
std::multimap< uint64_t, int > entries_
bool TryRecordEntry(intptr_t data, RelocInfo::Mode mode)
static constexpr uint32_t kMoveRipRelativeInstr
V8_INLINE EnsureSpace(Assembler *assembler)
constexpr Immediate64(int64_t value)
constexpr Immediate64(Address value, RelocInfo::Mode rmode)
const RelocInfo::Mode rmode_
constexpr Immediate64(int64_t value, RelocInfo::Mode rmode)
constexpr Immediate(int32_t value)
constexpr Immediate(int32_t value, RelocInfo::Mode rmode)
Immediate(Tagged< Smi > value)
RelocInfo::Mode rmode() const
V8_INLINE Operand256(Register base, int32_t disp)
V8_INLINE Operand256(Register base, Register index, ScaleFactor scale, int32_t disp)
V8_INLINE Operand256(Register index, ScaleFactor scale, int32_t disp)
Operand256(const Operand256 &) V8_NOEXCEPT=default
Operand256 & operator=(const Operand256 &) V8_NOEXCEPT=default
V8_INLINE void set_disp32(int disp)
V8_INLINE Operand(Register index, ScaleFactor scale, int32_t disp)
V8_INLINE constexpr bool is_label_operand() const
Operand(Operand base, int32_t offset)
V8_INLINE Operand(Label *label, int addend=0)
V8_INLINE constexpr void set_disp8(int disp)
Operand(const Operand &) V8_NOEXCEPT=default
V8_INLINE constexpr void set_sib(ScaleFactor scale, Register index, Register base)
V8_INLINE constexpr Operand(Register base, int32_t disp)
V8_INLINE const LabelOperand & label() const
V8_INLINE constexpr uint8_t rex() const
Operand & operator=(const Operand &) V8_NOEXCEPT=default
V8_INLINE const MemoryOperand & memory() const
V8_INLINE constexpr void set_modrm(int mod, Register rm_reg)
V8_INLINE Operand(Register base, Register index, ScaleFactor scale, int32_t disp)
bool AddressUsesRegister(Register reg) const
constexpr int8_t code() const
constexpr int low_bits() const
constexpr int high_bit() const
#define V8_ENABLE_SANDBOX_BOOL
Definition globals.h:160
#define DECLARE_INSTRUCTION(name, opcode_name, opcode_value)
Label label
BytecodeAssembler & assembler_
#define EXPORT_TEMPLATE_DECLARE(export)
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in allocation gc speed threshold for starting incremental marking via a task in percent of available threshold for starting incremental marking immediately in percent of available Use a single schedule for determining a marking schedule between JS and C objects schedules the minor GC task with kUserVisible priority max worker number of concurrent for NumberOfWorkerThreads start background threads that allocate memory concurrent_array_buffer_sweeping use parallel threads to clear weak refs in the atomic pause trace progress of the incremental marking trace object counts and memory usage * MB
#define FMA_INSTRUCTION_LIST(V)
Definition fma-instr.h:52
#define FMA_PD_INSTRUCTION_LIST(V)
Definition fma-instr.h:44
#define FMA_PS_INSTRUCTION_LIST(V)
Definition fma-instr.h:36
#define SSE_UNOP_INSTRUCTION_LIST(V)
Definition sse-instr.h:9
#define SSSE3_UNOP_INSTRUCTION_LIST(V)
Definition sse-instr.h:96
#define SSE4_INSTRUCTION_LIST(V)
Definition sse-instr.h:101
#define SSE2_INSTRUCTION_LIST(V)
Definition sse-instr.h:16
#define SSE2_INSTRUCTION_LIST_SD(V)
Definition sse-instr.h:75
#define SSSE3_INSTRUCTION_LIST(V)
Definition sse-instr.h:85
#define AVX2_BROADCAST_LIST(V)
Definition sse-instr.h:126
int32_t offset
std::string extension
Instruction * instr
LiftoffRegister reg
Label label_
int pc_offset
int x
int position
Definition liveedit.cc:290
uint32_t const mask
int m
Definition mul-fft.cc:294
int r
Definition mul-fft.cc:298
STL namespace.
constexpr VFPRoundingMode kRoundToNearest
constexpr int kTaggedSize
Definition globals.h:542
constexpr int kInt64Size
Definition globals.h:402
bool operator!=(ExternalReference lhs, ExternalReference rhs)
std::variant< Zone *, AccountingAllocator * > MaybeAssemblerZone
Definition assembler.h:262
constexpr int L
constexpr int kSystemPointerSize
Definition globals.h:410
constexpr bool SmiValuesAre31Bits()
Condition NegateCondition(Condition cond)
constexpr int kInt32Size
Definition globals.h:401
constexpr VFPRoundingMode kRoundToZero
constexpr int kMaxInt
Definition globals.h:374
@ times_external_pointer_size
@ times_half_system_pointer_size
#define V8_NOEXCEPT
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define ASSERT_TRIVIALLY_COPYABLE(T)
Definition macros.h:267
#define V8_EXPORT_PRIVATE
Definition macros.h:460
#define V8_INLINE
Definition v8config.h:500
#define V8_ASSUME
Definition v8config.h:533
#define V8_UNLIKELY(condition)
Definition v8config.h:660
#define V8_NOINLINE
Definition v8config.h:586
#define V8_PRESERVE_MOST
Definition v8config.h:598
std::unique_ptr< ValueMirror > value
#define SSE4_EXTRACT_INSTRUCTION_LIST(V)
Definition sse-instr.h:197
#define SSE_INSTRUCTION_LIST_SS(V)
Definition sse-instr.h:31
#define SSE2_INSTRUCTION_LIST_PI(V)
Definition sse-instr.h:56
#define SSE4_UNOP_INSTRUCTION_LIST_PMOV(V)
Definition sse-instr.h:188
#define SSE_BINOP_INSTRUCTION_LIST(V)
Definition sse-instr.h:17
#define SSE2_UNOP_INSTRUCTION_LIST(V)
Definition sse-instr.h:123
#define SSE2_INSTRUCTION_LIST_SHIFT(V)
Definition sse-instr.h:107
#define SSE2_INSTRUCTION_LIST_PD(V)
Definition sse-instr.h:43
#define SSE4_UNOP_INSTRUCTION_LIST(V)
Definition sse-instr.h:184
#define SSE4_2_INSTRUCTION_LIST(V)
Definition sse-instr.h:203
#define SSE2_INSTRUCTION_LIST_SHIFT_IMM(V)
Definition sse-instr.h:132