39 #if V8_TARGET_ARCH_X87
57 if (cross_compile)
return;
68 void Displacement::init(Label*
L,
Type type) {
77 data_ = NextField::encode(next) | TypeField::encode(type);
107 for (
int i = 0;
i < instruction_count;
i++) {
108 *(
pc_ +
i) = *(instructions +
i);
120 static const int kCallCodeSize = 5;
121 int code_size = kCallCodeSize + guard_bytes;
124 CodePatcher patcher(
pc_, code_size);
128 Label check_codesize;
129 patcher.masm()->bind(&check_codesize);
137 patcher.masm()->SizeOfCodeGeneratedSince(&check_codesize));
141 for (
int i = 0;
i < guard_bytes;
i++) {
142 patcher.masm()->int3();
165 set_dispr(disp, rmode);
180 set_sib(scale, index, base);
184 set_sib(scale, index, base);
189 set_sib(scale, index, base);
190 set_dispr(disp, rmode);
202 set_sib(scale, index,
ebp);
203 set_dispr(disp, rmode);
207 bool Operand::is_reg(Register reg)
const {
208 return ((buf_[0] & 0xF8) == 0xC0)
209 && ((buf_[0] & 0x07) ==
reg.
code());
213 bool Operand::is_reg_only()
const {
214 return (buf_[0] & 0xF8) == 0xC0;
232 #ifdef GENERATED_CODE_COVERAGE
233 static void InitCoverageLog();
237 : AssemblerBase(isolate, buffer, buffer_size),
238 positions_recorder_(this) {
244 memset(buffer_, 0xCC, buffer_size_);
248 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
250 #ifdef GENERATED_CODE_COVERAGE
256 void Assembler::GetCode(CodeDesc* desc) {
259 DCHECK(pc_ <= reloc_info_writer.pos());
261 desc->buffer = buffer_;
262 desc->buffer_size = buffer_size_;
263 desc->instr_size = pc_offset();
264 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
272 int addr = pc_offset();
273 Nop((m - (addr & mask)) & mask);
277 bool Assembler::IsNop(
Address addr) {
279 while (*a == 0x66) a++;
280 if (*a == 0x90)
return true;
281 if (a[0] == 0xf && a[1] == 0x1f)
return true;
286 void Assembler::Nop(
int bytes) {
287 EnsureSpace ensure_space(
this);
291 for (; bytes > 0; bytes--) {
298 void Assembler::CodeTargetAlign() {
303 void Assembler::cpuid() {
304 EnsureSpace ensure_space(
this);
310 void Assembler::pushad() {
311 EnsureSpace ensure_space(
this);
316 void Assembler::popad() {
317 EnsureSpace ensure_space(
this);
322 void Assembler::pushfd() {
323 EnsureSpace ensure_space(
this);
328 void Assembler::popfd() {
329 EnsureSpace ensure_space(
this);
334 void Assembler::push(
const Immediate& x) {
335 EnsureSpace ensure_space(
this);
346 void Assembler::push_imm32(
int32_t imm32) {
347 EnsureSpace ensure_space(
this);
353 void Assembler::push(Register src) {
354 EnsureSpace ensure_space(
this);
355 EMIT(0x50 | src.code());
359 void Assembler::push(
const Operand& src) {
360 EnsureSpace ensure_space(
this);
362 emit_operand(
esi, src);
366 void Assembler::pop(Register dst) {
368 EnsureSpace ensure_space(
this);
369 EMIT(0x58 | dst.code());
373 void Assembler::pop(
const Operand& dst) {
374 EnsureSpace ensure_space(
this);
376 emit_operand(
eax, dst);
380 void Assembler::enter(
const Immediate&
size) {
381 EnsureSpace ensure_space(
this);
388 void Assembler::leave() {
389 EnsureSpace ensure_space(
this);
394 void Assembler::mov_b(Register dst,
const Operand& src) {
395 CHECK(dst.is_byte_register());
396 EnsureSpace ensure_space(
this);
398 emit_operand(dst, src);
402 void Assembler::mov_b(
const Operand& dst, int8_t imm8) {
403 EnsureSpace ensure_space(
this);
405 emit_operand(
eax, dst);
410 void Assembler::mov_b(
const Operand& dst, Register src) {
411 CHECK(src.is_byte_register());
412 EnsureSpace ensure_space(
this);
414 emit_operand(src, dst);
418 void Assembler::mov_w(Register dst,
const Operand& src) {
419 EnsureSpace ensure_space(
this);
422 emit_operand(dst, src);
426 void Assembler::mov_w(
const Operand& dst, Register src) {
427 EnsureSpace ensure_space(
this);
430 emit_operand(src, dst);
434 void Assembler::mov_w(
const Operand& dst,
int16_t imm16) {
435 EnsureSpace ensure_space(
this);
438 emit_operand(
eax, dst);
439 EMIT(
static_cast<int8_t
>(imm16 & 0xff));
440 EMIT(
static_cast<int8_t
>(imm16 >> 8));
444 void Assembler::mov(Register dst,
int32_t imm32) {
445 EnsureSpace ensure_space(
this);
446 EMIT(0xB8 | dst.code());
451 void Assembler::mov(Register dst,
const Immediate& x) {
452 EnsureSpace ensure_space(
this);
453 EMIT(0xB8 | dst.code());
458 void Assembler::mov(Register dst, Handle<Object>
handle) {
459 EnsureSpace ensure_space(
this);
460 EMIT(0xB8 | dst.code());
465 void Assembler::mov(Register dst,
const Operand& src) {
466 EnsureSpace ensure_space(
this);
468 emit_operand(dst, src);
472 void Assembler::mov(Register dst, Register src) {
473 EnsureSpace ensure_space(
this);
475 EMIT(0xC0 | src.code() << 3 | dst.code());
479 void Assembler::mov(
const Operand& dst,
const Immediate& x) {
480 EnsureSpace ensure_space(
this);
482 emit_operand(
eax, dst);
487 void Assembler::mov(
const Operand& dst, Handle<Object>
handle) {
488 EnsureSpace ensure_space(
this);
490 emit_operand(
eax, dst);
495 void Assembler::mov(
const Operand& dst, Register src) {
496 EnsureSpace ensure_space(
this);
498 emit_operand(src, dst);
502 void Assembler::movsx_b(Register dst,
const Operand& src) {
503 EnsureSpace ensure_space(
this);
506 emit_operand(dst, src);
510 void Assembler::movsx_w(Register dst,
const Operand& src) {
511 EnsureSpace ensure_space(
this);
514 emit_operand(dst, src);
518 void Assembler::movzx_b(Register dst,
const Operand& src) {
519 EnsureSpace ensure_space(
this);
522 emit_operand(dst, src);
526 void Assembler::movzx_w(Register dst,
const Operand& src) {
527 EnsureSpace ensure_space(
this);
530 emit_operand(dst, src);
534 void Assembler::cld() {
535 EnsureSpace ensure_space(
this);
540 void Assembler::rep_movs() {
541 EnsureSpace ensure_space(
this);
547 void Assembler::rep_stos() {
548 EnsureSpace ensure_space(
this);
554 void Assembler::stos() {
555 EnsureSpace ensure_space(
this);
560 void Assembler::xchg(Register dst, Register src) {
561 EnsureSpace ensure_space(
this);
562 if (src.is(
eax) || dst.is(
eax)) {
563 EMIT(0x90 | (src.is(
eax) ? dst.code() : src.code()));
566 EMIT(0xC0 | src.code() << 3 | dst.code());
571 void Assembler::xchg(Register dst,
const Operand& src) {
572 EnsureSpace ensure_space(
this);
574 emit_operand(dst, src);
578 void Assembler::adc(Register dst,
int32_t imm32) {
579 EnsureSpace ensure_space(
this);
580 emit_arith(2, Operand(dst), Immediate(imm32));
584 void Assembler::adc(Register dst,
const Operand& src) {
585 EnsureSpace ensure_space(
this);
587 emit_operand(dst, src);
591 void Assembler::add(Register dst,
const Operand& src) {
592 EnsureSpace ensure_space(
this);
594 emit_operand(dst, src);
598 void Assembler::add(
const Operand& dst, Register src) {
599 EnsureSpace ensure_space(
this);
601 emit_operand(src, dst);
605 void Assembler::add(
const Operand& dst,
const Immediate& x) {
607 EnsureSpace ensure_space(
this);
608 emit_arith(0, dst, x);
612 void Assembler::and_(Register dst,
int32_t imm32) {
613 and_(dst, Immediate(imm32));
617 void Assembler::and_(Register dst,
const Immediate& x) {
618 EnsureSpace ensure_space(
this);
619 emit_arith(4, Operand(dst), x);
623 void Assembler::and_(Register dst,
const Operand& src) {
624 EnsureSpace ensure_space(
this);
626 emit_operand(dst, src);
630 void Assembler::and_(
const Operand& dst,
const Immediate& x) {
631 EnsureSpace ensure_space(
this);
632 emit_arith(4, dst, x);
636 void Assembler::and_(
const Operand& dst, Register src) {
637 EnsureSpace ensure_space(
this);
639 emit_operand(src, dst);
643 void Assembler::cmpb(
const Operand& op, int8_t imm8) {
644 EnsureSpace ensure_space(
this);
645 if (op.is_reg(
eax)) {
649 emit_operand(
edi, op);
655 void Assembler::cmpb(
const Operand& op, Register reg) {
656 CHECK(reg.is_byte_register());
657 EnsureSpace ensure_space(
this);
659 emit_operand(reg, op);
663 void Assembler::cmpb(Register reg,
const Operand& op) {
664 CHECK(reg.is_byte_register());
665 EnsureSpace ensure_space(
this);
667 emit_operand(reg, op);
671 void Assembler::cmpw(
const Operand& op, Immediate imm16) {
673 EnsureSpace ensure_space(
this);
676 emit_operand(
edi, op);
681 void Assembler::cmp(Register reg,
int32_t imm32) {
682 EnsureSpace ensure_space(
this);
683 emit_arith(7, Operand(reg), Immediate(imm32));
687 void Assembler::cmp(Register reg, Handle<Object>
handle) {
688 EnsureSpace ensure_space(
this);
689 emit_arith(7, Operand(reg), Immediate(
handle));
693 void Assembler::cmp(Register reg,
const Operand& op) {
694 EnsureSpace ensure_space(
this);
696 emit_operand(reg, op);
700 void Assembler::cmp(
const Operand& op,
const Immediate& imm) {
701 EnsureSpace ensure_space(
this);
702 emit_arith(7, op, imm);
706 void Assembler::cmp(
const Operand& op, Handle<Object>
handle) {
707 EnsureSpace ensure_space(
this);
708 emit_arith(7, op, Immediate(
handle));
712 void Assembler::cmpb_al(
const Operand& op) {
713 EnsureSpace ensure_space(
this);
715 emit_operand(
eax, op);
719 void Assembler::cmpw_ax(
const Operand& op) {
720 EnsureSpace ensure_space(
this);
723 emit_operand(
eax, op);
727 void Assembler::dec_b(Register dst) {
728 CHECK(dst.is_byte_register());
729 EnsureSpace ensure_space(
this);
731 EMIT(0xC8 | dst.code());
735 void Assembler::dec_b(
const Operand& dst) {
736 EnsureSpace ensure_space(
this);
738 emit_operand(
ecx, dst);
743 EnsureSpace ensure_space(
this);
744 EMIT(0x48 | dst.code());
749 EnsureSpace ensure_space(
this);
751 emit_operand(
ecx, dst);
755 void Assembler::cdq() {
756 EnsureSpace ensure_space(
this);
761 void Assembler::idiv(
const Operand& src) {
762 EnsureSpace ensure_space(
this);
764 emit_operand(
edi, src);
768 void Assembler::div(
const Operand& src) {
769 EnsureSpace ensure_space(
this);
771 emit_operand(
esi, src);
775 void Assembler::imul(Register reg) {
776 EnsureSpace ensure_space(
this);
778 EMIT(0xE8 | reg.code());
782 void Assembler::imul(Register dst,
const Operand& src) {
783 EnsureSpace ensure_space(
this);
786 emit_operand(dst, src);
790 void Assembler::imul(Register dst, Register src,
int32_t imm32) {
791 imul(dst, Operand(src), imm32);
795 void Assembler::imul(Register dst,
const Operand& src,
int32_t imm32) {
796 EnsureSpace ensure_space(
this);
797 if (is_int8(imm32)) {
799 emit_operand(dst, src);
803 emit_operand(dst, src);
809 void Assembler::inc(Register dst) {
810 EnsureSpace ensure_space(
this);
811 EMIT(0x40 | dst.code());
815 void Assembler::inc(
const Operand& dst) {
816 EnsureSpace ensure_space(
this);
818 emit_operand(
eax, dst);
822 void Assembler::lea(Register dst,
const Operand& src) {
823 EnsureSpace ensure_space(
this);
825 emit_operand(dst, src);
829 void Assembler::mul(Register src) {
830 EnsureSpace ensure_space(
this);
832 EMIT(0xE0 | src.code());
836 void Assembler::neg(Register dst) {
837 EnsureSpace ensure_space(
this);
839 EMIT(0xD8 | dst.code());
843 void Assembler::neg(
const Operand& dst) {
844 EnsureSpace ensure_space(
this);
846 emit_operand(
ebx, dst);
850 void Assembler::not_(Register dst) {
851 EnsureSpace ensure_space(
this);
853 EMIT(0xD0 | dst.code());
857 void Assembler::not_(
const Operand& dst) {
858 EnsureSpace ensure_space(
this);
860 emit_operand(
edx, dst);
864 void Assembler::or_(Register dst,
int32_t imm32) {
865 EnsureSpace ensure_space(
this);
866 emit_arith(1, Operand(dst), Immediate(imm32));
870 void Assembler::or_(Register dst,
const Operand& src) {
871 EnsureSpace ensure_space(
this);
873 emit_operand(dst, src);
877 void Assembler::or_(
const Operand& dst,
const Immediate& x) {
878 EnsureSpace ensure_space(
this);
879 emit_arith(1, dst, x);
883 void Assembler::or_(
const Operand& dst, Register src) {
884 EnsureSpace ensure_space(
this);
886 emit_operand(src, dst);
890 void Assembler::rcl(Register dst, uint8_t imm8) {
891 EnsureSpace ensure_space(
this);
895 EMIT(0xD0 | dst.code());
898 EMIT(0xD0 | dst.code());
904 void Assembler::rcr(Register dst, uint8_t imm8) {
905 EnsureSpace ensure_space(
this);
909 EMIT(0xD8 | dst.code());
912 EMIT(0xD8 | dst.code());
918 void Assembler::ror(Register dst, uint8_t imm8) {
919 EnsureSpace ensure_space(
this);
923 EMIT(0xC8 | dst.code());
926 EMIT(0xC8 | dst.code());
932 void Assembler::ror_cl(Register dst) {
933 EnsureSpace ensure_space(
this);
935 EMIT(0xC8 | dst.code());
939 void Assembler::sar(
const Operand& dst, uint8_t imm8) {
940 EnsureSpace ensure_space(
this);
944 emit_operand(
edi, dst);
947 emit_operand(
edi, dst);
953 void Assembler::sar_cl(
const Operand& dst) {
954 EnsureSpace ensure_space(
this);
956 emit_operand(
edi, dst);
960 void Assembler::sbb(Register dst,
const Operand& src) {
961 EnsureSpace ensure_space(
this);
963 emit_operand(dst, src);
967 void Assembler::shld(Register dst,
const Operand& src) {
968 EnsureSpace ensure_space(
this);
971 emit_operand(dst, src);
975 void Assembler::shl(
const Operand& dst, uint8_t imm8) {
976 EnsureSpace ensure_space(
this);
980 emit_operand(
esp, dst);
983 emit_operand(
esp, dst);
989 void Assembler::shl_cl(
const Operand& dst) {
990 EnsureSpace ensure_space(
this);
992 emit_operand(
esp, dst);
996 void Assembler::shrd(Register dst,
const Operand& src) {
997 EnsureSpace ensure_space(
this);
1000 emit_operand(dst, src);
1004 void Assembler::shr(
const Operand& dst, uint8_t imm8) {
1005 EnsureSpace ensure_space(
this);
1009 emit_operand(
ebp, dst);
1012 emit_operand(
ebp, dst);
1018 void Assembler::shr_cl(
const Operand& dst) {
1019 EnsureSpace ensure_space(
this);
1021 emit_operand(
ebp, dst);
1025 void Assembler::sub(
const Operand& dst,
const Immediate& x) {
1026 EnsureSpace ensure_space(
this);
1027 emit_arith(5, dst, x);
1031 void Assembler::sub(Register dst,
const Operand& src) {
1032 EnsureSpace ensure_space(
this);
1034 emit_operand(dst, src);
1038 void Assembler::sub(
const Operand& dst, Register src) {
1039 EnsureSpace ensure_space(
this);
1041 emit_operand(src, dst);
1045 void Assembler::test(Register reg,
const Immediate& imm) {
1046 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1047 test_b(reg, imm.x_);
1051 EnsureSpace ensure_space(
this);
1058 EMIT(0xC0 | reg.code());
1064 void Assembler::test(Register reg,
const Operand& op) {
1065 EnsureSpace ensure_space(
this);
1067 emit_operand(reg, op);
1071 void Assembler::test_b(Register reg,
const Operand& op) {
1072 CHECK(reg.is_byte_register());
1073 EnsureSpace ensure_space(
this);
1075 emit_operand(reg, op);
1079 void Assembler::test(
const Operand& op,
const Immediate& imm) {
1080 if (op.is_reg_only()) {
1081 test(op.reg(), imm);
1084 if (RelocInfo::IsNone(imm.rmode_) && is_uint8(imm.x_)) {
1085 return test_b(op, imm.x_);
1087 EnsureSpace ensure_space(
this);
1089 emit_operand(
eax, op);
1094 void Assembler::test_b(Register reg, uint8_t imm8) {
1095 EnsureSpace ensure_space(
this);
1101 }
else if (reg.is_byte_register()) {
1102 emit_arith_b(0xF6, 0xC0, reg, imm8);
1105 EMIT(0xC0 | reg.code());
1111 void Assembler::test_b(
const Operand& op, uint8_t imm8) {
1112 if (op.is_reg_only()) {
1113 test_b(op.reg(), imm8);
1116 EnsureSpace ensure_space(
this);
1118 emit_operand(
eax, op);
1123 void Assembler::xor_(Register dst,
int32_t imm32) {
1124 EnsureSpace ensure_space(
this);
1125 emit_arith(6, Operand(dst), Immediate(imm32));
1129 void Assembler::xor_(Register dst,
const Operand& src) {
1130 EnsureSpace ensure_space(
this);
1132 emit_operand(dst, src);
1136 void Assembler::xor_(
const Operand& dst, Register src) {
1137 EnsureSpace ensure_space(
this);
1139 emit_operand(src, dst);
1143 void Assembler::xor_(
const Operand& dst,
const Immediate& x) {
1144 EnsureSpace ensure_space(
this);
1145 emit_arith(6, dst, x);
1149 void Assembler::bt(
const Operand& dst, Register src) {
1150 EnsureSpace ensure_space(
this);
1153 emit_operand(src, dst);
1157 void Assembler::bts(
const Operand& dst, Register src) {
1158 EnsureSpace ensure_space(
this);
1161 emit_operand(src, dst);
1165 void Assembler::bsr(Register dst,
const Operand& src) {
1166 EnsureSpace ensure_space(
this);
1169 emit_operand(dst, src);
1173 void Assembler::hlt() {
1174 EnsureSpace ensure_space(
this);
1179 void Assembler::int3() {
1180 EnsureSpace ensure_space(
this);
1185 void Assembler::nop() {
1186 EnsureSpace ensure_space(
this);
1191 void Assembler::ret(
int imm16) {
1192 EnsureSpace ensure_space(
this);
1193 DCHECK(is_uint16(imm16));
1199 EMIT((imm16 >> 8) & 0xFF);
1215 void Assembler::print(Label*
L) {
1216 if (
L->is_unused()) {
1217 PrintF(
"unused label\n");
1218 }
else if (
L->is_bound()) {
1219 PrintF(
"bound label to %d\n",
L->pos());
1220 }
else if (
L->is_linked()) {
1223 while (l.is_linked()) {
1224 Displacement disp = disp_at(&l);
1225 PrintF(
"@ %d ", l.pos());
1231 PrintF(
"label in inconsistent state (pos = %d)\n",
L->pos_);
1236 void Assembler::bind_to(Label*
L,
int pos) {
1237 EnsureSpace ensure_space(
this);
1238 DCHECK(0 <= pos && pos <= pc_offset());
1239 while (
L->is_linked()) {
1240 Displacement disp = disp_at(
L);
1241 int fixup_pos =
L->pos();
1242 if (disp.type() == Displacement::CODE_RELATIVE) {
1244 long_at_put(fixup_pos, pos + Code::kHeaderSize -
kHeapObjectTag);
1246 if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
1247 DCHECK(byte_at(fixup_pos - 1) == 0xE9);
1250 int imm32 = pos - (fixup_pos +
sizeof(
int32_t));
1251 long_at_put(fixup_pos, imm32);
1255 while (
L->is_near_linked()) {
1256 int fixup_pos =
L->near_link_pos();
1257 int offset_to_next =
1258 static_cast<int>(*
reinterpret_cast<int8_t*
>(addr_at(fixup_pos)));
1259 DCHECK(offset_to_next <= 0);
1261 int disp = pos - fixup_pos -
sizeof(int8_t);
1262 CHECK(0 <= disp && disp <= 127);
1263 set_byte_at(fixup_pos, disp);
1264 if (offset_to_next < 0) {
1265 L->link_to(fixup_pos + offset_to_next, Label::kNear);
1274 void Assembler::bind(Label*
L) {
1275 EnsureSpace ensure_space(
this);
1277 bind_to(
L, pc_offset());
1281 void Assembler::call(Label*
L) {
1282 positions_recorder()->WriteRecordedPositions();
1283 EnsureSpace ensure_space(
this);
1284 if (
L->is_bound()) {
1285 const int long_size = 5;
1286 int offs =
L->pos() - pc_offset();
1290 emit(offs - long_size);
1299 void Assembler::call(
byte* entry, RelocInfo::Mode rmode) {
1300 positions_recorder()->WriteRecordedPositions();
1301 EnsureSpace ensure_space(
this);
1302 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1304 if (RelocInfo::IsRuntimeEntry(rmode)) {
1305 emit(
reinterpret_cast<uint32_t>(entry), rmode);
1307 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1312 int Assembler::CallSize(
const Operand& adr) {
1314 return 1 + adr.len_;
1318 void Assembler::call(
const Operand& adr) {
1319 positions_recorder()->WriteRecordedPositions();
1320 EnsureSpace ensure_space(
this);
1322 emit_operand(
edx, adr);
1326 int Assembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode) {
1331 void Assembler::call(Handle<Code> code,
1332 RelocInfo::Mode rmode,
1333 TypeFeedbackId ast_id) {
1334 positions_recorder()->WriteRecordedPositions();
1335 EnsureSpace ensure_space(
this);
1336 DCHECK(RelocInfo::IsCodeTarget(rmode)
1337 || rmode == RelocInfo::CODE_AGE_SEQUENCE);
1339 emit(code, rmode, ast_id);
1343 void Assembler::jmp(Label*
L, Label::Distance distance) {
1344 EnsureSpace ensure_space(
this);
1345 if (
L->is_bound()) {
1346 const int short_size = 2;
1347 const int long_size = 5;
1348 int offs =
L->pos() - pc_offset();
1350 if (is_int8(offs - short_size)) {
1353 EMIT((offs - short_size) & 0xFF);
1357 emit(offs - long_size);
1359 }
else if (distance == Label::kNear) {
1365 emit_disp(
L, Displacement::UNCONDITIONAL_JUMP);
1370 void Assembler::jmp(
byte* entry, RelocInfo::Mode rmode) {
1371 EnsureSpace ensure_space(
this);
1372 DCHECK(!RelocInfo::IsCodeTarget(rmode));
1374 if (RelocInfo::IsRuntimeEntry(rmode)) {
1375 emit(
reinterpret_cast<uint32_t>(entry), rmode);
1377 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1382 void Assembler::jmp(
const Operand& adr) {
1383 EnsureSpace ensure_space(
this);
1385 emit_operand(
esp, adr);
1389 void Assembler::jmp(Handle<Code> code, RelocInfo::Mode rmode) {
1390 EnsureSpace ensure_space(
this);
1391 DCHECK(RelocInfo::IsCodeTarget(rmode));
1397 void Assembler::j(
Condition cc, Label*
L, Label::Distance distance) {
1398 EnsureSpace ensure_space(
this);
1399 DCHECK(0 <=
cc &&
static_cast<int>(
cc) < 16);
1400 if (
L->is_bound()) {
1401 const int short_size = 2;
1402 const int long_size = 6;
1403 int offs =
L->pos() - pc_offset();
1405 if (is_int8(offs - short_size)) {
1408 EMIT((offs - short_size) & 0xFF);
1413 emit(offs - long_size);
1415 }
else if (distance == Label::kNear) {
1429 void Assembler::j(
Condition cc,
byte* entry, RelocInfo::Mode rmode) {
1430 EnsureSpace ensure_space(
this);
1431 DCHECK((0 <=
cc) && (
static_cast<int>(
cc) < 16));
1435 if (RelocInfo::IsRuntimeEntry(rmode)) {
1436 emit(
reinterpret_cast<uint32_t>(entry), rmode);
1438 emit(entry - (pc_ +
sizeof(
int32_t)), rmode);
1443 void Assembler::j(
Condition cc, Handle<Code> code) {
1444 EnsureSpace ensure_space(
this);
1448 emit(code, RelocInfo::CODE_TARGET);
1454 void Assembler::fld(
int i) {
1455 EnsureSpace ensure_space(
this);
1456 emit_farith(0xD9, 0xC0,
i);
1460 void Assembler::fstp(
int i) {
1461 EnsureSpace ensure_space(
this);
1462 emit_farith(0xDD, 0xD8,
i);
1466 void Assembler::fld1() {
1467 EnsureSpace ensure_space(
this);
1473 void Assembler::fldpi() {
1474 EnsureSpace ensure_space(
this);
1480 void Assembler::fldz() {
1481 EnsureSpace ensure_space(
this);
1487 void Assembler::fldln2() {
1488 EnsureSpace ensure_space(
this);
1494 void Assembler::fld_s(
const Operand& adr) {
1495 EnsureSpace ensure_space(
this);
1497 emit_operand(
eax, adr);
1501 void Assembler::fld_d(
const Operand& adr) {
1502 EnsureSpace ensure_space(
this);
1504 emit_operand(
eax, adr);
1508 void Assembler::fstp_s(
const Operand& adr) {
1509 EnsureSpace ensure_space(
this);
1511 emit_operand(
ebx, adr);
1515 void Assembler::fst_s(
const Operand& adr) {
1516 EnsureSpace ensure_space(
this);
1518 emit_operand(
edx, adr);
1522 void Assembler::fldcw(
const Operand& adr) {
1523 EnsureSpace ensure_space(
this);
1525 emit_operand(
ebp, adr);
1529 void Assembler::fnstcw(
const Operand& adr) {
1530 EnsureSpace ensure_space(
this);
1532 emit_operand(
edi, adr);
1536 void Assembler::fstp_d(
const Operand& adr) {
1537 EnsureSpace ensure_space(
this);
1539 emit_operand(
ebx, adr);
1543 void Assembler::fst_d(
const Operand& adr) {
1544 EnsureSpace ensure_space(
this);
1546 emit_operand(
edx, adr);
1550 void Assembler::fild_s(
const Operand& adr) {
1551 EnsureSpace ensure_space(
this);
1553 emit_operand(
eax, adr);
1557 void Assembler::fild_d(
const Operand& adr) {
1558 EnsureSpace ensure_space(
this);
1560 emit_operand(
ebp, adr);
1564 void Assembler::fistp_s(
const Operand& adr) {
1565 EnsureSpace ensure_space(
this);
1567 emit_operand(
ebx, adr);
1571 void Assembler::fisttp_s(
const Operand& adr) {
1573 EnsureSpace ensure_space(
this);
1575 emit_operand(
ecx, adr);
1579 void Assembler::fisttp_d(
const Operand& adr) {
1581 EnsureSpace ensure_space(
this);
1583 emit_operand(
ecx, adr);
1587 void Assembler::fist_s(
const Operand& adr) {
1588 EnsureSpace ensure_space(
this);
1590 emit_operand(
edx, adr);
1594 void Assembler::fistp_d(
const Operand& adr) {
1595 EnsureSpace ensure_space(
this);
1597 emit_operand(
edi, adr);
1601 void Assembler::fabs() {
1602 EnsureSpace ensure_space(
this);
1608 void Assembler::fchs() {
1609 EnsureSpace ensure_space(
this);
1615 void Assembler::fsqrt() {
1616 EnsureSpace ensure_space(
this);
1622 void Assembler::fcos() {
1623 EnsureSpace ensure_space(
this);
1629 void Assembler::fsin() {
1630 EnsureSpace ensure_space(
this);
1636 void Assembler::fptan() {
1637 EnsureSpace ensure_space(
this);
1643 void Assembler::fyl2x() {
1644 EnsureSpace ensure_space(
this);
1650 void Assembler::f2xm1() {
1651 EnsureSpace ensure_space(
this);
1657 void Assembler::fscale() {
1658 EnsureSpace ensure_space(
this);
1664 void Assembler::fninit() {
1665 EnsureSpace ensure_space(
this);
1671 void Assembler::fadd(
int i) {
1672 EnsureSpace ensure_space(
this);
1673 emit_farith(0xDC, 0xC0,
i);
1677 void Assembler::fadd_i(
int i) {
1678 EnsureSpace ensure_space(
this);
1679 emit_farith(0xD8, 0xC0,
i);
1683 void Assembler::fadd_d(
const Operand& adr) {
1684 EnsureSpace ensure_space(
this);
1686 emit_operand(
eax, adr);
1690 void Assembler::fsub(
int i) {
1691 EnsureSpace ensure_space(
this);
1692 emit_farith(0xDC, 0xE8,
i);
1696 void Assembler::fsub_i(
int i) {
1697 EnsureSpace ensure_space(
this);
1698 emit_farith(0xD8, 0xE0,
i);
1702 void Assembler::fisub_s(
const Operand& adr) {
1703 EnsureSpace ensure_space(
this);
1705 emit_operand(
esp, adr);
1709 void Assembler::fmul_i(
int i) {
1710 EnsureSpace ensure_space(
this);
1711 emit_farith(0xD8, 0xC8,
i);
1715 void Assembler::fmul(
int i) {
1716 EnsureSpace ensure_space(
this);
1717 emit_farith(0xDC, 0xC8,
i);
1721 void Assembler::fdiv(
int i) {
1722 EnsureSpace ensure_space(
this);
1723 emit_farith(0xDC, 0xF8,
i);
1727 void Assembler::fdiv_i(
int i) {
1728 EnsureSpace ensure_space(
this);
1729 emit_farith(0xD8, 0xF0,
i);
1733 void Assembler::faddp(
int i) {
1734 EnsureSpace ensure_space(
this);
1735 emit_farith(0xDE, 0xC0,
i);
1739 void Assembler::fsubp(
int i) {
1740 EnsureSpace ensure_space(
this);
1741 emit_farith(0xDE, 0xE8,
i);
1745 void Assembler::fsubrp(
int i) {
1746 EnsureSpace ensure_space(
this);
1747 emit_farith(0xDE, 0xE0,
i);
1751 void Assembler::fmulp(
int i) {
1752 EnsureSpace ensure_space(
this);
1753 emit_farith(0xDE, 0xC8,
i);
1757 void Assembler::fdivp(
int i) {
1758 EnsureSpace ensure_space(
this);
1759 emit_farith(0xDE, 0xF8,
i);
1763 void Assembler::fprem() {
1764 EnsureSpace ensure_space(
this);
1770 void Assembler::fprem1() {
1771 EnsureSpace ensure_space(
this);
1777 void Assembler::fxch(
int i) {
1778 EnsureSpace ensure_space(
this);
1779 emit_farith(0xD9, 0xC8,
i);
1783 void Assembler::fincstp() {
1784 EnsureSpace ensure_space(
this);
1790 void Assembler::ffree(
int i) {
1791 EnsureSpace ensure_space(
this);
1792 emit_farith(0xDD, 0xC0,
i);
1796 void Assembler::ftst() {
1797 EnsureSpace ensure_space(
this);
1803 void Assembler::fxam() {
1804 EnsureSpace ensure_space(
this);
1810 void Assembler::fucomp(
int i) {
1811 EnsureSpace ensure_space(
this);
1812 emit_farith(0xDD, 0xE8,
i);
1816 void Assembler::fucompp() {
1817 EnsureSpace ensure_space(
this);
1823 void Assembler::fucomi(
int i) {
1824 EnsureSpace ensure_space(
this);
1830 void Assembler::fucomip() {
1831 EnsureSpace ensure_space(
this);
1837 void Assembler::fcompp() {
1838 EnsureSpace ensure_space(
this);
1844 void Assembler::fnstsw_ax() {
1845 EnsureSpace ensure_space(
this);
1851 void Assembler::fwait() {
1852 EnsureSpace ensure_space(
this);
1857 void Assembler::frndint() {
1858 EnsureSpace ensure_space(
this);
1864 void Assembler::fnclex() {
1865 EnsureSpace ensure_space(
this);
1871 void Assembler::fnsave(
const Operand& adr) {
1872 EnsureSpace ensure_space(
this);
1874 emit_operand(
esi, adr);
1878 void Assembler::frstor(
const Operand& adr) {
1879 EnsureSpace ensure_space(
this);
1881 emit_operand(
esp, adr);
1885 void Assembler::sahf() {
1886 EnsureSpace ensure_space(
this);
1891 void Assembler::setcc(
Condition cc, Register reg) {
1892 DCHECK(reg.is_byte_register());
1893 EnsureSpace ensure_space(
this);
1896 EMIT(0xC0 | reg.code());
1900 void Assembler::RecordJSReturn() {
1901 positions_recorder()->WriteRecordedPositions();
1902 EnsureSpace ensure_space(
this);
1903 RecordRelocInfo(RelocInfo::JS_RETURN);
1907 void Assembler::RecordDebugBreakSlot() {
1908 positions_recorder()->WriteRecordedPositions();
1909 EnsureSpace ensure_space(
this);
1910 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
1914 void Assembler::RecordComment(
const char* msg,
bool force) {
1915 if (FLAG_code_comments || force) {
1916 EnsureSpace ensure_space(
this);
1917 RecordRelocInfo(RelocInfo::COMMENT,
reinterpret_cast<intptr_t
>(msg));
1922 void Assembler::GrowBuffer() {
1923 DCHECK(buffer_overflow());
1924 if (!own_buffer_)
FATAL(
"external code buffer is too small");
1928 desc.buffer_size = 2 * buffer_size_;
1932 if ((desc.buffer_size > kMaximalBufferSize) ||
1933 (desc.buffer_size > isolate()->heap()->MaxOldGenerationSize())) {
1938 desc.buffer = NewArray<byte>(desc.buffer_size);
1939 desc.instr_size = pc_offset();
1940 desc.reloc_size = (buffer_ + buffer_size_) - (reloc_info_writer.pos());
1945 memset(desc.buffer, 0xCC, desc.buffer_size);
1949 int pc_delta = desc.buffer - buffer_;
1950 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
1951 MemMove(desc.buffer, buffer_, desc.instr_size);
1952 MemMove(rc_delta + reloc_info_writer.pos(), reloc_info_writer.pos(),
1956 buffer_ = desc.buffer;
1957 buffer_size_ = desc.buffer_size;
1959 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
1960 reloc_info_writer.last_pc() + pc_delta);
1963 for (RelocIterator it(desc); !it.done(); it.next()) {
1964 RelocInfo::Mode rmode = it.rinfo()->rmode();
1965 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
1973 DCHECK(!buffer_overflow());
1977 void Assembler::emit_arith_b(
int op1,
int op2, Register dst,
int imm8) {
1978 DCHECK(is_uint8(op1) && is_uint8(op2));
1980 DCHECK((op1 & 0x01) == 0);
1982 EMIT(op2 | dst.code());
1987 void Assembler::emit_arith(
int sel, Operand dst,
const Immediate& x) {
1988 DCHECK((0 <= sel) && (sel <= 7));
1989 Register ireg = { sel };
1992 emit_operand(ireg, dst);
1994 }
else if (dst.is_reg(
eax)) {
1995 EMIT((sel << 3) | 0x05);
1999 emit_operand(ireg, dst);
2005 void Assembler::emit_operand(Register reg,
const Operand& adr) {
2006 const unsigned length = adr.len_;
2010 pc_[0] = (adr.buf_[0] & ~0x38) | (reg.code() << 3);
2013 for (
unsigned i = 1;
i < length;
i++) pc_[
i] = adr.buf_[
i];
2017 if (length >=
sizeof(
int32_t) && !RelocInfo::IsNone(adr.rmode_)) {
2019 RecordRelocInfo(adr.rmode_);
2025 void Assembler::emit_farith(
int b1,
int b2,
int i) {
2026 DCHECK(is_uint8(b1) && is_uint8(b2));
2034 EnsureSpace ensure_space(
this);
2039 void Assembler::dd(
uint32_t data) {
2040 EnsureSpace ensure_space(
this);
2045 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2046 DCHECK(!RelocInfo::IsNone(rmode));
2048 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2049 !serializer_enabled() && !emit_debug_code()) {
2052 RelocInfo rinfo(pc_, rmode, data,
NULL);
2053 reloc_info_writer.Write(&rinfo);
2057 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2059 DCHECK(!FLAG_enable_ool_constant_pool);
2060 return isolate->factory()->empty_constant_pool_array();
2064 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2066 DCHECK(!FLAG_enable_ool_constant_pool);
2071 #ifdef GENERATED_CODE_COVERAGE
2072 static FILE* coverage_log =
NULL;
2075 static void InitCoverageLog() {
2076 char* file_name = getenv(
"V8_GENERATED_CODE_COVERAGE_LOG");
2077 if (file_name !=
NULL) {
2078 coverage_log = fopen(file_name,
"aw+");
2083 void LogGeneratedCodeCoverage(
const char* file_line) {
2084 const char* return_address = (&file_line)[-1];
2085 char* push_insn =
const_cast<char*
>(return_address - 12);
2086 push_insn[0] = 0xeb;
2088 if (coverage_log !=
NULL) {
2089 fprintf(coverage_log,
"%s\n", file_line);
2090 fflush(coverage_log);
static const int kMaximalBufferSize
Assembler(Isolate *isolate, void *buffer, int buffer_size)
static void FlushICache(void *start, size_t size)
static void PrintFeatures()
static void PrintTarget()
static void ProbeImpl(bool cross_compile)
Operand(Register reg, Shift shift=LSL, unsigned shift_amount=0)
static const int kCodeTargetMask
static const int kApplyMask
static bool IsNone(Mode mode)
void PatchCode(byte *instructions, int instruction_count)
void PatchCodeWithCall(Address target, int guard_bytes)
enable harmony numeric enable harmony object literal extensions Optimize object size
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
bool IsPowerOfTwo32(uint32_t value)
void DeleteArray(T *array)
TypeImpl< ZoneTypeConfig > Type
void MemMove(void *dest, const void *src, size_t size)
Handle< T > handle(T *t, Isolate *isolate)
void PrintF(const char *format,...)
OStream & dec(OStream &os)
void FatalProcessOutOfMemory(const char *message)
Debugger support for the V8 JavaScript engine.
static const uint16_t * Align(const uint16_t *chars)
static Register from_code(int code)