17#include <sys/sysctl.h>
36#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
38V8_INLINE uint64_t xgetbv(
unsigned int xcr) {
47 __asm__
volatile(
".byte 0x0F, 0x01, 0xD0" :
"=a"(eax),
"=d"(edx) :
"c"(xcr));
48 return static_cast<uint64_t
>(eax) | (
static_cast<uint64_t
>(edx) << 32);
52bool OSHasAVXSupport() {
58 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
59 if (sysctl(ctl_name, 2, buffer, &buffer_size,
nullptr, 0) != 0) {
60 FATAL(
"V8 failed to get kernel version");
64 char* period_pos = strchr(buffer,
'.');
67 long kernel_version_major = strtol(buffer,
nullptr, 10);
68 if (kernel_version_major <= 13)
return false;
71 uint64_t feature_mask = xgetbv(0);
72 return (feature_mask & 0x6) == 0x6;
80#if V8_ENABLE_WEBASSEMBLY
89 if (cross_compile)
return;
91#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
93 CHECK(cpu.has_sse2());
94 CHECK(cpu.has_cmov());
101 if (cpu.has_avx() && cpu.has_osxsave() && OSHasAVXSupport()) {
105 if (cpu.has_avx_vnni_int8())
SetSupported(AVX_VNNI_INT8);
115 if (strcmp(
v8_flags.mcpu,
"auto") == 0) {
117 }
else if (strcmp(
v8_flags.mcpu,
"atom") == 0) {
120 if (cpu.has_intel_jcc_erratum() &&
v8_flags.intel_jcc_erratum_mitigation)
155 "SSE3=%d SSSE3=%d SSE4_1=%d SSE4_2=%d SAHF=%d AVX=%d AVX2=%d AVX_VNNI=%d "
162 "POPCNT=%d ATOM=%d\n",
178 return ReadUnalignedValue<uint32_t>(
pc_);
187 uint8_t modrm = operand.memory().buf[0];
189 bool has_sib = ((modrm & 0x07) == 0x04);
190 uint8_t mode = modrm & 0xC0;
191 int disp_offset = has_sib ? 2 : 1;
192 int base_reg = (has_sib ? operand.memory().buf[1] : modrm) & 0x07;
195 bool is_baseless = (mode == 0) && (base_reg == 0x05);
197 if (mode == 0x80 || is_baseless) {
199 disp_value = ReadUnalignedValue<int32_t>(
200 reinterpret_cast<Address>(&operand.memory().buf[disp_offset]));
201 }
else if (mode == 0x40) {
203 disp_value =
static_cast<signed char>(operand.memory().buf[disp_offset]);
208 : disp_value +
offset < disp_value);
211 if (!is_int8(disp_value) || is_baseless) {
213 memory_.
buf[0] = (modrm & 0x3F) | (is_baseless ? 0x00 : 0x80);
217 }
else if (disp_value != 0 || (base_reg == 0x05)) {
221 memory_.
buf[disp_offset] =
static_cast<uint8_t
>(disp_value);
239 if (base_code == rsp.code()) {
245 if (index_code != rsp.code() && index_code == code)
return true;
249 if (base_code == rbp.code() && ((
memory_.
buf[0] & 0xC0) == 0))
return false;
250 return code == base_code;
254 if (base_code == rbp.code() && ((
memory_.
buf[0] & 0xC0) == 0))
return false;
256 return code == base_code;
266 request.heap_number());
267 WriteUnalignedValue(
pc,
object);
273 auto existing =
entries_.find(data);
287 if (!
v8_flags.partial_constant_pool)
return false;
290 "The partial constant pool requires a readable .text section");
299 uint64_t raw_data =
static_cast<uint64_t
>(
data);
316 std::pair<uint64_t, int> first_entry_of_range = *iter;
319 if (first_entry_of_range.first != iter->first) {
325 first_entry_of_range = *iter;
328 int constant_entry_offset = first_entry_of_range.second;
331 DCHECK_LT(constant_entry_offset, iter->second);
339 DCHECK(ReadUnalignedValue<uint32_t>(disp_addr) == 0);
340 WriteUnalignedValue(disp_addr, disp32);
354 if (!
v8_flags.partial_constant_pool)
return false;
364 std::unique_ptr<AssemblerBuffer> buffer)
365 : AssemblerBase(options,
std::move(buffer)), constpool_(this) {
366 reloc_info_writer.Reposition(buffer_start_ +
buffer_->size(),
pc_);
367 if (CpuFeatures::IsSupported(SSE4_2)) {
368 EnableCpuFeature(SSE4_1);
370 if (CpuFeatures::IsSupported(SSE4_1)) {
371 EnableCpuFeature(SSSE3);
373 if (CpuFeatures::IsSupported(SSSE3)) {
374 EnableCpuFeature(SSE3);
377#if defined(V8_OS_WIN_X64)
378 if (options.collect_win64_unwind_info) {
379 xdata_encoder_ = std::make_unique<win64_unwindinfo::XdataEncoder>(*this);
384void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
385 GetCode(isolate->main_thread_local_isolate(), desc);
388void Assembler::GetCode(LocalIsolate* isolate, CodeDesc* desc,
389 SafepointTableBuilderBase* safepoint_table_builder,
390 int handler_table_offset) {
398 DataAlign(InstructionStream::kMetadataAlignment);
401 DCHECK(constpool_.IsEmpty());
403 const int code_comments_size = WriteCodeComments();
404 const int builtin_jump_table_info_size = WriteBuiltinJumpTableInfos();
410 AllocateAndInstallRequestedHeapNumbers(isolate);
416 static constexpr int kConstantPoolSize = 0;
417 const int instruction_size =
pc_offset();
418 const int builtin_jump_table_info_offset =
419 instruction_size - builtin_jump_table_info_size;
420 const int code_comments_offset =
421 builtin_jump_table_info_offset - code_comments_size;
422 const int constant_pool_offset = code_comments_offset - kConstantPoolSize;
423 const int handler_table_offset2 = (handler_table_offset == kNoHandlerTable)
424 ? constant_pool_offset
425 : handler_table_offset;
426 const int safepoint_table_offset =
427 (safepoint_table_builder == kNoSafepointTable)
428 ? handler_table_offset2
429 : safepoint_table_builder->safepoint_table_offset();
431 const int reloc_info_offset =
432 static_cast<int>(reloc_info_writer.pos() -
buffer_->start());
433 CodeDesc::Initialize(desc,
this, safepoint_table_offset,
434 handler_table_offset2, constant_pool_offset,
435 code_comments_offset, builtin_jump_table_info_offset,
439void Assembler::FinalizeJumpOptimizationInfo() {
441 auto jump_opt = jump_optimization_info();
442 if (jump_opt && jump_opt->is_collecting()) {
443 auto& dict = jump_opt->may_optimizable_farjmp;
444 int num =
static_cast<int>(jump_opt->farjmps.size());
445 if (num && dict.empty()) {
446 bool can_opt =
false;
447 for (
int i = 0;
i < num;
i++) {
448 auto jmp_info = jump_opt->farjmps[
i];
449 int disp = long_at(jmp_info.pos + jmp_info.opcode_size);
451 jmp_info.distance = disp;
457 jump_opt->set_optimizable();
463#if defined(V8_OS_WIN_X64)
464win64_unwindinfo::BuiltinUnwindInfo Assembler::GetUnwindInfo()
const {
467 return xdata_encoder_->unwinding_info();
471void Assembler::Align(
int m) {
472 DCHECK(base::bits::IsPowerOfTwo(
m));
477void Assembler::AlignForJCCErratum(
int inst_size) {
478 DCHECK(CpuFeatures::IsSupported(INTEL_JCC_ERRATUM_MITIGATION));
500 if (jump_optimization_info())
return;
501 constexpr int kJCCErratumAlignment = 32;
502 int delta = kJCCErratumAlignment - (
pc_offset() & (kJCCErratumAlignment - 1));
503 if (delta <= inst_size) Nop(delta);
506void Assembler::CodeTargetAlign() {
508 auto jump_opt = jump_optimization_info();
509 if (jump_opt && jump_opt->is_collecting()) {
510 jump_opt->align_pos_size[
pc_offset()] = 16;
514void Assembler::LoopHeaderAlign() {
516 auto jump_opt = jump_optimization_info();
517 if (jump_opt && jump_opt->is_collecting()) {
518 jump_opt->align_pos_size[
pc_offset()] = 64;
522bool Assembler::IsNop(Address addr) {
523 uint8_t* a =
reinterpret_cast<uint8_t*
>(addr);
524 while (*a == 0x66) a++;
525 if (*a == 0x90)
return true;
526 if (a[0] == 0xF && a[1] == 0x1F)
return true;
530bool Assembler::IsJmpRel(Address addr) {
531 uint8_t* a =
reinterpret_cast<uint8_t*
>(addr);
532 return *a == 0xEB || *a == 0xE9;
535void Assembler::bind_to(Label* L,
int pos) {
538 if (
L->is_linked()) {
539 int current =
L->pos();
540 int next = long_at(current);
541 while (next != current) {
542 if (current >= 4 && long_at(current - 4) == 0) {
544 intptr_t imm64 =
reinterpret_cast<intptr_t
>(buffer_start_ +
pos);
545 WriteUnalignedValue(addr_at(current - 4), imm64);
546 internal_reference_positions_.push_back(current - 4);
549 int imm32 =
pos - (current +
sizeof(
int32_t));
550 long_at_put(current, imm32);
553 next = long_at(next);
556 if (current >= 4 && long_at(current - 4) == 0) {
558 intptr_t imm64 =
reinterpret_cast<intptr_t
>(buffer_start_ +
pos);
559 WriteUnalignedValue(addr_at(current - 4), imm64);
560 internal_reference_positions_.push_back(current - 4);
563 int imm32 =
pos - (current +
sizeof(
int32_t));
564 long_at_put(current, imm32);
567 while (
L->is_near_linked()) {
568 int fixup_pos =
L->near_link_pos();
570 static_cast<int>(*
reinterpret_cast<int8_t*
>(addr_at(fixup_pos)));
572 int disp =
pos - (fixup_pos +
sizeof(int8_t));
573 CHECK(is_int8(disp));
574 set_byte_at(fixup_pos, disp);
575 if (offset_to_next < 0) {
576 L->link_to(fixup_pos + offset_to_next, Label::kNear);
583 auto jump_opt = jump_optimization_info();
584 if (jump_opt && jump_opt->is_optimizing()) {
585 auto it = jump_opt->label_farjmp_maps.find(L);
586 if (it != jump_opt->label_farjmp_maps.end()) {
587 auto& pos_vector = it->second;
588 for (
auto fixup_pos : pos_vector) {
589 int disp =
pos - (fixup_pos +
sizeof(int8_t));
590 CHECK(is_int8(disp));
591 set_byte_at(fixup_pos, disp);
593 jump_opt->label_farjmp_maps.erase(it);
599void Assembler::bind(Label* L) { bind_to(L,
pc_offset()); }
601void Assembler::record_farjmp_position(Label* L,
int pos) {
602 auto& pos_vector = jump_optimization_info()->label_farjmp_maps[
L];
603 pos_vector.push_back(
pos);
606bool Assembler::is_optimizable_farjmp(
int idx) {
607 if (predictable_code_size())
return false;
609 auto jump_opt = jump_optimization_info();
610 CHECK(jump_opt->is_optimizing());
612 auto& dict = jump_opt->may_optimizable_farjmp;
613 if (dict.find(idx) != dict.end()) {
614 auto record_jmp_info = dict[idx];
616 int record_pos = record_jmp_info.pos;
619 const int operand_size = 4;
620 int record_dest = record_jmp_info.pos + record_jmp_info.opcode_size +
621 operand_size + record_jmp_info.distance;
623 const int max_align_in_jmp_range =
624 jump_opt->MaxAlignInRange(record_pos, record_dest);
626 if (max_align_in_jmp_range == 0) {
632 const int saved_opcode_size = record_jmp_info.opcode_size - 1;
635 constexpr int saved_operand_size = 4 - 1;
640 int cur_jmp_length_max_increase =
641 (record_pos -
pc_offset() + saved_opcode_size + saved_operand_size) %
642 max_align_in_jmp_range;
644 if (is_int8(record_jmp_info.distance + cur_jmp_length_max_increase)) {
651void Assembler::GrowBuffer() {
652 DCHECK(buffer_overflow());
656 int old_size =
buffer_->size();
657 int new_size = 2 * old_size;
661 if (new_size > kMaximalBufferSize) {
662 V8::FatalProcessOutOfMemory(
nullptr,
"Assembler::GrowBuffer");
666 std::unique_ptr<AssemblerBuffer> new_buffer =
buffer_->Grow(new_size);
668 uint8_t* new_start = new_buffer->start();
671 intptr_t pc_delta = new_start - buffer_start_;
672 intptr_t rc_delta = (new_start + new_size) - (buffer_start_ + old_size);
673 size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos();
675 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
679 buffer_ = std::move(new_buffer);
680 buffer_start_ = new_start;
682 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
683 reloc_info_writer.last_pc() + pc_delta);
686 for (
auto pos : internal_reference_positions_) {
688 WriteUnalignedValue(p, ReadUnalignedValue<intptr_t>(p) + pc_delta);
691 DCHECK(!buffer_overflow());
694void Assembler::emit_operand(
int code, Operand adr) {
696 if (adr.is_label_operand()) {
697 emit_label_operand(code, adr.label().label, adr.label().addend);
701 const size_t length = adr.memory().len;
706 DCHECK_EQ((adr.memory().buf[0] & 0x38), 0);
707 uint8_t opcode_extension = code << 3;
717 uint32_t lower_four_bytes = ReadUnalignedValue<uint32_t>(src);
718 lower_four_bytes |= opcode_extension;
719 uint16_t upper_two_bytes = ReadUnalignedValue<uint16_t>(src + length - 2);
720 WriteUnalignedValue<uint16_t>(dst + length - 2, upper_two_bytes);
721 WriteUnalignedValue<uint32_t>(dst, lower_four_bytes);
724 uint8_t first_byte = ReadUnalignedValue<uint8_t>(src);
725 first_byte |= opcode_extension;
728 uint16_t upper_two_bytes = ReadUnalignedValue<uint16_t>(src + length - 2);
729 WriteUnalignedValue<uint16_t>(dst + length - 2, upper_two_bytes);
731 WriteUnalignedValue<uint8_t>(dst, first_byte);
737void Assembler::emit_label_operand(
int code, Label*
label,
int addend) {
738 DCHECK(addend == 0 || (is_int8(addend) &&
label->is_bound()));
741 *
pc_++ = 5 | (code << 3);
742 if (
label->is_bound()) {
746 }
else if (
label->is_linked()) {
753 label->link_to(current);
759void Assembler::arithmetic_op(uint8_t opcode, Register
reg, Operand op,
761 EnsureSpace ensure_space(
this);
762 emit_rex(
reg, op, size);
764 emit_operand(
reg, op);
767void Assembler::arithmetic_op(uint8_t opcode, Register
reg, Register rm_reg,
769 EnsureSpace ensure_space(
this);
771 if (rm_reg.low_bits() == 4) {
773 emit_rex(rm_reg,
reg, size);
775 emit_modrm(rm_reg,
reg);
777 emit_rex(
reg, rm_reg, size);
779 emit_modrm(
reg, rm_reg);
783void Assembler::arithmetic_op_16(uint8_t opcode, Register
reg,
785 EnsureSpace ensure_space(
this);
787 if (rm_reg.low_bits() == 4) {
790 emit_optional_rex_32(rm_reg,
reg);
792 emit_modrm(rm_reg,
reg);
795 emit_optional_rex_32(
reg, rm_reg);
797 emit_modrm(
reg, rm_reg);
801void Assembler::arithmetic_op_16(uint8_t opcode, Register
reg, Operand rm_reg) {
802 EnsureSpace ensure_space(
this);
804 emit_optional_rex_32(
reg, rm_reg);
806 emit_operand(
reg, rm_reg);
809void Assembler::arithmetic_op_8(uint8_t opcode, Register
reg, Operand op) {
810 EnsureSpace ensure_space(
this);
811 if (!
reg.is_byte_register()) {
812 emit_rex_32(
reg, op);
814 emit_optional_rex_32(
reg, op);
817 emit_operand(
reg, op);
820void Assembler::arithmetic_op_8(uint8_t opcode, Register
reg, Register rm_reg) {
821 EnsureSpace ensure_space(
this);
823 if (rm_reg.low_bits() == 4) {
825 if (!rm_reg.is_byte_register() || !
reg.is_byte_register()) {
827 emit_rex_32(rm_reg,
reg);
830 emit_modrm(rm_reg,
reg);
832 if (!
reg.is_byte_register() || !rm_reg.is_byte_register()) {
834 emit_rex_32(
reg, rm_reg);
837 emit_modrm(
reg, rm_reg);
841void Assembler::immediate_arithmetic_op(uint8_t subcode, Register dst,
842 Immediate src,
int size) {
843 EnsureSpace ensure_space(
this);
845 if (is_int8(src.value_) && RelocInfo::IsNoInfo(src.rmode_)) {
847 emit_modrm(subcode, dst);
849 }
else if (dst == rax) {
850 emit(0x05 | (subcode << 3));
854 emit_modrm(subcode, dst);
859void Assembler::immediate_arithmetic_op(uint8_t subcode, Operand dst,
860 Immediate src,
int size) {
861 EnsureSpace ensure_space(
this);
863 if (is_int8(src.value_) && RelocInfo::IsNoInfo(src.rmode_)) {
865 emit_operand(subcode, dst);
869 emit_operand(subcode, dst);
874void Assembler::immediate_arithmetic_op_16(uint8_t subcode, Register dst,
876 EnsureSpace ensure_space(
this);
878 emit_optional_rex_32(dst);
879 if (is_int8(src.value_)) {
881 emit_modrm(subcode, dst);
883 }
else if (dst == rax) {
884 emit(0x05 | (subcode << 3));
888 emit_modrm(subcode, dst);
893void Assembler::immediate_arithmetic_op_16(uint8_t subcode, Operand dst,
895 EnsureSpace ensure_space(
this);
897 emit_optional_rex_32(dst);
898 if (is_int8(src.value_)) {
900 emit_operand(subcode, dst);
904 emit_operand(subcode, dst);
909void Assembler::immediate_arithmetic_op_8(uint8_t subcode, Operand dst,
911 EnsureSpace ensure_space(
this);
912 emit_optional_rex_32(dst);
913 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
915 emit_operand(subcode, dst);
919void Assembler::immediate_arithmetic_op_8(uint8_t subcode, Register dst,
921 EnsureSpace ensure_space(
this);
922 if (!dst.is_byte_register()) {
926 DCHECK(is_int8(src.value_) || is_uint8(src.value_));
928 emit(0x04 | (subcode << 3));
932 emit_modrm(subcode, dst);
937void Assembler::shift(Register dst, Immediate shift_amount,
int subcode,
939 EnsureSpace ensure_space(
this);
940 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
941 : is_uint5(shift_amount.value_));
942 if (shift_amount.value_ == 1) {
945 emit_modrm(subcode, dst);
949 emit_modrm(subcode, dst);
950 emit(shift_amount.value_);
954void Assembler::shift(Operand dst, Immediate shift_amount,
int subcode,
956 EnsureSpace ensure_space(
this);
957 DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
958 : is_uint5(shift_amount.value_));
959 if (shift_amount.value_ == 1) {
962 emit_operand(subcode, dst);
966 emit_operand(subcode, dst);
967 emit(shift_amount.value_);
971void Assembler::shift(Register dst,
int subcode,
int size) {
972 EnsureSpace ensure_space(
this);
975 emit_modrm(subcode, dst);
978void Assembler::shift(Operand dst,
int subcode,
int size) {
979 EnsureSpace ensure_space(
this);
982 emit_operand(subcode, dst);
985void Assembler::bswapl(Register dst) {
986 EnsureSpace ensure_space(
this);
987 emit_optional_rex_32(dst);
989 emit(0xC8 + dst.low_bits());
992void Assembler::bswapq(Register dst) {
993 EnsureSpace ensure_space(
this);
996 emit(0xC8 + dst.low_bits());
999void Assembler::btq(Operand dst, Register src) {
1000 EnsureSpace ensure_space(
this);
1001 emit_rex_64(src, dst);
1004 emit_operand(src, dst);
1007void Assembler::btsq(Operand dst, Register src) {
1008 EnsureSpace ensure_space(
this);
1009 emit_rex_64(src, dst);
1012 emit_operand(src, dst);
1015void Assembler::btsq(Register dst, Immediate imm8) {
1016 EnsureSpace ensure_space(
this);
1020 emit_modrm(0x5, dst);
1024void Assembler::btrq(Register dst, Immediate imm8) {
1025 EnsureSpace ensure_space(
this);
1029 emit_modrm(0x6, dst);
1033void Assembler::bsrl(Register dst, Register src) {
1034 EnsureSpace ensure_space(
this);
1035 emit_optional_rex_32(dst, src);
1038 emit_modrm(dst, src);
1041void Assembler::bsrl(Register dst, Operand src) {
1042 EnsureSpace ensure_space(
this);
1043 emit_optional_rex_32(dst, src);
1046 emit_operand(dst, src);
1049void Assembler::bsrq(Register dst, Register src) {
1050 EnsureSpace ensure_space(
this);
1051 emit_rex_64(dst, src);
1054 emit_modrm(dst, src);
1057void Assembler::bsrq(Register dst, Operand src) {
1058 EnsureSpace ensure_space(
this);
1059 emit_rex_64(dst, src);
1062 emit_operand(dst, src);
1065void Assembler::bsfl(Register dst, Register src) {
1066 EnsureSpace ensure_space(
this);
1067 emit_optional_rex_32(dst, src);
1070 emit_modrm(dst, src);
1073void Assembler::bsfl(Register dst, Operand src) {
1074 EnsureSpace ensure_space(
this);
1075 emit_optional_rex_32(dst, src);
1078 emit_operand(dst, src);
1081void Assembler::bsfq(Register dst, Register src) {
1082 EnsureSpace ensure_space(
this);
1083 emit_rex_64(dst, src);
1086 emit_modrm(dst, src);
1089void Assembler::bsfq(Register dst, Operand src) {
1090 EnsureSpace ensure_space(
this);
1091 emit_rex_64(dst, src);
1094 emit_operand(dst, src);
1097void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t
mask) {
1098 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
1102void Assembler::pblendw(XMMRegister dst, XMMRegister src, uint8_t
mask) {
1103 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0E);
1107void Assembler::palignr(XMMRegister dst, Operand src, uint8_t
mask) {
1108 ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
1112void Assembler::palignr(XMMRegister dst, XMMRegister src, uint8_t
mask) {
1113 ssse3_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0F);
1117void Assembler::call(Label* L) {
1118 EnsureSpace ensure_space(
this);
1121 if (
L->is_bound()) {
1125 }
else if (
L->is_linked()) {
1132 L->link_to(current);
1136void Assembler::call(Handle<Code> target, RelocInfo::Mode rmode) {
1137 DCHECK(RelocInfo::IsCodeTarget(rmode));
1138 EnsureSpace ensure_space(
this);
1141 RecordRelocInfo(rmode);
1142 int code_target_index = AddCodeTarget(target);
1143 emitl(code_target_index);
1146void Assembler::near_call(intptr_t disp, RelocInfo::Mode rmode) {
1147 EnsureSpace ensure_space(
this);
1151 RecordRelocInfo(rmode);
1152 emitl(
static_cast<int32_t>(disp));
1155void Assembler::near_jmp(intptr_t disp, RelocInfo::Mode rmode) {
1156 EnsureSpace ensure_space(
this);
1160 if (!RelocInfo::IsNoInfo(rmode)) RecordRelocInfo(rmode);
1161 emitl(
static_cast<int32_t>(disp));
1164void Assembler::near_j(Condition cc, intptr_t disp, RelocInfo::Mode rmode) {
1165 EnsureSpace ensure_space(
this);
1170 if (!RelocInfo::IsNoInfo(rmode)) RecordRelocInfo(rmode);
1171 emitl(
static_cast<int32_t>(disp));
1174void Assembler::call(Register adr) {
1175 EnsureSpace ensure_space(
this);
1177 emit_optional_rex_32(adr);
1179 emit_modrm(0x2, adr);
1182void Assembler::call(Operand op) {
1183 EnsureSpace ensure_space(
this);
1185 emit_optional_rex_32(op);
1187 emit_operand(0x2, op);
1190void Assembler::clc() {
1191 EnsureSpace ensure_space(
this);
1195void Assembler::cld() {
1196 EnsureSpace ensure_space(
this);
1200void Assembler::cdq() {
1201 EnsureSpace ensure_space(
this);
1205void Assembler::cmovq(Condition cc, Register dst, Register src) {
1206 EnsureSpace ensure_space(
this);
1208 emit_rex_64(dst, src);
1211 emit_modrm(dst, src);
1214void Assembler::cmovq(Condition cc, Register dst, Operand src) {
1215 EnsureSpace ensure_space(
this);
1217 emit_rex_64(dst, src);
1220 emit_operand(dst, src);
1223void Assembler::cmovl(Condition cc, Register dst, Register src) {
1224 EnsureSpace ensure_space(
this);
1226 emit_optional_rex_32(dst, src);
1229 emit_modrm(dst, src);
1232void Assembler::cmovl(Condition cc, Register dst, Operand src) {
1233 EnsureSpace ensure_space(
this);
1235 emit_optional_rex_32(dst, src);
1238 emit_operand(dst, src);
1241void Assembler::cmpb_al(Immediate imm8) {
1242 DCHECK(is_int8(imm8.value_) || is_uint8(imm8.value_));
1243 EnsureSpace ensure_space(
this);
1248void Assembler::lock() {
1249 EnsureSpace ensure_space(
this);
1253void Assembler::xaddb(Operand dst, Register src) {
1254 EnsureSpace ensure_space(
this);
1255 emit_optional_rex_8(src, dst);
1258 emit_operand(src, dst);
1261void Assembler::xaddw(Operand dst, Register src) {
1262 EnsureSpace ensure_space(
this);
1264 emit_optional_rex_32(src, dst);
1267 emit_operand(src, dst);
1270void Assembler::xaddl(Operand dst, Register src) {
1271 EnsureSpace ensure_space(
this);
1272 emit_optional_rex_32(src, dst);
1275 emit_operand(src, dst);
1278void Assembler::xaddq(Operand dst, Register src) {
1279 EnsureSpace ensure_space(
this);
1280 emit_rex(src, dst, kInt64Size);
1283 emit_operand(src, dst);
1286void Assembler::cmpxchgb(Operand dst, Register src) {
1287 EnsureSpace ensure_space(
this);
1288 if (!src.is_byte_register()) {
1290 emit_rex_32(src, dst);
1292 emit_optional_rex_32(src, dst);
1296 emit_operand(src, dst);
1299void Assembler::cmpxchgw(Operand dst, Register src) {
1300 EnsureSpace ensure_space(
this);
1302 emit_optional_rex_32(src, dst);
1305 emit_operand(src, dst);
1308void Assembler::emit_cmpxchg(Operand dst, Register src,
int size) {
1309 EnsureSpace ensure_space(
this);
1310 emit_rex(src, dst, size);
1313 emit_operand(src, dst);
1316void Assembler::mfence() {
1317 EnsureSpace ensure_space(
this);
1323void Assembler::lfence() {
1324 EnsureSpace ensure_space(
this);
1330void Assembler::cpuid() {
1331 EnsureSpace ensure_space(
this);
1336void Assembler::cqo() {
1337 EnsureSpace ensure_space(
this);
1342void Assembler::emit_dec(Register dst,
int size) {
1343 EnsureSpace ensure_space(
this);
1344 emit_rex(dst, size);
1346 emit_modrm(0x1, dst);
1349void Assembler::emit_dec(Operand dst,
int size) {
1350 EnsureSpace ensure_space(
this);
1351 emit_rex(dst, size);
1353 emit_operand(1, dst);
1356void Assembler::decb(Register dst) {
1357 EnsureSpace ensure_space(
this);
1358 if (!dst.is_byte_register()) {
1363 emit_modrm(0x1, dst);
1366void Assembler::decb(Operand dst) {
1367 EnsureSpace ensure_space(
this);
1368 emit_optional_rex_32(dst);
1370 emit_operand(1, dst);
1373void Assembler::hlt() {
1374 EnsureSpace ensure_space(
this);
1378void Assembler::endbr64() {
1379#ifdef V8_ENABLE_CET_IBT
1380 EnsureSpace ensure_space(
this);
1388void Assembler::emit_idiv(Register src,
int size) {
1389 EnsureSpace ensure_space(
this);
1390 emit_rex(src, size);
1392 emit_modrm(0x7, src);
1395void Assembler::emit_div(Register src,
int size) {
1396 EnsureSpace ensure_space(
this);
1397 emit_rex(src, size);
1399 emit_modrm(0x6, src);
1402void Assembler::emit_imul(Register src,
int size) {
1403 EnsureSpace ensure_space(
this);
1404 emit_rex(src, size);
1406 emit_modrm(0x5, src);
1409void Assembler::emit_imul(Operand src,
int size) {
1410 EnsureSpace ensure_space(
this);
1411 emit_rex(src, size);
1413 emit_operand(0x5, src);
1416void Assembler::emit_imul(Register dst, Register src,
int size) {
1417 EnsureSpace ensure_space(
this);
1418 emit_rex(dst, src, size);
1421 emit_modrm(dst, src);
1424void Assembler::emit_imul(Register dst, Operand src,
int size) {
1425 EnsureSpace ensure_space(
this);
1426 emit_rex(dst, src, size);
1429 emit_operand(dst, src);
1432void Assembler::emit_imul(Register dst, Register src, Immediate imm,
int size) {
1433 EnsureSpace ensure_space(
this);
1434 emit_rex(dst, src, size);
1435 if (is_int8(imm.value_)) {
1437 emit_modrm(dst, src);
1441 emit_modrm(dst, src);
1446void Assembler::emit_imul(Register dst, Operand src, Immediate imm,
int size) {
1447 EnsureSpace ensure_space(
this);
1448 emit_rex(dst, src, size);
1449 if (is_int8(imm.value_)) {
1451 emit_operand(dst, src);
1455 emit_operand(dst, src);
1460void Assembler::emit_inc(Register dst,
int size) {
1461 EnsureSpace ensure_space(
this);
1462 emit_rex(dst, size);
1464 emit_modrm(0x0, dst);
1467void Assembler::emit_inc(Operand dst,
int size) {
1468 EnsureSpace ensure_space(
this);
1469 emit_rex(dst, size);
1471 emit_operand(0, dst);
1474void Assembler::int3() {
1475 EnsureSpace ensure_space(
this);
1479void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1480 EnsureSpace ensure_space(
this);
1482 if (
L->is_bound()) {
1483 const int short_size = 2;
1484 const int long_size = 6;
1496 if (is_int8(offs - short_size) && !predictable_code_size()) {
1499 emit((offs - short_size) & 0xFF);
1504 emitl(offs - long_size);
1506 }
else if (distance == Label::kNear) {
1509 uint8_t disp = 0x00;
1510 if (
L->is_near_linked()) {
1513 disp =
static_cast<uint8_t
>(
offset & 0xFF);
1518 auto jump_opt = jump_optimization_info();
1520 if (jump_opt->is_optimizing() &&
1521 is_optimizable_farjmp(jump_opt->farjmp_num++)) {
1528 if (jump_opt->is_collecting()) {
1529 jump_opt->farjmps.push_back({
pc_offset(), 2, 0});
1532 if (
L->is_linked()) {
1547 L->link_to(current);
1552void Assembler::j(Condition cc, Address entry, RelocInfo::Mode rmode) {
1553 DCHECK(RelocInfo::IsWasmStubCall(rmode));
1554 EnsureSpace ensure_space(
this);
1558 RecordRelocInfo(rmode);
1559 emitl(
static_cast<int32_t>(entry));
1562void Assembler::j(Condition cc, Handle<Code> target, RelocInfo::Mode rmode) {
1563 EnsureSpace ensure_space(
this);
1568 DCHECK(RelocInfo::IsCodeTarget(rmode));
1569 RecordRelocInfo(rmode);
1570 int code_target_index = AddCodeTarget(target);
1571 emitl(code_target_index);
1574void Assembler::jmp_rel(int32_t
offset) {
1575 EnsureSpace ensure_space(
this);
1577 constexpr int32_t kShortJmpDisplacement = 1 +
sizeof(int8_t);
1579 DCHECK_LE(std::numeric_limits<int32_t>::min() + kNearJmpDisplacement,
offset);
1580 if (is_int8(
offset - kShortJmpDisplacement) && !predictable_code_size()) {
1583 emit(
offset - kShortJmpDisplacement);
1587 emitl(
offset - kNearJmpDisplacement);
1591void Assembler::jmp(Label* L, Label::Distance distance) {
1592 const int long_size =
sizeof(
int32_t);
1594 if (
L->is_bound()) {
1601 EnsureSpace ensure_space(
this);
1602 if (distance == Label::kNear) {
1604 uint8_t disp = 0x00;
1605 if (
L->is_near_linked()) {
1608 disp =
static_cast<uint8_t
>(
offset & 0xFF);
1613 auto jump_opt = jump_optimization_info();
1615 if (jump_opt->is_optimizing() &&
1616 is_optimizable_farjmp(jump_opt->farjmp_num++)) {
1622 if (jump_opt->is_collecting()) {
1623 jump_opt->farjmps.push_back({
pc_offset(), 1, 0});
1626 if (
L->is_linked()) {
1640 L->link_to(current);
1645void Assembler::jmp(Handle<Code> target, RelocInfo::Mode rmode) {
1646 DCHECK(RelocInfo::IsCodeTarget(rmode));
1647 EnsureSpace ensure_space(
this);
1650 RecordRelocInfo(rmode);
1651 int code_target_index = AddCodeTarget(target);
1652 emitl(code_target_index);
1655void Assembler::jmp(Register target,
bool notrack) {
1656 EnsureSpace ensure_space(
this);
1657#ifdef V8_ENABLE_CET_IBT
1664 emit_optional_rex_32(target);
1666 emit_modrm(0x4, target);
1669void Assembler::jmp(Operand src,
bool notrack) {
1670 EnsureSpace ensure_space(
this);
1671#ifdef V8_ENABLE_CET_IBT
1678 emit_optional_rex_32(src);
1680 emit_operand(0x4, src);
1683void Assembler::emit_lea(Register dst, Operand src,
int size) {
1684 EnsureSpace ensure_space(
this);
1685 emit_rex(dst, src, size);
1687 emit_operand(dst, src);
1690void Assembler::load_rax(Address value, RelocInfo::Mode mode) {
1691 EnsureSpace ensure_space(
this);
1694 emit(Immediate64(value, mode));
1697void Assembler::load_rax(ExternalReference ref) {
1698 load_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
1701void Assembler::leave() {
1702 EnsureSpace ensure_space(
this);
1706void Assembler::movb(Register dst, Operand src) {
1707 EnsureSpace ensure_space(
this);
1708 if (!dst.is_byte_register()) {
1710 emit_rex_32(dst, src);
1712 emit_optional_rex_32(dst, src);
1715 emit_operand(dst, src);
1718void Assembler::movb(Register dst, Immediate imm) {
1719 EnsureSpace ensure_space(
this);
1720 if (!dst.is_byte_register()) {
1724 emit(0xB0 + dst.low_bits());
1728void Assembler::movb(Operand dst, Register src) {
1729 EnsureSpace ensure_space(
this);
1730 if (!src.is_byte_register()) {
1732 emit_rex_32(src, dst);
1734 emit_optional_rex_32(src, dst);
1737 emit_operand(src, dst);
1740void Assembler::movb(Operand dst, Immediate imm) {
1741 EnsureSpace ensure_space(
this);
1742 emit_optional_rex_32(dst);
1744 emit_operand(0x0, dst);
1745 emit(
static_cast<uint8_t
>(imm.value_));
1748void Assembler::movw(Register dst, Operand src) {
1749 EnsureSpace ensure_space(
this);
1751 emit_optional_rex_32(dst, src);
1753 emit_operand(dst, src);
1756void Assembler::movw(Operand dst, Register src) {
1757 EnsureSpace ensure_space(
this);
1759 emit_optional_rex_32(src, dst);
1761 emit_operand(src, dst);
1764void Assembler::movw(Operand dst, Immediate imm) {
1765 EnsureSpace ensure_space(
this);
1767 emit_optional_rex_32(dst);
1769 emit_operand(0x0, dst);
1770 emit(
static_cast<uint8_t
>(imm.value_ & 0xFF));
1771 emit(
static_cast<uint8_t
>(imm.value_ >> 8));
1774void Assembler::emit_mov(Register dst, Operand src,
int size) {
1775 EnsureSpace ensure_space(
this);
1776 emit_rex(dst, src, size);
1778 emit_operand(dst, src);
1781void Assembler::emit_mov(Register dst, Register src,
int size) {
1782 EnsureSpace ensure_space(
this);
1783 if (src.low_bits() == 4) {
1784 emit_rex(src, dst, size);
1786 emit_modrm(src, dst);
1788 emit_rex(dst, src, size);
1790 emit_modrm(dst, src);
1793#if defined(V8_OS_WIN_X64)
1794 if (xdata_encoder_ && dst == rbp && src == rsp) {
1795 xdata_encoder_->onMovRbpRsp();
1800void Assembler::emit_mov(Operand dst, Register src,
int size) {
1801 EnsureSpace ensure_space(
this);
1802 emit_rex(src, dst, size);
1804 emit_operand(src, dst);
1807void Assembler::emit_mov(Register dst, Immediate value,
int size) {
1808 EnsureSpace ensure_space(
this);
1809 emit_rex(dst, size);
1810 if (size == kInt64Size) {
1812 emit_modrm(0x0, dst);
1815 emit(0xB8 + dst.low_bits());
1820void Assembler::emit_mov(Operand dst, Immediate value,
int size) {
1821 EnsureSpace ensure_space(
this);
1822 emit_rex(dst, size);
1824 emit_operand(0x0, dst);
1828void Assembler::emit_mov(Register dst, Immediate64 value,
int size) {
1830 if (constpool_.TryRecordEntry(value.value_, value.rmode_)) {
1833 emit_mov(dst, Operand(&
label, 0), size);
1836 EnsureSpace ensure_space(
this);
1837 emit_rex(dst, size);
1838 emit(0xB8 | dst.low_bits());
1843void Assembler::movq_imm64(Register dst, int64_t value) {
1844 EnsureSpace ensure_space(
this);
1845 emit_rex(dst, kInt64Size);
1846 emit(0xB8 | dst.low_bits());
1847 emitq(
static_cast<uint64_t
>(value));
1850void Assembler::movq_heap_number(Register dst,
double value) {
1851 EnsureSpace ensure_space(
this);
1852 emit_rex(dst, kInt64Size);
1853 emit(0xB8 | dst.low_bits());
1854 RequestHeapNumber(HeapNumberRequest(value));
1855 emit(Immediate64(kNullAddress, RelocInfo::FULL_EMBEDDED_OBJECT));
1860void Assembler::movl(Operand dst, Label* src) {
1861 EnsureSpace ensure_space(
this);
1862 emit_optional_rex_32(dst);
1864 emit_operand(0, dst);
1865 if (src->is_bound()) {
1869 }
else if (src->is_linked()) {
1871 src->link_to(
pc_offset() -
sizeof(int32_t));
1873 DCHECK(src->is_unused());
1876 src->link_to(current);
1880void Assembler::movsxbl(Register dst, Register src) {
1881 EnsureSpace ensure_space(
this);
1882 if (!src.is_byte_register()) {
1884 emit_rex_32(dst, src);
1886 emit_optional_rex_32(dst, src);
1890 emit_modrm(dst, src);
1893void Assembler::movsxbl(Register dst, Operand src) {
1894 EnsureSpace ensure_space(
this);
1895 emit_optional_rex_32(dst, src);
1898 emit_operand(dst, src);
1901void Assembler::movsxbq(Register dst, Operand src) {
1902 EnsureSpace ensure_space(
this);
1903 emit_rex_64(dst, src);
1906 emit_operand(dst, src);
1909void Assembler::movsxbq(Register dst, Register src) {
1910 EnsureSpace ensure_space(
this);
1911 emit_rex_64(dst, src);
1914 emit_modrm(dst, src);
1917void Assembler::movsxwl(Register dst, Register src) {
1918 EnsureSpace ensure_space(
this);
1919 emit_optional_rex_32(dst, src);
1922 emit_modrm(dst, src);
1925void Assembler::movsxwl(Register dst, Operand src) {
1926 EnsureSpace ensure_space(
this);
1927 emit_optional_rex_32(dst, src);
1930 emit_operand(dst, src);
1933void Assembler::movsxwq(Register dst, Operand src) {
1934 EnsureSpace ensure_space(
this);
1935 emit_rex_64(dst, src);
1938 emit_operand(dst, src);
1941void Assembler::movsxwq(Register dst, Register src) {
1942 EnsureSpace ensure_space(
this);
1943 emit_rex_64(dst, src);
1946 emit_modrm(dst, src);
1949void Assembler::movsxlq(Register dst, Register src) {
1950 EnsureSpace ensure_space(
this);
1951 emit_rex_64(dst, src);
1953 emit_modrm(dst, src);
1956void Assembler::movsxlq(Register dst, Operand src) {
1957 EnsureSpace ensure_space(
this);
1958 emit_rex_64(dst, src);
1960 emit_operand(dst, src);
1963void Assembler::emit_movzxb(Register dst, Operand src,
int size) {
1964 EnsureSpace ensure_space(
this);
1967 emit_optional_rex_32(dst, src);
1970 emit_operand(dst, src);
1973void Assembler::emit_movzxb(Register dst, Register src,
int size) {
1974 EnsureSpace ensure_space(
this);
1977 if (!src.is_byte_register()) {
1979 emit_rex_32(dst, src);
1981 emit_optional_rex_32(dst, src);
1985 emit_modrm(dst, src);
1988void Assembler::emit_movzxw(Register dst, Operand src,
int size) {
1989 EnsureSpace ensure_space(
this);
1992 emit_optional_rex_32(dst, src);
1995 emit_operand(dst, src);
1998void Assembler::emit_movzxw(Register dst, Register src,
int size) {
1999 EnsureSpace ensure_space(
this);
2002 emit_optional_rex_32(dst, src);
2005 emit_modrm(dst, src);
2008void Assembler::repmovsb() {
2009 EnsureSpace ensure_space(
this);
2014void Assembler::repmovsw() {
2015 EnsureSpace ensure_space(
this);
2021void Assembler::emit_repmovs(
int size) {
2022 EnsureSpace ensure_space(
this);
2028void Assembler::repstosl() {
2029 EnsureSpace ensure_space(
this);
2034void Assembler::repstosq() {
2035 EnsureSpace ensure_space(
this);
2041void Assembler::mull(Register src) {
2042 EnsureSpace ensure_space(
this);
2043 emit_optional_rex_32(src);
2045 emit_modrm(0x4, src);
2048void Assembler::mull(Operand src) {
2049 EnsureSpace ensure_space(
this);
2050 emit_optional_rex_32(src);
2052 emit_operand(0x4, src);
2055void Assembler::mulq(Register src) {
2056 EnsureSpace ensure_space(
this);
2059 emit_modrm(0x4, src);
2062void Assembler::mulq(Operand src) {
2063 EnsureSpace ensure_space(
this);
2066 emit_operand(0x4, src);
2069void Assembler::negb(Register
reg) {
2070 EnsureSpace ensure_space(
this);
2071 emit_optional_rex_8(
reg);
2073 emit_modrm(0x3,
reg);
2076void Assembler::negw(Register
reg) {
2077 EnsureSpace ensure_space(
this);
2079 emit_optional_rex_32(
reg);
2081 emit_modrm(0x3,
reg);
2084void Assembler::negl(Register
reg) {
2085 EnsureSpace ensure_space(
this);
2086 emit_optional_rex_32(
reg);
2088 emit_modrm(0x3,
reg);
2091void Assembler::negq(Register
reg) {
2092 EnsureSpace ensure_space(
this);
2095 emit_modrm(0x3,
reg);
2098void Assembler::negb(Operand op) {
2099 EnsureSpace ensure_space(
this);
2100 emit_optional_rex_32(op);
2102 emit_operand(0x3, op);
2105void Assembler::negw(Operand op) {
2106 EnsureSpace ensure_space(
this);
2108 emit_optional_rex_32(op);
2110 emit_operand(0x3, op);
2113void Assembler::negl(Operand op) {
2114 EnsureSpace ensure_space(
this);
2115 emit_optional_rex_32(op);
2117 emit_operand(0x3, op);
2120void Assembler::negq(Operand op) {
2121 EnsureSpace ensure_space(
this);
2124 emit_operand(0x3, op);
2127void Assembler::nop() {
2128 EnsureSpace ensure_space(
this);
2132void Assembler::emit_not(Register dst,
int size) {
2133 EnsureSpace ensure_space(
this);
2134 emit_rex(dst, size);
2136 emit_modrm(0x2, dst);
2139void Assembler::emit_not(Operand dst,
int size) {
2140 EnsureSpace ensure_space(
this);
2141 emit_rex(dst, size);
2143 emit_operand(2, dst);
2146void Assembler::Nop(
int n) {
2161 constexpr const char* kNopSequences =
2165 "\x66\x0F\x1F\x44\x00\x00"
2166 "\x0F\x1F\x80\x00\x00\x00\x00"
2167 "\x66\x0F\x1F\x84\x00\x00\x00\x00\x00";
2168 constexpr int8_t kNopOffsets[10] = {0, 1, 0, 2, 5, 10, 9, 15, 23, 22};
2171 EnsureSpace ensure_space(
this);
2172 int nop_bytes = std::min(n, 9);
2173 const char* sequence = kNopSequences + kNopOffsets[nop_bytes];
2174 memcpy(
pc_, sequence, nop_bytes);
2180void Assembler::emit_trace_instruction(Immediate markid) {
2181 EnsureSpace ensure_space(
this);
2182 if (
v8_flags.wasm_trace_native !=
nullptr &&
2183 !strcmp(
v8_flags.wasm_trace_native,
"cpuid")) {
2188 uint32_t magic_num = 0x4711 | (
static_cast<uint32_t
>(markid.value_) << 16);
2194 movl(rax, Immediate(magic_num));
2216void Assembler::popq(Register dst) {
2217 EnsureSpace ensure_space(
this);
2218 emit_optional_rex_32(dst);
2219 emit(0x58 | dst.low_bits());
2222void Assembler::popq(Operand dst) {
2223 EnsureSpace ensure_space(
this);
2224 emit_optional_rex_32(dst);
2226 emit_operand(0, dst);
2229void Assembler::popfq() {
2230 EnsureSpace ensure_space(
this);
2234void Assembler::pushq(Register src) {
2235 EnsureSpace ensure_space(
this);
2236 emit_optional_rex_32(src);
2237 emit(0x50 | src.low_bits());
2239#if defined(V8_OS_WIN_X64)
2240 if (xdata_encoder_ && src == rbp) {
2241 xdata_encoder_->onPushRbp();
2246void Assembler::pushq(Operand src) {
2247 EnsureSpace ensure_space(
this);
2248 emit_optional_rex_32(src);
2250 emit_operand(6, src);
2253void Assembler::pushq(Immediate value) {
2254 EnsureSpace ensure_space(
this);
2255 if (is_int8(value.value_)) {
2260 emitl(value.value_);
2264void Assembler::pushq_imm32(int32_t imm32) {
2265 EnsureSpace ensure_space(
this);
2270void Assembler::pushfq() {
2271 EnsureSpace ensure_space(
this);
2275void Assembler::incsspq(Register number_of_words) {
2276 EnsureSpace ensure_space(
this);
2278 emit_rex_64(number_of_words);
2281 emit(0xE8 | number_of_words.low_bits());
2284void Assembler::ret(
int imm16) {
2285 EnsureSpace ensure_space(
this);
2286 DCHECK(is_uint16(imm16));
2292 emit((imm16 >> 8) & 0xFF);
2296void Assembler::ud2() {
2297 EnsureSpace ensure_space(
this);
2302void Assembler::setcc(Condition cc, Register
reg) {
2303 EnsureSpace ensure_space(
this);
2305 if (!
reg.is_byte_register()) {
2311 emit_modrm(0x0,
reg);
2314void Assembler::shld(Register dst, Register src) {
2315 EnsureSpace ensure_space(
this);
2316 emit_rex_64(src, dst);
2319 emit_modrm(src, dst);
2322void Assembler::shrd(Register dst, Register src) {
2323 EnsureSpace ensure_space(
this);
2324 emit_rex_64(src, dst);
2327 emit_modrm(src, dst);
2330void Assembler::xchgb(Register
reg, Operand op) {
2331 EnsureSpace ensure_space(
this);
2332 if (!
reg.is_byte_register()) {
2334 emit_rex_32(
reg, op);
2336 emit_optional_rex_32(
reg, op);
2339 emit_operand(
reg, op);
2342void Assembler::xchgw(Register
reg, Operand op) {
2343 EnsureSpace ensure_space(
this);
2345 emit_optional_rex_32(
reg, op);
2347 emit_operand(
reg, op);
2350void Assembler::emit_xchg(Register dst, Register src,
int size) {
2351 EnsureSpace ensure_space(
this);
2352 if (src == rax || dst == rax) {
2353 Register other = src == rax ? dst : src;
2354 emit_rex(other, size);
2355 emit(0x90 | other.low_bits());
2356 }
else if (dst.low_bits() == 4) {
2357 emit_rex(dst, src, size);
2359 emit_modrm(dst, src);
2361 emit_rex(src, dst, size);
2363 emit_modrm(src, dst);
2367void Assembler::emit_xchg(Register dst, Operand src,
int size) {
2368 EnsureSpace ensure_space(
this);
2369 emit_rex(dst, src, size);
2371 emit_operand(dst, src);
2374void Assembler::store_rax(Address dst, RelocInfo::Mode mode) {
2375 EnsureSpace ensure_space(
this);
2378 emit(Immediate64(dst, mode));
2381void Assembler::store_rax(ExternalReference ref) {
2382 store_rax(ref.address(), RelocInfo::EXTERNAL_REFERENCE);
2385void Assembler::sub_sp_32(uint32_t imm) {
2388 emit_modrm(0x5, rsp);
2392void Assembler::testb(Register dst, Register src) {
2393 EnsureSpace ensure_space(
this);
2394 emit_test(dst, src,
sizeof(int8_t));
2397void Assembler::testb(Register
reg, Immediate
mask) {
2399 emit_test(
reg,
mask,
sizeof(int8_t));
2402void Assembler::testb(Operand op, Immediate
mask) {
2404 emit_test(op,
mask,
sizeof(int8_t));
2407void Assembler::testb(Operand op, Register
reg) {
2408 emit_test(op,
reg,
sizeof(int8_t));
2411void Assembler::testw(Register dst, Register src) {
2412 emit_test(dst, src,
sizeof(uint16_t));
2415void Assembler::testw(Register
reg, Immediate
mask) {
2416 emit_test(
reg,
mask,
sizeof(int16_t));
2419void Assembler::testw(Operand op, Immediate
mask) {
2420 emit_test(op,
mask,
sizeof(int16_t));
2423void Assembler::testw(Operand op, Register
reg) {
2424 emit_test(op,
reg,
sizeof(int16_t));
2427void Assembler::emit_test(Register dst, Register src,
int size) {
2428 EnsureSpace ensure_space(
this);
2429 if (src.low_bits() == 4) std::swap(dst, src);
2430 if (size ==
sizeof(int16_t)) {
2434 bool byte_operand = size ==
sizeof(int8_t);
2437 if (!src.is_byte_register() || !dst.is_byte_register()) {
2438 emit_rex_32(dst, src);
2441 emit_rex(dst, src, size);
2443 emit(byte_operand ? 0x84 : 0x85);
2444 emit_modrm(dst, src);
2447void Assembler::emit_test(Register
reg, Immediate
mask,
int size) {
2448 if (is_uint8(
mask.value_)) {
2449 size =
sizeof(int8_t);
2450 }
else if (is_uint16(
mask.value_)) {
2453 EnsureSpace ensure_space(
this);
2454 bool half_word = size ==
sizeof(
int16_t);
2459 bool byte_operand = size ==
sizeof(int8_t);
2462 if (!
reg.is_byte_register()) emit_rex_32(
reg);
2464 emit_rex(
reg, size);
2467 emit(byte_operand ? 0xA8 : 0xA9);
2469 emit(byte_operand ? 0xF6 : 0xF7);
2470 emit_modrm(0x0,
reg);
2474 }
else if (half_word) {
2481void Assembler::emit_test(Operand op, Immediate
mask,
int size) {
2482 if (is_uint8(
mask.value_)) {
2483 size =
sizeof(int8_t);
2484 }
else if (is_uint16(
mask.value_)) {
2487 EnsureSpace ensure_space(
this);
2488 bool half_word = size ==
sizeof(
int16_t);
2493 bool byte_operand = size ==
sizeof(int8_t);
2497 emit_rex(rax, op, size);
2498 emit(byte_operand ? 0xF6 : 0xF7);
2499 emit_operand(rax, op);
2502 }
else if (half_word) {
2509void Assembler::emit_test(Operand op, Register
reg,
int size) {
2510 EnsureSpace ensure_space(
this);
2511 if (size ==
sizeof(int16_t)) {
2515 bool byte_operand = size ==
sizeof(int8_t);
2518 if (!
reg.is_byte_register()) {
2520 emit_rex_32(
reg, op);
2522 emit_optional_rex_32(
reg, op);
2525 emit_rex(
reg, op, size);
2527 emit(byte_operand ? 0x84 : 0x85);
2528 emit_operand(
reg, op);
2533void Assembler::fld(
int i) {
2534 EnsureSpace ensure_space(
this);
2535 emit_farith(0xD9, 0xC0,
i);
2538void Assembler::fld1() {
2539 EnsureSpace ensure_space(
this);
2544void Assembler::fldz() {
2545 EnsureSpace ensure_space(
this);
2550void Assembler::fldpi() {
2551 EnsureSpace ensure_space(
this);
2556void Assembler::fldln2() {
2557 EnsureSpace ensure_space(
this);
2562void Assembler::fld_s(Operand adr) {
2563 EnsureSpace ensure_space(
this);
2564 emit_optional_rex_32(adr);
2566 emit_operand(0, adr);
2569void Assembler::fld_d(Operand adr) {
2570 EnsureSpace ensure_space(
this);
2571 emit_optional_rex_32(adr);
2573 emit_operand(0, adr);
2576void Assembler::fstp_s(Operand adr) {
2577 EnsureSpace ensure_space(
this);
2578 emit_optional_rex_32(adr);
2580 emit_operand(3, adr);
2583void Assembler::fstp_d(Operand adr) {
2584 EnsureSpace ensure_space(
this);
2585 emit_optional_rex_32(adr);
2587 emit_operand(3, adr);
2590void Assembler::fstp(
int index) {
2592 EnsureSpace ensure_space(
this);
2593 emit_farith(0xDD, 0xD8, index);
2596void Assembler::fild_s(Operand adr) {
2597 EnsureSpace ensure_space(
this);
2598 emit_optional_rex_32(adr);
2600 emit_operand(0, adr);
2603void Assembler::fild_d(Operand adr) {
2604 EnsureSpace ensure_space(
this);
2605 emit_optional_rex_32(adr);
2607 emit_operand(5, adr);
2610void Assembler::fistp_s(Operand adr) {
2611 EnsureSpace ensure_space(
this);
2612 emit_optional_rex_32(adr);
2614 emit_operand(3, adr);
2617void Assembler::fisttp_s(Operand adr) {
2619 EnsureSpace ensure_space(
this);
2620 emit_optional_rex_32(adr);
2622 emit_operand(1, adr);
2625void Assembler::fisttp_d(Operand adr) {
2627 EnsureSpace ensure_space(
this);
2628 emit_optional_rex_32(adr);
2630 emit_operand(1, adr);
2633void Assembler::fist_s(Operand adr) {
2634 EnsureSpace ensure_space(
this);
2635 emit_optional_rex_32(adr);
2637 emit_operand(2, adr);
2640void Assembler::fistp_d(Operand adr) {
2641 EnsureSpace ensure_space(
this);
2642 emit_optional_rex_32(adr);
2644 emit_operand(7, adr);
2647void Assembler::fabs() {
2648 EnsureSpace ensure_space(
this);
2653void Assembler::fchs() {
2654 EnsureSpace ensure_space(
this);
2659void Assembler::fcos() {
2660 EnsureSpace ensure_space(
this);
2665void Assembler::fsin() {
2666 EnsureSpace ensure_space(
this);
2671void Assembler::fptan() {
2672 EnsureSpace ensure_space(
this);
2677void Assembler::fyl2x() {
2678 EnsureSpace ensure_space(
this);
2683void Assembler::f2xm1() {
2684 EnsureSpace ensure_space(
this);
2689void Assembler::fscale() {
2690 EnsureSpace ensure_space(
this);
2695void Assembler::fninit() {
2696 EnsureSpace ensure_space(
this);
2701void Assembler::fadd(
int i) {
2702 EnsureSpace ensure_space(
this);
2703 emit_farith(0xDC, 0xC0,
i);
2706void Assembler::fsub(
int i) {
2707 EnsureSpace ensure_space(
this);
2708 emit_farith(0xDC, 0xE8,
i);
2711void Assembler::fisub_s(Operand adr) {
2712 EnsureSpace ensure_space(
this);
2713 emit_optional_rex_32(adr);
2715 emit_operand(4, adr);
2718void Assembler::fmul(
int i) {
2719 EnsureSpace ensure_space(
this);
2720 emit_farith(0xDC, 0xC8,
i);
2723void Assembler::fdiv(
int i) {
2724 EnsureSpace ensure_space(
this);
2725 emit_farith(0xDC, 0xF8,
i);
2728void Assembler::faddp(
int i) {
2729 EnsureSpace ensure_space(
this);
2730 emit_farith(0xDE, 0xC0,
i);
2733void Assembler::fsubp(
int i) {
2734 EnsureSpace ensure_space(
this);
2735 emit_farith(0xDE, 0xE8,
i);
2738void Assembler::fsubrp(
int i) {
2739 EnsureSpace ensure_space(
this);
2740 emit_farith(0xDE, 0xE0,
i);
2743void Assembler::fmulp(
int i) {
2744 EnsureSpace ensure_space(
this);
2745 emit_farith(0xDE, 0xC8,
i);
2748void Assembler::fdivp(
int i) {
2749 EnsureSpace ensure_space(
this);
2750 emit_farith(0xDE, 0xF8,
i);
2753void Assembler::fprem() {
2754 EnsureSpace ensure_space(
this);
2759void Assembler::fprem1() {
2760 EnsureSpace ensure_space(
this);
2765void Assembler::fxch(
int i) {
2766 EnsureSpace ensure_space(
this);
2767 emit_farith(0xD9, 0xC8,
i);
2770void Assembler::fincstp() {
2771 EnsureSpace ensure_space(
this);
2776void Assembler::ffree(
int i) {
2777 EnsureSpace ensure_space(
this);
2778 emit_farith(0xDD, 0xC0,
i);
2781void Assembler::ftst() {
2782 EnsureSpace ensure_space(
this);
2787void Assembler::fucomp(
int i) {
2788 EnsureSpace ensure_space(
this);
2789 emit_farith(0xDD, 0xE8,
i);
2792void Assembler::fucompp() {
2793 EnsureSpace ensure_space(
this);
2798void Assembler::fucomi(
int i) {
2799 EnsureSpace ensure_space(
this);
2804void Assembler::fucomip() {
2805 EnsureSpace ensure_space(
this);
2810void Assembler::fcompp() {
2811 EnsureSpace ensure_space(
this);
2816void Assembler::fnstsw_ax() {
2817 EnsureSpace ensure_space(
this);
2822void Assembler::fwait() {
2823 EnsureSpace ensure_space(
this);
2827void Assembler::frndint() {
2828 EnsureSpace ensure_space(
this);
2833void Assembler::fnclex() {
2834 EnsureSpace ensure_space(
this);
2839void Assembler::sahf() {
2843 EnsureSpace ensure_space(
this);
2847void Assembler::emit_farith(
int b1,
int b2,
int i) {
2848 DCHECK(is_uint8(b1) && is_uint8(b2));
2856void Assembler::movd(XMMRegister dst, Register src) {
2858 EnsureSpace ensure_space(
this);
2860 emit_optional_rex_32(dst, src);
2863 emit_sse_operand(dst, src);
2866void Assembler::movd(XMMRegister dst, Operand src) {
2868 EnsureSpace ensure_space(
this);
2870 emit_optional_rex_32(dst, src);
2873 emit_sse_operand(dst, src);
2876void Assembler::movd(Register dst, XMMRegister src) {
2878 EnsureSpace ensure_space(
this);
2880 emit_optional_rex_32(src, dst);
2883 emit_sse_operand(src, dst);
2886void Assembler::movq(XMMRegister dst, Register src) {
2889 EnsureSpace ensure_space(
this);
2891 emit_rex_64(dst, src);
2894 emit_sse_operand(dst, src);
2897void Assembler::movq(XMMRegister dst, Operand src) {
2900 EnsureSpace ensure_space(
this);
2902 emit_rex_64(dst, src);
2905 emit_sse_operand(dst, src);
2908void Assembler::movq(Register dst, XMMRegister src) {
2911 EnsureSpace ensure_space(
this);
2913 emit_rex_64(src, dst);
2916 emit_sse_operand(src, dst);
2919void Assembler::movq(XMMRegister dst, XMMRegister src) {
2922 EnsureSpace ensure_space(
this);
2923 if (dst.low_bits() == 4) {
2926 emit_optional_rex_32(dst, src);
2929 emit_sse_operand(dst, src);
2932 emit_optional_rex_32(src, dst);
2935 emit_sse_operand(src, dst);
2939void Assembler::movdqa(Operand dst, XMMRegister src) {
2940 EnsureSpace ensure_space(
this);
2942 emit_rex_64(src, dst);
2945 emit_sse_operand(src, dst);
2948void Assembler::movdqa(XMMRegister dst, Operand src) {
2949 EnsureSpace ensure_space(
this);
2951 emit_rex_64(dst, src);
2954 emit_sse_operand(dst, src);
2957void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
2958 EnsureSpace ensure_space(
this);
2960 emit_rex_64(src, dst);
2963 emit_sse_operand(src, dst);
2966void Assembler::movdqu(Operand dst, XMMRegister src) {
2967 EnsureSpace ensure_space(
this);
2969 emit_rex_64(src, dst);
2972 emit_sse_operand(src, dst);
2975void Assembler::movdqu(XMMRegister dst, Operand src) {
2976 EnsureSpace ensure_space(
this);
2978 emit_rex_64(dst, src);
2981 emit_sse_operand(dst, src);
2984void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
2985 EnsureSpace ensure_space(
this);
2987 emit_rex_64(dst, src);
2990 emit_sse_operand(dst, src);
2993void Assembler::pinsrw(XMMRegister dst, Register src, uint8_t imm8) {
2994 EnsureSpace ensure_space(
this);
2996 emit_optional_rex_32(dst, src);
2999 emit_sse_operand(dst, src);
3003void Assembler::pinsrw(XMMRegister dst, Operand src, uint8_t imm8) {
3004 EnsureSpace ensure_space(
this);
3006 emit_optional_rex_32(dst, src);
3009 emit_sse_operand(dst, src);
3013void Assembler::pextrq(Register dst, XMMRegister src, int8_t imm8) {
3014 DCHECK(IsEnabled(SSE4_1));
3015 EnsureSpace ensure_space(
this);
3017 emit_rex_64(src, dst);
3021 emit_sse_operand(src, dst);
3025void Assembler::pinsrq(XMMRegister dst, Register src, uint8_t imm8) {
3026 DCHECK(IsEnabled(SSE4_1));
3027 EnsureSpace ensure_space(
this);
3029 emit_rex_64(dst, src);
3033 emit_sse_operand(dst, src);
3037void Assembler::pinsrq(XMMRegister dst, Operand src, uint8_t imm8) {
3038 DCHECK(IsEnabled(SSE4_1));
3039 EnsureSpace ensure_space(
this);
3041 emit_rex_64(dst, src);
3045 emit_sse_operand(dst, src);
3049void Assembler::pinsrd(XMMRegister dst, Register src, uint8_t imm8) {
3050 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x22, imm8);
3053void Assembler::pinsrd(XMMRegister dst, Operand src, uint8_t imm8) {
3054 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x22);
3058void Assembler::pinsrb(XMMRegister dst, Register src, uint8_t imm8) {
3059 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x20, imm8);
3062void Assembler::pinsrb(XMMRegister dst, Operand src, uint8_t imm8) {
3063 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x20);
3067void Assembler::insertps(XMMRegister dst, XMMRegister src, uint8_t imm8) {
3069 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x21);
3073void Assembler::insertps(XMMRegister dst, Operand src, uint8_t imm8) {
3075 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x21);
3079void Assembler::movsd(Operand dst, XMMRegister src) {
3081 EnsureSpace ensure_space(
this);
3083 emit_optional_rex_32(src, dst);
3086 emit_sse_operand(src, dst);
3089void Assembler::movsd(XMMRegister dst, XMMRegister src) {
3091 EnsureSpace ensure_space(
this);
3093 emit_optional_rex_32(dst, src);
3096 emit_sse_operand(dst, src);
3099void Assembler::movsd(XMMRegister dst, Operand src) {
3101 EnsureSpace ensure_space(
this);
3103 emit_optional_rex_32(dst, src);
3106 emit_sse_operand(dst, src);
3109void Assembler::movaps(XMMRegister dst, XMMRegister src) {
3111 EnsureSpace ensure_space(
this);
3112 if (src.low_bits() == 4) {
3114 emit_optional_rex_32(src, dst);
3117 emit_sse_operand(src, dst);
3119 emit_optional_rex_32(dst, src);
3122 emit_sse_operand(dst, src);
3126void Assembler::movaps(XMMRegister dst, Operand src) {
3128 EnsureSpace ensure_space(
this);
3129 emit_optional_rex_32(dst, src);
3132 emit_sse_operand(dst, src);
3135void Assembler::shufps(XMMRegister dst, XMMRegister src, uint8_t imm8) {
3137 EnsureSpace ensure_space(
this);
3138 emit_optional_rex_32(dst, src);
3141 emit_sse_operand(dst, src);
3145void Assembler::movapd(XMMRegister dst, XMMRegister src) {
3147 EnsureSpace ensure_space(
this);
3148 if (src.low_bits() == 4) {
3151 emit_optional_rex_32(src, dst);
3154 emit_sse_operand(src, dst);
3157 emit_optional_rex_32(dst, src);
3160 emit_sse_operand(dst, src);
3164void Assembler::movupd(XMMRegister dst, Operand src) {
3165 EnsureSpace ensure_space(
this);
3167 emit_optional_rex_32(dst, src);
3170 emit_sse_operand(dst, src);
3173void Assembler::movupd(Operand dst, XMMRegister src) {
3174 EnsureSpace ensure_space(
this);
3176 emit_optional_rex_32(src, dst);
3179 emit_sse_operand(src, dst);
3182void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
3184 EnsureSpace ensure_space(
this);
3185 emit_optional_rex_32(dst, src);
3188 emit_sse_operand(dst, src);
3191void Assembler::ucomiss(XMMRegister dst, Operand src) {
3193 EnsureSpace ensure_space(
this);
3194 emit_optional_rex_32(dst, src);
3197 emit_sse_operand(dst, src);
3200void Assembler::movss(XMMRegister dst, XMMRegister src) {
3202 EnsureSpace ensure_space(
this);
3204 emit_optional_rex_32(dst, src);
3207 emit_sse_operand(dst, src);
3210void Assembler::movss(XMMRegister dst, Operand src) {
3212 EnsureSpace ensure_space(
this);
3214 emit_optional_rex_32(dst, src);
3217 emit_sse_operand(dst, src);
3220void Assembler::movss(Operand src, XMMRegister dst) {
3222 EnsureSpace ensure_space(
this);
3224 emit_optional_rex_32(dst, src);
3227 emit_sse_operand(dst, src);
3230void Assembler::movlps(XMMRegister dst, Operand src) {
3232 EnsureSpace ensure_space(
this);
3233 emit_optional_rex_32(dst, src);
3236 emit_sse_operand(dst, src);
3239void Assembler::movlps(Operand src, XMMRegister dst) {
3241 EnsureSpace ensure_space(
this);
3242 emit_optional_rex_32(dst, src);
3245 emit_sse_operand(dst, src);
3248void Assembler::movhps(XMMRegister dst, Operand src) {
3250 EnsureSpace ensure_space(
this);
3251 emit_optional_rex_32(dst, src);
3254 emit_sse_operand(dst, src);
3257void Assembler::movhps(Operand src, XMMRegister dst) {
3259 EnsureSpace ensure_space(
this);
3260 emit_optional_rex_32(dst, src);
3263 emit_sse_operand(dst, src);
3266void Assembler::cmpps(XMMRegister dst, XMMRegister src, int8_t cmp) {
3267 EnsureSpace ensure_space(
this);
3268 emit_optional_rex_32(dst, src);
3271 emit_sse_operand(dst, src);
3275void Assembler::cmpps(XMMRegister dst, Operand src, int8_t cmp) {
3276 EnsureSpace ensure_space(
this);
3277 emit_optional_rex_32(dst, src);
3280 emit_sse_operand(dst, src);
3284void Assembler::cmppd(XMMRegister dst, XMMRegister src, int8_t cmp) {
3285 EnsureSpace ensure_space(
this);
3287 emit_optional_rex_32(dst, src);
3290 emit_sse_operand(dst, src);
3294void Assembler::cmppd(XMMRegister dst, Operand src, int8_t cmp) {
3295 EnsureSpace ensure_space(
this);
3297 emit_optional_rex_32(dst, src);
3300 emit_sse_operand(dst, src);
3304void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
3305 sse2_instr(dst, src, 0xF3, 0x0F, 0xE6);
3308void Assembler::cvttss2si(Register dst, Operand src) {
3310 EnsureSpace ensure_space(
this);
3312 emit_optional_rex_32(dst, src);
3315 emit_operand(dst, src);
3318void Assembler::cvttss2si(Register dst, XMMRegister src) {
3320 EnsureSpace ensure_space(
this);
3322 emit_optional_rex_32(dst, src);
3325 emit_sse_operand(dst, src);
3328void Assembler::cvttsd2si(Register dst, Operand src) {
3330 EnsureSpace ensure_space(
this);
3332 emit_optional_rex_32(dst, src);
3335 emit_operand(dst, src);
3338void Assembler::cvttsd2si(Register dst, XMMRegister src) {
3340 EnsureSpace ensure_space(
this);
3342 emit_optional_rex_32(dst, src);
3345 emit_sse_operand(dst, src);
3348void Assembler::cvttss2siq(Register dst, XMMRegister src) {
3350 EnsureSpace ensure_space(
this);
3352 emit_rex_64(dst, src);
3355 emit_sse_operand(dst, src);
3358void Assembler::cvttss2siq(Register dst, Operand src) {
3360 EnsureSpace ensure_space(
this);
3362 emit_rex_64(dst, src);
3365 emit_sse_operand(dst, src);
3368void Assembler::cvttsd2siq(Register dst, XMMRegister src) {
3370 EnsureSpace ensure_space(
this);
3372 emit_rex_64(dst, src);
3375 emit_sse_operand(dst, src);
3378void Assembler::cvttsd2siq(Register dst, Operand src) {
3380 EnsureSpace ensure_space(
this);
3382 emit_rex_64(dst, src);
3385 emit_sse_operand(dst, src);
3388void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
3389 EnsureSpace ensure_space(
this);
3391 emit_rex_64(dst, src);
3394 emit_sse_operand(dst, src);
3397void Assembler::cvttps2dq(XMMRegister dst, XMMRegister src) {
3398 EnsureSpace ensure_space(
this);
3400 emit_rex_64(dst, src);
3403 emit_sse_operand(dst, src);
3406void Assembler::cvtlsi2sd(XMMRegister dst, Operand src) {
3408 EnsureSpace ensure_space(
this);
3410 emit_optional_rex_32(dst, src);
3413 emit_sse_operand(dst, src);
3416void Assembler::cvtlsi2sd(XMMRegister dst, Register src) {
3418 EnsureSpace ensure_space(
this);
3420 emit_optional_rex_32(dst, src);
3423 emit_sse_operand(dst, src);
3426void Assembler::cvtlsi2ss(XMMRegister dst, Operand src) {
3428 EnsureSpace ensure_space(
this);
3430 emit_optional_rex_32(dst, src);
3433 emit_sse_operand(dst, src);
3436void Assembler::cvtlsi2ss(XMMRegister dst, Register src) {
3437 EnsureSpace ensure_space(
this);
3439 emit_optional_rex_32(dst, src);
3442 emit_sse_operand(dst, src);
3445void Assembler::cvtqsi2ss(XMMRegister dst, Operand src) {
3447 EnsureSpace ensure_space(
this);
3449 emit_rex_64(dst, src);
3452 emit_sse_operand(dst, src);
3455void Assembler::cvtqsi2ss(XMMRegister dst, Register src) {
3457 EnsureSpace ensure_space(
this);
3459 emit_rex_64(dst, src);
3462 emit_sse_operand(dst, src);
3465void Assembler::cvtqsi2sd(XMMRegister dst, Operand src) {
3467 EnsureSpace ensure_space(
this);
3469 emit_rex_64(dst, src);
3472 emit_sse_operand(dst, src);
3475void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
3477 EnsureSpace ensure_space(
this);
3479 emit_rex_64(dst, src);
3482 emit_sse_operand(dst, src);
3485void Assembler::cvtsd2si(Register dst, XMMRegister src) {
3487 EnsureSpace ensure_space(
this);
3489 emit_optional_rex_32(dst, src);
3492 emit_sse_operand(dst, src);
3495void Assembler::cvtsd2siq(Register dst, XMMRegister src) {
3497 EnsureSpace ensure_space(
this);
3499 emit_rex_64(dst, src);
3502 emit_sse_operand(dst, src);
3505void Assembler::haddps(XMMRegister dst, XMMRegister src) {
3507 EnsureSpace ensure_space(
this);
3509 emit_optional_rex_32(dst, src);
3512 emit_sse_operand(dst, src);
3515void Assembler::haddps(XMMRegister dst, Operand src) {
3517 EnsureSpace ensure_space(
this);
3519 emit_optional_rex_32(dst, src);
3522 emit_sse_operand(dst, src);
3525void Assembler::cmpeqss(XMMRegister dst, XMMRegister src) {
3527 EnsureSpace ensure_space(
this);
3529 emit_optional_rex_32(dst, src);
3532 emit_sse_operand(dst, src);
3536void Assembler::cmpeqsd(XMMRegister dst, XMMRegister src) {
3538 EnsureSpace ensure_space(
this);
3540 emit_optional_rex_32(dst, src);
3543 emit_sse_operand(dst, src);
3547void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
3548 EnsureSpace ensure_space(
this);
3550 emit_optional_rex_32(dst, src);
3553 emit_sse_operand(dst, src);
3557void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3559 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0A);
3561 emit(
static_cast<uint8_t
>(mode) | 0x8);
3564void Assembler::roundss(XMMRegister dst, Operand src, RoundingMode mode) {
3566 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0A);
3568 emit(
static_cast<uint8_t
>(mode) | 0x8);
3571void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3573 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0B);
3575 emit(
static_cast<uint8_t
>(mode) | 0x8);
3578void Assembler::roundsd(XMMRegister dst, Operand src, RoundingMode mode) {
3580 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x0B);
3582 emit(
static_cast<uint8_t
>(mode) | 0x8);
3585void Assembler::roundps(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3587 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x08);
3589 emit(
static_cast<uint8_t
>(mode) | 0x8);
3592void Assembler::roundpd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3594 sse4_instr(dst, src, 0x66, 0x0F, 0x3A, 0x09);
3596 emit(
static_cast<uint8_t
>(mode) | 0x8);
3599void Assembler::movmskpd(Register dst, XMMRegister src) {
3600 EnsureSpace ensure_space(
this);
3602 emit_optional_rex_32(dst, src);
3605 emit_sse_operand(dst, src);
3608void Assembler::movmskps(Register dst, XMMRegister src) {
3609 EnsureSpace ensure_space(
this);
3610 emit_optional_rex_32(dst, src);
3613 emit_sse_operand(dst, src);
3616void Assembler::pmovmskb(Register dst, XMMRegister src) {
3617 EnsureSpace ensure_space(
this);
3619 emit_optional_rex_32(dst, src);
3622 emit_sse_operand(dst, src);
3626#define VMOV_DUP(SIMDRegister, length) \
3627 void Assembler::vmovddup(SIMDRegister dst, SIMDRegister src) { \
3628 DCHECK(IsEnabled(AVX)); \
3629 EnsureSpace ensure_space(this); \
3630 emit_vex_prefix(dst, xmm0, src, k##length, kF2, k0F, kWIG); \
3632 emit_sse_operand(dst, src); \
3635 void Assembler::vmovddup(SIMDRegister dst, Operand src) { \
3636 DCHECK(IsEnabled(AVX)); \
3637 EnsureSpace ensure_space(this); \
3638 emit_vex_prefix(dst, xmm0, src, k##length, kF2, k0F, kWIG); \
3640 emit_sse_operand(dst, src); \
3643 void Assembler::vmovshdup(SIMDRegister dst, SIMDRegister src) { \
3644 DCHECK(IsEnabled(AVX)); \
3645 EnsureSpace ensure_space(this); \
3646 emit_vex_prefix(dst, xmm0, src, k##length, kF3, k0F, kWIG); \
3648 emit_sse_operand(dst, src); \
3650VMOV_DUP(XMMRegister, L128)
3651VMOV_DUP(YMMRegister, L256)
3654#define BROADCAST(suffix, SIMDRegister, length, opcode) \
3655 void Assembler::vbroadcast##suffix(SIMDRegister dst, Operand src) { \
3656 DCHECK(IsEnabled(AVX)); \
3657 EnsureSpace ensure_space(this); \
3658 emit_vex_prefix(dst, xmm0, src, k##length, k66, k0F38, kW0); \
3660 emit_sse_operand(dst, src); \
3662 void Assembler::vbroadcast##suffix(SIMDRegister dst, XMMRegister src) { \
3663 DCHECK(IsEnabled(AVX2)); \
3664 EnsureSpace ensure_space(this); \
3665 emit_vex_prefix(dst, xmm0, src, k##length, k66, k0F38, kW0); \
3667 emit_sse_operand(dst, src); \
3669BROADCAST(ss, XMMRegister, L128, 18)
3670BROADCAST(ss, YMMRegister, L256, 18)
3671BROADCAST(sd, YMMRegister, L256, 19)
3674void Assembler::vinserti128(YMMRegister dst, YMMRegister src1, XMMRegister src2,
3677 EnsureSpace ensure_space(
this);
3678 emit_vex_prefix(dst, src1, src2, kL256, k66, k0F3A, kW0);
3680 emit_sse_operand(dst, src2);
3684void Assembler::vperm2f128(YMMRegister dst, YMMRegister src1, YMMRegister src2,
3688 EnsureSpace ensure_space(
this);
3689 emit_vex_prefix(dst, src1, src2, kL256, k66, k0F3A, kW0);
3691 emit_sse_operand(dst, src2);
3695void Assembler::vextractf128(XMMRegister dst, YMMRegister src, uint8_t imm8) {
3697 EnsureSpace ensure_space(
this);
3698 emit_vex_prefix(src, xmm0, dst, kL256, k66, k0F3A, kW0);
3700 emit_sse_operand(src, dst);
3704template <
typename Reg1,
typename Reg2,
typename Op>
3705void Assembler::fma_instr(uint8_t op, Reg1 dst, Reg2 src1, Op src2,
3706 VectorLength l, SIMDPrefix pp, LeadingOpcode
m,
3709 EnsureSpace ensure_space(
this);
3710 emit_vex_prefix(dst, src1, src2, l, pp,
m, w);
3712 emit_sse_operand(dst, src2);
3716 uint8_t op, XMMRegister dst, XMMRegister src1, XMMRegister src2,
3717 VectorLength l, SIMDPrefix pp, LeadingOpcode
m, VexW w);
3720 uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2,
3721 VectorLength l, SIMDPrefix pp, LeadingOpcode
m, VexW w);
3724 uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2, VectorLength l,
3725 SIMDPrefix pp, LeadingOpcode
m, VexW w);
3728 uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2, VectorLength l,
3729 SIMDPrefix pp, LeadingOpcode
m, VexW w);
3731void Assembler::vmovd(XMMRegister dst, Register src) {
3733 EnsureSpace ensure_space(
this);
3734 XMMRegister isrc = XMMRegister::from_code(src.code());
3735 emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW0);
3737 emit_sse_operand(dst, src);
3740void Assembler::vmovd(XMMRegister dst, Operand src) {
3742 EnsureSpace ensure_space(
this);
3743 emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW0);
3745 emit_sse_operand(dst, src);
3748void Assembler::vmovd(Register dst, XMMRegister src) {
3750 EnsureSpace ensure_space(
this);
3751 XMMRegister idst = XMMRegister::from_code(dst.code());
3752 emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW0);
3754 emit_sse_operand(src, dst);
3757void Assembler::vmovq(XMMRegister dst, Register src) {
3759 EnsureSpace ensure_space(
this);
3760 XMMRegister isrc = XMMRegister::from_code(src.code());
3761 emit_vex_prefix(dst, xmm0, isrc, kL128, k66, k0F, kW1);
3763 emit_sse_operand(dst, src);
3766void Assembler::vmovq(XMMRegister dst, Operand src) {
3768 EnsureSpace ensure_space(
this);
3769 emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kW1);
3771 emit_sse_operand(dst, src);
3774void Assembler::vmovq(Register dst, XMMRegister src) {
3776 EnsureSpace ensure_space(
this);
3777 XMMRegister idst = XMMRegister::from_code(dst.code());
3778 emit_vex_prefix(src, xmm0, idst, kL128, k66, k0F, kW1);
3780 emit_sse_operand(src, dst);
3783void Assembler::vmovdqa(XMMRegister dst, Operand src) {
3785 EnsureSpace ensure_space(
this);
3786 emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kWIG);
3788 emit_sse_operand(dst, src);
3791void Assembler::vmovdqa(XMMRegister dst, XMMRegister src) {
3793 EnsureSpace ensure_space(
this);
3794 emit_vex_prefix(dst, xmm0, src, kL128, k66, k0F, kWIG);
3796 emit_sse_operand(dst, src);
3799void Assembler::vmovdqa(YMMRegister dst, Operand src) {
3801 EnsureSpace ensure_space(
this);
3802 emit_vex_prefix(dst, ymm0, src, kL256, k66, k0F, kWIG);
3804 emit_sse_operand(dst, src);
3807void Assembler::vmovdqa(YMMRegister dst, YMMRegister src) {
3809 EnsureSpace ensure_space(
this);
3810 emit_vex_prefix(dst, ymm0, src, kL256, k66, k0F, kWIG);
3812 emit_sse_operand(dst, src);
3815void Assembler::vmovdqu(XMMRegister dst, Operand src) {
3817 EnsureSpace ensure_space(
this);
3818 emit_vex_prefix(dst, xmm0, src, kL128, kF3, k0F, kWIG);
3820 emit_sse_operand(dst, src);
3823void Assembler::vmovdqu(Operand dst, XMMRegister src) {
3825 EnsureSpace ensure_space(
this);
3826 emit_vex_prefix(src, xmm0, dst, kL128, kF3, k0F, kWIG);
3828 emit_sse_operand(src, dst);
3831void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
3833 EnsureSpace ensure_space(
this);
3834 emit_vex_prefix(src, xmm0, dst, kL128, kF3, k0F, kWIG);
3836 emit_sse_operand(src, dst);
3839void Assembler::vmovdqu(YMMRegister dst, Operand src) {
3841 EnsureSpace ensure_space(
this);
3842 emit_vex_prefix(dst, ymm0, src, kL256, kF3, k0F, kWIG);
3844 emit_sse_operand(dst, src);
3847void Assembler::vmovdqu(Operand dst, YMMRegister src) {
3849 EnsureSpace ensure_space(
this);
3850 emit_vex_prefix(src, ymm0, dst, kL256, kF3, k0F, kWIG);
3852 emit_sse_operand(src, dst);
3855void Assembler::vmovdqu(YMMRegister dst, YMMRegister src) {
3857 EnsureSpace ensure_space(
this);
3858 emit_vex_prefix(src, ymm0, dst, kL256, kF3, k0F, kWIG);
3860 emit_sse_operand(src, dst);
3863void Assembler::vmovlps(XMMRegister dst, XMMRegister src1, Operand src2) {
3865 EnsureSpace ensure_space(
this);
3866 emit_vex_prefix(dst, src1, src2, kL128, kNoPrefix, k0F, kWIG);
3868 emit_sse_operand(dst, src2);
3871void Assembler::vmovlps(Operand dst, XMMRegister src) {
3873 EnsureSpace ensure_space(
this);
3874 emit_vex_prefix(src, xmm0, dst, kL128, kNoPrefix, k0F, kWIG);
3876 emit_sse_operand(src, dst);
3879void Assembler::vmovhps(XMMRegister dst, XMMRegister src1, Operand src2) {
3881 EnsureSpace ensure_space(
this);
3882 emit_vex_prefix(dst, src1, src2, kL128, kNoPrefix, k0F, kWIG);
3884 emit_sse_operand(dst, src2);
3887void Assembler::vmovhps(Operand dst, XMMRegister src) {
3889 EnsureSpace ensure_space(
this);
3890 emit_vex_prefix(src, xmm0, dst, kL128, kNoPrefix, k0F, kWIG);
3892 emit_sse_operand(src, dst);
3895void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3896 XMMRegister src2, SIMDPrefix pp, LeadingOpcode
m, VexW w,
3897 CpuFeature feature) {
3898 DCHECK(IsEnabled(feature));
3899 DCHECK(feature == AVX || feature == AVX2 || feature == AVX_VNNI ||
3900 feature == AVX_VNNI_INT8);
3901 EnsureSpace ensure_space(
this);
3902 emit_vex_prefix(dst, src1, src2, kLIG, pp,
m, w);
3904 emit_sse_operand(dst, src2);
3907void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3908 Operand src2, SIMDPrefix pp, LeadingOpcode
m, VexW w,
3909 CpuFeature feature) {
3910 DCHECK(IsEnabled(feature));
3911 DCHECK(feature == AVX || feature == AVX2);
3912 EnsureSpace ensure_space(
this);
3913 emit_vex_prefix(dst, src1, src2, kLIG, pp,
m, w);
3915 emit_sse_operand(dst, src2);
3918template <
typename Reg1,
typename Reg2,
typename Op>
3919void Assembler::vinstr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, SIMDPrefix pp,
3920 LeadingOpcode
m, VexW w, CpuFeature feature) {
3921 DCHECK(IsEnabled(feature));
3922 DCHECK(feature == AVX || feature == AVX2 || feature == AVX_VNNI ||
3923 feature == AVX_VNNI_INT8);
3925 (std::is_same_v<Reg1, YMMRegister> || std::is_same_v<Reg2, YMMRegister>));
3926 EnsureSpace ensure_space(
this);
3927 emit_vex_prefix(dst, src1, src2, kL256, pp,
m, w);
3929 emit_sse_operand(dst, src2);
3933 uint8_t op, YMMRegister dst, YMMRegister src1, YMMRegister src2,
3934 SIMDPrefix pp, LeadingOpcode
m, VexW w, CpuFeature feature);
3936 uint8_t op, YMMRegister dst, XMMRegister src1, XMMRegister src2,
3937 SIMDPrefix pp, LeadingOpcode
m, VexW w, CpuFeature feature);
3939 uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2, SIMDPrefix pp,
3940 LeadingOpcode
m, VexW w, CpuFeature feature);
3942 uint8_t op, YMMRegister dst, YMMRegister src1, XMMRegister src2,
3943 SIMDPrefix pp, LeadingOpcode
m, VexW w, CpuFeature feature);
3945 uint8_t op, YMMRegister dst, XMMRegister src1, Operand src2, SIMDPrefix pp,
3946 LeadingOpcode
m, VexW w, CpuFeature feature);
3948 uint8_t op, YMMRegister dst, XMMRegister src1, YMMRegister src2,
3949 SIMDPrefix pp, LeadingOpcode
m, VexW w, CpuFeature feature);
3951void Assembler::vps(uint8_t op, XMMRegister dst, XMMRegister src1,
3954 EnsureSpace ensure_space(
this);
3955 emit_vex_prefix(dst, src1, src2, kL128, kNoPrefix, k0F, kWIG);
3957 emit_sse_operand(dst, src2);
3960void Assembler::vps(uint8_t op, YMMRegister dst, YMMRegister src1,
3963 EnsureSpace ensure_space(
this);
3964 emit_vex_prefix(dst, src1, src2, kL256, kNoPrefix, k0F, kWIG);
3966 emit_sse_operand(dst, src2);
3969void Assembler::vps(uint8_t op, XMMRegister dst, XMMRegister src1,
3972 EnsureSpace ensure_space(
this);
3973 emit_vex_prefix(dst, src1, src2, kL128, kNoPrefix, k0F, kWIG);
3975 emit_sse_operand(dst, src2);
3978void Assembler::vps(uint8_t op, YMMRegister dst, YMMRegister src1,
3981 EnsureSpace ensure_space(
this);
3982 emit_vex_prefix(dst, src1, src2, kL256, kNoPrefix, k0F, kWIG);
3984 emit_sse_operand(dst, src2);
3987void Assembler::vps(uint8_t op, XMMRegister dst, XMMRegister src1,
3988 XMMRegister src2, uint8_t imm8) {
3990 EnsureSpace ensure_space(
this);
3991 emit_vex_prefix(dst, src1, src2, kL128, kNoPrefix, k0F, kWIG);
3993 emit_sse_operand(dst, src2);
3997void Assembler::vps(uint8_t op, YMMRegister dst, YMMRegister src1,
3998 YMMRegister src2, uint8_t imm8) {
4000 EnsureSpace ensure_space(
this);
4001 emit_vex_prefix(dst, src1, src2, kL256, kNoPrefix, k0F, kWIG);
4003 emit_sse_operand(dst, src2);
4007#define VPD(DSTRegister, SRCRegister, length) \
4008 void Assembler::vpd(uint8_t op, DSTRegister dst, SRCRegister src1, \
4009 SRCRegister src2) { \
4010 DCHECK(IsEnabled(AVX)); \
4011 EnsureSpace ensure_space(this); \
4012 emit_vex_prefix(dst, src1, src2, k##length, k66, k0F, kWIG); \
4014 emit_sse_operand(dst, src2); \
4017 void Assembler::vpd(uint8_t op, DSTRegister dst, SRCRegister src1, \
4019 DCHECK(IsEnabled(AVX)); \
4020 EnsureSpace ensure_space(this); \
4021 emit_vex_prefix(dst, src1, src2, k##length, k66, k0F, kWIG); \
4023 emit_sse_operand(dst, src2); \
4025VPD(XMMRegister, XMMRegister, L128)
4026VPD(XMMRegister, YMMRegister, L256)
4027VPD(YMMRegister, YMMRegister, L256)
4030#define F16C(Dst, Src, Pref, Op, PP, Tmp) \
4031 DCHECK(IsEnabled(F16C)); \
4032 EnsureSpace ensure_space(this); \
4033 emit_vex_prefix(Dst, Tmp, Src, PP, k66, Pref, kW0); \
4035 emit_sse_operand(Dst, Src);
4037void Assembler::vcvtph2ps(XMMRegister dst, XMMRegister src) {
4038 F16C(dst, src, k0F38, 0x13, kLIG, xmm0);
4041void Assembler::vcvtph2ps(YMMRegister dst, XMMRegister src) {
4042 F16C(dst, src, k0F38, 0x13, kL256, ymm0);
4045void Assembler::vcvtps2ph(XMMRegister dst, YMMRegister src, uint8_t imm8) {
4046 F16C(src, dst, k0F3A, 0x1D, kL256, xmm0);
4050void Assembler::vcvtps2ph(XMMRegister dst, XMMRegister src, uint8_t imm8) {
4051 F16C(src, dst, k0F3A, 0x1D, kLIG, ymm0);
4057void Assembler::vucomiss(XMMRegister dst, XMMRegister src) {
4059 EnsureSpace ensure_space(
this);
4060 emit_vex_prefix(dst, xmm0, src, kLIG, kNoPrefix, k0F, kWIG);
4062 emit_sse_operand(dst, src);
4065void Assembler::vucomiss(XMMRegister dst, Operand src) {
4067 EnsureSpace ensure_space(
this);
4068 emit_vex_prefix(dst, xmm0, src, kLIG, kNoPrefix, k0F, kWIG);
4070 emit_sse_operand(dst, src);
4073void Assembler::vpmovmskb(Register dst, XMMRegister src) {
4074 XMMRegister idst = XMMRegister::from_code(dst.code());
4076 EnsureSpace ensure_space(
this);
4077 emit_vex_prefix(idst, xmm0, src, kL128, k66, k0F, kWIG);
4079 emit_sse_operand(idst, src);
4082void Assembler::vss(uint8_t op, XMMRegister dst, XMMRegister src1,
4085 EnsureSpace ensure_space(
this);
4086 emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
4088 emit_sse_operand(dst, src2);
4091void Assembler::vss(uint8_t op, XMMRegister dst, XMMRegister src1,
4094 EnsureSpace ensure_space(
this);
4095 emit_vex_prefix(dst, src1, src2, kLIG, kF3, k0F, kWIG);
4097 emit_sse_operand(dst, src2);
4100void Assembler::bmi1q(uint8_t op, Register
reg, Register vreg, Register rm) {
4102 EnsureSpace ensure_space(
this);
4103 emit_vex_prefix(
reg, vreg, rm, kLZ, kNoPrefix, k0F38, kW1);
4105 emit_modrm(
reg, rm);
4108void Assembler::bmi1q(uint8_t op, Register
reg, Register vreg, Operand rm) {
4110 EnsureSpace ensure_space(
this);
4111 emit_vex_prefix(
reg, vreg, rm, kLZ, kNoPrefix, k0F38, kW1);
4113 emit_operand(
reg, rm);
4116void Assembler::bmi1l(uint8_t op, Register
reg, Register vreg, Register rm) {
4118 EnsureSpace ensure_space(
this);
4119 emit_vex_prefix(
reg, vreg, rm, kLZ, kNoPrefix, k0F38, kW0);
4121 emit_modrm(
reg, rm);
4124void Assembler::bmi1l(uint8_t op, Register
reg, Register vreg, Operand rm) {
4126 EnsureSpace ensure_space(
this);
4127 emit_vex_prefix(
reg, vreg, rm, kLZ, kNoPrefix, k0F38, kW0);
4129 emit_operand(
reg, rm);
4132void Assembler::tzcntq(Register dst, Register src) {
4134 EnsureSpace ensure_space(
this);
4136 emit_rex_64(dst, src);
4139 emit_modrm(dst, src);
4142void Assembler::tzcntq(Register dst, Operand src) {
4144 EnsureSpace ensure_space(
this);
4146 emit_rex_64(dst, src);
4149 emit_operand(dst, src);
4152void Assembler::tzcntl(Register dst, Register src) {
4154 EnsureSpace ensure_space(
this);
4156 emit_optional_rex_32(dst, src);
4159 emit_modrm(dst, src);
4162void Assembler::tzcntl(Register dst, Operand src) {
4164 EnsureSpace ensure_space(
this);
4166 emit_optional_rex_32(dst, src);
4169 emit_operand(dst, src);
4172void Assembler::lzcntq(Register dst, Register src) {
4173 DCHECK(IsEnabled(LZCNT));
4174 EnsureSpace ensure_space(
this);
4176 emit_rex_64(dst, src);
4179 emit_modrm(dst, src);
4182void Assembler::lzcntq(Register dst, Operand src) {
4183 DCHECK(IsEnabled(LZCNT));
4184 EnsureSpace ensure_space(
this);
4186 emit_rex_64(dst, src);
4189 emit_operand(dst, src);
4192void Assembler::lzcntl(Register dst, Register src) {
4193 DCHECK(IsEnabled(LZCNT));
4194 EnsureSpace ensure_space(
this);
4196 emit_optional_rex_32(dst, src);
4199 emit_modrm(dst, src);
4202void Assembler::lzcntl(Register dst, Operand src) {
4203 DCHECK(IsEnabled(LZCNT));
4204 EnsureSpace ensure_space(
this);
4206 emit_optional_rex_32(dst, src);
4209 emit_operand(dst, src);
4212void Assembler::popcntq(Register dst, Register src) {
4213 DCHECK(IsEnabled(POPCNT));
4214 EnsureSpace ensure_space(
this);
4216 emit_rex_64(dst, src);
4219 emit_modrm(dst, src);
4222void Assembler::popcntq(Register dst, Operand src) {
4223 DCHECK(IsEnabled(POPCNT));
4224 EnsureSpace ensure_space(
this);
4226 emit_rex_64(dst, src);
4229 emit_operand(dst, src);
4232void Assembler::popcntl(Register dst, Register src) {
4233 DCHECK(IsEnabled(POPCNT));
4234 EnsureSpace ensure_space(
this);
4236 emit_optional_rex_32(dst, src);
4239 emit_modrm(dst, src);
4242void Assembler::popcntl(Register dst, Operand src) {
4243 DCHECK(IsEnabled(POPCNT));
4244 EnsureSpace ensure_space(
this);
4246 emit_optional_rex_32(dst, src);
4249 emit_operand(dst, src);
4252void Assembler::bmi2q(SIMDPrefix pp, uint8_t op, Register
reg, Register vreg,
4255 EnsureSpace ensure_space(
this);
4256 emit_vex_prefix(
reg, vreg, rm, kLZ, pp, k0F38, kW1);
4258 emit_modrm(
reg, rm);
4261void Assembler::bmi2q(SIMDPrefix pp, uint8_t op, Register
reg, Register vreg,
4264 EnsureSpace ensure_space(
this);
4265 emit_vex_prefix(
reg, vreg, rm, kLZ, pp, k0F38, kW1);
4267 emit_operand(
reg, rm);
4270void Assembler::bmi2l(SIMDPrefix pp, uint8_t op, Register
reg, Register vreg,
4273 EnsureSpace ensure_space(
this);
4274 emit_vex_prefix(
reg, vreg, rm, kLZ, pp, k0F38, kW0);
4276 emit_modrm(
reg, rm);
4279void Assembler::bmi2l(SIMDPrefix pp, uint8_t op, Register
reg, Register vreg,
4282 EnsureSpace ensure_space(
this);
4283 emit_vex_prefix(
reg, vreg, rm, kLZ, pp, k0F38, kW0);
4285 emit_operand(
reg, rm);
4288void Assembler::rorxq(Register dst, Register src, uint8_t imm8) {
4291 Register vreg = Register::from_code(0);
4292 EnsureSpace ensure_space(
this);
4293 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
4295 emit_modrm(dst, src);
4299void Assembler::rorxq(Register dst, Operand src, uint8_t imm8) {
4302 Register vreg = Register::from_code(0);
4303 EnsureSpace ensure_space(
this);
4304 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW1);
4306 emit_operand(dst, src);
4310void Assembler::rorxl(Register dst, Register src, uint8_t imm8) {
4313 Register vreg = Register::from_code(0);
4314 EnsureSpace ensure_space(
this);
4315 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
4317 emit_modrm(dst, src);
4321void Assembler::rorxl(Register dst, Operand src, uint8_t imm8) {
4324 Register vreg = Register::from_code(0);
4325 EnsureSpace ensure_space(
this);
4326 emit_vex_prefix(dst, vreg, src, kLZ, kF2, k0F3A, kW0);
4328 emit_operand(dst, src);
4332void Assembler::pause() {
4337void Assembler::movups(XMMRegister dst, XMMRegister src) {
4338 EnsureSpace ensure_space(
this);
4339 if (src.low_bits() == 4) {
4341 emit_optional_rex_32(src, dst);
4344 emit_sse_operand(src, dst);
4346 emit_optional_rex_32(dst, src);
4349 emit_sse_operand(dst, src);
4353void Assembler::movups(XMMRegister dst, Operand src) {
4354 EnsureSpace ensure_space(
this);
4355 emit_optional_rex_32(dst, src);
4358 emit_sse_operand(dst, src);
4361void Assembler::movups(Operand dst, XMMRegister src) {
4362 EnsureSpace ensure_space(
this);
4363 emit_optional_rex_32(src, dst);
4366 emit_sse_operand(src, dst);
4369void Assembler::sse_instr(XMMRegister dst, XMMRegister src, uint8_t escape,
4371 EnsureSpace ensure_space(
this);
4372 emit_optional_rex_32(dst, src);
4375 emit_sse_operand(dst, src);
4378void Assembler::sse_instr(XMMRegister dst, Operand src, uint8_t escape,
4380 EnsureSpace ensure_space(
this);
4381 emit_optional_rex_32(dst, src);
4384 emit_sse_operand(dst, src);
4387void Assembler::sse2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
4388 uint8_t escape, uint8_t opcode) {
4389 EnsureSpace ensure_space(
this);
4391 emit_optional_rex_32(dst, src);
4394 emit_sse_operand(dst, src);
4397void Assembler::sse2_instr(XMMRegister dst, Operand src, uint8_t prefix,
4398 uint8_t escape, uint8_t opcode) {
4399 EnsureSpace ensure_space(
this);
4401 emit_optional_rex_32(dst, src);
4404 emit_sse_operand(dst, src);
4407void Assembler::ssse3_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
4408 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4409 DCHECK(IsEnabled(SSSE3));
4410 EnsureSpace ensure_space(
this);
4412 emit_optional_rex_32(dst, src);
4416 emit_sse_operand(dst, src);
4419void Assembler::ssse3_instr(XMMRegister dst, Operand src, uint8_t prefix,
4420 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4421 DCHECK(IsEnabled(SSSE3));
4422 EnsureSpace ensure_space(
this);
4424 emit_optional_rex_32(dst, src);
4428 emit_sse_operand(dst, src);
4431void Assembler::sse4_instr(XMMRegister dst, Register src, uint8_t prefix,
4432 uint8_t escape1, uint8_t escape2, uint8_t opcode,
4435 DCHECK(IsEnabled(SSE4_1));
4436 EnsureSpace ensure_space(
this);
4438 emit_optional_rex_32(dst, src);
4442 emit_sse_operand(dst, src);
4446void Assembler::sse4_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
4447 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4448 DCHECK(IsEnabled(SSE4_1));
4449 EnsureSpace ensure_space(
this);
4451 emit_optional_rex_32(dst, src);
4455 emit_sse_operand(dst, src);
4458void Assembler::sse4_instr(XMMRegister dst, Operand src, uint8_t prefix,
4459 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4460 DCHECK(IsEnabled(SSE4_1));
4461 EnsureSpace ensure_space(
this);
4463 emit_optional_rex_32(dst, src);
4467 emit_sse_operand(dst, src);
4470void Assembler::sse4_instr(Register dst, XMMRegister src, uint8_t prefix,
4471 uint8_t escape1, uint8_t escape2, uint8_t opcode,
4474 DCHECK(IsEnabled(SSE4_1));
4475 EnsureSpace ensure_space(
this);
4477 emit_optional_rex_32(src, dst);
4481 emit_sse_operand(src, dst);
4485void Assembler::sse4_instr(Operand dst, XMMRegister src, uint8_t prefix,
4486 uint8_t escape1, uint8_t escape2, uint8_t opcode,
4489 DCHECK(IsEnabled(SSE4_1));
4490 EnsureSpace ensure_space(
this);
4492 emit_optional_rex_32(src, dst);
4496 emit_sse_operand(src, dst);
4500void Assembler::sse4_2_instr(XMMRegister dst, XMMRegister src, uint8_t prefix,
4501 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4502 DCHECK(IsEnabled(SSE4_2));
4503 EnsureSpace ensure_space(
this);
4505 emit_optional_rex_32(dst, src);
4509 emit_sse_operand(dst, src);
4512void Assembler::sse4_2_instr(XMMRegister dst, Operand src, uint8_t prefix,
4513 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
4514 DCHECK(IsEnabled(SSE4_2));
4515 EnsureSpace ensure_space(
this);
4517 emit_optional_rex_32(dst, src);
4521 emit_sse_operand(dst, src);
4524void Assembler::lddqu(XMMRegister dst, Operand src) {
4526 EnsureSpace ensure_space(
this);
4528 emit_optional_rex_32(dst, src);
4531 emit_sse_operand(dst, src);
4534void Assembler::movddup(XMMRegister dst, XMMRegister src) {
4536 EnsureSpace ensure_space(
this);
4538 emit_optional_rex_32(dst, src);
4541 emit_sse_operand(dst, src);
4544void Assembler::movddup(XMMRegister dst, Operand src) {
4546 EnsureSpace ensure_space(
this);
4548 emit_optional_rex_32(dst, src);
4551 emit_sse_operand(dst, src);
4554void Assembler::movshdup(XMMRegister dst, XMMRegister src) {
4556 EnsureSpace ensure_space(
this);
4558 emit_optional_rex_32(dst, src);
4561 emit_sse_operand(dst, src);
4564void Assembler::psrldq(XMMRegister dst, uint8_t shift) {
4565 EnsureSpace ensure_space(
this);
4567 emit_optional_rex_32(dst);
4570 emit_sse_operand(dst);
4574void Assembler::pshufhw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4575 EnsureSpace ensure_space(
this);
4577 emit_optional_rex_32(dst, src);
4580 emit_sse_operand(dst, src);
4584void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
4585 EnsureSpace ensure_space(
this);
4587 emit_optional_rex_32(dst, src);
4590 emit_sse_operand(dst, src);
4594void Assembler::pshuflw(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4595 EnsureSpace ensure_space(
this);
4597 emit_optional_rex_32(dst, src);
4600 emit_sse_operand(dst, src);
4604void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
4605 EnsureSpace ensure_space(
this);
4607 emit_optional_rex_32(dst, src);
4610 emit_sse_operand(dst, src);
4614void Assembler::pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle) {
4615 EnsureSpace ensure_space(
this);
4617 emit_optional_rex_32(dst, src);
4620 emit_sse_operand(dst, src);
4624void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
4625 EnsureSpace ensure_space(
this);
4627 emit_optional_rex_32(dst, src);
4630 emit_sse_operand(dst, src);
4634void Assembler::emit_sse_operand(XMMRegister
reg, Operand adr) {
4636 emit_operand(ireg, adr);
4639void Assembler::emit_sse_operand(Register
reg, Operand adr) {
4640 emit_operand(
reg, adr);
4643void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
4644 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4647void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
4648 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4651void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
4652 emit(0xC0 | (dst.low_bits() << 3) | src.low_bits());
4655void Assembler::emit_sse_operand(XMMRegister dst) {
4656 emit(0xD8 | dst.low_bits());
4659void Assembler::db(uint8_t data) {
4660 EnsureSpace ensure_space(
this);
4664void Assembler::dd(uint32_t data) {
4665 EnsureSpace ensure_space(
this);
4669void Assembler::dq(uint64_t data) {
4670 EnsureSpace ensure_space(
this);
4674void Assembler::dq(Label*
label) {
4675 EnsureSpace ensure_space(
this);
4676 if (
label->is_bound()) {
4677 internal_reference_positions_.push_back(
pc_offset());
4678 emit(Immediate64(
reinterpret_cast<Address>(buffer_start_) +
label->pos(),
4679 RelocInfo::INTERNAL_REFERENCE));
4681 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
4683 if (
label->is_linked()) {
4684 emitl(
label->pos());
4690 label->link_to(current);
4695void Assembler::WriteBuiltinJumpTableEntry(Label*
label,
int table_pos) {
4696 EnsureSpace ensure_space(
this);
4705int Assembler::WriteBuiltinJumpTableInfos() {
4706 if (builtin_jump_table_info_writer_.entry_count() == 0)
return 0;
4709 builtin_jump_table_info_writer_.Emit(
this);
4711 DCHECK_EQ(size, builtin_jump_table_info_writer_.size_in_bytes());
4717void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
4718 if (!ShouldRecordRelocInfo(rmode))
return;
4719 RelocInfo rinfo(
reinterpret_cast<Address>(
pc_), rmode, data);
4720 reloc_info_writer.Write(&rinfo);
4723const int RelocInfo::kApplyMask =
4724 RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
4725 RelocInfo::ModeMask(RelocInfo::NEAR_BUILTIN_ENTRY) |
4726 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
4727 RelocInfo::ModeMask(RelocInfo::WASM_CALL) |
4728 RelocInfo::ModeMask(RelocInfo::WASM_STUB_CALL);
4730bool RelocInfo::IsCodedSpecially() {
4734 return (1 << rmode_) & kApplyMask;
4737bool RelocInfo::IsInConstantPool() {
return false; }
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
static bool IsHardwareEnforcedShadowStacksEnabled()
std::forward_list< HeapNumberRequest > heap_number_requests_
void AllocateAndInstallRequestedHeapNumbers(LocalIsolate *isolate)
Assembler(const AssemblerOptions &, std::unique_ptr< AssemblerBuffer >={})
static bool UseConstPoolFor(RelocInfo::Mode rmode)
bool IsMoveRipRelative(Address instr)
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
static bool IsSupported(CpuFeature f)
static bool supports_wasm_simd_128_
static bool SupportsWasmSimd128()
static void PrintFeatures()
static void SetSupported(CpuFeature f)
static bool supports_cetss_
static void PrintTarget()
static void SetUnsupported(CpuFeature f)
static void ProbeImpl(bool cross_compile)
V8_INLINE constexpr bool is_label_operand() const
bool AddressUsesRegister(Register reg) const
V8_INLINE Operand(int32_t immediate, RelocInfo::Mode rmode=RelocInfo::NO_INFO)
constexpr int8_t code() const
static constexpr bool IsShareableRelocMode(Mode mode)
uint32_t wasm_call_tag() const
base::OwnedVector< uint8_t > buffer_
#define V8_BUILTIN_JUMP_TABLE_INFO_BOOL
#define EXPORT_TEMPLATE_DEFINE(export)
DirectHandle< JSReceiver > options
V8_EXPORT_PRIVATE void MemMove(void *dest, const void *src, size_t size)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK_LE(v1, v2)
#define DCHECK_WITH_MSG(condition, msg)
#define DCHECK_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_EXPORT_PRIVATE
#define V8_UNLIKELY(condition)