37 #include "src/ia32/assembler-ia32.h" 41 #if V8_TARGET_ARCH_IA32 47 #include <sys/sysctl.h> 50 #include "src/assembler-inl.h" 51 #include "src/base/bits.h" 52 #include "src/base/cpu.h" 53 #include "src/code-stubs.h" 54 #include "src/conversions-inl.h" 55 #include "src/deoptimizer.h" 56 #include "src/disassembler.h" 57 #include "src/macro-assembler.h" 58 #include "src/string-constants.h" 64 Immediate Immediate::EmbeddedNumber(
double value) {
66 if (DoubleToSmiInteger(value, &smi))
return Immediate(Smi::FromInt(smi));
67 Immediate result(0, RelocInfo::EMBEDDED_OBJECT);
68 result.is_heap_object_request_ =
true;
69 result.value_.heap_object_request = HeapObjectRequest(value);
73 Immediate Immediate::EmbeddedCode(CodeStub* stub) {
74 Immediate result(0, RelocInfo::CODE_TARGET);
75 result.is_heap_object_request_ =
true;
76 result.value_.heap_object_request = HeapObjectRequest(stub);
80 Immediate Immediate::EmbeddedStringConstant(
const StringConstantBase* str) {
81 Immediate result(0, RelocInfo::EMBEDDED_OBJECT);
82 result.is_heap_object_request_ =
true;
83 result.value_.heap_object_request = HeapObjectRequest(str);
94 V8_INLINE uint64_t _xgetbv(
unsigned int xcr) {
100 __asm__
volatile(
".byte 0x0F, 0x01, 0xD0" :
"=a"(eax),
"=d"(edx) :
"c"(xcr));
101 return static_cast<uint64_t
>(eax) | (static_cast<uint64_t>(edx) << 32);
104 #define _XCR_XFEATURE_ENABLED_MASK 0 106 #endif // !V8_LIBC_MSVCRT 109 bool OSHasAVXSupport() {
114 size_t buffer_size = arraysize(buffer);
115 int ctl_name[] = {CTL_KERN, KERN_OSRELEASE};
116 if (sysctl(ctl_name, 2, buffer, &buffer_size,
nullptr, 0) != 0) {
117 FATAL(
"V8 failed to get kernel version");
121 char* period_pos = strchr(buffer,
'.');
122 DCHECK_NOT_NULL(period_pos);
124 long kernel_version_major = strtol(buffer,
nullptr, 10);
125 if (kernel_version_major <= 13)
return false;
126 #endif // V8_OS_MACOSX 128 uint64_t feature_mask = _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
129 return (feature_mask & 0x6) == 0x6;
135 void CpuFeatures::ProbeImpl(
bool cross_compile) {
137 CHECK(cpu.has_sse2());
138 CHECK(cpu.has_cmov());
141 if (cross_compile)
return;
143 if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
144 if (cpu.has_ssse3() && FLAG_enable_ssse3) supported_ |= 1u << SSSE3;
145 if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
146 if (cpu.has_avx() && FLAG_enable_avx && cpu.has_osxsave() &&
148 supported_ |= 1u << AVX;
150 if (cpu.has_fma3() && FLAG_enable_fma3 && cpu.has_osxsave() &&
152 supported_ |= 1u << FMA3;
154 if (cpu.has_bmi1() && FLAG_enable_bmi1) supported_ |= 1u << BMI1;
155 if (cpu.has_bmi2() && FLAG_enable_bmi2) supported_ |= 1u << BMI2;
156 if (cpu.has_lzcnt() && FLAG_enable_lzcnt) supported_ |= 1u << LZCNT;
157 if (cpu.has_popcnt() && FLAG_enable_popcnt) supported_ |= 1u << POPCNT;
158 if (strcmp(FLAG_mcpu,
"auto") == 0) {
159 if (cpu.is_atom()) supported_ |= 1u << ATOM;
160 }
else if (strcmp(FLAG_mcpu,
"atom") == 0) {
161 supported_ |= 1u << ATOM;
166 void CpuFeatures::PrintTarget() { }
167 void CpuFeatures::PrintFeatures() {
169 "SSE3=%d SSSE3=%d SSE4_1=%d AVX=%d FMA3=%d BMI1=%d BMI2=%d LZCNT=%d " 170 "POPCNT=%d ATOM=%d\n",
171 CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3),
172 CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX),
173 CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(BMI1),
174 CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT),
175 CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(ATOM));
182 void Displacement::init(Label* L,
Type type) {
183 DCHECK(!L->is_bound());
185 if (L->is_linked()) {
190 DCHECK(NextField::is_valid(Assembler::kMaximalBufferSize));
191 data_ = NextField::encode(next) | TypeField::encode(type);
198 const int RelocInfo::kApplyMask =
199 RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
200 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) |
201 RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET) |
202 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
204 bool RelocInfo::IsCodedSpecially() {
209 return RelocInfo::ModeMask(rmode_) & kApplyMask;
213 bool RelocInfo::IsInConstantPool() {
217 int RelocInfo::GetDeoptimizationId(Isolate* isolate, DeoptimizeKind kind) {
218 DCHECK(IsRuntimeEntry(rmode_));
219 return Deoptimizer::GetDeoptimizationId(isolate, target_address(), kind);
222 uint32_t RelocInfo::wasm_call_tag()
const {
223 DCHECK(rmode_ == WASM_CALL || rmode_ == WASM_STUB_CALL);
224 return Memory<uint32_t>(pc_);
230 Operand::Operand(Register base, int32_t disp, RelocInfo::Mode rmode) {
232 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) {
235 if (base == esp) set_sib(times_1, esp, base);
236 }
else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
239 if (base == esp) set_sib(times_1, esp, base);
244 if (base == esp) set_sib(times_1, esp, base);
245 set_dispr(disp, rmode);
250 Operand::Operand(Register base,
254 RelocInfo::Mode rmode) {
255 DCHECK(index != esp);
257 if (disp == 0 && RelocInfo::IsNone(rmode) && base != ebp) {
260 set_sib(scale, index, base);
261 }
else if (is_int8(disp) && RelocInfo::IsNone(rmode)) {
264 set_sib(scale, index, base);
269 set_sib(scale, index, base);
270 set_dispr(disp, rmode);
275 Operand::Operand(Register index,
278 RelocInfo::Mode rmode) {
279 DCHECK(index != esp);
282 set_sib(scale, index, ebp);
283 set_dispr(disp, rmode);
287 bool Operand::is_reg_only()
const {
288 return (buf_[0] & 0xF8) == 0xC0;
292 Register Operand::reg()
const {
293 DCHECK(is_reg_only());
294 return Register::from_code(buf_[0] & 0x07);
297 void Assembler::AllocateAndInstallRequestedHeapObjects(Isolate* isolate) {
298 DCHECK_IMPLIES(isolate ==
nullptr, heap_object_requests_.empty());
299 for (
auto& request : heap_object_requests_) {
300 Handle<HeapObject> object;
301 switch (request.kind()) {
302 case HeapObjectRequest::kHeapNumber:
304 isolate->factory()->NewHeapNumber(request.heap_number(), TENURED);
306 case HeapObjectRequest::kCodeStub:
307 request.code_stub()->set_isolate(isolate);
308 object = request.code_stub()->GetCode();
310 case HeapObjectRequest::kStringConstant: {
311 const StringConstantBase* str = request.string();
313 object = str->AllocateStringConstant(isolate);
317 Address pc =
reinterpret_cast<Address
>(buffer_) + request.offset();
318 Memory<Handle<Object>>(pc) =
object;
329 Assembler::Assembler(
const AssemblerOptions& options,
void* buffer,
331 : AssemblerBase(options, buffer, buffer_size) {
336 if (own_buffer_) ZapCode(reinterpret_cast<Address>(buffer_), buffer_size_);
339 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
342 void Assembler::GetCode(Isolate* isolate, CodeDesc* desc) {
345 DCHECK(pc_ <= reloc_info_writer.pos());
347 AllocateAndInstallRequestedHeapObjects(isolate);
350 desc->buffer = buffer_;
351 desc->buffer_size = buffer_size_;
352 desc->instr_size = pc_offset();
353 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
355 desc->constant_pool_size = 0;
356 desc->unwinding_info_size = 0;
357 desc->unwinding_info =
nullptr;
360 auto jump_opt = jump_optimization_info();
361 if (jump_opt && jump_opt->is_collecting()) {
362 auto& bitmap = jump_opt->farjmp_bitmap();
363 int num =
static_cast<int>(farjmp_positions_.size());
364 if (num && bitmap.empty()) {
365 bool can_opt =
false;
367 bitmap.resize((num + 31) / 32, 0);
368 for (
int i = 0;
i < num;
i++) {
369 int disp_pos = farjmp_positions_[
i];
370 int disp = long_at(disp_pos);
372 bitmap[
i / 32] |= 1 << (
i & 31);
377 jump_opt->set_optimizable();
384 void Assembler::Align(
int m) {
385 DCHECK(base::bits::IsPowerOfTwo(m));
387 int addr = pc_offset();
388 Nop((m - (addr & mask)) & mask);
392 bool Assembler::IsNop(Address addr) {
393 byte* a =
reinterpret_cast<byte*
>(addr);
394 while (*a == 0x66) a++;
395 if (*a == 0x90)
return true;
396 if (a[0] == 0xF && a[1] == 0x1F)
return true;
401 void Assembler::Nop(
int bytes) {
402 EnsureSpace ensure_space(
this);
471 void Assembler::CodeTargetAlign() {
476 void Assembler::cpuid() {
477 EnsureSpace ensure_space(
this);
483 void Assembler::pushad() {
484 EnsureSpace ensure_space(
this);
489 void Assembler::popad() {
490 EnsureSpace ensure_space(
this);
495 void Assembler::pushfd() {
496 EnsureSpace ensure_space(
this);
501 void Assembler::popfd() {
502 EnsureSpace ensure_space(
this);
507 void Assembler::push(
const Immediate& x) {
508 EnsureSpace ensure_space(
this);
519 void Assembler::push_imm32(int32_t imm32) {
520 EnsureSpace ensure_space(
this);
526 void Assembler::push(Register src) {
527 EnsureSpace ensure_space(
this);
528 EMIT(0x50 | src.code());
531 void Assembler::push(Operand src) {
532 EnsureSpace ensure_space(
this);
534 emit_operand(esi, src);
538 void Assembler::pop(Register dst) {
539 DCHECK_NOT_NULL(reloc_info_writer.last_pc());
540 EnsureSpace ensure_space(
this);
541 EMIT(0x58 | dst.code());
544 void Assembler::pop(Operand dst) {
545 EnsureSpace ensure_space(
this);
547 emit_operand(eax, dst);
551 void Assembler::enter(
const Immediate& size) {
552 EnsureSpace ensure_space(
this);
559 void Assembler::leave() {
560 EnsureSpace ensure_space(
this);
564 void Assembler::mov_b(Register dst, Operand src) {
565 CHECK(dst.is_byte_register());
566 EnsureSpace ensure_space(
this);
568 emit_operand(dst, src);
571 void Assembler::mov_b(Operand dst,
const Immediate& src) {
572 EnsureSpace ensure_space(
this);
574 emit_operand(eax, dst);
575 EMIT(static_cast<int8_t>(src.immediate()));
578 void Assembler::mov_b(Operand dst, Register src) {
579 CHECK(src.is_byte_register());
580 EnsureSpace ensure_space(
this);
582 emit_operand(src, dst);
585 void Assembler::mov_w(Register dst, Operand src) {
586 EnsureSpace ensure_space(
this);
589 emit_operand(dst, src);
592 void Assembler::mov_w(Operand dst, Register src) {
593 EnsureSpace ensure_space(
this);
596 emit_operand(src, dst);
599 void Assembler::mov_w(Operand dst,
const Immediate& src) {
600 EnsureSpace ensure_space(
this);
603 emit_operand(eax, dst);
604 EMIT(static_cast<int8_t>(src.immediate() & 0xFF));
605 EMIT(static_cast<int8_t>(src.immediate() >> 8));
609 void Assembler::mov(Register dst, int32_t imm32) {
610 EnsureSpace ensure_space(
this);
611 EMIT(0xB8 | dst.code());
616 void Assembler::mov(Register dst,
const Immediate& x) {
617 EnsureSpace ensure_space(
this);
618 EMIT(0xB8 | dst.code());
622 void Assembler::mov(Register dst, Handle<HeapObject> handle) {
623 EnsureSpace ensure_space(
this);
624 EMIT(0xB8 | dst.code());
628 void Assembler::mov(Register dst, Operand src) {
629 EnsureSpace ensure_space(
this);
631 emit_operand(dst, src);
635 void Assembler::mov(Register dst, Register src) {
636 EnsureSpace ensure_space(
this);
638 EMIT(0xC0 | src.code() << 3 | dst.code());
641 void Assembler::mov(Operand dst,
const Immediate& x) {
642 EnsureSpace ensure_space(
this);
644 emit_operand(eax, dst);
648 void Assembler::mov(Operand dst, Address src, RelocInfo::Mode rmode) {
649 EnsureSpace ensure_space(
this);
651 emit_operand(eax, dst);
655 void Assembler::mov(Operand dst, Handle<HeapObject> handle) {
656 EnsureSpace ensure_space(
this);
658 emit_operand(eax, dst);
662 void Assembler::mov(Operand dst, Register src) {
663 EnsureSpace ensure_space(
this);
665 emit_operand(src, dst);
668 void Assembler::movsx_b(Register dst, Operand src) {
669 DCHECK_IMPLIES(src.is_reg_only(), src.reg().is_byte_register());
670 EnsureSpace ensure_space(
this);
673 emit_operand(dst, src);
676 void Assembler::movsx_w(Register dst, Operand src) {
677 EnsureSpace ensure_space(
this);
680 emit_operand(dst, src);
683 void Assembler::movzx_b(Register dst, Operand src) {
684 DCHECK_IMPLIES(src.is_reg_only(), src.reg().is_byte_register());
685 EnsureSpace ensure_space(
this);
688 emit_operand(dst, src);
691 void Assembler::movzx_w(Register dst, Operand src) {
692 EnsureSpace ensure_space(
this);
695 emit_operand(dst, src);
698 void Assembler::movq(XMMRegister dst, Operand src) {
699 EnsureSpace ensure_space(
this);
703 emit_operand(dst, src);
706 void Assembler::cmov(Condition cc, Register dst, Operand src) {
707 EnsureSpace ensure_space(
this);
711 emit_operand(dst, src);
715 void Assembler::cld() {
716 EnsureSpace ensure_space(
this);
721 void Assembler::rep_movs() {
722 EnsureSpace ensure_space(
this);
728 void Assembler::rep_stos() {
729 EnsureSpace ensure_space(
this);
735 void Assembler::stos() {
736 EnsureSpace ensure_space(
this);
741 void Assembler::xchg(Register dst, Register src) {
742 EnsureSpace ensure_space(
this);
743 if (src == eax || dst == eax) {
744 EMIT(0x90 | (src == eax ? dst.code() : src.code()));
747 EMIT(0xC0 | src.code() << 3 | dst.code());
751 void Assembler::xchg(Register dst, Operand src) {
752 EnsureSpace ensure_space(
this);
754 emit_operand(dst, src);
757 void Assembler::xchg_b(Register reg, Operand op) {
758 DCHECK(reg.is_byte_register());
759 EnsureSpace ensure_space(
this);
761 emit_operand(reg, op);
764 void Assembler::xchg_w(Register reg, Operand op) {
765 EnsureSpace ensure_space(
this);
768 emit_operand(reg, op);
771 void Assembler::lock() {
772 EnsureSpace ensure_space(
this);
776 void Assembler::cmpxchg(Operand dst, Register src) {
777 EnsureSpace ensure_space(
this);
780 emit_operand(src, dst);
783 void Assembler::cmpxchg_b(Operand dst, Register src) {
784 DCHECK(src.is_byte_register());
785 EnsureSpace ensure_space(
this);
788 emit_operand(src, dst);
791 void Assembler::cmpxchg_w(Operand dst, Register src) {
792 EnsureSpace ensure_space(
this);
796 emit_operand(src, dst);
799 void Assembler::cmpxchg8b(Operand dst) {
800 EnsureSpace enure_space(
this);
803 emit_operand(ecx, dst);
806 void Assembler::lfence() {
807 EnsureSpace ensure_space(
this);
813 void Assembler::pause() {
814 EnsureSpace ensure_space(
this);
819 void Assembler::adc(Register dst, int32_t imm32) {
820 EnsureSpace ensure_space(
this);
821 emit_arith(2, Operand(dst), Immediate(imm32));
824 void Assembler::adc(Register dst, Operand src) {
825 EnsureSpace ensure_space(
this);
827 emit_operand(dst, src);
830 void Assembler::add(Register dst, Operand src) {
831 EnsureSpace ensure_space(
this);
833 emit_operand(dst, src);
836 void Assembler::add(Operand dst, Register src) {
837 EnsureSpace ensure_space(
this);
839 emit_operand(src, dst);
842 void Assembler::add(Operand dst,
const Immediate& x) {
843 DCHECK_NOT_NULL(reloc_info_writer.last_pc());
844 EnsureSpace ensure_space(
this);
845 emit_arith(0, dst, x);
849 void Assembler::and_(Register dst, int32_t imm32) {
850 and_(dst, Immediate(imm32));
854 void Assembler::and_(Register dst,
const Immediate& x) {
855 EnsureSpace ensure_space(
this);
856 emit_arith(4, Operand(dst), x);
859 void Assembler::and_(Register dst, Operand src) {
860 EnsureSpace ensure_space(
this);
862 emit_operand(dst, src);
865 void Assembler::and_(Operand dst,
const Immediate& x) {
866 EnsureSpace ensure_space(
this);
867 emit_arith(4, dst, x);
870 void Assembler::and_(Operand dst, Register src) {
871 EnsureSpace ensure_space(
this);
873 emit_operand(src, dst);
876 void Assembler::cmpb(Operand op, Immediate imm8) {
877 DCHECK(imm8.is_int8() || imm8.is_uint8());
878 EnsureSpace ensure_space(
this);
879 if (op.is_reg(eax)) {
883 emit_operand(edi, op);
888 void Assembler::cmpb(Operand op, Register reg) {
889 CHECK(reg.is_byte_register());
890 EnsureSpace ensure_space(
this);
892 emit_operand(reg, op);
895 void Assembler::cmpb(Register reg, Operand op) {
896 CHECK(reg.is_byte_register());
897 EnsureSpace ensure_space(
this);
899 emit_operand(reg, op);
902 void Assembler::cmpw(Operand op, Immediate imm16) {
903 DCHECK(imm16.is_int16() || imm16.is_uint16());
904 EnsureSpace ensure_space(
this);
907 emit_operand(edi, op);
911 void Assembler::cmpw(Register reg, Operand op) {
912 EnsureSpace ensure_space(
this);
915 emit_operand(reg, op);
918 void Assembler::cmpw(Operand op, Register reg) {
919 EnsureSpace ensure_space(
this);
922 emit_operand(reg, op);
925 void Assembler::cmp(Register reg, int32_t imm32) {
926 EnsureSpace ensure_space(
this);
927 emit_arith(7, Operand(reg), Immediate(imm32));
930 void Assembler::cmp(Register reg, Handle<HeapObject> handle) {
931 EnsureSpace ensure_space(
this);
932 emit_arith(7, Operand(reg), Immediate(handle));
935 void Assembler::cmp(Register reg, Operand op) {
936 EnsureSpace ensure_space(
this);
938 emit_operand(reg, op);
941 void Assembler::cmp(Operand op, Register reg) {
942 EnsureSpace ensure_space(
this);
944 emit_operand(reg, op);
947 void Assembler::cmp(Operand op,
const Immediate& imm) {
948 EnsureSpace ensure_space(
this);
949 emit_arith(7, op, imm);
952 void Assembler::cmp(Operand op, Handle<HeapObject> handle) {
953 EnsureSpace ensure_space(
this);
954 emit_arith(7, op, Immediate(handle));
957 void Assembler::cmpb_al(Operand op) {
958 EnsureSpace ensure_space(
this);
960 emit_operand(eax, op);
963 void Assembler::cmpw_ax(Operand op) {
964 EnsureSpace ensure_space(
this);
967 emit_operand(eax, op);
971 void Assembler::dec_b(Register dst) {
972 CHECK(dst.is_byte_register());
973 EnsureSpace ensure_space(
this);
975 EMIT(0xC8 | dst.code());
978 void Assembler::dec_b(Operand dst) {
979 EnsureSpace ensure_space(
this);
981 emit_operand(ecx, dst);
985 void Assembler::dec(Register dst) {
986 EnsureSpace ensure_space(
this);
987 EMIT(0x48 | dst.code());
990 void Assembler::dec(Operand dst) {
991 EnsureSpace ensure_space(
this);
993 emit_operand(ecx, dst);
997 void Assembler::cdq() {
998 EnsureSpace ensure_space(
this);
1002 void Assembler::idiv(Operand src) {
1003 EnsureSpace ensure_space(
this);
1005 emit_operand(edi, src);
1008 void Assembler::div(Operand src) {
1009 EnsureSpace ensure_space(
this);
1011 emit_operand(esi, src);
1015 void Assembler::imul(Register reg) {
1016 EnsureSpace ensure_space(
this);
1018 EMIT(0xE8 | reg.code());
1021 void Assembler::imul(Register dst, Operand src) {
1022 EnsureSpace ensure_space(
this);
1025 emit_operand(dst, src);
1029 void Assembler::imul(Register dst, Register src, int32_t imm32) {
1030 imul(dst, Operand(src), imm32);
1033 void Assembler::imul(Register dst, Operand src, int32_t imm32) {
1034 EnsureSpace ensure_space(
this);
1035 if (is_int8(imm32)) {
1037 emit_operand(dst, src);
1041 emit_operand(dst, src);
1047 void Assembler::inc(Register dst) {
1048 EnsureSpace ensure_space(
this);
1049 EMIT(0x40 | dst.code());
1052 void Assembler::inc(Operand dst) {
1053 EnsureSpace ensure_space(
this);
1055 emit_operand(eax, dst);
1058 void Assembler::lea(Register dst, Operand src) {
1059 EnsureSpace ensure_space(
this);
1061 emit_operand(dst, src);
1065 void Assembler::mul(Register src) {
1066 EnsureSpace ensure_space(
this);
1068 EMIT(0xE0 | src.code());
1072 void Assembler::neg(Register dst) {
1073 EnsureSpace ensure_space(
this);
1075 EMIT(0xD8 | dst.code());
1078 void Assembler::neg(Operand dst) {
1079 EnsureSpace ensure_space(
this);
1081 emit_operand(ebx, dst);
1085 void Assembler::not_(Register dst) {
1086 EnsureSpace ensure_space(
this);
1088 EMIT(0xD0 | dst.code());
1091 void Assembler::not_(Operand dst) {
1092 EnsureSpace ensure_space(
this);
1094 emit_operand(edx, dst);
1098 void Assembler::or_(Register dst, int32_t imm32) {
1099 EnsureSpace ensure_space(
this);
1100 emit_arith(1, Operand(dst), Immediate(imm32));
1103 void Assembler::or_(Register dst, Operand src) {
1104 EnsureSpace ensure_space(
this);
1106 emit_operand(dst, src);
1109 void Assembler::or_(Operand dst,
const Immediate& x) {
1110 EnsureSpace ensure_space(
this);
1111 emit_arith(1, dst, x);
1114 void Assembler::or_(Operand dst, Register src) {
1115 EnsureSpace ensure_space(
this);
1117 emit_operand(src, dst);
1121 void Assembler::rcl(Register dst, uint8_t imm8) {
1122 EnsureSpace ensure_space(
this);
1123 DCHECK(is_uint5(imm8));
1126 EMIT(0xD0 | dst.code());
1129 EMIT(0xD0 | dst.code());
1135 void Assembler::rcr(Register dst, uint8_t imm8) {
1136 EnsureSpace ensure_space(
this);
1137 DCHECK(is_uint5(imm8));
1140 EMIT(0xD8 | dst.code());
1143 EMIT(0xD8 | dst.code());
1148 void Assembler::ror(Operand dst, uint8_t imm8) {
1149 EnsureSpace ensure_space(
this);
1150 DCHECK(is_uint5(imm8));
1153 emit_operand(ecx, dst);
1156 emit_operand(ecx, dst);
1161 void Assembler::ror_cl(Operand dst) {
1162 EnsureSpace ensure_space(
this);
1164 emit_operand(ecx, dst);
1167 void Assembler::sar(Operand dst, uint8_t imm8) {
1168 EnsureSpace ensure_space(
this);
1169 DCHECK(is_uint5(imm8));
1172 emit_operand(edi, dst);
1175 emit_operand(edi, dst);
1180 void Assembler::sar_cl(Operand dst) {
1181 EnsureSpace ensure_space(
this);
1183 emit_operand(edi, dst);
1186 void Assembler::sbb(Register dst, Operand src) {
1187 EnsureSpace ensure_space(
this);
1189 emit_operand(dst, src);
1192 void Assembler::shld(Register dst, Register src, uint8_t shift) {
1193 DCHECK(is_uint5(shift));
1194 EnsureSpace ensure_space(
this);
1197 emit_operand(src, Operand(dst));
1201 void Assembler::shld_cl(Register dst, Register src) {
1202 EnsureSpace ensure_space(
this);
1205 emit_operand(src, Operand(dst));
1208 void Assembler::shl(Operand dst, uint8_t imm8) {
1209 EnsureSpace ensure_space(
this);
1210 DCHECK(is_uint5(imm8));
1213 emit_operand(esp, dst);
1216 emit_operand(esp, dst);
1221 void Assembler::shl_cl(Operand dst) {
1222 EnsureSpace ensure_space(
this);
1224 emit_operand(esp, dst);
1227 void Assembler::shr(Operand dst, uint8_t imm8) {
1228 EnsureSpace ensure_space(
this);
1229 DCHECK(is_uint5(imm8));
1232 emit_operand(ebp, dst);
1235 emit_operand(ebp, dst);
1240 void Assembler::shr_cl(Operand dst) {
1241 EnsureSpace ensure_space(
this);
1243 emit_operand(ebp, dst);
1246 void Assembler::shrd(Register dst, Register src, uint8_t shift) {
1247 DCHECK(is_uint5(shift));
1248 EnsureSpace ensure_space(
this);
1251 emit_operand(dst, Operand(src));
1255 void Assembler::shrd_cl(Operand dst, Register src) {
1256 EnsureSpace ensure_space(
this);
1259 emit_operand(src, dst);
1262 void Assembler::sub(Operand dst,
const Immediate& x) {
1263 EnsureSpace ensure_space(
this);
1264 emit_arith(5, dst, x);
1267 void Assembler::sub(Register dst, Operand src) {
1268 EnsureSpace ensure_space(
this);
1270 emit_operand(dst, src);
1273 void Assembler::sub(Operand dst, Register src) {
1274 EnsureSpace ensure_space(
this);
1276 emit_operand(src, dst);
1279 void Assembler::sub_sp_32(
uint32_t imm) {
1280 EnsureSpace ensure_space(
this);
1282 static constexpr Register ireg = Register::from_code<5>();
1283 emit_operand(ireg, Operand(esp));
1287 void Assembler::test(Register reg,
const Immediate& imm) {
1288 if (imm.is_uint8()) {
1293 EnsureSpace ensure_space(
this);
1300 EMIT(0xC0 | reg.code());
1305 void Assembler::test(Register reg, Operand op) {
1306 EnsureSpace ensure_space(
this);
1308 emit_operand(reg, op);
1311 void Assembler::test_b(Register reg, Operand op) {
1312 CHECK(reg.is_byte_register());
1313 EnsureSpace ensure_space(
this);
1315 emit_operand(reg, op);
1318 void Assembler::test(Operand op,
const Immediate& imm) {
1319 if (op.is_reg_only()) {
1320 test(op.reg(), imm);
1323 if (imm.is_uint8()) {
1324 return test_b(op, imm);
1326 EnsureSpace ensure_space(
this);
1328 emit_operand(eax, op);
1332 void Assembler::test_b(Register reg, Immediate imm8) {
1333 DCHECK(imm8.is_uint8());
1334 EnsureSpace ensure_space(
this);
1340 }
else if (reg.is_byte_register()) {
1341 emit_arith_b(0xF6, 0xC0, reg, static_cast<uint8_t>(imm8.immediate()));
1345 EMIT(0xC0 | reg.code());
1350 void Assembler::test_b(Operand op, Immediate imm8) {
1351 if (op.is_reg_only()) {
1352 test_b(op.reg(), imm8);
1355 EnsureSpace ensure_space(
this);
1357 emit_operand(eax, op);
1361 void Assembler::test_w(Register reg, Immediate imm16) {
1362 DCHECK(imm16.is_int16() || imm16.is_uint16());
1363 EnsureSpace ensure_space(
this);
1370 EMIT(0xC0 | reg.code());
1375 void Assembler::test_w(Register reg, Operand op) {
1376 EnsureSpace ensure_space(
this);
1379 emit_operand(reg, op);
1382 void Assembler::test_w(Operand op, Immediate imm16) {
1383 DCHECK(imm16.is_int16() || imm16.is_uint16());
1384 if (op.is_reg_only()) {
1385 test_w(op.reg(), imm16);
1388 EnsureSpace ensure_space(
this);
1391 emit_operand(eax, op);
1395 void Assembler::xor_(Register dst, int32_t imm32) {
1396 EnsureSpace ensure_space(
this);
1397 emit_arith(6, Operand(dst), Immediate(imm32));
1400 void Assembler::xor_(Register dst, Operand src) {
1401 EnsureSpace ensure_space(
this);
1403 emit_operand(dst, src);
1406 void Assembler::xor_(Operand dst, Register src) {
1407 EnsureSpace ensure_space(
this);
1409 emit_operand(src, dst);
1412 void Assembler::xor_(Operand dst,
const Immediate& x) {
1413 EnsureSpace ensure_space(
this);
1414 emit_arith(6, dst, x);
1417 void Assembler::bswap(Register dst) {
1418 EnsureSpace ensure_space(
this);
1420 EMIT(0xC8 + dst.code());
1423 void Assembler::bt(Operand dst, Register src) {
1424 EnsureSpace ensure_space(
this);
1427 emit_operand(src, dst);
1430 void Assembler::bts(Operand dst, Register src) {
1431 EnsureSpace ensure_space(
this);
1434 emit_operand(src, dst);
1437 void Assembler::bsr(Register dst, Operand src) {
1438 EnsureSpace ensure_space(
this);
1441 emit_operand(dst, src);
1444 void Assembler::bsf(Register dst, Operand src) {
1445 EnsureSpace ensure_space(
this);
1448 emit_operand(dst, src);
1452 void Assembler::hlt() {
1453 EnsureSpace ensure_space(
this);
1458 void Assembler::int3() {
1459 EnsureSpace ensure_space(
this);
1464 void Assembler::nop() {
1465 EnsureSpace ensure_space(
this);
1470 void Assembler::ret(
int imm16) {
1471 EnsureSpace ensure_space(
this);
1472 DCHECK(is_uint16(imm16));
1478 EMIT((imm16 >> 8) & 0xFF);
1483 void Assembler::ud2() {
1484 EnsureSpace ensure_space(
this);
1500 void Assembler::print(
const Label* L) {
1501 if (L->is_unused()) {
1502 PrintF(
"unused label\n");
1503 }
else if (L->is_bound()) {
1504 PrintF(
"bound label to %d\n", L->pos());
1505 }
else if (L->is_linked()) {
1507 l.link_to(L->pos());
1508 PrintF(
"unbound label");
1509 while (l.is_linked()) {
1510 Displacement disp = disp_at(&l);
1511 PrintF(
"@ %d ", l.pos());
1517 PrintF(
"label in inconsistent state (pos = %d)\n", L->pos_);
1522 void Assembler::bind_to(Label* L,
int pos) {
1523 EnsureSpace ensure_space(
this);
1524 DCHECK(0 <= pos && pos <= pc_offset());
1525 while (L->is_linked()) {
1526 Displacement disp = disp_at(L);
1527 int fixup_pos = L->pos();
1528 if (disp.type() == Displacement::CODE_ABSOLUTE) {
1529 long_at_put(fixup_pos, reinterpret_cast<int>(buffer_ + pos));
1530 internal_reference_positions_.push_back(fixup_pos);
1531 }
else if (disp.type() == Displacement::CODE_RELATIVE) {
1533 long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
1535 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1536 DCHECK_EQ(byte_at(fixup_pos - 1), 0xE9);
1539 int imm32 = pos - (fixup_pos +
sizeof(int32_t));
1540 long_at_put(fixup_pos, imm32);
1544 while (L->is_near_linked()) {
1545 int fixup_pos = L->near_link_pos();
1546 int offset_to_next =
1547 static_cast<int>(*
reinterpret_cast<int8_t*
>(addr_at(fixup_pos)));
1548 DCHECK_LE(offset_to_next, 0);
1550 int disp = pos - fixup_pos -
sizeof(int8_t);
1551 CHECK(0 <= disp && disp <= 127);
1552 set_byte_at(fixup_pos, disp);
1553 if (offset_to_next < 0) {
1554 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1561 auto jump_opt = jump_optimization_info();
1562 if (jump_opt && jump_opt->is_optimizing()) {
1563 auto it = label_farjmp_maps_.find(L);
1564 if (it != label_farjmp_maps_.end()) {
1565 auto& pos_vector = it->second;
1566 for (
auto fixup_pos : pos_vector) {
1567 int disp = pos - (fixup_pos +
sizeof(int8_t));
1568 CHECK(is_int8(disp));
1569 set_byte_at(fixup_pos, disp);
1571 label_farjmp_maps_.erase(it);
1578 void Assembler::bind(Label* L) {
1579 EnsureSpace ensure_space(
this);
1580 DCHECK(!L->is_bound());
1581 bind_to(L, pc_offset());
1584 void Assembler::record_farjmp_position(Label* L,
int pos) {
1585 auto& pos_vector = label_farjmp_maps_[L];
1586 pos_vector.push_back(pos);
1589 bool Assembler::is_optimizable_farjmp(
int idx) {
1590 if (predictable_code_size())
return false;
1592 auto jump_opt = jump_optimization_info();
1593 CHECK(jump_opt->is_optimizing());
1595 auto& bitmap = jump_opt->farjmp_bitmap();
1596 CHECK(idx < static_cast<int>(bitmap.size() * 32));
1597 return !!(bitmap[idx / 32] & (1 << (idx & 31)));
1600 void Assembler::call(Label* L) {
1601 EnsureSpace ensure_space(
this);
1602 if (L->is_bound()) {
1603 const int long_size = 5;
1604 int offs = L->pos() - pc_offset();
1608 emit(offs - long_size);
1612 emit_disp(L, Displacement::OTHER);
1616 void Assembler::call(Address entry, RelocInfo::Mode rmode) {
1617 EnsureSpace ensure_space(
this);
1618 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1620 if (RelocInfo::IsRuntimeEntry(rmode)) {
1623 emit(entry - (reinterpret_cast<Address>(pc_) +
sizeof(int32_t)), rmode);
1627 void Assembler::wasm_call(Address entry, RelocInfo::Mode rmode) {
1628 EnsureSpace ensure_space(
this);
1633 void Assembler::call(Operand adr) {
1634 EnsureSpace ensure_space(
this);
1636 emit_operand(edx, adr);
1639 void Assembler::call(Handle<Code> code, RelocInfo::Mode rmode) {
1640 EnsureSpace ensure_space(
this);
1641 DCHECK(RelocInfo::IsCodeTarget(rmode));
1646 void Assembler::call(CodeStub* stub) {
1647 EnsureSpace ensure_space(
this);
1649 emit(Immediate::EmbeddedCode(stub));
1652 void Assembler::jmp_rel(
int offset) {
1653 EnsureSpace ensure_space(
this);
1654 const int short_size = 2;
1655 const int long_size = 5;
1656 if (is_int8(offset - short_size)) {
1659 EMIT((offset - short_size) & 0xFF);
1663 emit(offset - long_size);
1667 void Assembler::jmp(Label* L, Label::Distance distance) {
1668 if (L->is_bound()) {
1669 int offset = L->pos() - pc_offset();
1670 DCHECK_LE(offset, 0);
1675 EnsureSpace ensure_space(
this);
1676 if (distance == Label::kNear) {
1680 auto jump_opt = jump_optimization_info();
1681 if (V8_UNLIKELY(jump_opt)) {
1682 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1684 record_farjmp_position(L, pc_offset());
1688 if (jump_opt->is_collecting()) {
1689 farjmp_positions_.push_back(pc_offset() + 1);
1694 emit_disp(L, Displacement::UNCONDITIONAL_JUMP);
1698 void Assembler::jmp(Address entry, RelocInfo::Mode rmode) {
1699 EnsureSpace ensure_space(
this);
1700 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1702 if (RelocInfo::IsRuntimeEntry(rmode)) {
1705 emit(entry - (reinterpret_cast<Address>(pc_) +
sizeof(int32_t)), rmode);
1709 void Assembler::jmp(Operand adr) {
1710 EnsureSpace ensure_space(
this);
1712 emit_operand(esp, adr);
1716 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1717 EnsureSpace ensure_space(
this);
1718 DCHECK(RelocInfo::IsCodeTarget(rmode));
1724 void Assembler::j(Condition cc, Label* L, Label::Distance distance) {
1725 EnsureSpace ensure_space(
this);
1726 DCHECK(0 <= cc && static_cast<int>(cc) < 16);
1727 if (L->is_bound()) {
1728 const int short_size = 2;
1729 const int long_size = 6;
1730 int offs = L->pos() - pc_offset();
1732 if (is_int8(offs - short_size)) {
1735 EMIT((offs - short_size) & 0xFF);
1740 emit(offs - long_size);
1742 }
else if (distance == Label::kNear) {
1746 auto jump_opt = jump_optimization_info();
1747 if (V8_UNLIKELY(jump_opt)) {
1748 if (jump_opt->is_optimizing() && is_optimizable_farjmp(farjmp_num_++)) {
1751 record_farjmp_position(L, pc_offset());
1755 if (jump_opt->is_collecting()) {
1756 farjmp_positions_.push_back(pc_offset() + 2);
1764 emit_disp(L, Displacement::OTHER);
1769 void Assembler::j(Condition cc, byte* entry, RelocInfo::Mode rmode) {
1770 EnsureSpace ensure_space(
this);
1771 DCHECK((0 <= cc) && (static_cast<int>(cc) < 16));
1775 if (RelocInfo::IsRuntimeEntry(rmode)) {
1776 emit(reinterpret_cast<uint32_t>(entry), rmode);
1778 emit(entry - (pc_ +
sizeof(int32_t)), rmode);
1783 void Assembler::j(Condition cc, Handle<Code> code, RelocInfo::Mode rmode) {
1784 EnsureSpace ensure_space(
this);
1794 void Assembler::fld(
int i) {
1795 EnsureSpace ensure_space(
this);
1796 emit_farith(0xD9, 0xC0,
i);
1800 void Assembler::fstp(
int i) {
1801 EnsureSpace ensure_space(
this);
1802 emit_farith(0xDD, 0xD8,
i);
1806 void Assembler::fld1() {
1807 EnsureSpace ensure_space(
this);
1813 void Assembler::fldpi() {
1814 EnsureSpace ensure_space(
this);
1820 void Assembler::fldz() {
1821 EnsureSpace ensure_space(
this);
1827 void Assembler::fldln2() {
1828 EnsureSpace ensure_space(
this);
1833 void Assembler::fld_s(Operand adr) {
1834 EnsureSpace ensure_space(
this);
1836 emit_operand(eax, adr);
1839 void Assembler::fld_d(Operand adr) {
1840 EnsureSpace ensure_space(
this);
1842 emit_operand(eax, adr);
1845 void Assembler::fstp_s(Operand adr) {
1846 EnsureSpace ensure_space(
this);
1848 emit_operand(ebx, adr);
1851 void Assembler::fst_s(Operand adr) {
1852 EnsureSpace ensure_space(
this);
1854 emit_operand(edx, adr);
1857 void Assembler::fstp_d(Operand adr) {
1858 EnsureSpace ensure_space(
this);
1860 emit_operand(ebx, adr);
1863 void Assembler::fst_d(Operand adr) {
1864 EnsureSpace ensure_space(
this);
1866 emit_operand(edx, adr);
1869 void Assembler::fild_s(Operand adr) {
1870 EnsureSpace ensure_space(
this);
1872 emit_operand(eax, adr);
1875 void Assembler::fild_d(Operand adr) {
1876 EnsureSpace ensure_space(
this);
1878 emit_operand(ebp, adr);
1881 void Assembler::fistp_s(Operand adr) {
1882 EnsureSpace ensure_space(
this);
1884 emit_operand(ebx, adr);
1887 void Assembler::fisttp_s(Operand adr) {
1888 DCHECK(IsEnabled(SSE3));
1889 EnsureSpace ensure_space(
this);
1891 emit_operand(ecx, adr);
1894 void Assembler::fisttp_d(Operand adr) {
1895 DCHECK(IsEnabled(SSE3));
1896 EnsureSpace ensure_space(
this);
1898 emit_operand(ecx, adr);
1901 void Assembler::fist_s(Operand adr) {
1902 EnsureSpace ensure_space(
this);
1904 emit_operand(edx, adr);
1907 void Assembler::fistp_d(Operand adr) {
1908 EnsureSpace ensure_space(
this);
1910 emit_operand(edi, adr);
1914 void Assembler::fabs() {
1915 EnsureSpace ensure_space(
this);
1921 void Assembler::fchs() {
1922 EnsureSpace ensure_space(
this);
1928 void Assembler::fcos() {
1929 EnsureSpace ensure_space(
this);
1935 void Assembler::fsin() {
1936 EnsureSpace ensure_space(
this);
1942 void Assembler::fptan() {
1943 EnsureSpace ensure_space(
this);
1949 void Assembler::fyl2x() {
1950 EnsureSpace ensure_space(
this);
1956 void Assembler::f2xm1() {
1957 EnsureSpace ensure_space(
this);
1963 void Assembler::fscale() {
1964 EnsureSpace ensure_space(
this);
1970 void Assembler::fninit() {
1971 EnsureSpace ensure_space(
this);
1977 void Assembler::fadd(
int i) {
1978 EnsureSpace ensure_space(
this);
1979 emit_farith(0xDC, 0xC0,
i);
1983 void Assembler::fadd_i(
int i) {
1984 EnsureSpace ensure_space(
this);
1985 emit_farith(0xD8, 0xC0,
i);
1989 void Assembler::fsub(
int i) {
1990 EnsureSpace ensure_space(
this);
1991 emit_farith(0xDC, 0xE8,
i);
1995 void Assembler::fsub_i(
int i) {
1996 EnsureSpace ensure_space(
this);
1997 emit_farith(0xD8, 0xE0,
i);
2000 void Assembler::fisub_s(Operand adr) {
2001 EnsureSpace ensure_space(
this);
2003 emit_operand(esp, adr);
2007 void Assembler::fmul_i(
int i) {
2008 EnsureSpace ensure_space(
this);
2009 emit_farith(0xD8, 0xC8,
i);
2013 void Assembler::fmul(
int i) {
2014 EnsureSpace ensure_space(
this);
2015 emit_farith(0xDC, 0xC8,
i);
2019 void Assembler::fdiv(
int i) {
2020 EnsureSpace ensure_space(
this);
2021 emit_farith(0xDC, 0xF8,
i);
2025 void Assembler::fdiv_i(
int i) {
2026 EnsureSpace ensure_space(
this);
2027 emit_farith(0xD8, 0xF0,
i);
2031 void Assembler::faddp(
int i) {
2032 EnsureSpace ensure_space(
this);
2033 emit_farith(0xDE, 0xC0,
i);
2037 void Assembler::fsubp(
int i) {
2038 EnsureSpace ensure_space(
this);
2039 emit_farith(0xDE, 0xE8,
i);
2043 void Assembler::fsubrp(
int i) {
2044 EnsureSpace ensure_space(
this);
2045 emit_farith(0xDE, 0xE0,
i);
2049 void Assembler::fmulp(
int i) {
2050 EnsureSpace ensure_space(
this);
2051 emit_farith(0xDE, 0xC8,
i);
2055 void Assembler::fdivp(
int i) {
2056 EnsureSpace ensure_space(
this);
2057 emit_farith(0xDE, 0xF8,
i);
2061 void Assembler::fprem() {
2062 EnsureSpace ensure_space(
this);
2068 void Assembler::fprem1() {
2069 EnsureSpace ensure_space(
this);
2075 void Assembler::fxch(
int i) {
2076 EnsureSpace ensure_space(
this);
2077 emit_farith(0xD9, 0xC8,
i);
2081 void Assembler::fincstp() {
2082 EnsureSpace ensure_space(
this);
2088 void Assembler::ffree(
int i) {
2089 EnsureSpace ensure_space(
this);
2090 emit_farith(0xDD, 0xC0,
i);
2094 void Assembler::ftst() {
2095 EnsureSpace ensure_space(
this);
2101 void Assembler::fucomp(
int i) {
2102 EnsureSpace ensure_space(
this);
2103 emit_farith(0xDD, 0xE8,
i);
2107 void Assembler::fucompp() {
2108 EnsureSpace ensure_space(
this);
2114 void Assembler::fucomi(
int i) {
2115 EnsureSpace ensure_space(
this);
2121 void Assembler::fucomip() {
2122 EnsureSpace ensure_space(
this);
2128 void Assembler::fcompp() {
2129 EnsureSpace ensure_space(
this);
2135 void Assembler::fnstsw_ax() {
2136 EnsureSpace ensure_space(
this);
2142 void Assembler::fwait() {
2143 EnsureSpace ensure_space(
this);
2148 void Assembler::frndint() {
2149 EnsureSpace ensure_space(
this);
2155 void Assembler::fnclex() {
2156 EnsureSpace ensure_space(
this);
2162 void Assembler::sahf() {
2163 EnsureSpace ensure_space(
this);
2168 void Assembler::setcc(Condition cc, Register reg) {
2169 DCHECK(reg.is_byte_register());
2170 EnsureSpace ensure_space(
this);
2173 EMIT(0xC0 | reg.code());
2176 void Assembler::cvttss2si(Register dst, Operand src) {
2177 EnsureSpace ensure_space(
this);
2183 emit_operand(dst, src);
2186 void Assembler::cvttsd2si(Register dst, Operand src) {
2187 EnsureSpace ensure_space(
this);
2193 emit_operand(dst, src);
2197 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
2198 EnsureSpace ensure_space(
this);
2202 emit_sse_operand(dst, src);
2205 void Assembler::cvtsi2ss(XMMRegister dst, Operand src) {
2206 EnsureSpace ensure_space(
this);
2210 emit_sse_operand(dst, src);
2213 void Assembler::cvtsi2sd(XMMRegister dst, Operand src) {
2214 EnsureSpace ensure_space(
this);
2218 emit_sse_operand(dst, src);
2221 void Assembler::cvtss2sd(XMMRegister dst, Operand src) {
2222 EnsureSpace ensure_space(
this);
2226 emit_sse_operand(dst, src);
2229 void Assembler::cvtsd2ss(XMMRegister dst, Operand src) {
2230 EnsureSpace ensure_space(
this);
2234 emit_sse_operand(dst, src);
2237 void Assembler::cvtdq2ps(XMMRegister dst, Operand src) {
2238 EnsureSpace ensure_space(
this);
2241 emit_sse_operand(dst, src);
2244 void Assembler::cvttps2dq(XMMRegister dst, Operand src) {
2245 EnsureSpace ensure_space(
this);
2249 emit_sse_operand(dst, src);
2252 void Assembler::addsd(XMMRegister dst, Operand src) {
2253 EnsureSpace ensure_space(
this);
2257 emit_sse_operand(dst, src);
2260 void Assembler::mulsd(XMMRegister dst, Operand src) {
2261 EnsureSpace ensure_space(
this);
2265 emit_sse_operand(dst, src);
2268 void Assembler::subsd(XMMRegister dst, Operand src) {
2269 EnsureSpace ensure_space(
this);
2273 emit_sse_operand(dst, src);
2276 void Assembler::divsd(XMMRegister dst, Operand src) {
2277 EnsureSpace ensure_space(
this);
2281 emit_sse_operand(dst, src);
2284 void Assembler::xorpd(XMMRegister dst, Operand src) {
2285 EnsureSpace ensure_space(
this);
2289 emit_sse_operand(dst, src);
2292 void Assembler::andps(XMMRegister dst, Operand src) {
2293 EnsureSpace ensure_space(
this);
2296 emit_sse_operand(dst, src);
2299 void Assembler::orps(XMMRegister dst, Operand src) {
2300 EnsureSpace ensure_space(
this);
2303 emit_sse_operand(dst, src);
2306 void Assembler::xorps(XMMRegister dst, Operand src) {
2307 EnsureSpace ensure_space(
this);
2310 emit_sse_operand(dst, src);
2313 void Assembler::addps(XMMRegister dst, Operand src) {
2314 EnsureSpace ensure_space(
this);
2317 emit_sse_operand(dst, src);
2320 void Assembler::subps(XMMRegister dst, Operand src) {
2321 EnsureSpace ensure_space(
this);
2324 emit_sse_operand(dst, src);
2327 void Assembler::mulps(XMMRegister dst, Operand src) {
2328 EnsureSpace ensure_space(
this);
2331 emit_sse_operand(dst, src);
2334 void Assembler::divps(XMMRegister dst, Operand src) {
2335 EnsureSpace ensure_space(
this);
2338 emit_sse_operand(dst, src);
2341 void Assembler::rcpps(XMMRegister dst, Operand src) {
2342 EnsureSpace ensure_space(
this);
2345 emit_sse_operand(dst, src);
2348 void Assembler::rsqrtps(XMMRegister dst, Operand src) {
2349 EnsureSpace ensure_space(
this);
2352 emit_sse_operand(dst, src);
2355 void Assembler::minps(XMMRegister dst, Operand src) {
2356 EnsureSpace ensure_space(
this);
2359 emit_sse_operand(dst, src);
2362 void Assembler::maxps(XMMRegister dst, Operand src) {
2363 EnsureSpace ensure_space(
this);
2366 emit_sse_operand(dst, src);
2369 void Assembler::cmpps(XMMRegister dst, Operand src, uint8_t cmp) {
2370 EnsureSpace ensure_space(
this);
2373 emit_sse_operand(dst, src);
2377 void Assembler::sqrtsd(XMMRegister dst, Operand src) {
2378 EnsureSpace ensure_space(
this);
2382 emit_sse_operand(dst, src);
2385 void Assembler::haddps(XMMRegister dst, Operand src) {
2386 DCHECK(IsEnabled(SSE3));
2387 EnsureSpace ensure_space(
this);
2391 emit_sse_operand(dst, src);
2394 void Assembler::andpd(XMMRegister dst, Operand src) {
2395 EnsureSpace ensure_space(
this);
2399 emit_sse_operand(dst, src);
2402 void Assembler::orpd(XMMRegister dst, Operand src) {
2403 EnsureSpace ensure_space(
this);
2407 emit_sse_operand(dst, src);
2410 void Assembler::ucomisd(XMMRegister dst, Operand src) {
2411 EnsureSpace ensure_space(
this);
2415 emit_sse_operand(dst, src);
2419 void Assembler::roundss(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2420 DCHECK(IsEnabled(SSE4_1));
2421 EnsureSpace ensure_space(
this);
2426 emit_sse_operand(dst, src);
2428 EMIT(static_cast<byte>(mode) | 0x8);
2432 void Assembler::roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode) {
2433 DCHECK(IsEnabled(SSE4_1));
2434 EnsureSpace ensure_space(
this);
2439 emit_sse_operand(dst, src);
2441 EMIT(static_cast<byte>(mode) | 0x8);
2445 void Assembler::movmskpd(Register dst, XMMRegister src) {
2446 EnsureSpace ensure_space(
this);
2450 emit_sse_operand(dst, src);
2454 void Assembler::movmskps(Register dst, XMMRegister src) {
2455 EnsureSpace ensure_space(
this);
2458 emit_sse_operand(dst, src);
2461 void Assembler::maxsd(XMMRegister dst, Operand src) {
2462 EnsureSpace ensure_space(
this);
2466 emit_sse_operand(dst, src);
2469 void Assembler::minsd(XMMRegister dst, Operand src) {
2470 EnsureSpace ensure_space(
this);
2474 emit_sse_operand(dst, src);
2478 void Assembler::cmpltsd(XMMRegister dst, XMMRegister src) {
2479 EnsureSpace ensure_space(
this);
2483 emit_sse_operand(dst, src);
2488 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
2489 EnsureSpace ensure_space(
this);
2492 emit_sse_operand(dst, src);
2495 void Assembler::movups(XMMRegister dst, XMMRegister src) {
2496 EnsureSpace ensure_space(
this);
2499 emit_sse_operand(dst, src);
2502 void Assembler::movups(XMMRegister dst, Operand src) {
2503 EnsureSpace ensure_space(
this);
2506 emit_sse_operand(dst, src);
2509 void Assembler::movups(Operand dst, XMMRegister src) {
2510 EnsureSpace ensure_space(
this);
2513 emit_sse_operand(src, dst);
2516 void Assembler::shufps(XMMRegister dst, XMMRegister src, byte imm8) {
2517 DCHECK(is_uint8(imm8));
2518 EnsureSpace ensure_space(
this);
2521 emit_sse_operand(dst, src);
2525 void Assembler::movdqa(Operand dst, XMMRegister src) {
2526 EnsureSpace ensure_space(
this);
2530 emit_sse_operand(src, dst);
2533 void Assembler::movdqa(XMMRegister dst, Operand src) {
2534 EnsureSpace ensure_space(
this);
2538 emit_sse_operand(dst, src);
2541 void Assembler::movdqu(Operand dst, XMMRegister src) {
2542 EnsureSpace ensure_space(
this);
2546 emit_sse_operand(src, dst);
2549 void Assembler::movdqu(XMMRegister dst, Operand src) {
2550 EnsureSpace ensure_space(
this);
2554 emit_sse_operand(dst, src);
2557 void Assembler::prefetch(Operand src,
int level) {
2558 DCHECK(is_uint2(level));
2559 EnsureSpace ensure_space(
this);
2563 XMMRegister code = XMMRegister::from_code(level);
2564 emit_sse_operand(code, src);
2567 void Assembler::movsd(Operand dst, XMMRegister src) {
2568 EnsureSpace ensure_space(
this);
2572 emit_sse_operand(src, dst);
2575 void Assembler::movsd(XMMRegister dst, Operand src) {
2576 EnsureSpace ensure_space(
this);
2580 emit_sse_operand(dst, src);
2583 void Assembler::movss(Operand dst, XMMRegister src) {
2584 EnsureSpace ensure_space(
this);
2588 emit_sse_operand(src, dst);
2591 void Assembler::movss(XMMRegister dst, Operand src) {
2592 EnsureSpace ensure_space(
this);
2596 emit_sse_operand(dst, src);
2599 void Assembler::movd(XMMRegister dst, Operand src) {
2600 EnsureSpace ensure_space(
this);
2604 emit_sse_operand(dst, src);
2607 void Assembler::movd(Operand dst, XMMRegister src) {
2608 EnsureSpace ensure_space(
this);
2612 emit_sse_operand(src, dst);
2616 void Assembler::extractps(Register dst, XMMRegister src, byte imm8) {
2617 DCHECK(IsEnabled(SSE4_1));
2618 DCHECK(is_uint8(imm8));
2619 EnsureSpace ensure_space(
this);
2624 emit_sse_operand(src, dst);
2628 void Assembler::psllw(XMMRegister reg, uint8_t shift) {
2629 EnsureSpace ensure_space(
this);
2633 emit_sse_operand(esi, reg);
2637 void Assembler::pslld(XMMRegister reg, uint8_t shift) {
2638 EnsureSpace ensure_space(
this);
2642 emit_sse_operand(esi, reg);
2646 void Assembler::psrlw(XMMRegister reg, uint8_t shift) {
2647 EnsureSpace ensure_space(
this);
2651 emit_sse_operand(edx, reg);
2655 void Assembler::psrld(XMMRegister reg, uint8_t shift) {
2656 EnsureSpace ensure_space(
this);
2660 emit_sse_operand(edx, reg);
2664 void Assembler::psraw(XMMRegister reg, uint8_t shift) {
2665 EnsureSpace ensure_space(
this);
2669 emit_sse_operand(esp, reg);
2673 void Assembler::psrad(XMMRegister reg, uint8_t shift) {
2674 EnsureSpace ensure_space(
this);
2678 emit_sse_operand(esp, reg);
2682 void Assembler::psllq(XMMRegister reg, uint8_t shift) {
2683 EnsureSpace ensure_space(
this);
2687 emit_sse_operand(esi, reg);
2692 void Assembler::psllq(XMMRegister dst, XMMRegister src) {
2693 EnsureSpace ensure_space(
this);
2697 emit_sse_operand(dst, src);
2700 void Assembler::psrlq(XMMRegister reg, uint8_t shift) {
2701 EnsureSpace ensure_space(
this);
2705 emit_sse_operand(edx, reg);
2710 void Assembler::psrlq(XMMRegister dst, XMMRegister src) {
2711 EnsureSpace ensure_space(
this);
2715 emit_sse_operand(dst, src);
2718 void Assembler::pshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
2719 EnsureSpace ensure_space(
this);
2723 emit_sse_operand(dst, src);
2727 void Assembler::pshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
2728 EnsureSpace ensure_space(
this);
2732 emit_sse_operand(dst, src);
2736 void Assembler::pshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
2737 EnsureSpace ensure_space(
this);
2741 emit_sse_operand(dst, src);
2745 void Assembler::pblendw(XMMRegister dst, Operand src, uint8_t mask) {
2746 DCHECK(IsEnabled(SSE4_1));
2747 EnsureSpace ensure_space(
this);
2752 emit_sse_operand(dst, src);
2756 void Assembler::palignr(XMMRegister dst, Operand src, uint8_t mask) {
2757 DCHECK(IsEnabled(SSSE3));
2758 EnsureSpace ensure_space(
this);
2763 emit_sse_operand(dst, src);
2767 void Assembler::pextrb(Operand dst, XMMRegister src, uint8_t offset) {
2768 DCHECK(IsEnabled(SSE4_1));
2769 EnsureSpace ensure_space(
this);
2774 emit_sse_operand(src, dst);
2778 void Assembler::pextrw(Operand dst, XMMRegister src, uint8_t offset) {
2779 DCHECK(IsEnabled(SSE4_1));
2780 EnsureSpace ensure_space(
this);
2785 emit_sse_operand(src, dst);
2789 void Assembler::pextrd(Operand dst, XMMRegister src, uint8_t offset) {
2790 DCHECK(IsEnabled(SSE4_1));
2791 EnsureSpace ensure_space(
this);
2796 emit_sse_operand(src, dst);
2800 void Assembler::insertps(XMMRegister dst, Operand src, uint8_t offset) {
2801 DCHECK(IsEnabled(SSE4_1));
2802 EnsureSpace ensure_space(
this);
2807 emit_sse_operand(dst, src);
2811 void Assembler::pinsrb(XMMRegister dst, Operand src, uint8_t offset) {
2812 DCHECK(IsEnabled(SSE4_1));
2813 EnsureSpace ensure_space(
this);
2818 emit_sse_operand(dst, src);
2822 void Assembler::pinsrw(XMMRegister dst, Operand src, uint8_t offset) {
2823 DCHECK(is_uint8(offset));
2824 EnsureSpace ensure_space(
this);
2828 emit_sse_operand(dst, src);
2832 void Assembler::pinsrd(XMMRegister dst, Operand src, uint8_t offset) {
2833 DCHECK(IsEnabled(SSE4_1));
2834 EnsureSpace ensure_space(
this);
2839 emit_sse_operand(dst, src);
2843 void Assembler::addss(XMMRegister dst, Operand src) {
2844 EnsureSpace ensure_space(
this);
2848 emit_sse_operand(dst, src);
2851 void Assembler::subss(XMMRegister dst, Operand src) {
2852 EnsureSpace ensure_space(
this);
2856 emit_sse_operand(dst, src);
2859 void Assembler::mulss(XMMRegister dst, Operand src) {
2860 EnsureSpace ensure_space(
this);
2864 emit_sse_operand(dst, src);
2867 void Assembler::divss(XMMRegister dst, Operand src) {
2868 EnsureSpace ensure_space(
this);
2872 emit_sse_operand(dst, src);
2875 void Assembler::sqrtss(XMMRegister dst, Operand src) {
2876 EnsureSpace ensure_space(
this);
2880 emit_sse_operand(dst, src);
2883 void Assembler::ucomiss(XMMRegister dst, Operand src) {
2884 EnsureSpace ensure_space(
this);
2887 emit_sse_operand(dst, src);
2890 void Assembler::maxss(XMMRegister dst, Operand src) {
2891 EnsureSpace ensure_space(
this);
2895 emit_sse_operand(dst, src);
2898 void Assembler::minss(XMMRegister dst, Operand src) {
2899 EnsureSpace ensure_space(
this);
2903 emit_sse_operand(dst, src);
2908 void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
2910 DCHECK(IsEnabled(FMA3));
2911 EnsureSpace ensure_space(
this);
2912 emit_vex_prefix(src1, kLIG, k66, k0F38, kW1);
2914 emit_sse_operand(dst, src2);
2917 void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
2919 DCHECK(IsEnabled(FMA3));
2920 EnsureSpace ensure_space(
this);
2921 emit_vex_prefix(src1, kLIG, k66, k0F38, kW0);
2923 emit_sse_operand(dst, src2);
2926 void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2927 vinstr(op, dst, src1, src2, kF2, k0F, kWIG);
2930 void Assembler::vss(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2931 vinstr(op, dst, src1, src2, kF3, k0F, kWIG);
2934 void Assembler::vps(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2935 vinstr(op, dst, src1, src2, kNone, k0F, kWIG);
2938 void Assembler::vpd(byte op, XMMRegister dst, XMMRegister src1, Operand src2) {
2939 vinstr(op, dst, src1, src2, k66, k0F, kWIG);
2942 void Assembler::vcmpps(XMMRegister dst, XMMRegister src1, Operand src2,
2944 vps(0xC2, dst, src1, src2);
2948 void Assembler::vshufps(XMMRegister dst, XMMRegister src1, Operand src2,
2950 DCHECK(is_uint8(imm8));
2951 vps(0xC6, dst, src1, src2);
2955 void Assembler::vpsllw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2956 XMMRegister iop = XMMRegister::from_code(6);
2957 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2961 void Assembler::vpslld(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2962 XMMRegister iop = XMMRegister::from_code(6);
2963 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2967 void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2968 XMMRegister iop = XMMRegister::from_code(2);
2969 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2973 void Assembler::vpsrld(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2974 XMMRegister iop = XMMRegister::from_code(2);
2975 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2979 void Assembler::vpsraw(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2980 XMMRegister iop = XMMRegister::from_code(4);
2981 vinstr(0x71, iop, dst, Operand(src), k66, k0F, kWIG);
2985 void Assembler::vpsrad(XMMRegister dst, XMMRegister src, uint8_t imm8) {
2986 XMMRegister iop = XMMRegister::from_code(4);
2987 vinstr(0x72, iop, dst, Operand(src), k66, k0F, kWIG);
2991 void Assembler::vpshufhw(XMMRegister dst, Operand src, uint8_t shuffle) {
2992 vinstr(0x70, dst, xmm0, src, kF3, k0F, kWIG);
2996 void Assembler::vpshuflw(XMMRegister dst, Operand src, uint8_t shuffle) {
2997 vinstr(0x70, dst, xmm0, src, kF2, k0F, kWIG);
3001 void Assembler::vpshufd(XMMRegister dst, Operand src, uint8_t shuffle) {
3002 vinstr(0x70, dst, xmm0, src, k66, k0F, kWIG);
3006 void Assembler::vpblendw(XMMRegister dst, XMMRegister src1, Operand src2,
3008 vinstr(0x0E, dst, src1, src2, k66, k0F3A, kWIG);
3012 void Assembler::vpalignr(XMMRegister dst, XMMRegister src1, Operand src2,
3014 vinstr(0x0F, dst, src1, src2, k66, k0F3A, kWIG);
3018 void Assembler::vpextrb(Operand dst, XMMRegister src, uint8_t offset) {
3019 vinstr(0x14, src, xmm0, dst, k66, k0F3A, kWIG);
3023 void Assembler::vpextrw(Operand dst, XMMRegister src, uint8_t offset) {
3024 vinstr(0x15, src, xmm0, dst, k66, k0F3A, kWIG);
3028 void Assembler::vpextrd(Operand dst, XMMRegister src, uint8_t offset) {
3029 vinstr(0x16, src, xmm0, dst, k66, k0F3A, kWIG);
3033 void Assembler::vinsertps(XMMRegister dst, XMMRegister src1, Operand src2,
3035 vinstr(0x21, dst, src1, src2, k66, k0F3A, kWIG);
3039 void Assembler::vpinsrb(XMMRegister dst, XMMRegister src1, Operand src2,
3041 vinstr(0x20, dst, src1, src2, k66, k0F3A, kWIG);
3045 void Assembler::vpinsrw(XMMRegister dst, XMMRegister src1, Operand src2,
3047 vinstr(0xC4, dst, src1, src2, k66, k0F, kWIG);
3051 void Assembler::vpinsrd(XMMRegister dst, XMMRegister src1, Operand src2,
3053 vinstr(0x22, dst, src1, src2, k66, k0F3A, kWIG);
3057 void Assembler::bmi1(byte op, Register reg, Register vreg, Operand rm) {
3058 DCHECK(IsEnabled(BMI1));
3059 EnsureSpace ensure_space(
this);
3060 emit_vex_prefix(vreg, kLZ, kNone, k0F38, kW0);
3062 emit_operand(reg, rm);
3065 void Assembler::tzcnt(Register dst, Operand src) {
3066 DCHECK(IsEnabled(BMI1));
3067 EnsureSpace ensure_space(
this);
3071 emit_operand(dst, src);
3074 void Assembler::lzcnt(Register dst, Operand src) {
3075 DCHECK(IsEnabled(LZCNT));
3076 EnsureSpace ensure_space(
this);
3080 emit_operand(dst, src);
3083 void Assembler::popcnt(Register dst, Operand src) {
3084 DCHECK(IsEnabled(POPCNT));
3085 EnsureSpace ensure_space(
this);
3089 emit_operand(dst, src);
3092 void Assembler::bmi2(SIMDPrefix pp, byte op, Register reg, Register vreg,
3094 DCHECK(IsEnabled(BMI2));
3095 EnsureSpace ensure_space(
this);
3096 emit_vex_prefix(vreg, kLZ, pp, k0F38, kW0);
3098 emit_operand(reg, rm);
3101 void Assembler::rorx(Register dst, Operand src, byte imm8) {
3102 DCHECK(IsEnabled(BMI2));
3103 DCHECK(is_uint8(imm8));
3104 Register vreg = Register::from_code<0>();
3105 EnsureSpace ensure_space(
this);
3106 emit_vex_prefix(vreg, kLZ, kF2, k0F3A, kW0);
3108 emit_operand(dst, src);
3112 void Assembler::sse2_instr(XMMRegister dst, Operand src, byte prefix,
3113 byte escape, byte opcode) {
3114 EnsureSpace ensure_space(
this);
3118 emit_sse_operand(dst, src);
3121 void Assembler::ssse3_instr(XMMRegister dst, Operand src, byte prefix,
3122 byte escape1, byte escape2, byte opcode) {
3123 DCHECK(IsEnabled(SSSE3));
3124 EnsureSpace ensure_space(
this);
3129 emit_sse_operand(dst, src);
3132 void Assembler::sse4_instr(XMMRegister dst, Operand src, byte prefix,
3133 byte escape1, byte escape2, byte opcode) {
3134 DCHECK(IsEnabled(SSE4_1));
3135 EnsureSpace ensure_space(
this);
3140 emit_sse_operand(dst, src);
3143 void Assembler::vinstr(byte op, XMMRegister dst, XMMRegister src1, Operand src2,
3144 SIMDPrefix pp, LeadingOpcode m, VexW w) {
3145 DCHECK(IsEnabled(AVX));
3146 EnsureSpace ensure_space(
this);
3147 emit_vex_prefix(src1, kL128, pp, m, w);
3149 emit_sse_operand(dst, src2);
3152 void Assembler::emit_sse_operand(XMMRegister reg, Operand adr) {
3153 Register ireg = Register::from_code(reg.code());
3154 emit_operand(ireg, adr);
3158 void Assembler::emit_sse_operand(XMMRegister dst, XMMRegister src) {
3159 EMIT(0xC0 | dst.code() << 3 | src.code());
3163 void Assembler::emit_sse_operand(Register dst, XMMRegister src) {
3164 EMIT(0xC0 | dst.code() << 3 | src.code());
3168 void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
3169 EMIT(0xC0 | (dst.code() << 3) | src.code());
3173 void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp,
3174 LeadingOpcode mm, VexW w) {
3175 if (mm != k0F || w != kW0) {
3179 EMIT(w | ((~vreg.code() & 0xF) << 3) | l | pp);
3182 EMIT(((~vreg.code()) << 3) | l | pp);
3187 void Assembler::emit_vex_prefix(Register vreg, VectorLength l, SIMDPrefix pp,
3188 LeadingOpcode mm, VexW w) {
3189 XMMRegister ivreg = XMMRegister::from_code(vreg.code());
3190 emit_vex_prefix(ivreg, l, pp, mm, w);
3194 void Assembler::GrowBuffer() {
3195 DCHECK(buffer_overflow());
3196 if (!own_buffer_) FATAL(
"external code buffer is too small");
3200 desc.buffer_size = 2 * buffer_size_;
3204 if (desc.buffer_size > kMaximalBufferSize) {
3205 V8::FatalProcessOutOfMemory(
nullptr,
"Assembler::GrowBuffer");
3209 desc.buffer = NewArray<byte>(desc.buffer_size);
3211 desc.instr_size = pc_offset();
3212 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
3217 ZapCode(reinterpret_cast<Address>(desc.buffer), desc.buffer_size);
3221 int pc_delta = desc.buffer - buffer_;
3222 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
3223 MemMove(desc.buffer, buffer_, desc.instr_size);
3224 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
3228 DeleteArray(buffer_);
3229 buffer_ = desc.buffer;
3230 buffer_size_ = desc.buffer_size;
3232 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
3233 reloc_info_writer.last_pc() + pc_delta);
3236 for (
auto pos : internal_reference_positions_) {
3237 int32_t* p =
reinterpret_cast<int32_t*
>(buffer_ + pos);
3242 int mode_mask = RelocInfo::ModeMask(RelocInfo::OFF_HEAP_TARGET);
3243 DCHECK_EQ(mode_mask, RelocInfo::kApplyMask & mode_mask);
3244 for (RelocIterator it(desc, mode_mask); !it.done(); it.next()) {
3245 it.rinfo()->apply(pc_delta);
3248 DCHECK(!buffer_overflow());
3252 void Assembler::emit_arith_b(
int op1,
int op2, Register dst,
int imm8) {
3253 DCHECK(is_uint8(op1) && is_uint8(op2));
3254 DCHECK(is_uint8(imm8));
3255 DCHECK_EQ(op1 & 0x01, 0);
3257 EMIT(op2 | dst.code());
3262 void Assembler::emit_arith(
int sel, Operand dst,
const Immediate& x) {
3263 DCHECK((0 <= sel) && (sel <= 7));
3264 Register ireg = Register::from_code(sel);
3267 emit_operand(ireg, dst);
3268 EMIT(x.immediate() & 0xFF);
3269 }
else if (dst.is_reg(eax)) {
3270 EMIT((sel << 3) | 0x05);
3274 emit_operand(ireg, dst);
3279 void Assembler::emit_operand(Register reg, Operand adr) {
3280 emit_operand(reg.code(), adr);
3283 void Assembler::emit_operand(XMMRegister reg, Operand adr) {
3284 Register ireg = Register::from_code(reg.code());
3285 emit_operand(ireg, adr);
3288 void Assembler::emit_operand(
int code, Operand adr) {
3290 DCHECK(!options().isolate_independent_code ||
3291 adr.rmode_ != RelocInfo::CODE_TARGET);
3292 DCHECK(!options().isolate_independent_code ||
3293 adr.rmode_ != RelocInfo::EMBEDDED_OBJECT);
3294 DCHECK(!options().isolate_independent_code ||
3295 adr.rmode_ != RelocInfo::EXTERNAL_REFERENCE);
3297 const unsigned length = adr.len_;
3298 DCHECK_GT(length, 0);
3301 pc_[0] = (adr.buf_[0] & ~0x38) | (code << 3);
3304 for (
unsigned i = 1;
i < length;
i++) pc_[
i] = adr.buf_[
i];
3308 if (length >=
sizeof(int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
3309 pc_ -=
sizeof(int32_t);
3310 RecordRelocInfo(adr.rmode_);
3311 if (adr.rmode_ == RelocInfo::INTERNAL_REFERENCE) {
3312 emit_label(*reinterpret_cast<Label**>(pc_));
3314 pc_ +=
sizeof(int32_t);
3320 void Assembler::emit_label(Label* label) {
3321 if (label->is_bound()) {
3322 internal_reference_positions_.push_back(pc_offset());
3323 emit(reinterpret_cast<uint32_t>(buffer_ + label->pos()));
3325 emit_disp(label, Displacement::CODE_ABSOLUTE);
3330 void Assembler::emit_farith(
int b1,
int b2,
int i) {
3331 DCHECK(is_uint8(b1) && is_uint8(b2));
3332 DCHECK(0 <=
i &&
i < 8);
3338 void Assembler::db(uint8_t data) {
3339 EnsureSpace ensure_space(
this);
3344 void Assembler::dd(
uint32_t data) {
3345 EnsureSpace ensure_space(
this);
3350 void Assembler::dq(uint64_t data) {
3351 EnsureSpace ensure_space(
this);
3356 void Assembler::dd(Label* label) {
3357 EnsureSpace ensure_space(
this);
3358 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
3363 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
3364 if (!ShouldRecordRelocInfo(rmode))
return;
3365 RelocInfo rinfo(reinterpret_cast<Address>(pc_), rmode, data, Code());
3366 reloc_info_writer.Write(&rinfo);
3372 #endif // V8_TARGET_ARCH_IA32