38 #if V8_TARGET_ARCH_MIPS
52 static unsigned CpuFeaturesImpliedByCompiler() {
54 #ifdef CAN_USE_FPU_INSTRUCTIONS
61 #if defined(__mips__) && defined(__mips_hard_float) && __mips_hard_float != 0
71 const char*
const names[] = {
95 if (cross_compile)
return;
102 #if defined(_MIPS_ARCH_MIPS32R6)
106 #if defined(FPU_MODE_FP64)
113 #if defined(FPU_MODE_FPXX)
115 #elif defined(FPU_MODE_FP64)
118 #if defined(_MIPS_ARCH_MIPS32RX)
119 if (cpu.architecture() == 6) {
121 }
else if (cpu.architecture() == 2) {
138 const int kNumbers[] = {
172 return kNumbers[reg.code()];
178 const Register kRegisters[] = {
183 t0, t1, t2, t3, t4, t5, t6, t7,
192 return kRegisters[num];
219 Instr* instr =
reinterpret_cast<Instr*
>(instructions);
220 for (
int i = 0;
i < instruction_count;
i++) {
221 *(
pc +
i) = *(instr +
i);
246 if (obj->IsHeapObject()) {
247 DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
248 imm32_ =
reinterpret_cast<intptr_t
>(
handle.location());
252 imm32_ =
reinterpret_cast<intptr_t
>(obj);
264 OffsetAddend offset_addend) : Operand(rm) {
265 offset_ = unit * multiplier + offset_addend;
272 static const int kNegOffset = 0x00008000;
307 Assembler::Assembler(Isolate* isolate,
void* buffer,
int buffer_size)
308 : AssemblerBase(isolate, buffer, buffer_size),
309 recorded_ast_id_(TypeFeedbackId::
None()),
310 positions_recorder_(this) {
311 reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
313 last_trampoline_pool_end_ = 0;
314 no_trampoline_pool_before_ = 0;
315 trampoline_pool_blocked_nesting_ = 0;
318 next_buffer_check_ = FLAG_force_long_branches
319 ?
kMaxInt : kMaxBranchOffset - kTrampolineSlotsSize * 16;
320 internal_trampoline_exception_ =
false;
323 trampoline_emitted_ = FLAG_force_long_branches;
324 unbound_labels_count_ = 0;
325 block_buffer_growth_ =
false;
327 ClearRecordedAstId();
331 void Assembler::GetCode(CodeDesc* desc) {
332 DCHECK(pc_ <= reloc_info_writer.pos());
334 desc->buffer = buffer_;
335 desc->buffer_size = buffer_size_;
336 desc->instr_size = pc_offset();
337 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
344 while ((pc_offset() & (m - 1)) != 0) {
350 void Assembler::CodeTargetAlign() {
357 Register Assembler::GetRtReg(
Instr instr) {
364 Register Assembler::GetRsReg(
Instr instr) {
371 Register Assembler::GetRdReg(
Instr instr) {
443 bool Assembler::IsPop(
Instr instr) {
448 bool Assembler::IsPush(
Instr instr) {
453 bool Assembler::IsSwRegFpOffset(
Instr instr) {
458 bool Assembler::IsLwRegFpOffset(
Instr instr) {
463 bool Assembler::IsSwRegFpNegOffset(
Instr instr) {
469 bool Assembler::IsLwRegFpNegOffset(
Instr instr) {
490 const int kEndOfChain = -4;
492 const int kEndOfJumpChain = 0;
496 uint32_t opcode = GetOpcodeField(instr);
497 uint32_t rt_field = GetRtField(instr);
498 uint32_t rs_field = GetRsField(instr);
500 return opcode ==
BEQ ||
510 (opcode ==
COP1 && rs_field ==
BC1) ||
516 bool Assembler::IsEmittedConstant(
Instr instr) {
517 uint32_t label_constant = GetLabelConst(instr);
518 return label_constant == 0;
522 bool Assembler::IsBeq(
Instr instr) {
523 return GetOpcodeField(instr) ==
BEQ;
527 bool Assembler::IsBne(
Instr instr) {
528 return GetOpcodeField(instr) ==
BNE;
532 bool Assembler::IsJump(
Instr instr) {
533 uint32_t opcode = GetOpcodeField(instr);
534 uint32_t rt_field = GetRtField(instr);
535 uint32_t rd_field = GetRdField(instr);
536 uint32_t function_field = GetFunctionField(instr);
538 return opcode ==
J || opcode ==
JAL ||
539 (opcode ==
SPECIAL && rt_field == 0 &&
540 ((function_field ==
JALR) || (rd_field == 0 && (function_field ==
JR))));
544 bool Assembler::IsJ(
Instr instr) {
545 uint32_t opcode = GetOpcodeField(instr);
551 bool Assembler::IsJal(
Instr instr) {
552 return GetOpcodeField(instr) ==
JAL;
556 bool Assembler::IsJr(
Instr instr) {
558 return GetOpcodeField(instr) ==
SPECIAL && GetFunctionField(instr) ==
JR;
560 return GetOpcodeField(instr) ==
SPECIAL &&
561 GetRdField(instr) == 0 && GetFunctionField(instr) ==
JALR;
566 bool Assembler::IsJalr(
Instr instr) {
567 return GetOpcodeField(instr) ==
SPECIAL &&
568 GetRdField(instr) != 0 && GetFunctionField(instr) ==
JALR;
572 bool Assembler::IsLui(
Instr instr) {
573 uint32_t opcode = GetOpcodeField(instr);
575 return opcode ==
LUI;
579 bool Assembler::IsOri(
Instr instr) {
580 uint32_t opcode = GetOpcodeField(instr);
582 return opcode ==
ORI;
586 bool Assembler::IsNop(
Instr instr,
unsigned int type) {
589 uint32_t opcode = GetOpcodeField(instr);
590 uint32_t function = GetFunctionField(instr);
600 Register nop_rt_reg = (type == 0) ? zero_reg : at;
601 bool ret = (opcode ==
SPECIAL &&
function ==
SLL &&
616 bool Assembler::IsLw(
Instr instr) {
638 bool Assembler::IsSw(
Instr instr) {
649 bool Assembler::IsAddImmediate(
Instr instr) {
655 DCHECK(IsAddImmediate(instr));
660 bool Assembler::IsAndImmediate(
Instr instr) {
661 return GetOpcodeField(instr) ==
ANDI;
665 int Assembler::target_at(
int32_t pos) {
666 Instr instr = instr_at(pos);
673 return (imm18 + pos);
683 if (imm18 == kEndOfChain) {
687 return pos + kBranchPCOffset + imm18;
689 }
else if (IsLui(instr)) {
690 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
691 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
696 if (imm == kEndOfJumpChain) {
701 int32_t delta = instr_address - imm;
707 if (imm28 == kEndOfJumpChain) {
713 int32_t delta = instr_address - imm28;
722 Instr instr = instr_at(pos);
724 DCHECK(target_pos == kEndOfChain || target_pos >= 0);
727 instr_at_put(pos, target_pos + (Code::kHeaderSize -
kHeapObjectTag));
733 int32_t imm18 = target_pos - (pos + kBranchPCOffset);
740 instr_at_put(pos, instr | (imm16 &
kImm16Mask));
741 }
else if (IsLui(instr)) {
742 Instr instr_lui = instr_at(pos + 0 * Assembler::kInstrSize);
743 Instr instr_ori = instr_at(pos + 1 * Assembler::kInstrSize);
751 instr_at_put(pos + 0 * Assembler::kInstrSize,
753 instr_at_put(pos + 1 * Assembler::kInstrSize,
764 instr_at_put(pos, instr | (imm26 &
kImm26Mask));
769 void Assembler::print(Label*
L) {
770 if (
L->is_unused()) {
772 }
else if (
L->is_bound()) {
773 PrintF(
"bound label to %d\n",
L->pos());
774 }
else if (
L->is_linked()) {
777 while (l.is_linked()) {
779 Instr instr = instr_at(l.pos());
788 PrintF(
"label in inconsistent state (pos = %d)\n",
L->pos_);
793 void Assembler::bind_to(Label*
L,
int pos) {
794 DCHECK(0 <= pos && pos <= pc_offset());
795 int32_t trampoline_pos = kInvalidSlotPos;
796 if (
L->is_linked() && !trampoline_emitted_) {
797 unbound_labels_count_--;
798 next_buffer_check_ += kTrampolineSlotsSize;
801 while (
L->is_linked()) {
803 int32_t dist = pos - fixup_pos;
805 Instr instr = instr_at(fixup_pos);
807 if (dist > kMaxBranchOffset) {
808 if (trampoline_pos == kInvalidSlotPos) {
809 trampoline_pos = get_trampoline_entry(fixup_pos);
810 CHECK(trampoline_pos != kInvalidSlotPos);
812 DCHECK((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
813 target_at_put(fixup_pos, trampoline_pos);
814 fixup_pos = trampoline_pos;
815 dist = pos - fixup_pos;
817 target_at_put(fixup_pos, pos);
819 DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
820 target_at_put(fixup_pos, pos);
827 if (pos > last_bound_pos_)
828 last_bound_pos_ = pos;
832 void Assembler::bind(Label*
L) {
834 bind_to(
L, pc_offset());
838 void Assembler::next(Label*
L) {
840 int link = target_at(
L->pos());
841 if (link == kEndOfChain) {
850 bool Assembler::is_near(Label*
L) {
852 return ((pc_offset() -
L->pos()) < kMaxBranchOffset - 4 * kInstrSize);
862 bool Assembler::MustUseReg(RelocInfo::Mode rmode) {
863 return !RelocInfo::IsNone(rmode);
866 void Assembler::GenInstrRegister(
Opcode opcode,
872 DCHECK(rd.is_valid() && rs.is_valid() && rt.is_valid() && is_uint5(sa));
879 void Assembler::GenInstrRegister(
Opcode opcode,
885 DCHECK(rs.is_valid() && rt.is_valid() && is_uint5(msb) && is_uint5(lsb));
892 void Assembler::GenInstrRegister(
Opcode opcode,
898 DCHECK(fd.is_valid() && fs.is_valid() && ft.is_valid());
905 void Assembler::GenInstrRegister(
Opcode opcode,
911 DCHECK(fd.is_valid() && fr.is_valid() && fs.is_valid() && ft.is_valid());
918 void Assembler::GenInstrRegister(
Opcode opcode,
924 DCHECK(fd.is_valid() && fs.is_valid() && rt.is_valid());
931 void Assembler::GenInstrRegister(
Opcode opcode,
934 FPUControlRegister fs,
936 DCHECK(fs.is_valid() && rt.is_valid());
945 void Assembler::GenInstrImmediate(
Opcode opcode,
949 DCHECK(rs.is_valid() && rt.is_valid() && (is_int16(j) || is_uint16(j)));
956 void Assembler::GenInstrImmediate(
Opcode opcode,
960 DCHECK(rs.is_valid() && (is_int16(j) || is_uint16(j)));
966 void Assembler::GenInstrImmediate(
Opcode opcode,
970 DCHECK(rs.is_valid() && ft.is_valid() && (is_int16(j) || is_uint16(j)));
977 void Assembler::GenInstrJump(
Opcode opcode,
979 BlockTrampolinePoolScope block_trampoline_pool(
this);
980 DCHECK(is_uint26(address));
981 Instr instr = opcode | address;
983 BlockTrampolinePoolFor(1);
989 int32_t trampoline_entry = kInvalidSlotPos;
991 if (!internal_trampoline_exception_) {
992 if (trampoline_.start() > pos) {
993 trampoline_entry = trampoline_.take_slot();
996 if (kInvalidSlotPos == trampoline_entry) {
997 internal_trampoline_exception_ =
true;
1000 return trampoline_entry;
1004 uint32_t Assembler::jump_address(Label*
L) {
1007 if (
L->is_bound()) {
1008 target_pos =
L->pos();
1010 if (
L->is_linked()) {
1011 target_pos =
L->pos();
1012 L->link_to(pc_offset());
1014 L->link_to(pc_offset());
1015 return kEndOfJumpChain;
1026 int32_t Assembler::branch_offset(Label*
L,
bool jump_elimination_allowed) {
1029 if (
L->is_bound()) {
1030 target_pos =
L->pos();
1032 if (
L->is_linked()) {
1033 target_pos =
L->pos();
1034 L->link_to(pc_offset());
1036 L->link_to(pc_offset());
1037 if (!trampoline_emitted_) {
1038 unbound_labels_count_++;
1039 next_buffer_check_ -= kTrampolineSlotsSize;
1045 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1046 DCHECK((offset & 3) == 0);
1047 DCHECK(is_int16(offset >> 2));
1053 int32_t Assembler::branch_offset_compact(Label*
L,
1054 bool jump_elimination_allowed) {
1056 if (
L->is_bound()) {
1057 target_pos =
L->pos();
1059 if (
L->is_linked()) {
1060 target_pos =
L->pos();
1061 L->link_to(pc_offset());
1063 L->link_to(pc_offset());
1064 if (!trampoline_emitted_) {
1065 unbound_labels_count_++;
1066 next_buffer_check_ -= kTrampolineSlotsSize;
1072 int32_t offset = target_pos - pc_offset();
1073 DCHECK((offset & 3) == 0);
1074 DCHECK(is_int16(offset >> 2));
1080 int32_t Assembler::branch_offset21(Label*
L,
bool jump_elimination_allowed) {
1083 if (
L->is_bound()) {
1084 target_pos =
L->pos();
1086 if (
L->is_linked()) {
1087 target_pos =
L->pos();
1088 L->link_to(pc_offset());
1090 L->link_to(pc_offset());
1091 if (!trampoline_emitted_) {
1092 unbound_labels_count_++;
1093 next_buffer_check_ -= kTrampolineSlotsSize;
1099 int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
1100 DCHECK((offset & 3) == 0);
1101 DCHECK(((offset >> 2) & 0xFFE00000) == 0);
1107 int32_t Assembler::branch_offset21_compact(Label*
L,
1108 bool jump_elimination_allowed) {
1111 if (
L->is_bound()) {
1112 target_pos =
L->pos();
1114 if (
L->is_linked()) {
1115 target_pos =
L->pos();
1116 L->link_to(pc_offset());
1118 L->link_to(pc_offset());
1119 if (!trampoline_emitted_) {
1120 unbound_labels_count_++;
1121 next_buffer_check_ -= kTrampolineSlotsSize;
1127 int32_t offset = target_pos - pc_offset();
1128 DCHECK((offset & 3) == 0);
1129 DCHECK(((offset >> 2) & 0xFFe00000) == 0);
1135 void Assembler::label_at_put(Label*
L,
int at_offset) {
1137 if (
L->is_bound()) {
1138 target_pos =
L->pos();
1139 instr_at_put(at_offset, target_pos + (Code::kHeaderSize -
kHeapObjectTag));
1141 if (
L->is_linked()) {
1142 target_pos =
L->pos();
1143 int32_t imm18 = target_pos - at_offset;
1144 DCHECK((imm18 & 3) == 0);
1147 instr_at_put(at_offset, (imm16 &
kImm16Mask));
1149 target_pos = kEndOfChain;
1150 instr_at_put(at_offset, 0);
1151 if (!trampoline_emitted_) {
1152 unbound_labels_count_++;
1153 next_buffer_check_ -= kTrampolineSlotsSize;
1156 L->link_to(at_offset);
1163 void Assembler::b(
int16_t offset) {
1164 beq(zero_reg, zero_reg, offset);
1168 void Assembler::bal(
int16_t offset) {
1169 positions_recorder()->WriteRecordedPositions();
1170 bgezal(zero_reg, offset);
1174 void Assembler::beq(Register rs, Register rt,
int16_t offset) {
1175 BlockTrampolinePoolScope block_trampoline_pool(
this);
1176 GenInstrImmediate(
BEQ, rs, rt, offset);
1177 BlockTrampolinePoolFor(1);
1181 void Assembler::bgez(Register rs,
int16_t offset) {
1182 BlockTrampolinePoolScope block_trampoline_pool(
this);
1184 BlockTrampolinePoolFor(1);
1188 void Assembler::bgezc(Register rt,
int16_t offset) {
1190 DCHECK(!(rt.is(zero_reg)));
1191 GenInstrImmediate(
BLEZL, rt, rt, offset);
1195 void Assembler::bgeuc(Register rs, Register rt,
int16_t offset) {
1197 DCHECK(!(rs.is(zero_reg)));
1198 DCHECK(!(rt.is(zero_reg)));
1199 DCHECK(rs.code() != rt.code());
1200 GenInstrImmediate(
BLEZ, rs, rt, offset);
1204 void Assembler::bgec(Register rs, Register rt,
int16_t offset) {
1206 DCHECK(!(rs.is(zero_reg)));
1207 DCHECK(!(rt.is(zero_reg)));
1208 DCHECK(rs.code() != rt.code());
1209 GenInstrImmediate(
BLEZL, rs, rt, offset);
1213 void Assembler::bgezal(Register rs,
int16_t offset) {
1215 BlockTrampolinePoolScope block_trampoline_pool(
this);
1216 positions_recorder()->WriteRecordedPositions();
1218 BlockTrampolinePoolFor(1);
1222 void Assembler::bgtz(Register rs,
int16_t offset) {
1223 BlockTrampolinePoolScope block_trampoline_pool(
this);
1224 GenInstrImmediate(
BGTZ, rs, zero_reg, offset);
1225 BlockTrampolinePoolFor(1);
1229 void Assembler::bgtzc(Register rt,
int16_t offset) {
1231 DCHECK(!(rt.is(zero_reg)));
1232 GenInstrImmediate(
BGTZL, zero_reg, rt, offset);
1236 void Assembler::blez(Register rs,
int16_t offset) {
1237 BlockTrampolinePoolScope block_trampoline_pool(
this);
1238 GenInstrImmediate(
BLEZ, rs, zero_reg, offset);
1239 BlockTrampolinePoolFor(1);
1243 void Assembler::blezc(Register rt,
int16_t offset) {
1245 DCHECK(!(rt.is(zero_reg)));
1246 GenInstrImmediate(
BLEZL, zero_reg, rt, offset);
1250 void Assembler::bltzc(Register rt,
int16_t offset) {
1252 DCHECK(!(rt.is(zero_reg)));
1253 GenInstrImmediate(
BGTZL, rt, rt, offset);
1257 void Assembler::bltuc(Register rs, Register rt,
int16_t offset) {
1259 DCHECK(!(rs.is(zero_reg)));
1260 DCHECK(!(rt.is(zero_reg)));
1261 DCHECK(rs.code() != rt.code());
1262 GenInstrImmediate(
BGTZ, rs, rt, offset);
1266 void Assembler::bltc(Register rs, Register rt,
int16_t offset) {
1268 DCHECK(!(rs.is(zero_reg)));
1269 DCHECK(!(rt.is(zero_reg)));
1270 DCHECK(rs.code() != rt.code());
1271 GenInstrImmediate(
BGTZL, rs, rt, offset);
1275 void Assembler::bltz(Register rs,
int16_t offset) {
1276 BlockTrampolinePoolScope block_trampoline_pool(
this);
1278 BlockTrampolinePoolFor(1);
1282 void Assembler::bltzal(Register rs,
int16_t offset) {
1284 BlockTrampolinePoolScope block_trampoline_pool(
this);
1285 positions_recorder()->WriteRecordedPositions();
1287 BlockTrampolinePoolFor(1);
1291 void Assembler::bne(Register rs, Register rt,
int16_t offset) {
1292 BlockTrampolinePoolScope block_trampoline_pool(
this);
1293 GenInstrImmediate(
BNE, rs, rt, offset);
1294 BlockTrampolinePoolFor(1);
1298 void Assembler::bovc(Register rs, Register rt,
int16_t offset) {
1300 DCHECK(!(rs.is(zero_reg)));
1301 DCHECK(rs.code() >= rt.code());
1302 GenInstrImmediate(
ADDI, rs, rt, offset);
1306 void Assembler::bnvc(Register rs, Register rt,
int16_t offset) {
1308 DCHECK(!(rs.is(zero_reg)));
1309 DCHECK(rs.code() >= rt.code());
1310 GenInstrImmediate(
DADDI, rs, rt, offset);
1314 void Assembler::blezalc(Register rt,
int16_t offset) {
1316 DCHECK(!(rt.is(zero_reg)));
1317 GenInstrImmediate(
BLEZ, zero_reg, rt, offset);
1321 void Assembler::bgezalc(Register rt,
int16_t offset) {
1323 DCHECK(!(rt.is(zero_reg)));
1324 GenInstrImmediate(
BLEZ, rt, rt, offset);
1328 void Assembler::bgezall(Register rs,
int16_t offset) {
1330 DCHECK(!(rs.is(zero_reg)));
1335 void Assembler::bltzalc(Register rt,
int16_t offset) {
1337 DCHECK(!(rt.is(zero_reg)));
1338 GenInstrImmediate(
BGTZ, rt, rt, offset);
1342 void Assembler::bgtzalc(Register rt,
int16_t offset) {
1344 DCHECK(!(rt.is(zero_reg)));
1345 GenInstrImmediate(
BGTZ, zero_reg, rt, offset);
1349 void Assembler::beqzalc(Register rt,
int16_t offset) {
1351 DCHECK(!(rt.is(zero_reg)));
1352 GenInstrImmediate(
ADDI, zero_reg, rt, offset);
1356 void Assembler::bnezalc(Register rt,
int16_t offset) {
1358 DCHECK(!(rt.is(zero_reg)));
1359 GenInstrImmediate(
DADDI, zero_reg, rt, offset);
1363 void Assembler::beqc(Register rs, Register rt,
int16_t offset) {
1365 DCHECK(rs.code() < rt.code());
1366 GenInstrImmediate(
ADDI, rs, rt, offset);
1370 void Assembler::beqzc(Register rs,
int32_t offset) {
1372 DCHECK(!(rs.is(zero_reg)));
1378 void Assembler::bnec(Register rs, Register rt,
int16_t offset) {
1380 DCHECK(rs.code() < rt.code());
1381 GenInstrImmediate(
DADDI, rs, rt, offset);
1385 void Assembler::bnezc(Register rs,
int32_t offset) {
1387 DCHECK(!(rs.is(zero_reg)));
1393 void Assembler::j(
int32_t target) {
1397 bool in_range = (ipc ^
static_cast<uint32_t>(target) >>
1399 DCHECK(in_range && ((target & 3) == 0));
1401 GenInstrJump(
J, target >> 2);
1405 void Assembler::jr(Register rs) {
1407 BlockTrampolinePoolScope block_trampoline_pool(
this);
1409 positions_recorder()->WriteRecordedPositions();
1411 GenInstrRegister(
SPECIAL, rs, zero_reg, zero_reg, 0,
JR);
1412 BlockTrampolinePoolFor(1);
1419 void Assembler::jal(
int32_t target) {
1423 bool in_range = (ipc ^
static_cast<uint32_t>(target) >>
1425 DCHECK(in_range && ((target & 3) == 0));
1427 positions_recorder()->WriteRecordedPositions();
1428 GenInstrJump(
JAL, target >> 2);
1432 void Assembler::jalr(Register rs, Register rd) {
1433 BlockTrampolinePoolScope block_trampoline_pool(
this);
1434 positions_recorder()->WriteRecordedPositions();
1435 GenInstrRegister(
SPECIAL, rs, zero_reg, rd, 0,
JALR);
1436 BlockTrampolinePoolFor(1);
1440 void Assembler::j_or_jr(
int32_t target, Register rs) {
1443 bool in_range = (ipc ^
static_cast<uint32_t>(target) >>
1453 void Assembler::jal_or_jalr(
int32_t target, Register rs) {
1456 bool in_range = (ipc ^
static_cast<uint32_t>(target) >>
1470 void Assembler::addu(Register rd, Register rs, Register rt) {
1475 void Assembler::addiu(Register rd, Register rs,
int32_t j) {
1476 GenInstrImmediate(
ADDIU, rs, rd, j);
1480 void Assembler::subu(Register rd, Register rs, Register rt) {
1485 void Assembler::mul(Register rd, Register rs, Register rt) {
1494 void Assembler::mulu(Register rd, Register rs, Register rt) {
1500 void Assembler::muh(Register rd, Register rs, Register rt) {
1506 void Assembler::muhu(Register rd, Register rs, Register rt) {
1512 void Assembler::mod(Register rd, Register rs, Register rt) {
1518 void Assembler::modu(Register rd, Register rs, Register rt) {
1524 void Assembler::mult(Register rs, Register rt) {
1525 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
MULT);
1529 void Assembler::multu(Register rs, Register rt) {
1534 void Assembler::div(Register rs, Register rt) {
1535 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
DIV);
1539 void Assembler::div(Register rd, Register rs, Register rt) {
1545 void Assembler::divu(Register rs, Register rt) {
1546 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
DIVU);
1550 void Assembler::divu(Register rd, Register rs, Register rt) {
1558 void Assembler::and_(Register rd, Register rs, Register rt) {
1559 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
AND);
1563 void Assembler::andi(Register rt, Register rs,
int32_t j) {
1565 GenInstrImmediate(
ANDI, rs, rt, j);
1569 void Assembler::or_(Register rd, Register rs, Register rt) {
1570 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
OR);
1574 void Assembler::ori(Register rt, Register rs,
int32_t j) {
1576 GenInstrImmediate(
ORI, rs, rt, j);
1580 void Assembler::xor_(Register rd, Register rs, Register rt) {
1581 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
XOR);
1585 void Assembler::xori(Register rt, Register rs,
int32_t j) {
1587 GenInstrImmediate(
XORI, rs, rt, j);
1591 void Assembler::nor(Register rd, Register rs, Register rt) {
1592 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
NOR);
1597 void Assembler::sll(Register rd,
1600 bool coming_from_nop) {
1605 DCHECK(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
1606 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SLL);
1610 void Assembler::sllv(Register rd, Register rt, Register rs) {
1615 void Assembler::srl(Register rd, Register rt,
uint16_t sa) {
1616 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SRL);
1620 void Assembler::srlv(Register rd, Register rt, Register rs) {
1625 void Assembler::sra(Register rd, Register rt,
uint16_t sa) {
1626 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SRA);
1630 void Assembler::srav(Register rd, Register rt, Register rs) {
1635 void Assembler::rotr(Register rd, Register rt,
uint16_t sa) {
1637 DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
1645 void Assembler::rotrv(Register rd, Register rt, Register rs) {
1647 DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1658 void Assembler::LoadRegPlusOffsetToAt(
const MemOperand& src) {
1659 DCHECK(!src.rm().is(at));
1662 addu(at, at, src.rm());
1666 void Assembler::lb(Register rd,
const MemOperand& rs) {
1667 if (is_int16(rs.offset_)) {
1668 GenInstrImmediate(
LB, rs.rm(), rd, rs.offset_);
1670 LoadRegPlusOffsetToAt(rs);
1671 GenInstrImmediate(
LB, at, rd, 0);
1676 void Assembler::lbu(Register rd,
const MemOperand& rs) {
1677 if (is_int16(rs.offset_)) {
1678 GenInstrImmediate(
LBU, rs.rm(), rd, rs.offset_);
1680 LoadRegPlusOffsetToAt(rs);
1681 GenInstrImmediate(
LBU, at, rd, 0);
1686 void Assembler::lh(Register rd,
const MemOperand& rs) {
1687 if (is_int16(rs.offset_)) {
1688 GenInstrImmediate(
LH, rs.rm(), rd, rs.offset_);
1690 LoadRegPlusOffsetToAt(rs);
1691 GenInstrImmediate(
LH, at, rd, 0);
1696 void Assembler::lhu(Register rd,
const MemOperand& rs) {
1697 if (is_int16(rs.offset_)) {
1698 GenInstrImmediate(
LHU, rs.rm(), rd, rs.offset_);
1700 LoadRegPlusOffsetToAt(rs);
1701 GenInstrImmediate(
LHU, at, rd, 0);
1706 void Assembler::lw(Register rd,
const MemOperand& rs) {
1707 if (is_int16(rs.offset_)) {
1708 GenInstrImmediate(
LW, rs.rm(), rd, rs.offset_);
1710 LoadRegPlusOffsetToAt(rs);
1711 GenInstrImmediate(
LW, at, rd, 0);
1716 void Assembler::lwl(Register rd,
const MemOperand& rs) {
1717 GenInstrImmediate(
LWL, rs.rm(), rd, rs.offset_);
1721 void Assembler::lwr(Register rd,
const MemOperand& rs) {
1722 GenInstrImmediate(
LWR, rs.rm(), rd, rs.offset_);
1726 void Assembler::sb(Register rd,
const MemOperand& rs) {
1727 if (is_int16(rs.offset_)) {
1728 GenInstrImmediate(
SB, rs.rm(), rd, rs.offset_);
1730 LoadRegPlusOffsetToAt(rs);
1731 GenInstrImmediate(
SB, at, rd, 0);
1736 void Assembler::sh(Register rd,
const MemOperand& rs) {
1737 if (is_int16(rs.offset_)) {
1738 GenInstrImmediate(
SH, rs.rm(), rd, rs.offset_);
1740 LoadRegPlusOffsetToAt(rs);
1741 GenInstrImmediate(
SH, at, rd, 0);
1746 void Assembler::sw(Register rd,
const MemOperand& rs) {
1747 if (is_int16(rs.offset_)) {
1748 GenInstrImmediate(
SW, rs.rm(), rd, rs.offset_);
1750 LoadRegPlusOffsetToAt(rs);
1751 GenInstrImmediate(
SW, at, rd, 0);
1756 void Assembler::swl(Register rd,
const MemOperand& rs) {
1757 GenInstrImmediate(
SWL, rs.rm(), rd, rs.offset_);
1761 void Assembler::swr(Register rd,
const MemOperand& rs) {
1762 GenInstrImmediate(
SWR, rs.rm(), rd, rs.offset_);
1766 void Assembler::lui(Register rd,
int32_t j) {
1768 GenInstrImmediate(
LUI, zero_reg, rd, j);
1772 void Assembler::aui(Register rs, Register rt,
int32_t j) {
1776 GenInstrImmediate(
LUI, rs, rt, j);
1783 void Assembler::break_(
uint32_t code,
bool break_as_stop) {
1784 DCHECK((code & ~0xfffff) == 0);
1799 void Assembler::stop(
const char* msg,
uint32_t code) {
1802 #if V8_HOST_ARCH_MIPS
1805 BlockTrampolinePoolFor(2);
1809 emit(
reinterpret_cast<Instr>(msg));
1814 void Assembler::tge(Register rs, Register rt,
uint16_t code) {
1817 | rt.code() <<
kRtShift | code << 6;
1822 void Assembler::tgeu(Register rs, Register rt,
uint16_t code) {
1825 | rt.code() <<
kRtShift | code << 6;
1830 void Assembler::tlt(Register rs, Register rt,
uint16_t code) {
1838 void Assembler::tltu(Register rs, Register rt,
uint16_t code) {
1842 | rt.code() <<
kRtShift | code << 6;
1847 void Assembler::teq(Register rs, Register rt,
uint16_t code) {
1855 void Assembler::tne(Register rs, Register rt,
uint16_t code) {
1865 void Assembler::mfhi(Register rd) {
1866 GenInstrRegister(
SPECIAL, zero_reg, zero_reg, rd, 0,
MFHI);
1870 void Assembler::mflo(Register rd) {
1871 GenInstrRegister(
SPECIAL, zero_reg, zero_reg, rd, 0,
MFLO);
1876 void Assembler::slt(Register rd, Register rs, Register rt) {
1877 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
SLT);
1881 void Assembler::sltu(Register rd, Register rs, Register rt) {
1886 void Assembler::slti(Register rt, Register rs,
int32_t j) {
1887 GenInstrImmediate(
SLTI, rs, rt, j);
1891 void Assembler::sltiu(Register rt, Register rs,
int32_t j) {
1892 GenInstrImmediate(
SLTIU, rs, rt, j);
1897 void Assembler::movz(Register rd, Register rs, Register rt) {
1902 void Assembler::movn(Register rd, Register rs, Register rt) {
1907 void Assembler::movt(Register rd, Register rs,
uint16_t cc) {
1909 rt.code_ = (
cc & 0x0007) << 2 | 1;
1914 void Assembler::movf(Register rd, Register rs,
uint16_t cc) {
1916 rt.code_ = (
cc & 0x0007) << 2 | 0;
1922 void Assembler::clz(Register rd, Register rs) {
1950 DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
1960 void Assembler::lwc1(FPURegister fd,
const MemOperand& src) {
1961 GenInstrImmediate(
LWC1, src.rm(), fd, src.offset_);
1965 void Assembler::ldc1(FPURegister fd,
const MemOperand& src) {
1969 GenInstrImmediate(
LWC1, src.rm(), fd, src.offset_ +
1970 Register::kMantissaOffset);
1971 GenInstrImmediate(
LW, src.rm(), at, src.offset_ +
1972 Register::kExponentOffset);
1975 GenInstrImmediate(
LWC1, src.rm(), fd, src.offset_ +
1976 Register::kMantissaOffset);
1977 FPURegister nextfpreg;
1978 nextfpreg.setcode(fd.code() + 1);
1979 GenInstrImmediate(
LWC1, src.rm(), nextfpreg, src.offset_ +
1980 Register::kExponentOffset);
1985 void Assembler::swc1(FPURegister fd,
const MemOperand& src) {
1986 GenInstrImmediate(
SWC1, src.rm(), fd, src.offset_);
1990 void Assembler::sdc1(FPURegister fd,
const MemOperand& src) {
1994 GenInstrImmediate(
SWC1, src.rm(), fd, src.offset_ +
1995 Register::kMantissaOffset);
1997 GenInstrImmediate(
SW, src.rm(), at, src.offset_ +
1998 Register::kExponentOffset);
2000 GenInstrImmediate(
SWC1, src.rm(), fd, src.offset_ +
2001 Register::kMantissaOffset);
2002 FPURegister nextfpreg;
2003 nextfpreg.setcode(fd.code() + 1);
2004 GenInstrImmediate(
SWC1, src.rm(), nextfpreg, src.offset_ +
2005 Register::kExponentOffset);
2010 void Assembler::mtc1(Register rt, FPURegister fs) {
2015 void Assembler::mthc1(Register rt, FPURegister fs) {
2020 void Assembler::mfc1(Register rt, FPURegister fs) {
2025 void Assembler::mfhc1(Register rt, FPURegister fs) {
2030 void Assembler::ctc1(Register rt, FPUControlRegister fs) {
2031 GenInstrRegister(
COP1,
CTC1, rt, fs);
2035 void Assembler::cfc1(Register rt, FPUControlRegister fs) {
2036 GenInstrRegister(
COP1,
CFC1, rt, fs);
2044 *
lo =
i & 0xffffffff;
2051 void Assembler::add_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2052 GenInstrRegister(
COP1,
D, ft, fs, fd,
ADD_D);
2056 void Assembler::sub_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2057 GenInstrRegister(
COP1,
D, ft, fs, fd,
SUB_D);
2061 void Assembler::mul_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2062 GenInstrRegister(
COP1,
D, ft, fs, fd,
MUL_D);
2066 void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
2072 void Assembler::div_d(FPURegister fd, FPURegister fs, FPURegister ft) {
2073 GenInstrRegister(
COP1,
D, ft, fs, fd,
DIV_D);
2077 void Assembler::abs_d(FPURegister fd, FPURegister fs) {
2082 void Assembler::mov_d(FPURegister fd, FPURegister fs) {
2087 void Assembler::neg_d(FPURegister fd, FPURegister fs) {
2092 void Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
2099 void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
2104 void Assembler::cvt_w_d(FPURegister fd, FPURegister fs) {
2109 void Assembler::trunc_w_s(FPURegister fd, FPURegister fs) {
2114 void Assembler::trunc_w_d(FPURegister fd, FPURegister fs) {
2119 void Assembler::round_w_s(FPURegister fd, FPURegister fs) {
2124 void Assembler::round_w_d(FPURegister fd, FPURegister fs) {
2129 void Assembler::floor_w_s(FPURegister fd, FPURegister fs) {
2134 void Assembler::floor_w_d(FPURegister fd, FPURegister fs) {
2139 void Assembler::ceil_w_s(FPURegister fd, FPURegister fs) {
2144 void Assembler::ceil_w_d(FPURegister fd, FPURegister fs) {
2149 void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
2155 void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
2161 void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
2167 void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
2173 void Assembler::round_l_s(FPURegister fd, FPURegister fs) {
2178 void Assembler::round_l_d(FPURegister fd, FPURegister fs) {
2183 void Assembler::floor_l_s(FPURegister fd, FPURegister fs) {
2188 void Assembler::floor_l_d(FPURegister fd, FPURegister fs) {
2193 void Assembler::ceil_l_s(FPURegister fd, FPURegister fs) {
2198 void Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
2207 GenInstrRegister(
COP1, fmt, ft, fs, fd,
MIN);
2211 void Assembler::mina(
SecondaryField fmt, FPURegister fd, FPURegister ft,
2215 GenInstrRegister(
COP1, fmt, ft, fs, fd,
MINA);
2219 void Assembler::max(
SecondaryField fmt, FPURegister fd, FPURegister ft,
2223 GenInstrRegister(
COP1, fmt, ft, fs, fd,
MAX);
2227 void Assembler::maxa(
SecondaryField fmt, FPURegister fd, FPURegister ft,
2231 GenInstrRegister(
COP1, fmt, ft, fs, fd,
MAXA);
2235 void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
2240 void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
2246 void Assembler::cvt_s_d(FPURegister fd, FPURegister fs) {
2251 void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
2256 void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
2262 void Assembler::cvt_d_s(FPURegister fd, FPURegister fs) {
2269 FPURegister fd, FPURegister fs, FPURegister ft) {
2278 void Assembler::bc1eqz(
int16_t offset, FPURegister ft) {
2285 void Assembler::bc1nez(
int16_t offset, FPURegister ft) {
2294 FPURegister fs, FPURegister ft,
uint16_t cc) {
2298 |
cc << 8 | 3 << 4 | cond;
2303 void Assembler::fcmp(FPURegister src1,
const double src2,
2306 mtc1(zero_reg,
f14);
2308 c(cond,
D, src1,
f14, 0);
2327 void Assembler::RecordJSReturn() {
2328 positions_recorder()->WriteRecordedPositions();
2330 RecordRelocInfo(RelocInfo::JS_RETURN);
2334 void Assembler::RecordDebugBreakSlot() {
2335 positions_recorder()->WriteRecordedPositions();
2337 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
2341 void Assembler::RecordComment(
const char* msg) {
2342 if (FLAG_code_comments) {
2344 RecordRelocInfo(RelocInfo::COMMENT,
reinterpret_cast<intptr_t
>(msg));
2349 int Assembler::RelocateInternalReference(
byte*
pc, intptr_t pc_delta) {
2351 DCHECK(IsJ(instr) || IsLui(instr));
2353 Instr instr_lui = instr_at(
pc + 0 * Assembler::kInstrSize);
2354 Instr instr_ori = instr_at(
pc + 1 * Assembler::kInstrSize);
2355 DCHECK(IsOri(instr_ori));
2358 if (imm == kEndOfJumpChain) {
2367 instr_at_put(
pc + 0 * Assembler::kInstrSize,
2369 instr_at_put(
pc + 1 * Assembler::kInstrSize,
2374 if (
static_cast<int32_t>(imm28) == kEndOfJumpChain) {
2379 DCHECK((imm28 & 3) == 0);
2383 DCHECK(is_uint26(imm26));
2391 void Assembler::GrowBuffer() {
2392 if (!own_buffer_)
FATAL(
"external code buffer is too small");
2396 if (buffer_size_ < 1 *
MB) {
2397 desc.buffer_size = 2*buffer_size_;
2399 desc.buffer_size = buffer_size_ + 1*
MB;
2404 desc.buffer = NewArray<byte>(desc.buffer_size);
2406 desc.instr_size = pc_offset();
2407 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
2410 int pc_delta = desc.buffer - buffer_;
2411 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
2412 MemMove(desc.buffer, buffer_, desc.instr_size);
2413 MemMove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
2418 buffer_ = desc.buffer;
2419 buffer_size_ = desc.buffer_size;
2421 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
2422 reloc_info_writer.last_pc() + pc_delta);
2425 for (RelocIterator it(desc); !it.done(); it.next()) {
2426 RelocInfo::Mode rmode = it.rinfo()->rmode();
2427 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2428 byte* p =
reinterpret_cast<byte*
>(it.rinfo()->pc());
2429 RelocateInternalReference(p, pc_delta);
2439 *
reinterpret_cast<uint8_t*
>(pc_) = data;
2440 pc_ +=
sizeof(uint8_t);
2444 void Assembler::dd(
uint32_t data) {
2446 *
reinterpret_cast<uint32_t*
>(pc_) = data;
2451 void Assembler::emit_code_stub_address(Code* stub) {
2453 *
reinterpret_cast<uint32_t*
>(pc_) =
2454 reinterpret_cast<uint32_t>(stub->instruction_start());
2459 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2461 RelocInfo rinfo(pc_, rmode, data,
NULL);
2462 if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
2464 DCHECK(RelocInfo::IsDebugBreakSlot(rmode)
2465 || RelocInfo::IsJSReturn(rmode)
2466 || RelocInfo::IsComment(rmode)
2467 || RelocInfo::IsPosition(rmode));
2470 if (!RelocInfo::IsNone(rinfo.rmode())) {
2472 if (rmode == RelocInfo::EXTERNAL_REFERENCE &&
2473 !serializer_enabled() && !emit_debug_code()) {
2476 DCHECK(buffer_space() >= kMaxRelocSize);
2477 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2478 RelocInfo reloc_info_with_ast_id(pc_,
2480 RecordedAstId().ToInt(),
2482 ClearRecordedAstId();
2483 reloc_info_writer.Write(&reloc_info_with_ast_id);
2485 reloc_info_writer.Write(&rinfo);
2491 void Assembler::BlockTrampolinePoolFor(
int instructions) {
2492 BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
2496 void Assembler::CheckTrampolinePool() {
2502 if ((trampoline_pool_blocked_nesting_ > 0) ||
2503 (pc_offset() < no_trampoline_pool_before_)) {
2506 if (trampoline_pool_blocked_nesting_ > 0) {
2507 next_buffer_check_ = pc_offset() + kInstrSize;
2509 next_buffer_check_ = no_trampoline_pool_before_;
2514 DCHECK(!trampoline_emitted_);
2515 DCHECK(unbound_labels_count_ >= 0);
2516 if (unbound_labels_count_ > 0) {
2518 { BlockTrampolinePoolScope block_trampoline_pool(
this);
2523 int pool_start = pc_offset();
2524 for (
int i = 0;
i < unbound_labels_count_;
i++) {
2526 imm32 = jump_address(&after_pool);
2527 { BlockGrowBufferScope block_buf_growth(
this);
2531 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2539 trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2541 trampoline_emitted_ =
true;
2549 next_buffer_check_ = pc_offset() +
2550 kMaxBranchOffset - kTrampolineSlotsSize * 16;
2558 Instr instr2 = instr_at(
pc + kInstrSize);
2560 if ((GetOpcodeField(instr1) ==
LUI) && (GetOpcodeField(instr2) ==
ORI)) {
2562 return reinterpret_cast<Address>(
2563 (GetImmediate16(instr1) << 16) | GetImmediate16(instr2));
2576 void Assembler::QuietNaN(HeapObject*
object) {
2577 HeapNumber::cast(
object)->set_value(base::OS::nan_value());
2588 void Assembler::set_target_address_at(
Address pc,
2591 Instr instr2 = instr_at(
pc + kInstrSize);
2592 uint32_t rt_code = GetRtField(instr2);
2599 CHECK((GetOpcodeField(instr1) ==
LUI && GetOpcodeField(instr2) ==
ORI));
2606 *(p + 1) =
ORI | rt_code | (rt_code << 5) | (itarget &
kImm16Mask);
2624 Instr instr3 = instr_at(
pc + 2 * kInstrSize);
2629 bool patched_jump =
false;
2631 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION
2639 uint32_t segment_mask = ((256 *
MB) - 1) ^ ((32 *
KB) - 1);
2640 uint32_t ipc_segment_addr = ipc & segment_mask;
2641 if (ipc_segment_addr == 0 || ipc_segment_addr == segment_mask)
2646 if (IsJalr(instr3)) {
2648 if (in_range && GetRt(instr2) == GetRs(instr3)) {
2649 *(p + 2) =
JAL | target_field;
2650 patched_jump =
true;
2652 }
else if (IsJr(instr3)) {
2654 bool is_ret =
static_cast<int>(GetRs(instr3)) == ra.code();
2655 if (in_range && !is_ret && GetRt(instr2) == GetRs(instr3)) {
2656 *(p + 2) =
J | target_field;
2657 patched_jump =
true;
2659 }
else if (IsJal(instr3)) {
2662 *(p + 2) =
JAL | target_field;
2670 patched_jump =
true;
2671 }
else if (IsJ(instr3)) {
2674 *(p + 2) =
J | target_field;
2685 patched_jump =
true;
2689 CpuFeatures::FlushICache(
pc, (patched_jump ? 3 : 2) *
sizeof(
int32_t));
2694 void Assembler::JumpLabelToJumpRegister(
Address pc) {
2701 Instr instr2 = instr_at(
pc + 1 * kInstrSize);
2702 Instr instr3 = instr_at(
pc + 2 * kInstrSize);
2703 bool patched =
false;
2705 if (IsJal(instr3)) {
2713 }
else if (IsJ(instr3)) {
2727 CpuFeatures::FlushICache(
pc + 2,
sizeof(
Address));
2732 Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
2734 DCHECK(!FLAG_enable_ool_constant_pool);
2735 return isolate->factory()->empty_constant_pool_array();
2739 void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
2741 DCHECK(!FLAG_enable_ool_constant_pool);
static const int kInstrSize
static void FlushICache(void *start, size_t size)
static unsigned supported_
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
void PatchCode(byte *instructions, int instruction_count)
void PatchCodeWithCall(Address target, int guard_bytes)
#define UNIMPLEMENTED_MIPS()
#define IsMipsArchVariant(check)
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(condition)
bool IsPowerOfTwo32(uint32_t value)
Matcher< Node * > IsBranch(const Matcher< Node * > &value_matcher, const Matcher< Node * > &control_matcher)
LinkageHelper< ArmLinkageHelperTraits > LH
const Instr kSwRegFpNegOffsetPattern
void DeleteArray(T *array)
const Instr kPopInstruction
static int min(int a, int b)
const uint32_t kMaxStopCode
const uint32_t kMaxWatchpointCode
const Instr kLwSwInstrArgumentMask
void MemMove(void *dest, const void *src, size_t size)
int ToNumber(Register reg)
kSerializedDataOffset Object
const int kFunctionFieldMask
const Instr kLwSwOffsetMask
Handle< T > handle(T *t, Isolate *isolate)
const Instr kSwRegFpOffsetPattern
const Instr kLwRegFpNegOffsetPattern
void PrintF(const char *format,...)
Register ToRegister(int num)
const int kRegister_fp_Code
const Instr kPushRegPattern
const Instr kLwRegFpOffsetPattern
const Instr kPushInstruction
const Instr kPopRegPattern
const Instr kLwSwInstrTypeMask
PerThreadAssertScopeDebugOnly< DEFERRED_HANDLE_DEREFERENCE_ASSERT, true > AllowDeferredHandleDereference
const int kRegister_sp_Code
Debugger support for the V8 JavaScript engine.
static const uint16_t * Align(const uint16_t *chars)
static const char * AllocationIndexToString(int index)
static const int kMaxNumAllocatableRegisters