41#if V8_TARGET_ARCH_IA32
47#include <sys/sysctl.h>
66 result.is_heap_number_request_ =
true;
67 result.value_.heap_number_request = HeapNumberRequest(value);
76V8_INLINE uint64_t xgetbv(
unsigned int xcr) {
85 __asm__
volatile(
".byte 0x0F, 0x01, 0xD0" :
"=a"(eax),
"=d"(edx) :
"c"(xcr));
86 return static_cast<uint64_t
>(eax) | (
static_cast<uint64_t
>(edx) << 32);
90bool OSHasAVXSupport() {
96 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
97 if (sysctl(ctl_name, 2, buffer, &buffer_size,
nullptr, 0) != 0) {
98 FATAL(
"V8 failed to get kernel version");
102 char* period_pos = strchr(buffer,
'.');
105 long kernel_version_major = strtol(buffer,
nullptr, 10);
106 if (kernel_version_major <= 13)
return false;
109 uint64_t feature_mask = xgetbv(0);
110 return (feature_mask & 0x6) == 0x6;
113#undef _XCR_XFEATURE_ENABLED_MASK
118#if V8_ENABLE_WEBASSEMBLY
127 CHECK(cpu.has_sse2());
128 CHECK(cpu.has_cmov());
131 if (cross_compile)
return;
137 if (cpu.has_avx() && cpu.has_osxsave() && OSHasAVXSupport()) {
147 if (strcmp(
v8_flags.mcpu,
"auto") == 0) {
149 }
else if (strcmp(
v8_flags.mcpu,
"atom") == 0) {
175 "SSE3=%d SSSE3=%d SSE4_1=%d AVX=%d AVX2=%d FMA3=%d BMI1=%d BMI2=%d "
177 "POPCNT=%d ATOM=%d\n",
192 if (
L->is_linked()) {
222 return ReadUnalignedValue<uint32_t>(
pc_);
278 return (
buf_[0] & 0xF8) == 0xC0;
286bool operator!=(Operand op, XMMRegister
r) {
return !op.is_reg(
r); }
291 Handle<HeapObject>
object =
293 request.heap_number());
295 WriteUnalignedValue(
pc,
object);
303#define EMIT(x) *pc_++ = (x)
306 std::unique_ptr<AssemblerBuffer> buffer)
307 : AssemblerBase(options,
std::move(buffer)) {
308 reloc_info_writer.Reposition(buffer_start_ +
buffer_->size(),
pc_);
309 if (CpuFeatures::IsSupported(SSE4_2)) {
310 EnableCpuFeature(SSE4_1);
312 if (CpuFeatures::IsSupported(SSE4_1)) {
313 EnableCpuFeature(SSSE3);
315 if (CpuFeatures::IsSupported(SSSE3)) {
316 EnableCpuFeature(SSE3);
320void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
321 GetCode(isolate->main_thread_local_isolate(), desc);
323void Assembler::GetCode(LocalIsolate* isolate, CodeDesc* desc,
324 SafepointTableBuilder* safepoint_table_builder,
325 int handler_table_offset) {
333 DataAlign(InstructionStream::kMetadataAlignment);
335 const int code_comments_size = WriteCodeComments();
341 AllocateAndInstallRequestedHeapNumbers(isolate);
347 static constexpr int kConstantPoolSize = 0;
348 static constexpr int kBuiltinJumpTableInfoSize = 0;
349 const int instruction_size =
pc_offset();
350 const int builtin_jump_table_info_offset =
351 instruction_size - kBuiltinJumpTableInfoSize;
352 const int code_comments_offset =
353 builtin_jump_table_info_offset - code_comments_size;
354 const int constant_pool_offset = code_comments_offset - kConstantPoolSize;
355 const int handler_table_offset2 = (handler_table_offset == kNoHandlerTable)
356 ? constant_pool_offset
357 : handler_table_offset;
358 const int safepoint_table_offset =
359 (safepoint_table_builder == kNoSafepointTable)
360 ? handler_table_offset2
361 : safepoint_table_builder->safepoint_table_offset();
362 const int reloc_info_offset =
363 static_cast<int>(reloc_info_writer.pos() -
buffer_->start());
364 CodeDesc::Initialize(desc,
this, safepoint_table_offset,
365 handler_table_offset2, constant_pool_offset,
366 code_comments_offset, builtin_jump_table_info_offset,
370void Assembler::FinalizeJumpOptimizationInfo() {
372 auto jump_opt = jump_optimization_info();
373 if (jump_opt && jump_opt->is_collecting()) {
374 auto& dict = jump_opt->may_optimizable_farjmp;
375 int num =
static_cast<int>(jump_opt->farjmps.size());
376 if (num && dict.empty()) {
377 bool can_opt =
false;
378 for (
int i = 0;
i < num;
i++) {
379 auto jmp_info = jump_opt->farjmps[
i];
380 int disp = long_at(jmp_info.pos + jmp_info.opcode_size);
382 jmp_info.distance = disp;
388 jump_opt->set_optimizable();
394void Assembler::Align(
int m) {
395 DCHECK(base::bits::IsPowerOfTwo(
m));
401bool Assembler::IsNop(Address addr) {
402 uint8_t* a =
reinterpret_cast<uint8_t*
>(addr);
403 while (*a == 0x66) a++;
404 if (*a == 0x90)
return true;
405 if (a[0] == 0xF && a[1] == 0x1F)
return true;
409void Assembler::Nop(
int bytes) {
410 EnsureSpace ensure_space(
this);
477void Assembler::CodeTargetAlign() {
479 auto jump_opt = jump_optimization_info();
480 if (jump_opt && jump_opt->is_collecting()) {
481 jump_opt->align_pos_size[
pc_offset()] = 16;
485void Assembler::cpuid() {
486 EnsureSpace ensure_space(
this);
491void Assembler::pushad() {
492 EnsureSpace ensure_space(
this);
496void Assembler::popad() {
497 EnsureSpace ensure_space(
this);
501void Assembler::pushfd() {
502 EnsureSpace ensure_space(
this);
506void Assembler::popfd() {
507 EnsureSpace ensure_space(
this);
511void Assembler::push(
const Immediate&
x) {
512 EnsureSpace ensure_space(
this);
522void Assembler::push_imm32(int32_t imm32) {
523 EnsureSpace ensure_space(
this);
528void Assembler::push(Register src) {
529 EnsureSpace ensure_space(
this);
530 EMIT(0x50 | src.code());
533void Assembler::push(Operand src) {
534 EnsureSpace ensure_space(
this);
536 emit_operand(esi, src);
539void Assembler::pop(Register dst) {
541 EnsureSpace ensure_space(
this);
542 EMIT(0x58 | dst.code());
545void Assembler::pop(Operand dst) {
546 EnsureSpace ensure_space(
this);
548 emit_operand(eax, dst);
551void Assembler::leave() {
552 EnsureSpace ensure_space(
this);
556void Assembler::mov_b(Register dst, Operand src) {
557 CHECK(dst.is_byte_register());
558 EnsureSpace ensure_space(
this);
560 emit_operand(dst, src);
563void Assembler::mov_b(Operand dst,
const Immediate& src) {
564 EnsureSpace ensure_space(
this);
566 emit_operand(eax, dst);
567 EMIT(
static_cast<int8_t
>(src.immediate()));
570void Assembler::mov_b(Operand dst, Register src) {
571 CHECK(src.is_byte_register());
572 EnsureSpace ensure_space(
this);
574 emit_operand(src, dst);
577void Assembler::mov_w(Register dst, Operand src) {
578 EnsureSpace ensure_space(
this);
581 emit_operand(dst, src);
584void Assembler::mov_w(Operand dst, Register src) {
585 EnsureSpace ensure_space(
this);
588 emit_operand(src, dst);
591void Assembler::mov_w(Operand dst,
const Immediate& src) {
592 EnsureSpace ensure_space(
this);
595 emit_operand(eax, dst);
596 EMIT(
static_cast<int8_t
>(src.immediate() & 0xFF));
597 EMIT(
static_cast<int8_t
>(src.immediate() >> 8));
600void Assembler::mov(Register dst, int32_t imm32) {
601 EnsureSpace ensure_space(
this);
602 EMIT(0xB8 | dst.code());
606void Assembler::mov(Register dst,
const Immediate&
x) {
607 EnsureSpace ensure_space(
this);
608 EMIT(0xB8 | dst.code());
612void Assembler::mov(Register dst, Handle<HeapObject> handle) {
613 EnsureSpace ensure_space(
this);
614 EMIT(0xB8 | dst.code());
618void Assembler::mov(Register dst, Operand src) {
619 EnsureSpace ensure_space(
this);
621 emit_operand(dst, src);
624void Assembler::mov(Register dst, Register src) {
625 EnsureSpace ensure_space(
this);
627 EMIT(0xC0 | src.code() << 3 | dst.code());
630void Assembler::mov(Operand dst,
const Immediate&
x) {
631 EnsureSpace ensure_space(
this);
633 emit_operand(eax, dst);
637void Assembler::mov(Operand dst, Address src, RelocInfo::Mode rmode) {
638 EnsureSpace ensure_space(
this);
640 emit_operand(eax, dst);
644void Assembler::mov(Operand dst, Handle<HeapObject> handle) {
645 EnsureSpace ensure_space(
this);
647 emit_operand(eax, dst);
651void Assembler::mov(Operand dst, Register src) {
652 EnsureSpace ensure_space(
this);
654 emit_operand(src, dst);
657void Assembler::movsx_b(Register dst, Operand src) {
659 EnsureSpace ensure_space(
this);
662 emit_operand(dst, src);
665void Assembler::movsx_w(Register dst, Operand src) {
666 EnsureSpace ensure_space(
this);
669 emit_operand(dst, src);
672void Assembler::movzx_b(Register dst, Operand src) {
674 EnsureSpace ensure_space(
this);
677 emit_operand(dst, src);
680void Assembler::movzx_w(Register dst, Operand src) {
681 EnsureSpace ensure_space(
this);
684 emit_operand(dst, src);
687void Assembler::movq(XMMRegister dst, Operand src) {
688 EnsureSpace ensure_space(
this);
692 emit_operand(dst, src);
695void Assembler::movq(Operand dst, XMMRegister src) {
696 EnsureSpace ensure_space(
this);
700 emit_operand(src, dst);
703void Assembler::cmov(Condition cc, Register dst, Operand src) {
704 EnsureSpace ensure_space(
this);
708 emit_operand(dst, src);
711void Assembler::cld() {
712 EnsureSpace ensure_space(
this);
716void Assembler::rep_movs() {
717 EnsureSpace ensure_space(
this);
722void Assembler::rep_stos() {
723 EnsureSpace ensure_space(
this);
728void Assembler::stos() {
729 EnsureSpace ensure_space(
this);
733void Assembler::xadd(Operand dst, Register src) {
734 EnsureSpace ensure_space(
this);
737 emit_operand(src, dst);
740void Assembler::xadd_b(Operand dst, Register src) {
741 DCHECK(src.is_byte_register());
742 EnsureSpace ensure_space(
this);
745 emit_operand(src, dst);
748void Assembler::xadd_w(Operand dst, Register src) {
749 EnsureSpace ensure_space(
this);
753 emit_operand(src, dst);
756void Assembler::xchg(Register dst, Register src) {
757 EnsureSpace ensure_space(
this);
758 if (src == eax || dst == eax) {
759 EMIT(0x90 | (src == eax ? dst.code() : src.code()));
762 EMIT(0xC0 | src.code() << 3 | dst.code());
766void Assembler::xchg(Register dst, Operand src) {
767 EnsureSpace ensure_space(
this);
769 emit_operand(dst, src);
772void Assembler::xchg_b(Register
reg, Operand op) {
774 EnsureSpace ensure_space(
this);
776 emit_operand(
reg, op);
779void Assembler::xchg_w(Register
reg, Operand op) {
780 EnsureSpace ensure_space(
this);
783 emit_operand(
reg, op);
786void Assembler::lock() {
787 EnsureSpace ensure_space(
this);
791void Assembler::cmpxchg(Operand dst, Register src) {
792 EnsureSpace ensure_space(
this);
795 emit_operand(src, dst);
798void Assembler::cmpxchg_b(Operand dst, Register src) {
799 DCHECK(src.is_byte_register());
800 EnsureSpace ensure_space(
this);
803 emit_operand(src, dst);
806void Assembler::cmpxchg_w(Operand dst, Register src) {
807 EnsureSpace ensure_space(
this);
811 emit_operand(src, dst);
814void Assembler::cmpxchg8b(Operand dst) {
815 EnsureSpace enure_space(
this);
818 emit_operand(ecx, dst);
821void Assembler::mfence() {
822 EnsureSpace ensure_space(
this);
828void Assembler::lfence() {
829 EnsureSpace ensure_space(
this);
835void Assembler::pause() {
836 EnsureSpace ensure_space(
this);
841void Assembler::adc(Register dst, int32_t imm32) {
842 EnsureSpace ensure_space(
this);
843 emit_arith(2, Operand(dst), Immediate(imm32));
846void Assembler::adc(Register dst, Operand src) {
847 EnsureSpace ensure_space(
this);
849 emit_operand(dst, src);
852void Assembler::add(Register dst, Operand src) {
853 EnsureSpace ensure_space(
this);
855 emit_operand(dst, src);
858void Assembler::add(Operand dst, Register src) {
859 EnsureSpace ensure_space(
this);
861 emit_operand(src, dst);
864void Assembler::add(Operand dst,
const Immediate&
x) {
866 EnsureSpace ensure_space(
this);
867 emit_arith(0, dst,
x);
870void Assembler::and_(Register dst, int32_t imm32) {
871 and_(dst, Immediate(imm32));
874void Assembler::and_(Register dst,
const Immediate&
x) {
875 EnsureSpace ensure_space(
this);
876 emit_arith(4, Operand(dst),
x);
879void Assembler::and_(Register dst, Operand src) {
880 EnsureSpace ensure_space(
this);
882 emit_operand(dst, src);
885void Assembler::and_(Operand dst,
const Immediate&
x) {
886 EnsureSpace ensure_space(
this);
887 emit_arith(4, dst,
x);
890void Assembler::and_(Operand dst, Register src) {
891 EnsureSpace ensure_space(
this);
893 emit_operand(src, dst);
896void Assembler::cmpb(Operand op, Immediate imm8) {
897 DCHECK(imm8.is_int8() || imm8.is_uint8());
898 EnsureSpace ensure_space(
this);
899 if (op.is_reg(eax)) {
903 emit_operand(edi, op);
908void Assembler::cmpb(Operand op, Register
reg) {
910 EnsureSpace ensure_space(
this);
912 emit_operand(
reg, op);
915void Assembler::cmpb(Register
reg, Operand op) {
917 EnsureSpace ensure_space(
this);
919 emit_operand(
reg, op);
922void Assembler::cmpw(Operand op, Immediate imm16) {
923 DCHECK(imm16.is_int16() || imm16.is_uint16());
924 EnsureSpace ensure_space(
this);
927 emit_operand(edi, op);
931void Assembler::cmpw(Register
reg, Operand op) {
932 EnsureSpace ensure_space(
this);
935 emit_operand(
reg, op);
938void Assembler::cmpw(Operand op, Register
reg) {
939 EnsureSpace ensure_space(
this);
942 emit_operand(
reg, op);
945void Assembler::cmp(Register
reg, int32_t imm32) {
946 EnsureSpace ensure_space(
this);
947 emit_arith(7, Operand(
reg), Immediate(imm32));
950void Assembler::cmp(Register
reg, Handle<HeapObject> handle) {
951 EnsureSpace ensure_space(
this);
952 emit_arith(7, Operand(
reg), Immediate(handle));
955void Assembler::cmp(Register
reg, Operand op) {
956 EnsureSpace ensure_space(
this);
958 emit_operand(
reg, op);
961void Assembler::cmp(Operand op, Register
reg) {
962 EnsureSpace ensure_space(
this);
964 emit_operand(
reg, op);
967void Assembler::cmp(Operand op,
const Immediate& imm) {
968 EnsureSpace ensure_space(
this);
969 emit_arith(7, op, imm);
972void Assembler::cmp(Operand op, Handle<HeapObject> handle) {
973 EnsureSpace ensure_space(
this);
974 emit_arith(7, op, Immediate(handle));
977void Assembler::cmpb_al(Operand op) {
978 EnsureSpace ensure_space(
this);
980 emit_operand(eax, op);
983void Assembler::cmpw_ax(Operand op) {
984 EnsureSpace ensure_space(
this);
987 emit_operand(eax, op);
990void Assembler::dec_b(Register dst) {
991 CHECK(dst.is_byte_register());
992 EnsureSpace ensure_space(
this);
994 EMIT(0xC8 | dst.code());
997void Assembler::dec_b(Operand dst) {
998 EnsureSpace ensure_space(
this);
1000 emit_operand(ecx, dst);
1003void Assembler::dec(Register dst) {
1004 EnsureSpace ensure_space(
this);
1005 EMIT(0x48 | dst.code());
1008void Assembler::dec(Operand dst) {
1009 EnsureSpace ensure_space(
this);
1011 emit_operand(ecx, dst);
1014void Assembler::cdq() {
1015 EnsureSpace ensure_space(
this);
1019void Assembler::idiv(Operand src) {
1020 EnsureSpace ensure_space(
this);
1022 emit_operand(edi, src);
1025void Assembler::div(Operand src) {
1026 EnsureSpace ensure_space(
this);
1028 emit_operand(esi, src);
1031void Assembler::imul(Register
reg) {
1032 EnsureSpace ensure_space(
this);
1034 EMIT(0xE8 |
reg.code());
1037void Assembler::imul(Register dst, Operand src) {
1038 EnsureSpace ensure_space(
this);
1041 emit_operand(dst, src);
1044void Assembler::imul(Register dst, Register src, int32_t imm32) {
1045 imul(dst, Operand(src), imm32);
1048void Assembler::imul(Register dst, Operand src, int32_t imm32) {
1049 EnsureSpace ensure_space(
this);
1050 if (is_int8(imm32)) {
1052 emit_operand(dst, src);
1056 emit_operand(dst, src);
1061void Assembler::inc(Register dst) {
1062 EnsureSpace ensure_space(
this);
1063 EMIT(0x40 | dst.code());
1066void Assembler::inc(Operand dst) {
1067 EnsureSpace ensure_space(
this);
1069 emit_operand(eax, dst);
1072void Assembler::lea(Register dst, Operand src) {
1073 EnsureSpace ensure_space(
this);
1075 emit_operand(dst, src);
1078void Assembler::lea(Register dst, Register src, Label* lbl) {
1079 EnsureSpace ensure_space(
this);
1083 EMIT(((0x2) << 6) | (dst.code() << 3) | src.code());
1085 if (lbl->is_bound()) {
1090 emit_disp(lbl, Displacement::OTHER);
1094void Assembler::mul(Register src) {
1095 EnsureSpace ensure_space(
this);
1097 EMIT(0xE0 | src.code());
1100void Assembler::neg(Register dst) {
1101 EnsureSpace ensure_space(
this);
1103 EMIT(0xD8 | dst.code());
1106void Assembler::neg(Operand dst) {
1107 EnsureSpace ensure_space(
this);
1109 emit_operand(ebx, dst);
1112void Assembler::not_(Register dst) {
1113 EnsureSpace ensure_space(
this);
1115 EMIT(0xD0 | dst.code());
1118void Assembler::not_(Operand dst) {
1119 EnsureSpace ensure_space(
this);
1121 emit_operand(edx, dst);
1124void Assembler::or_(Register dst, int32_t imm32) {
1125 EnsureSpace ensure_space(
this);
1126 emit_arith(1, Operand(dst), Immediate(imm32));
1129void Assembler::or_(Register dst, Operand src) {
1130 EnsureSpace ensure_space(
this);
1132 emit_operand(dst, src);
1135void Assembler::or_(Operand dst,
const Immediate&
x) {
1136 EnsureSpace ensure_space(
this);
1137 emit_arith(1, dst,
x);
1140void Assembler::or_(Operand dst, Register src) {
1141 EnsureSpace ensure_space(
this);
1143 emit_operand(src, dst);
1146void Assembler::rcl(Register dst, uint8_t imm8) {
1147 EnsureSpace ensure_space(
this);
1151 EMIT(0xD0 | dst.code());
1154 EMIT(0xD0 | dst.code());
1159void Assembler::rcr(Register dst, uint8_t imm8) {
1160 EnsureSpace ensure_space(
this);
1164 EMIT(0xD8 | dst.code());
1167 EMIT(0xD8 | dst.code());
1172void Assembler::rol(Operand dst, uint8_t imm8) {
1173 EnsureSpace ensure_space(
this);
1177 emit_operand(eax, dst);
1180 emit_operand(eax, dst);
1185void Assembler::rol_cl(Operand dst) {
1186 EnsureSpace ensure_space(
this);
1188 emit_operand(eax, dst);
1191void Assembler::ror(Operand dst, uint8_t imm8) {
1192 EnsureSpace ensure_space(
this);
1196 emit_operand(ecx, dst);
1199 emit_operand(ecx, dst);
1204void Assembler::ror_cl(Operand dst) {
1205 EnsureSpace ensure_space(
this);
1207 emit_operand(ecx, dst);
1210void Assembler::sar(Operand dst, uint8_t imm8) {
1211 EnsureSpace ensure_space(
this);
1215 emit_operand(edi, dst);
1218 emit_operand(edi, dst);
1223void Assembler::sar_cl(Operand dst) {
1224 EnsureSpace ensure_space(
this);
1226 emit_operand(edi, dst);
1229void Assembler::sbb(Register dst, Operand src) {
1230 EnsureSpace ensure_space(
this);
1232 emit_operand(dst, src);
1235void Assembler::shld(Register dst, Register src, uint8_t shift) {
1237 EnsureSpace ensure_space(
this);
1240 emit_operand(src, Operand(dst));
1244void Assembler::shld_cl(Register dst, Register src) {
1245 EnsureSpace ensure_space(
this);
1248 emit_operand(src, Operand(dst));
1251void Assembler::shl(Operand dst, uint8_t imm8) {
1252 EnsureSpace ensure_space(
this);
1256 emit_operand(esp, dst);
1259 emit_operand(esp, dst);
1264void Assembler::shl_cl(Operand dst) {
1265 EnsureSpace ensure_space(
this);
1267 emit_operand(esp, dst);
1270void Assembler::shr(Operand dst, uint8_t imm8) {
1271 EnsureSpace ensure_space(
this);
1275 emit_operand(ebp, dst);
1278 emit_operand(ebp, dst);
1283void Assembler::shr_cl(Operand dst) {
1284 EnsureSpace ensure_space(
this);
1286 emit_operand(ebp, dst);
1289void Assembler::shrd(Register dst, Register src, uint8_t shift) {
1291 EnsureSpace ensure_space(
this);
1294 emit_operand(src, Operand(dst));
1298void Assembler::shrd_cl(Operand dst, Register src) {
1299 EnsureSpace ensure_space(
this);
1302 emit_operand(src, dst);
1305void Assembler::sub(Operand dst,
const Immediate&
x) {
1306 EnsureSpace ensure_space(
this);
1307 emit_arith(5, dst,
x);
1310void Assembler::sub(Register dst, Operand src) {
1311 EnsureSpace ensure_space(
this);
1313 emit_operand(dst, src);
1316void Assembler::sub(Operand dst, Register src) {
1317 EnsureSpace ensure_space(
this);
1319 emit_operand(src, dst);
1322void Assembler::sub_sp_32(uint32_t imm) {
1323 EnsureSpace ensure_space(
this);
1325 static constexpr Register ireg = Register::from_code(5);
1326 emit_operand(ireg, Operand(esp));
1330void Assembler::test(Register
reg,
const Immediate& imm) {
1331 if (imm.is_uint8()) {
1336 EnsureSpace ensure_space(
this);
1343 EMIT(0xC0 |
reg.code());
1348void Assembler::test(Register
reg, Operand op) {
1349 EnsureSpace ensure_space(
this);
1351 emit_operand(
reg, op);
1354void Assembler::test_b(Register
reg, Operand op) {
1356 EnsureSpace ensure_space(
this);
1358 emit_operand(
reg, op);
1361void Assembler::test(Operand op,
const Immediate& imm) {
1362 if (op.is_reg_only()) {
1363 test(op.reg(), imm);
1366 if (imm.is_uint8()) {
1367 return test_b(op, imm);
1369 EnsureSpace ensure_space(
this);
1371 emit_operand(eax, op);
1375void Assembler::test_b(Register
reg, Immediate imm8) {
1377 EnsureSpace ensure_space(
this);
1383 }
else if (
reg.is_byte_register()) {
1384 emit_arith_b(0xF6, 0xC0,
reg,
static_cast<uint8_t
>(imm8.immediate()));
1388 EMIT(0xC0 |
reg.code());
1393void Assembler::test_b(Operand op, Immediate imm8) {
1394 if (op.is_reg_only()) {
1395 test_b(op.reg(), imm8);
1398 EnsureSpace ensure_space(
this);
1400 emit_operand(eax, op);
1404void Assembler::test_w(Register
reg, Immediate imm16) {
1405 DCHECK(imm16.is_int16() || imm16.is_uint16());
1406 EnsureSpace ensure_space(
this);
1413 EMIT(0xC0 |
reg.code());
1418void Assembler::test_w(Register
reg, Operand op) {
1419 EnsureSpace ensure_space(
this);
1422 emit_operand(
reg, op);
1425void Assembler::test_w(Operand op, Immediate imm16) {
1426 DCHECK(imm16.is_int16() || imm16.is_uint16());
1427 if (op.is_reg_only()) {
1428 test_w(op.reg(), imm16);
1431 EnsureSpace ensure_space(
this);
1434 emit_operand(eax, op);
1438void Assembler::xor_(Register dst, int32_t imm32) {
1439 EnsureSpace ensure_space(
this);
1440 emit_arith(6, Operand(dst), Immediate(imm32));
1443void Assembler::xor_(Register dst, Operand src) {
1444 EnsureSpace ensure_space(
this);
1446 emit_operand(dst, src);
1449void Assembler::xor_(Operand dst, Register src) {
1450 EnsureSpace ensure_space(
this);
1452 emit_operand(src, dst);
1455void Assembler::xor_(Operand dst,
const Immediate&
x) {
1456 EnsureSpace ensure_space(
this);
1457 emit_arith(6, dst,
x);
1460void Assembler::bswap(Register dst) {
1461 EnsureSpace ensure_space(
this);
1463 EMIT(0xC8 + dst.code());
1466void Assembler::bt(Operand dst, Register src) {
1467 EnsureSpace ensure_space(
this);
1470 emit_operand(src, dst);
1473void Assembler::bts(Operand dst, Register src) {
1474 EnsureSpace ensure_space(
this);
1477 emit_operand(src, dst);
1480void Assembler::bsr(Register dst, Operand src) {
1481 EnsureSpace ensure_space(
this);
1484 emit_operand(dst, src);
1487void Assembler::bsf(Register dst, Operand src) {
1488 EnsureSpace ensure_space(
this);
1491 emit_operand(dst, src);
1494void Assembler::hlt() {
1495 EnsureSpace ensure_space(
this);
1499void Assembler::int3() {
1500 EnsureSpace ensure_space(
this);
1504void Assembler::nop() {
1505 EnsureSpace ensure_space(
this);
1509void Assembler::ret(
int imm16) {
1510 EnsureSpace ensure_space(
this);
1511 DCHECK(is_uint16(imm16));
1517 EMIT((imm16 >> 8) & 0xFF);
1521void Assembler::ud2() {
1522 EnsureSpace ensure_space(
this);
1537void Assembler::print(
const Label* L) {
1538 if (
L->is_unused()) {
1539 PrintF(
"unused label\n");
1540 }
else if (
L->is_bound()) {
1541 PrintF(
"bound label to %d\n",
L->pos());
1542 }
else if (
L->is_linked()) {
1544 l.link_to(
L->pos());
1546 while (l.is_linked()) {
1547 Displacement disp = disp_at(&l);
1548 PrintF(
"@ %d ", l.pos());
1554 PrintF(
"label in inconsistent state (pos = %d)\n",
L->pos_);
1558void Assembler::bind_to(Label* L,
int pos) {
1559 EnsureSpace ensure_space(
this);
1561 while (
L->is_linked()) {
1562 Displacement disp = disp_at(L);
1563 int fixup_pos =
L->pos();
1564 if (disp.type() == Displacement::CODE_ABSOLUTE) {
1565 long_at_put(fixup_pos,
reinterpret_cast<int>(buffer_start_ +
pos));
1566 internal_reference_positions_.push_back(fixup_pos);
1567 }
else if (disp.type() == Displacement::CODE_RELATIVE) {
1569 long_at_put(fixup_pos,
1570 pos + InstructionStream::kHeaderSize - kHeapObjectTag);
1572 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1573 DCHECK_EQ(byte_at(fixup_pos - 1), 0xE9);
1576 int imm32 =
pos - (fixup_pos +
sizeof(
int32_t));
1577 long_at_put(fixup_pos, imm32);
1581 while (
L->is_near_linked()) {
1582 int fixup_pos =
L->near_link_pos();
1583 int offset_to_next =
1584 static_cast<int>(*
reinterpret_cast<int8_t*
>(addr_at(fixup_pos)));
1587 int disp =
pos - fixup_pos -
sizeof(int8_t);
1588 CHECK(0 <= disp && disp <= 127);
1589 set_byte_at(fixup_pos, disp);
1590 if (offset_to_next < 0) {
1591 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1598 auto jump_opt = jump_optimization_info();
1599 if (jump_opt && jump_opt->is_optimizing()) {
1600 auto it = jump_opt->label_farjmp_maps.find(L);
1601 if (it != jump_opt->label_farjmp_maps.end()) {
1602 auto& pos_vector = it->second;
1603 for (
auto fixup_pos : pos_vector) {
1604 int disp =
pos - (fixup_pos +
sizeof(int8_t));
1605 CHECK(is_int8(disp));
1606 set_byte_at(fixup_pos, disp);
1608 jump_opt->label_farjmp_maps.erase(it);
1614void Assembler::bind(Label* L) {
1615 EnsureSpace ensure_space(
this);
1620void Assembler::record_farjmp_position(Label* L,
int pos) {
1621 auto& pos_vector = jump_optimization_info()->label_farjmp_maps[
L];
1622 pos_vector.push_back(
pos);
1625bool Assembler::is_optimizable_farjmp(
int idx) {
1626 if (predictable_code_size())
return false;
1628 auto jump_opt = jump_optimization_info();
1629 CHECK(jump_opt->is_optimizing());
1631 auto& dict = jump_opt->may_optimizable_farjmp;
1632 if (dict.find(idx) != dict.end()) {
1633 auto record_jmp_info = dict[idx];
1635 int record_pos = record_jmp_info.pos;
1638 const int operand_size = 4;
1639 int record_dest = record_jmp_info.pos + record_jmp_info.opcode_size +
1640 operand_size + record_jmp_info.distance;
1642 const int max_align_in_jmp_range =
1643 jump_opt->MaxAlignInRange(record_pos, record_dest);
1645 if (max_align_in_jmp_range == 0) {
1651 const int saved_opcode_size = record_jmp_info.opcode_size - 1;
1654 constexpr int saved_operand_size = 4 - 1;
1659 int cur_jmp_length_max_increase =
1660 (record_pos -
pc_offset() + saved_opcode_size + saved_operand_size) %
1661 max_align_in_jmp_range;
1663 if (is_int8(record_jmp_info.distance + cur_jmp_length_max_increase)) {
1670void Assembler::call(Label* L) {
1671 EnsureSpace ensure_space(
this);
1672 if (
L->is_bound()) {
1673 const int long_size = 5;
1678 emit(offs - long_size);
1682 emit_disp(L, Displacement::OTHER);
1686void Assembler::call(Address entry, RelocInfo::Mode rmode) {
1687 EnsureSpace ensure_space(
this);
1688 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1690 emit(entry - (
reinterpret_cast<Address>(
pc_) +
sizeof(int32_t)), rmode);
1693void Assembler::wasm_call(Address entry, RelocInfo::Mode rmode) {
1694 EnsureSpace ensure_space(
this);
1699void Assembler::call(Operand adr) {
1700 EnsureSpace ensure_space(
this);
1702 emit_operand(edx, adr);
1705void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) {
1706 EnsureSpace ensure_space(
this);
1707 DCHECK(RelocInfo::IsCodeTarget(rmode));
1712void Assembler::jmp_rel(
int offset) {
1713 EnsureSpace ensure_space(
this);
1714 const int short_size = 2;
1715 const int long_size = 5;
1716 if (is_int8(
offset - short_size) && !predictable_code_size()) {
1719 EMIT((
offset - short_size) & 0xFF);
1723 emit(
offset - long_size);
1727void Assembler::jmp(Label* L, Label::Distance distance) {
1728 if (
L->is_bound()) {
1735 EnsureSpace ensure_space(
this);
1736 if (distance == Label::kNear) {
1740 auto jump_opt = jump_optimization_info();
1742 if (jump_opt->is_optimizing() &&
1743 is_optimizable_farjmp(jump_opt->farjmp_num++)) {
1749 if (jump_opt->is_collecting()) {
1750 jump_opt->farjmps.push_back({
pc_offset(), 1, 0});
1755 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1759void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1760 EnsureSpace ensure_space(
this);
1761 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1763 if (RelocInfo::IsWasmCall(rmode)) {
1766 emit(entry - (
reinterpret_cast<Address>(
pc_) +
sizeof(int32_t)), rmode);
1770void Assembler::jmp(Operand adr) {
1771 EnsureSpace ensure_space(
this);
1773 emit_operand(esp, adr);
1776void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1777 EnsureSpace ensure_space(
this);
1778 DCHECK(RelocInfo::IsCodeTarget(rmode));
1783void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1784 EnsureSpace ensure_space(
this);
1785 DCHECK(0 <= cc &&
static_cast<int>(cc) < 16);
1786 if (
L->is_bound()) {
1787 const int short_size = 2;
1788 const int long_size = 6;
1791 if (is_int8(offs - short_size)) {
1794 EMIT((offs - short_size) & 0xFF);
1799 emit(offs - long_size);
1801 }
else if (distance == Label::kNear) {
1805 auto jump_opt = jump_optimization_info();
1807 if (jump_opt->is_optimizing() &&
1808 is_optimizable_farjmp(jump_opt->farjmp_num++)) {
1815 if (jump_opt->is_collecting()) {
1816 jump_opt->farjmps.push_back({
pc_offset(), 2, 0});
1824 emit_disp(L, Displacement::OTHER);
1828void Assembler::j(Condition cc, uint8_t* entry, RelocInfo::Mode rmode) {
1829 EnsureSpace ensure_space(
this);
1830 DCHECK((0 <= cc) && (
static_cast<int>(cc) < 16));
1834 emit(entry - (
pc_ +
sizeof(int32_t)), rmode);
1837void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) {
1838 EnsureSpace ensure_space(
this);
1847void Assembler::fld(
int i) {
1848 EnsureSpace ensure_space(
this);
1849 emit_farith(0xD9, 0xC0,
i);
1852void Assembler::fstp(
int i) {
1853 EnsureSpace ensure_space(
this);
1854 emit_farith(0xDD, 0xD8,
i);
1857void Assembler::fld1() {
1858 EnsureSpace ensure_space(
this);
1863void Assembler::fldpi() {
1864 EnsureSpace ensure_space(
this);
1869void Assembler::fldz() {
1870 EnsureSpace ensure_space(
this);
1875void Assembler::fldln2() {
1876 EnsureSpace ensure_space(
this);
1881void Assembler::fld_s(Operand adr) {
1882 EnsureSpace ensure_space(
this);
1884 emit_operand(eax, adr);
1887void Assembler::fld_d(Operand adr) {
1888 EnsureSpace ensure_space(
this);
1890 emit_operand(eax, adr);
1893void Assembler::fstp_s(Operand adr) {
1894 EnsureSpace ensure_space(
this);
1896 emit_operand(ebx, adr);
1899void Assembler::fst_s(Operand adr) {
1900 EnsureSpace ensure_space(
this);
1902 emit_operand(edx, adr);
1905void Assembler::fstp_d(Operand adr) {
1906 EnsureSpace ensure_space(
this);
1908 emit_operand(ebx, adr);
1911void Assembler::fst_d(Operand adr) {
1912 EnsureSpace ensure_space(
this);
1914 emit_operand(edx, adr);
1917void Assembler::fild_s(Operand adr) {
1918 EnsureSpace ensure_space(
this);
1920 emit_operand(eax, adr);
1923void Assembler::fild_d(Operand adr) {
1924 EnsureSpace ensure_space(
this);
1926 emit_operand(ebp, adr);
1929void Assembler::fistp_s(Operand adr) {
1930 EnsureSpace ensure_space(
this);
1932 emit_operand(ebx, adr);
1935void Assembler::fisttp_s(Operand adr) {
1937 EnsureSpace ensure_space(
this);
1939 emit_operand(ecx, adr);
1942void Assembler::fisttp_d(Operand adr) {
1944 EnsureSpace ensure_space(
this);
1946 emit_operand(ecx, adr);
1949void Assembler::fist_s(Operand adr) {
1950 EnsureSpace ensure_space(
this);
1952 emit_operand(edx, adr);
1955void Assembler::fistp_d(Operand adr) {
1956 EnsureSpace ensure_space(
this);
1958 emit_operand(edi, adr);
1961void Assembler::fabs() {
1962 EnsureSpace ensure_space(
this);
1967void Assembler::fchs() {
1968 EnsureSpace ensure_space(
this);
1973void Assembler::fcos() {
1974 EnsureSpace ensure_space(
this);
1979void Assembler::fsin() {
1980 EnsureSpace ensure_space(
this);
1985void Assembler::fptan() {
1986 EnsureSpace ensure_space(
this);
1991void Assembler::fyl2x() {
1992 EnsureSpace ensure_space(
this);
1997void Assembler::f2xm1() {
1998 EnsureSpace ensure_space(
this);
2003void Assembler::fscale() {
2004 EnsureSpace ensure_space(
this);
2009void Assembler::fninit() {
2010 EnsureSpace ensure_space(
this);
2015void Assembler::fadd(
int i) {
2016 EnsureSpace ensure_space(
this);
2017 emit_farith(0xDC, 0xC0,
i);
2020void Assembler::fadd_i(
int i) {
2021 EnsureSpace ensure_space(
this);
2022 emit_farith(0xD8, 0xC0,
i);
2025void Assembler::fsub(
int i) {
2026 EnsureSpace ensure_space(
this);
2027 emit_farith(0xDC, 0xE8,
i);
2030void Assembler::fsub_i(
int i) {
2031 EnsureSpace ensure_space(
this);
2032 emit_farith(0xD8, 0xE0,
i);
2035void Assembler::fisub_s(Operand adr) {
2036 EnsureSpace ensure_space(
this);
2038 emit_operand(esp, adr);
2041void Assembler::fmul_i(
int i) {
2042 EnsureSpace ensure_space(
this);
2043 emit_farith(0xD8, 0xC8,
i);
2046void Assembler::fmul(
int i) {
2047 EnsureSpace ensure_space(
this);
2048 emit_farith(0xDC, 0xC8,
i);
2051void Assembler::fdiv(
int i) {
2052 EnsureSpace ensure_space(
this);
2053 emit_farith(0xDC, 0xF8,
i);
2056void Assembler::fdiv_i(
int i) {
2057 EnsureSpace ensure_space(
this);
2058 emit_farith(0xD8, 0xF0,
i);
2061void Assembler::faddp(
int i) {
2062 EnsureSpace ensure_space(
this);
2063 emit_farith(0xDE, 0xC0,
i);
2066void Assembler::fsubp(
int i) {
2067 EnsureSpace ensure_space(
this);
2068 emit_farith(0xDE, 0xE8,
i);
2071void Assembler::fsubrp(
int i) {
2072 EnsureSpace ensure_space(
this);
2073 emit_farith(0xDE, 0xE0,
i);
2076void Assembler::fmulp(
int i) {
2077 EnsureSpace ensure_space(
this);
2078 emit_farith(0xDE, 0xC8,
i);
2081void Assembler::fdivp(
int i) {
2082 EnsureSpace ensure_space(
this);
2083 emit_farith(0xDE, 0xF8,
i);
2086void Assembler::fprem() {
2087 EnsureSpace ensure_space(
this);
2092void Assembler::fprem1() {
2093 EnsureSpace ensure_space(
this);
2098void Assembler::fxch(
int i) {
2099 EnsureSpace ensure_space(
this);
2100 emit_farith(0xD9, 0xC8,
i);
2103void Assembler::fincstp() {
2104 EnsureSpace ensure_space(
this);
2109void Assembler::ffree(
int i) {
2110 EnsureSpace ensure_space(
this);
2111 emit_farith(0xDD, 0xC0,
i);
2114void Assembler::ftst() {
2115 EnsureSpace ensure_space(
this);
2120void Assembler::fucomp(
int i) {
2121 EnsureSpace ensure_space(
this);
2122 emit_farith(0xDD, 0xE8,
i);
2125void Assembler::fucompp() {
2126 EnsureSpace ensure_space(
this);
2131void Assembler::fucomi(
int i) {
2132 EnsureSpace ensure_space(
this);
2137void Assembler::fucomip() {
2138 EnsureSpace ensure_space(
this);
2143void Assembler::fcompp() {
2144 EnsureSpace ensure_space(
this);
2149void Assembler::fnstsw_ax() {
2150 EnsureSpace ensure_space(
this);
2155void Assembler::fwait() {
2156 EnsureSpace ensure_space(
this);
2160void Assembler::frndint() {
2161 EnsureSpace ensure_space(
this);
2166void Assembler::fnclex() {
2167 EnsureSpace ensure_space(
this);
2172void Assembler::sahf() {
2173 EnsureSpace ensure_space(
this);
2177void Assembler::setcc(Condition cc, Register
reg) {
2179 EnsureSpace ensure_space(
this);
2182 EMIT(0xC0 |
reg.code());
2185void Assembler::cvttss2si(Register dst, Operand src) {
2186 EnsureSpace ensure_space(
this);
2192 emit_operand(dst, src);
2195void Assembler::cvttsd2si(Register dst, Operand src) {
2196 EnsureSpace ensure_space(
this);
2202 emit_operand(dst, src);
2205void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2206 EnsureSpace ensure_space(
this);
2210 emit_sse_operand(dst, src);
2213void Assembler::cvtsi2ss(XMMRegister dst, Operand src) {
2214 EnsureSpace ensure_space(
this);
2218 emit_sse_operand(dst, src);
2221void Assembler::cvtsi2sd(XMMRegister dst, Operand src) {
2222 EnsureSpace ensure_space(
this);
2226 emit_sse_operand(dst, src);
2229void Assembler::cvtss2sd(XMMRegister dst, Operand src) {
2230 EnsureSpace ensure_space(
this);
2234 emit_sse_operand(dst, src);
2237void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
2238 EnsureSpace ensure_space(
this);
2242 emit_sse_operand(dst, src);
2245void Assembler::cvtpd2ps(XMMRegister dst, XMMRegister src) {
2246 EnsureSpace ensure_space(
this);
2250 emit_sse_operand(dst, src);
2253void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
2254 EnsureSpace ensure_space(
this);
2258 emit_sse_operand(dst, src);
2261void Assembler::cvttpd2dq(XMMRegister dst, XMMRegister src) {
2262 EnsureSpace ensure_space(
this);
2266 emit_sse_operand(dst, src);
2269void Assembler::cmpps(XMMRegister dst, Operand src, uint8_t cmp) {
2270 EnsureSpace ensure_space(
this);
2273 emit_sse_operand(dst, src);
2277void Assembler::cmppd(XMMRegister dst, Operand src, uint8_t cmp) {
2278 EnsureSpace ensure_space(
this);
2282 emit_sse_operand(dst, src);
2286void Assembler::haddps(XMMRegister dst, Operand src) {
2288 EnsureSpace ensure_space(
this);
2292 emit_sse_operand(dst, src);
2295void Assembler::ucomisd(XMMRegister dst, Operand src) {
2296 EnsureSpace ensure_space(
this);
2300 emit_sse_operand(dst, src);
2303void Assembler::roundps(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2304 DCHECK(IsEnabled(SSE4_1));
2305 EnsureSpace ensure_space(
this);
2310 emit_sse_operand(dst, src);
2312 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
2315void Assembler::roundpd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2316 DCHECK(IsEnabled(SSE4_1));
2317 EnsureSpace ensure_space(
this);
2322 emit_sse_operand(dst, src);
2324 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
2327void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2328 DCHECK(IsEnabled(SSE4_1));
2329 EnsureSpace ensure_space(
this);
2334 emit_sse_operand(dst, src);
2336 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
2339void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2340 DCHECK(IsEnabled(SSE4_1));
2341 EnsureSpace ensure_space(
this);
2346 emit_sse_operand(dst, src);
2348 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
2351void Assembler::movmskpd(Register dst, XMMRegister src) {
2352 EnsureSpace ensure_space(
this);
2356 emit_sse_operand(dst, src);
2359void Assembler::movmskps(Register dst, XMMRegister src) {
2360 EnsureSpace ensure_space(
this);
2363 emit_sse_operand(dst, src);
2366void Assembler::pmovmskb(Register dst, XMMRegister src) {
2367 EnsureSpace ensure_space(
this);
2371 emit_sse_operand(dst, src);
2374void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2375 EnsureSpace ensure_space(
this);
2379 emit_sse_operand(dst, src);
2383void Assembler::movaps(XMMRegister dst, Operand src) {
2384 EnsureSpace ensure_space(
this);
2387 emit_sse_operand(dst, src);
2390void Assembler::movups(XMMRegister dst, Operand src) {
2391 EnsureSpace ensure_space(
this);
2394 emit_sse_operand(dst, src);
2397void Assembler::movups(Operand dst, XMMRegister src) {
2398 EnsureSpace ensure_space(
this);
2401 emit_sse_operand(src, dst);
2404void Assembler::movddup(XMMRegister dst, Operand src) {
2406 EnsureSpace ensure_space(
this);
2410 emit_sse_operand(dst, src);
2413void Assembler::movshdup(XMMRegister dst, XMMRegister src) {
2415 EnsureSpace ensure_space(
this);
2419 emit_sse_operand(dst, src);
2422void Assembler::shufps(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2424 EnsureSpace ensure_space(
this);
2427 emit_sse_operand(dst, src);
2431void Assembler::shufpd(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2433 EnsureSpace ensure_space(
this);
2437 emit_sse_operand(dst, src);
2441void Assembler::movhlps(XMMRegister dst, XMMRegister src) {
2442 EnsureSpace ensure_space(
this);
2445 emit_sse_operand(dst, src);
2448void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
2449 EnsureSpace ensure_space(
this);
2452 emit_sse_operand(dst, src);
2455void Assembler::movlps(XMMRegister dst, Operand src) {
2456 EnsureSpace ensure_space(
this);
2459 emit_sse_operand(dst, src);
2462void Assembler::movlps(Operand dst, XMMRegister src) {
2463 EnsureSpace ensure_space(
this);
2466 emit_sse_operand(src, dst);
2469void Assembler::movhps(XMMRegister dst, Operand src) {
2470 EnsureSpace ensure_space(
this);
2473 emit_sse_operand(dst, src);
2476void Assembler::movhps(Operand dst, XMMRegister src) {
2477 EnsureSpace ensure_space(
this);
2480 emit_sse_operand(src, dst);
2483void Assembler::movdqa(Operand dst, XMMRegister src) {
2484 EnsureSpace ensure_space(
this);
2488 emit_sse_operand(src, dst);
2491void Assembler::movdqa(XMMRegister dst, Operand src) {
2492 EnsureSpace ensure_space(
this);
2496 emit_sse_operand(dst, src);
2499void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
2500 EnsureSpace ensure_space(
this);
2504 emit_sse_operand(dst, src);
2507void Assembler::movdqu(Operand dst, XMMRegister src) {
2508 EnsureSpace ensure_space(
this);
2512 emit_sse_operand(src, dst);
2515void Assembler::movdqu(XMMRegister dst, Operand src) {
2516 EnsureSpace ensure_space(
this);
2520 emit_sse_operand(dst, src);
2523void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
2524 EnsureSpace ensure_space(
this);
2528 emit_sse_operand(src, dst);
2531void Assembler::prefetch(Operand src,
int level) {
2533 EnsureSpace ensure_space(
this);
2537 XMMRegister code = XMMRegister::from_code(level);
2538 emit_sse_operand(code, src);
2541void Assembler::movsd(Operand dst, XMMRegister src) {
2542 EnsureSpace ensure_space(
this);
2546 emit_sse_operand(src, dst);
2549void Assembler::movsd(XMMRegister dst, Operand src) {
2550 EnsureSpace ensure_space(
this);
2554 emit_sse_operand(dst, src);
2557void Assembler::movss(Operand dst, XMMRegister src) {
2558 EnsureSpace ensure_space(
this);
2562 emit_sse_operand(src, dst);
2565void Assembler::movss(XMMRegister dst, Operand src) {
2566 EnsureSpace ensure_space(
this);
2570 emit_sse_operand(dst, src);
2573void Assembler::movd(XMMRegister dst, Operand src) {
2574 EnsureSpace ensure_space(
this);
2578 emit_sse_operand(dst, src);
2581void Assembler::movd(Operand dst, XMMRegister src) {
2582 EnsureSpace ensure_space(
this);
2586 emit_sse_operand(src, dst);
2589void Assembler::extractps(Operand dst, XMMRegister src, uint8_t imm8) {
2590 DCHECK(IsEnabled(SSE4_1));
2592 EnsureSpace ensure_space(
this);
2597 emit_sse_operand(src, dst);
2601void Assembler::extractps(Register dst, XMMRegister src, uint8_t imm8) {
2602 DCHECK(IsEnabled(SSE4_1));
2604 EnsureSpace ensure_space(
this);
2609 emit_sse_operand(src, dst);
2613void Assembler::pcmpgtq(XMMRegister dst, XMMRegister src) {
2614 DCHECK(IsEnabled(SSE4_2));
2615 EnsureSpace ensure_space(
this);
2620 emit_sse_operand(dst, src);
2623void Assembler::psllw(XMMRegister
reg, uint8_t shift) {
2624 EnsureSpace ensure_space(
this);
2628 emit_sse_operand(esi,
reg);
2632void Assembler::pslld(XMMRegister
reg, uint8_t shift) {
2633 EnsureSpace ensure_space(
this);
2637 emit_sse_operand(esi,
reg);
2641void Assembler::psrlw(XMMRegister
reg, uint8_t shift) {
2642 EnsureSpace ensure_space(
this);
2646 emit_sse_operand(edx,
reg);
2650void Assembler::psrld(XMMRegister
reg, uint8_t shift) {
2651 EnsureSpace ensure_space(
this);
2655 emit_sse_operand(edx,
reg);
2659void Assembler::psraw(XMMRegister
reg, uint8_t shift) {
2660 EnsureSpace ensure_space(
this);
2664 emit_sse_operand(esp,
reg);
2668void Assembler::psrad(XMMRegister
reg, uint8_t shift) {
2669 EnsureSpace ensure_space(
this);
2673 emit_sse_operand(esp,
reg);
2677void Assembler::psllq(XMMRegister
reg, uint8_t shift) {
2678 EnsureSpace ensure_space(
this);
2682 emit_sse_operand(esi,
reg);
2686void Assembler::psrlq(XMMRegister
reg, uint8_t shift) {
2687 EnsureSpace ensure_space(
this);
2691 emit_sse_operand(edx,
reg);
2695void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
2696 EnsureSpace ensure_space(
this);
2700 emit_sse_operand(dst, src);
2704void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
2705 EnsureSpace ensure_space(
this);
2709 emit_sse_operand(dst, src);
2713void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
2714 EnsureSpace ensure_space(
this);
2718 emit_sse_operand(dst, src);
2722void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t
mask) {
2723 DCHECK(IsEnabled(SSE4_1));
2724 EnsureSpace ensure_space(
this);
2729 emit_sse_operand(dst, src);
2733void Assembler::palignr(XMMRegister dst, Operand src, uint8_t
mask) {
2734 DCHECK(IsEnabled(SSSE3));
2735 EnsureSpace ensure_space(
this);
2740 emit_sse_operand(dst, src);
2744void Assembler::pextrb(Operand dst, XMMRegister src, uint8_t
offset) {
2745 DCHECK(IsEnabled(SSE4_1));
2746 EnsureSpace ensure_space(
this);
2751 emit_sse_operand(src, dst);
2755void Assembler::pextrw(Operand dst, XMMRegister src, uint8_t
offset) {
2756 DCHECK(IsEnabled(SSE4_1));
2757 EnsureSpace ensure_space(
this);
2762 emit_sse_operand(src, dst);
2766void Assembler::pextrd(Operand dst, XMMRegister src, uint8_t
offset) {
2767 DCHECK(IsEnabled(SSE4_1));
2768 EnsureSpace ensure_space(
this);
2773 emit_sse_operand(src, dst);
2777void Assembler::insertps(XMMRegister dst, Operand src, uint8_t
offset) {
2778 DCHECK(IsEnabled(SSE4_1));
2779 EnsureSpace ensure_space(
this);
2784 emit_sse_operand(dst, src);
2788void Assembler::pinsrb(XMMRegister dst, Operand src, uint8_t
offset) {
2789 DCHECK(IsEnabled(SSE4_1));
2790 EnsureSpace ensure_space(
this);
2795 emit_sse_operand(dst, src);
2799void Assembler::pinsrw(XMMRegister dst, Operand src, uint8_t
offset) {
2801 EnsureSpace ensure_space(
this);
2805 emit_sse_operand(dst, src);
2809void Assembler::pinsrd(XMMRegister dst, Operand src, uint8_t
offset) {
2810 DCHECK(IsEnabled(SSE4_1));
2811 EnsureSpace ensure_space(
this);
2816 emit_sse_operand(dst, src);
2820void Assembler::addss(XMMRegister dst, Operand src) {
2821 EnsureSpace ensure_space(
this);
2825 emit_sse_operand(dst, src);
2828void Assembler::subss(XMMRegister dst, Operand src) {
2829 EnsureSpace ensure_space(
this);
2833 emit_sse_operand(dst, src);
2836void Assembler::mulss(XMMRegister dst, Operand src) {
2837 EnsureSpace ensure_space(
this);
2841 emit_sse_operand(dst, src);
2844void Assembler::divss(XMMRegister dst, Operand src) {
2845 EnsureSpace ensure_space(
this);
2849 emit_sse_operand(dst, src);
2852void Assembler::sqrtss(XMMRegister dst, Operand src) {
2853 EnsureSpace ensure_space(
this);
2857 emit_sse_operand(dst, src);
2860void Assembler::ucomiss(XMMRegister dst, Operand src) {
2861 EnsureSpace ensure_space(
this);
2864 emit_sse_operand(dst, src);
2867void Assembler::maxss(XMMRegister dst, Operand src) {
2868 EnsureSpace ensure_space(
this);
2872 emit_sse_operand(dst, src);
2875void Assembler::minss(XMMRegister dst, Operand src) {
2876 EnsureSpace ensure_space(
this);
2880 emit_sse_operand(dst, src);
2884void Assembler::ps(uint8_t opcode, XMMRegister dst, Operand src) {
2885 EnsureSpace ensure_space(
this);
2888 emit_sse_operand(dst, src);
2892void Assembler::pd(uint8_t opcode, XMMRegister dst, Operand src) {
2893 EnsureSpace ensure_space(
this);
2897 emit_sse_operand(dst, src);
2902void Assembler::vss(uint8_t op, XMMRegister dst, XMMRegister src1,
2904 vinstr(op, dst, src1, src2, kF3, k0F, kWIG);
2907void Assembler::vps(uint8_t op, XMMRegister dst, XMMRegister src1,
2909 vinstr(op, dst, src1, src2, kNoPrefix, k0F, kWIG);
2912void Assembler::vpd(uint8_t op, XMMRegister dst, XMMRegister src1,
2914 vinstr(op, dst, src1, src2, k66, k0F, kWIG);
2917void Assembler::vshufpd(XMMRegister dst, XMMRegister src1, Operand src2,
2920 vpd(0xC6, dst, src1, src2);
2924void Assembler::vmovhlps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
2925 vinstr(0x12, dst, src1, src2, kNoPrefix, k0F, kWIG);
2928void Assembler::vmovlhps(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
2929 vinstr(0x16, dst, src1, src2, kNoPrefix, k0F, kWIG);
2932void Assembler::vmovlps(XMMRegister dst, XMMRegister src1, Operand src2) {
2933 vinstr(0x12, dst, src1, src2, kNoPrefix, k0F, kWIG);
2936void Assembler::vmovlps(Operand dst, XMMRegister src) {
2937 vinstr(0x13, src, xmm0, dst, kNoPrefix, k0F, kWIG);
2940void Assembler::vmovhps(XMMRegister dst, XMMRegister src1, Operand src2) {
2941 vinstr(0x16, dst, src1, src2, kNoPrefix, k0F, kWIG);
2944void Assembler::vmovhps(Operand dst, XMMRegister src) {
2945 vinstr(0x17, src, xmm0, dst, kNoPrefix, k0F, kWIG);
2948void Assembler::vcmpps(XMMRegister dst, XMMRegister src1, Operand src2,
2950 vps(0xC2, dst, src1, src2);
2954void Assembler::vcmppd(XMMRegister dst, XMMRegister src1, Operand src2,
2956 vpd(0xC2, dst, src1, src2);
2960void Assembler::vshufps(XMMRegister dst, XMMRegister src1, Operand src2,
2963 vps(0xC6, dst, src1, src2);
2967void Assembler::vpsllw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2968 XMMRegister
iop = XMMRegister::from_code(6);
2969 vinstr(0x71,
iop, dst, Operand(src), k66, k0F, kWIG);
2973void Assembler::vpslld(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2974 XMMRegister
iop = XMMRegister::from_code(6);
2975 vinstr(0x72,
iop, dst, Operand(src), k66, k0F, kWIG);
2979void Assembler::vpsllq(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2980 XMMRegister
iop = XMMRegister::from_code(6);
2981 vinstr(0x73,
iop, dst, Operand(src), k66, k0F, kWIG);
2985void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2986 XMMRegister
iop = XMMRegister::from_code(2);
2987 vinstr(0x71,
iop, dst, Operand(src), k66, k0F, kWIG);
2991void Assembler::vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2992 XMMRegister
iop = XMMRegister::from_code(2);
2993 vinstr(0x72,
iop, dst, Operand(src), k66, k0F, kWIG);
2997void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2998 XMMRegister
iop = XMMRegister::from_code(2);
2999 vinstr(0x73,
iop, dst, Operand(src), k66, k0F, kWIG);
3003void Assembler::vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
3004 XMMRegister
iop = XMMRegister::from_code(4);
3005 vinstr(0x71,
iop, dst, Operand(src), k66, k0F, kWIG);
3009void Assembler::vpsrad(XMMRegister dst, XMMRegister src, uint8_t imm8) {
3010 XMMRegister
iop = XMMRegister::from_code(4);
3011 vinstr(0x72,
iop, dst, Operand(src), k66, k0F, kWIG);
3015void Assembler::vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
3016 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG);
3020void Assembler::vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
3021 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG);
3025void Assembler::vpshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
3026 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
3030void Assembler::vblendvps(XMMRegister dst, XMMRegister src1, XMMRegister src2,
3032 vinstr(0x4A, dst, src1, src2, k66, k0F3A, kW0);
3033 EMIT(
mask.code() << 4);
3036void Assembler::vblendvpd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
3038 vinstr(0x4B, dst, src1, src2, k66, k0F3A, kW0);
3039 EMIT(
mask.code() << 4);
3042void Assembler::vpblendvb(XMMRegister dst, XMMRegister src1, XMMRegister src2,
3044 vinstr(0x4C, dst, src1, src2, k66, k0F3A, kW0);
3045 EMIT(
mask.code() << 4);
3048void Assembler::vpblendw(XMMRegister dst, XMMRegister src1, Operand src2,
3050 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
3054void Assembler::vpalignr(XMMRegister dst, XMMRegister src1, Operand src2,
3056 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
3060void Assembler::vpextrb(Operand dst, XMMRegister src, uint8_t
offset) {
3061 vinstr(0x14, src, xmm0, dst, k66, k0F3A, kWIG);
3065void Assembler::vpextrw(Operand dst, XMMRegister src, uint8_t
offset) {
3066 vinstr(0x15, src, xmm0, dst, k66, k0F3A, kWIG);
3070void Assembler::vpextrd(Operand dst, XMMRegister src, uint8_t
offset) {
3071 vinstr(0x16, src, xmm0, dst, k66, k0F3A, kWIG);
3075void Assembler::vinsertps(XMMRegister dst, XMMRegister src1, Operand src2,
3077 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG);
3081void Assembler::vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2,
3083 vinstr(0x20, dst, src1, src2, k66, k0F3A, kWIG);
3087void Assembler::vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2,
3089 vinstr(0xC4, dst, src1, src2, k66, k0F, kWIG);
3093void Assembler::vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2,
3095 vinstr(0x22, dst, src1, src2, k66, k0F3A, kWIG);
3099void Assembler::vroundsd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
3100 RoundingMode mode) {
3101 vinstr(0x0b, dst, src1, src2, k66, k0F3A, kWIG);
3102 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
3104void Assembler::vroundss(XMMRegister dst, XMMRegister src1, XMMRegister src2,
3105 RoundingMode mode) {
3106 vinstr(0x0a, dst, src1, src2, k66, k0F3A, kWIG);
3107 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
3109void Assembler::vroundps(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3110 vinstr(0x08, dst, xmm0, Operand(src), k66, k0F3A, kWIG);
3111 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
3113void Assembler::vroundpd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
3114 vinstr(0x09, dst, xmm0, Operand(src), k66, k0F3A, kWIG);
3115 EMIT(
static_cast<uint8_t
>(mode) | 0x8);
3118void Assembler::vmovmskpd(Register dst, XMMRegister src) {
3120 EnsureSpace ensure_space(
this);
3121 emit_vex_prefix(xmm0, kL128, k66, k0F, kWIG);
3123 emit_sse_operand(dst, src);
3126void Assembler::vmovmskps(Register dst, XMMRegister src) {
3128 EnsureSpace ensure_space(
this);
3129 emit_vex_prefix(xmm0, kL128, kNoPrefix, k0F, kWIG);
3131 emit_sse_operand(dst, src);
3134void Assembler::vpmovmskb(Register dst, XMMRegister src) {
3136 EnsureSpace ensure_space(
this);
3137 emit_vex_prefix(xmm0, kL128, k66, k0F, kWIG);
3139 emit_sse_operand(dst, src);
3142void Assembler::vextractps(Operand dst, XMMRegister src, uint8_t imm8) {
3143 vinstr(0x17, src, xmm0, dst, k66, k0F3A, VexW::kWIG);
3147void Assembler::vpcmpgtq(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
3148 vinstr(0x37, dst, src1, src2, k66, k0F38, VexW::kWIG);
3151void Assembler::bmi1(uint8_t op, Register
reg, Register vreg, Operand rm) {
3153 EnsureSpace ensure_space(
this);
3154 emit_vex_prefix(vreg, kLZ, kNoPrefix, k0F38, kW0);
3156 emit_operand(
reg, rm);
3159void Assembler::tzcnt(Register dst, Operand src) {
3161 EnsureSpace ensure_space(
this);
3165 emit_operand(dst, src);
3168void Assembler::lzcnt(Register dst, Operand src) {
3169 DCHECK(IsEnabled(LZCNT));
3170 EnsureSpace ensure_space(
this);
3174 emit_operand(dst, src);
3177void Assembler::popcnt(Register dst, Operand src) {
3178 DCHECK(IsEnabled(POPCNT));
3179 EnsureSpace ensure_space(
this);
3183 emit_operand(dst, src);
3186void Assembler::bmi2(SIMDPrefix pp, uint8_t op, Register
reg, Register vreg,
3189 EnsureSpace ensure_space(
this);
3190 emit_vex_prefix(vreg, kLZ, pp, k0F38, kW0);
3192 emit_operand(
reg, rm);
3195void Assembler::rorx(Register dst, Operand src, uint8_t imm8) {
3198 Register vreg = Register::from_code(0);
3199 EnsureSpace ensure_space(
this);
3200 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0);
3202 emit_operand(dst, src);
3206void Assembler::sse_instr(XMMRegister dst, Operand src, uint8_t escape,
3208 EnsureSpace ensure_space(
this);
3211 emit_sse_operand(dst, src);
3214void Assembler::sse2_instr(XMMRegister dst, Operand src, uint8_t prefix,
3215 uint8_t escape, uint8_t opcode) {
3216 EnsureSpace ensure_space(
this);
3220 emit_sse_operand(dst, src);
3223void Assembler::ssse3_instr(XMMRegister dst, Operand src, uint8_t prefix,
3224 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
3225 DCHECK(IsEnabled(SSSE3));
3226 EnsureSpace ensure_space(
this);
3231 emit_sse_operand(dst, src);
3234void Assembler::sse4_instr(XMMRegister dst, Operand src, uint8_t prefix,
3235 uint8_t escape1, uint8_t escape2, uint8_t opcode) {
3236 DCHECK(IsEnabled(SSE4_1));
3237 EnsureSpace ensure_space(
this);
3242 emit_sse_operand(dst, src);
3245void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3246 XMMRegister src2, SIMDPrefix pp, LeadingOpcode
m, VexW w,
3247 CpuFeature feature) {
3248 vinstr(op, dst, src1, src2, kL128, pp,
m, w, feature);
3251void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3252 Operand src2, SIMDPrefix pp, LeadingOpcode
m, VexW w,
3253 CpuFeature feature) {
3254 vinstr(op, dst, src1, src2, kL128, pp,
m, w, feature);
3257void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3258 XMMRegister src2, VectorLength l, SIMDPrefix pp,
3259 LeadingOpcode
m, VexW w, CpuFeature feature) {
3260 DCHECK(IsEnabled(feature));
3261 EnsureSpace ensure_space(
this);
3262 emit_vex_prefix(src1, l, pp,
m, w);
3264 emit_sse_operand(dst, src2);
3267void Assembler::vinstr(uint8_t op, XMMRegister dst, XMMRegister src1,
3268 Operand src2, VectorLength l, SIMDPrefix pp,
3269 LeadingOpcode
m, VexW w, CpuFeature feature) {
3270 DCHECK(IsEnabled(feature));
3271 EnsureSpace ensure_space(
this);
3272 emit_vex_prefix(src1, l, pp,
m, w);
3274 emit_sse_operand(dst, src2);
3277void Assembler::emit_sse_operand(XMMRegister
reg, Operand adr) {
3279 emit_operand(ireg, adr);
3282void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3283 EMIT(0xC0 | dst.code() << 3 | src.code());
3286void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3287 EMIT(0xC0 | dst.code() << 3 | src.code());
3290void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3291 EMIT(0xC0 | (dst.code() << 3) | src.code());
3294void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp,
3295 LeadingOpcode mm, VexW w) {
3296 if (mm != k0F || w != kW0) {
3300 EMIT(w | ((~vreg.code() & 0xF) << 3) | l | pp);
3303 EMIT(((~vreg.code()) << 3) | l | pp);
3307void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp,
3308 LeadingOpcode mm, VexW w) {
3309 XMMRegister ivreg = XMMRegister::from_code(vreg.code());
3310 emit_vex_prefix(ivreg, l, pp, mm, w);
3313void Assembler::GrowBuffer() {
3314 DCHECK(buffer_overflow());
3318 int old_size =
buffer_->size();
3319 int new_size = 2 * old_size;
3323 if (new_size > kMaximalBufferSize) {
3324 V8::FatalProcessOutOfMemory(
nullptr,
"Assembler::GrowBuffer");
3328 std::unique_ptr<AssemblerBuffer> new_buffer =
buffer_->Grow(new_size);
3329 DCHECK_EQ(new_size, new_buffer->size());
3330 uint8_t* new_start = new_buffer->start();
3333 intptr_t pc_delta = new_start - buffer_start_;
3334 intptr_t rc_delta = (new_start + new_size) - (buffer_start_ + old_size);
3335 size_t reloc_size = (buffer_start_ + old_size) - reloc_info_writer.pos();
3337 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
3341 buffer_ = std::move(new_buffer);
3342 buffer_start_ = new_start;
3344 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3345 reloc_info_writer.last_pc() + pc_delta);
3348 for (
auto pos : internal_reference_positions_) {
3350 WriteUnalignedValue(p, ReadUnalignedValue<int>(p) + pc_delta);
3354 int mode_mask = RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET);
3355 DCHECK_EQ(mode_mask, RelocInfo::kApplyMask & mode_mask);
3356 base::Vector<uint8_t> instructions{buffer_start_,
3358 base::Vector<const uint8_t> reloc_info{reloc_info_writer.pos(), reloc_size};
3359 WritableJitAllocation jit_allocation =
3360 WritableJitAllocation::ForNonExecutableMemory(
3361 reinterpret_cast<Address>(instructions.begin()), instructions.size(),
3362 ThreadIsolation::JitAllocationType::kInstructionStream);
3363 for (WritableRelocIterator it(jit_allocation, instructions, reloc_info, 0,
3365 !it.done(); it.next()) {
3366 it.rinfo()->apply(pc_delta);
3369 DCHECK(!buffer_overflow());
3372void Assembler::emit_arith_b(
int op1,
int op2, Register dst,
int imm8) {
3373 DCHECK(is_uint8(op1) && is_uint8(op2));
3377 EMIT(op2 | dst.code());
3381void Assembler::emit_arith(
int sel, Operand dst,
const Immediate&
x) {
3382 DCHECK((0 <= sel) && (sel <= 7));
3383 Register ireg = Register::from_code(sel);
3386 emit_operand(ireg, dst);
3387 EMIT(
x.immediate() & 0xFF);
3388 }
else if (dst.is_reg(eax)) {
3389 EMIT((sel << 3) | 0x05);
3393 emit_operand(ireg, dst);
3398void Assembler::emit_operand(Register
reg, Operand adr) {
3399 emit_operand(
reg.code(), adr);
3402void Assembler::emit_operand(XMMRegister
reg, Operand adr) {
3404 emit_operand(ireg, adr);
3407void Assembler::emit_operand(
int code, Operand adr) {
3410 adr.rmode() != RelocInfo::CODE_TARGET);
3412 adr.rmode() != RelocInfo::FULL_EMBEDDED_OBJECT);
3414 adr.rmode() != RelocInfo::EXTERNAL_REFERENCE);
3416 const unsigned length = adr.encoded_bytes().length();
3420 EMIT((adr.encoded_bytes()[0] & ~0x38) | (code << 3));
3423 for (
unsigned i = 1;
i <
length;
i++) EMIT(adr.encoded_bytes()[
i]);
3426 if (length >=
sizeof(int32_t) && !RelocInfo::IsNoInfo(adr.rmode())) {
3428 RecordRelocInfo(adr.rmode());
3429 if (adr.rmode() == RelocInfo::INTERNAL_REFERENCE) {
3430 emit_label(ReadUnalignedValue<Label*>(
reinterpret_cast<Address>(
pc_)));
3437void Assembler::emit_label(Label*
label) {
3438 if (
label->is_bound()) {
3439 internal_reference_positions_.push_back(
pc_offset());
3440 emit(
reinterpret_cast<uint32_t
>(buffer_start_ +
label->pos()));
3442 emit_disp(
label, Displacement::CODE_ABSOLUTE);
3446void Assembler::emit_farith(
int b1,
int b2,
int i) {
3447 DCHECK(is_uint8(b1) && is_uint8(b2));
3453void Assembler::db(uint8_t data) {
3454 EnsureSpace ensure_space(
this);
3458void Assembler::dd(uint32_t data) {
3459 EnsureSpace ensure_space(
this);
3463void Assembler::dq(uint64_t data) {
3464 EnsureSpace ensure_space(
this);
3468void Assembler::dd(Label*
label) {
3469 EnsureSpace ensure_space(
this);
3470 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3474void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3475 if (!ShouldRecordRelocInfo(rmode))
return;
3476 RelocInfo rinfo(
reinterpret_cast<Address>(
pc_), rmode, data);
3477 reloc_info_writer.Write(&rinfo);
interpreter::OperandScale scale
static constexpr bool is_valid(T value)
static constexpr U encode(T value)
std::forward_list< HeapNumberRequest > heap_number_requests_
static const int kMaximalBufferSize
void AllocateAndInstallRequestedHeapNumbers(LocalIsolate *isolate)
Assembler(const AssemblerOptions &, std::unique_ptr< AssemblerBuffer >={})
static bool IsSupported(CpuFeature f)
static bool supports_wasm_simd_128_
static bool SupportsWasmSimd128()
static void PrintFeatures()
static void SetSupported(CpuFeature f)
static void PrintTarget()
static void SetUnsupported(CpuFeature f)
static void ProbeImpl(bool cross_compile)
void next(Label *L) const
void init(Label *L, Type type)
void set_disp8(int8_t disp)
void set_sib(ScaleFactor scale, Register index, Register base)
void set_dispr(int32_t disp, RelocInfo::Mode rmode)
void set_modrm(int mod, Register rm)
V8_INLINE Operand(int32_t immediate, RelocInfo::Mode rmode=RelocInfo::NO_INFO)
static constexpr Register from_code(int code)
static const int kApplyMask
uint32_t wasm_call_tag() const
static constexpr int ModeMask(Mode mode)
static constexpr bool IsNoInfo(Mode mode)
static constexpr Tagged< Smi > FromInt(int value)
base::OwnedVector< uint8_t > buffer_
DirectHandle< JSReceiver > options
ZoneVector< RpoNumber > & result
bool operator!=(ExternalReference lhs, ExternalReference rhs)
bool DoubleToSmiInteger(double value, int *smi_int_value)
void PrintF(const char *format,...)
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_NOT_NULL(val)
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_UNLIKELY(condition)