38 #if defined(V8_TARGET_ARCH_MIPS)
47 bool CpuFeatures::initialized_ =
false;
49 unsigned CpuFeatures::supported_ = 0;
50 unsigned CpuFeatures::found_by_runtime_probing_ = 0;
57 static uint64_t CpuFeaturesImpliedByCompiler() {
59 #ifdef CAN_USE_FPU_INSTRUCTIONS
61 #endif // def CAN_USE_FPU_INSTRUCTIONS
67 #if(defined(__mips_hard_float) && __mips_hard_float != 0)
69 #endif // defined(__mips_hard_float) && __mips_hard_float != 0
70 #endif // def __mips__
78 CpuFeaturesImpliedByCompiler());
79 ASSERT(supported_ == 0 || supported_ == standard_features);
87 supported_ |= standard_features;
96 #if !defined(__mips__)
98 if (FLAG_enable_fpu) {
99 supported_ |= 1u <<
FPU;
106 supported_ |= 1u <<
FPU;
107 found_by_runtime_probing_ |= 1u <<
FPU;
115 const int kNumbers[] = {
149 return kNumbers[reg.code()];
155 const Register kRegisters[] = {
160 t0, t1, t2, t3, t4, t5, t6, t7,
169 return kRegisters[num];
176 const int RelocInfo::kApplyMask = RelocInfo::kCodeTargetMask |
177 1 << RelocInfo::INTERNAL_REFERENCE;
180 bool RelocInfo::IsCodedSpecially() {
192 for (
int i = 0; i < instruction_count; i++) {
193 *(pc + i) = *(instr + i);
203 void RelocInfo::PatchCodeWithCall(
Address target,
int guard_bytes) {
213 Operand::Operand(Handle<Object> handle) {
218 if (obj->IsHeapObject()) {
219 imm32_ =
reinterpret_cast<intptr_t
>(handle.location());
220 rmode_ = RelocInfo::EMBEDDED_OBJECT;
223 imm32_ =
reinterpret_cast<intptr_t
>(obj);
237 static const int kNegOffset = 0x00008000;
262 | (kNegOffset & kImm16Mask);
271 static const int kMinimalBufferSize = 4 *
KB;
275 : AssemblerBase(arg_isolate),
276 positions_recorder_(this),
277 emit_debug_code_(FLAG_debug_code) {
278 if (buffer ==
NULL) {
280 if (buffer_size <= kMinimalBufferSize) {
281 buffer_size = kMinimalBufferSize;
283 if (isolate()->assembler_spare_buffer() !=
NULL) {
284 buffer = isolate()->assembler_spare_buffer();
285 isolate()->set_assembler_spare_buffer(
NULL);
288 if (buffer ==
NULL) {
289 buffer_ = NewArray<byte>(buffer_size);
293 buffer_size_ = buffer_size;
300 buffer_size_ = buffer_size;
307 reloc_info_writer.Reposition(
buffer_ + buffer_size, pc_);
309 last_trampoline_pool_end_ = 0;
310 no_trampoline_pool_before_ = 0;
311 trampoline_pool_blocked_nesting_ = 0;
314 next_buffer_check_ = kMaxBranchOffset - kTrampolineSlotsSize * 16;
315 internal_trampoline_exception_ =
false;
318 trampoline_emitted_ =
false;
319 unbound_labels_count_ = 0;
320 block_buffer_growth_ =
false;
322 ClearRecordedAstId();
330 isolate()->set_assembler_spare_buffer(buffer_);
339 ASSERT(pc_ <= reloc_info_writer.pos());
341 desc->buffer = buffer_;
342 desc->buffer_size = buffer_size_;
344 desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
445 return instr & ~kImm16Mask;
496 const int kEndOfChain = -4;
498 const int kEndOfJumpChain = 0;
507 return opcode ==
BEQ ||
517 (opcode ==
COP1 && rs_field ==
BC1) ||
538 return opcode ==
J || opcode ==
JAL ||
539 (opcode ==
SPECIAL && rt_field == 0 &&
540 ((function_field ==
JALR) || (rd_field == 0 && (function_field ==
JR))));
567 return opcode ==
LUI;
574 return opcode ==
ORI;
582 uint32_t rt =
GetRt(instr);
583 uint32_t rs =
GetRs(instr);
584 uint32_t sa =
GetSa(instr);
590 bool ret = (opcode ==
SLL &&
591 rt ==
static_cast<uint32_t
>(
ToNumber(zero_reg)) &&
592 rs == static_cast<uint32_t>(
ToNumber(zero_reg)) &&
601 return ((
int16_t)(instr & kImm16Mask)) << 2;
612 return ((instr & kImm16Mask));
634 return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
645 return ((instr & ~kImm16Mask) | (offset & kImm16Mask));
656 if ((instr & ~kImm16Mask) == 0) {
662 return (imm18 + pos);
672 if (imm18 == kEndOfChain) {
678 }
else if (
IsLui(instr)) {
685 if (imm == kEndOfJumpChain) {
689 uint32_t instr_address =
reinterpret_cast<int32_t>(buffer_ + pos);
690 int32_t delta = instr_address - imm;
696 if (imm28 == kEndOfJumpChain) {
700 uint32_t instr_address =
reinterpret_cast<int32_t>(buffer_ + pos);
702 int32_t delta = instr_address - imm28;
712 if ((instr & ~kImm16Mask) == 0) {
713 ASSERT(target_pos == kEndOfChain || target_pos >= 0);
725 instr &= ~kImm16Mask;
730 }
else if (
IsLui(instr)) {
734 uint32_t imm = (uint32_t)buffer_ + target_pos;
737 instr_lui &= ~kImm16Mask;
738 instr_ori &= ~kImm16Mask;
743 instr_ori | (imm & kImm16Mask));
745 uint32_t imm28 = (uint32_t)buffer_ + target_pos;
750 uint32_t imm26 = imm28 >> 2;
758 void Assembler::print(Label*
L) {
759 if (L->is_unused()) {
761 }
else if (L->is_bound()) {
762 PrintF(
"bound label to %d\n", L->pos());
763 }
else if (L->is_linked()) {
766 while (l.is_linked()) {
769 if ((instr & ~kImm16Mask) == 0) {
777 PrintF(
"label in inconsistent state (pos = %d)\n", L->pos_);
782 void Assembler::bind_to(Label* L,
int pos) {
784 int32_t trampoline_pos = kInvalidSlotPos;
785 if (L->is_linked() && !trampoline_emitted_) {
786 unbound_labels_count_--;
787 next_buffer_check_ += kTrampolineSlotsSize;
790 while (L->is_linked()) {
792 int32_t dist = pos - fixup_pos;
796 if (dist > kMaxBranchOffset) {
797 if (trampoline_pos == kInvalidSlotPos) {
798 trampoline_pos = get_trampoline_entry(fixup_pos);
799 CHECK(trampoline_pos != kInvalidSlotPos);
801 ASSERT((trampoline_pos - fixup_pos) <= kMaxBranchOffset);
803 fixup_pos = trampoline_pos;
804 dist = pos - fixup_pos;
816 if (pos > last_bound_pos_)
817 last_bound_pos_ = pos;
827 void Assembler::next(Label* L) {
830 if (link == kEndOfChain) {
853 void Assembler::GenInstrRegister(
Opcode opcode,
859 ASSERT(rd.is_valid() && rs.is_valid() && rt.is_valid() &&
is_uint5(sa));
866 void Assembler::GenInstrRegister(
Opcode opcode,
879 void Assembler::GenInstrRegister(
Opcode opcode,
885 ASSERT(fd.is_valid() && fs.is_valid() && ft.is_valid());
893 void Assembler::GenInstrRegister(
Opcode opcode,
899 ASSERT(fd.is_valid() && fs.is_valid() && rt.is_valid());
907 void Assembler::GenInstrRegister(
Opcode opcode,
910 FPUControlRegister fs,
912 ASSERT(fs.is_valid() && rt.is_valid());
922 void Assembler::GenInstrImmediate(
Opcode opcode,
933 void Assembler::GenInstrImmediate(
Opcode opcode,
938 Instr instr = opcode | (rs.code() <<
kRsShift) | SF | (j & kImm16Mask);
943 void Assembler::GenInstrImmediate(
Opcode opcode,
955 void Assembler::GenInstrJump(
Opcode opcode,
959 Instr instr = opcode | address;
967 int32_t trampoline_entry = kInvalidSlotPos;
969 if (!internal_trampoline_exception_) {
970 if (trampoline_.start() > pos) {
971 trampoline_entry = trampoline_.take_slot();
974 if (kInvalidSlotPos == trampoline_entry) {
975 internal_trampoline_exception_ =
true;
978 return trampoline_entry;
986 target_pos = L->pos();
988 if (L->is_linked()) {
989 target_pos = L->pos();
993 return kEndOfJumpChain;
997 uint32_t imm = (uint32_t)buffer_ + target_pos;
1007 if (L->is_bound()) {
1008 target_pos = L->pos();
1010 if (L->is_linked()) {
1011 target_pos = L->pos();
1015 if (!trampoline_emitted_) {
1016 unbound_labels_count_++;
1017 next_buffer_check_ -= kTrampolineSlotsSize;
1024 ASSERT((offset & 3) == 0);
1033 if (L->is_bound()) {
1034 target_pos = L->pos();
1037 if (L->is_linked()) {
1038 target_pos = L->pos();
1039 int32_t imm18 = target_pos - at_offset;
1040 ASSERT((imm18 & 3) == 0);
1045 target_pos = kEndOfChain;
1047 if (!trampoline_emitted_) {
1048 unbound_labels_count_++;
1049 next_buffer_check_ -= kTrampolineSlotsSize;
1052 L->link_to(at_offset);
1060 beq(zero_reg, zero_reg, offset);
1066 bgezal(zero_reg, offset);
1072 GenInstrImmediate(
BEQ, rs, rt, offset);
1094 GenInstrImmediate(
BGTZ, rs, zero_reg, offset);
1101 GenInstrImmediate(
BLEZ, rs, zero_reg, offset);
1123 GenInstrImmediate(
BNE, rs, rt, offset);
1131 uint32_t ipc =
reinterpret_cast<uint32_t
>(pc_ + 1 *
kInstrSize);
1133 ASSERT(in_range && ((target & 3) == 0));
1135 GenInstrJump(
J, target >> 2);
1144 GenInstrRegister(
SPECIAL, rs, zero_reg, zero_reg, 0,
JR);
1152 uint32_t ipc =
reinterpret_cast<uint32_t
>(pc_ + 1 *
kInstrSize);
1154 ASSERT(in_range && ((target & 3) == 0));
1157 GenInstrJump(
JAL, target >> 2);
1164 GenInstrRegister(
SPECIAL, rs, zero_reg, rd, 0,
JALR);
1171 uint32_t ipc =
reinterpret_cast<uint32_t
>(pc_ + 1 *
kInstrSize);
1184 uint32_t ipc =
reinterpret_cast<uint32_t
>(pc_ + 1 *
kInstrSize);
1205 GenInstrImmediate(
ADDIU, rs, rd, j);
1220 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
MULT);
1230 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
DIV);
1235 GenInstrRegister(
SPECIAL, rs, rt, zero_reg, 0,
DIVU);
1242 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
AND);
1248 GenInstrImmediate(
ANDI, rs, rt, j);
1253 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
OR);
1259 GenInstrImmediate(
ORI, rs, rt, j);
1264 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
XOR);
1270 GenInstrImmediate(
XORI, rs, rt, j);
1275 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
NOR);
1283 bool coming_from_nop) {
1288 ASSERT(coming_from_nop || !(rd.is(zero_reg) && rt.is(zero_reg)));
1289 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SLL);
1299 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SRL);
1309 GenInstrRegister(
SPECIAL, zero_reg, rt, rd, sa,
SRA);
1330 ASSERT(rd.is_valid() && rt.is_valid() && rs.is_valid() );
1341 void Assembler::LoadRegPlusOffsetToAt(
const MemOperand& src) {
1342 ASSERT(!src.rm().is(at));
1344 ori(at, at, src.offset_ & kImm16Mask);
1345 addu(at, at, src.rm());
1351 GenInstrImmediate(
LB, rs.rm(), rd, rs.offset_);
1353 LoadRegPlusOffsetToAt(rs);
1354 GenInstrImmediate(
LB, at, rd, 0);
1361 GenInstrImmediate(
LBU, rs.rm(), rd, rs.offset_);
1363 LoadRegPlusOffsetToAt(rs);
1364 GenInstrImmediate(
LBU, at, rd, 0);
1371 GenInstrImmediate(
LH, rs.rm(), rd, rs.offset_);
1373 LoadRegPlusOffsetToAt(rs);
1374 GenInstrImmediate(
LH, at, rd, 0);
1381 GenInstrImmediate(
LHU, rs.rm(), rd, rs.offset_);
1383 LoadRegPlusOffsetToAt(rs);
1384 GenInstrImmediate(
LHU, at, rd, 0);
1391 GenInstrImmediate(
LW, rs.rm(), rd, rs.offset_);
1393 LoadRegPlusOffsetToAt(rs);
1394 GenInstrImmediate(
LW, at, rd, 0);
1400 GenInstrImmediate(
LWL, rs.rm(), rd, rs.offset_);
1405 GenInstrImmediate(
LWR, rs.rm(), rd, rs.offset_);
1411 GenInstrImmediate(
SB, rs.rm(), rd, rs.offset_);
1413 LoadRegPlusOffsetToAt(rs);
1414 GenInstrImmediate(
SB, at, rd, 0);
1421 GenInstrImmediate(
SH, rs.rm(), rd, rs.offset_);
1423 LoadRegPlusOffsetToAt(rs);
1424 GenInstrImmediate(
SH, at, rd, 0);
1431 GenInstrImmediate(
SW, rs.rm(), rd, rs.offset_);
1433 LoadRegPlusOffsetToAt(rs);
1434 GenInstrImmediate(
SW, at, rd, 0);
1440 GenInstrImmediate(
SWL, rs.rm(), rd, rs.offset_);
1445 GenInstrImmediate(
SWR, rs.rm(), rd, rs.offset_);
1451 GenInstrImmediate(
LUI, zero_reg, rd, j);
1459 ASSERT((code & ~0xfffff) == 0);
1477 #if defined(V8_HOST_ARCH_MIPS)
1479 #else // V8_HOST_ARCH_MIPS
1484 emit(reinterpret_cast<Instr>(msg));
1492 | rt.code() <<
kRtShift | code << 6;
1500 | rt.code() <<
kRtShift | code << 6;
1517 | rt.code() <<
kRtShift | code << 6;
1541 GenInstrRegister(
SPECIAL, zero_reg, zero_reg, rd, 0,
MFHI);
1546 GenInstrRegister(
SPECIAL, zero_reg, zero_reg, rd, 0,
MFLO);
1552 GenInstrRegister(
SPECIAL, rs, rt, rd, 0,
SLT);
1562 GenInstrImmediate(
SLTI, rs, rt, j);
1567 GenInstrImmediate(
SLTIU, rs, rt, j);
1584 rt.code_ = (cc & 0x0007) << 2 | 1;
1591 rt.code_ = (cc & 0x0007) << 2 | 0;
1607 GenInstrRegister(
SPECIAL3, rs, rt, pos + size - 1, pos,
INS);
1615 GenInstrRegister(
SPECIAL3, rs, rt, size - 1, pos,
EXT);
1623 GenInstrImmediate(
LWC1, src.rm(), fd, src.offset_);
1630 GenInstrImmediate(
LWC1, src.rm(), fd, src.offset_);
1631 FPURegister nextfpreg;
1632 nextfpreg.setcode(fd.code() + 1);
1633 GenInstrImmediate(
LWC1, src.rm(), nextfpreg, src.offset_ + 4);
1638 GenInstrImmediate(
SWC1, src.rm(), fd, src.offset_);
1645 GenInstrImmediate(
SWC1, src.rm(), fd, src.offset_);
1646 FPURegister nextfpreg;
1647 nextfpreg.setcode(fd.code() + 1);
1648 GenInstrImmediate(
SWC1, src.rm(), nextfpreg, src.offset_ + 4);
1663 GenInstrRegister(
COP1,
CTC1, rt, fs);
1668 GenInstrRegister(
COP1,
CFC1, rt, fs);
1675 *lo = i & 0xffffffff;
1682 GenInstrRegister(
COP1,
D, ft, fs, fd,
ADD_D);
1687 GenInstrRegister(
COP1,
D, ft, fs, fd,
SUB_D);
1692 GenInstrRegister(
COP1,
D, ft, fs, fd,
MUL_D);
1697 GenInstrRegister(
COP1,
D, ft, fs, fd,
DIV_D);
1861 FPURegister fs, FPURegister ft,
uint16_t cc) {
1866 | cc << 8 | 3 << 4 | cond;
1877 c(cond,
D, src1,
f14, 0);
1901 RecordRelocInfo(RelocInfo::JS_RETURN);
1908 RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
1913 if (FLAG_code_comments) {
1915 RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
1929 if (imm == kEndOfJumpChain) {
1935 instr_lui &= ~kImm16Mask;
1936 instr_ori &= ~kImm16Mask;
1939 instr_lui | ((imm >>
kLuiShift) & kImm16Mask));
1941 instr_ori | (imm & kImm16Mask));
1945 if ((
int32_t)imm28 == kEndOfJumpChain) {
1950 ASSERT((imm28 & 3) == 0);
1953 uint32_t imm26 = imm28 >> 2;
1962 void Assembler::GrowBuffer() {
1963 if (!own_buffer_)
FATAL(
"external code buffer is too small");
1967 if (buffer_size_ < 4*
KB) {
1968 desc.buffer_size = 4*
KB;
1969 }
else if (buffer_size_ < 1*
MB) {
1970 desc.buffer_size = 2*buffer_size_;
1972 desc.buffer_size = buffer_size_ + 1*
MB;
1977 desc.buffer = NewArray<byte>(desc.buffer_size);
1980 desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
1983 int pc_delta = desc.buffer - buffer_;
1984 int rc_delta = (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
1985 memmove(desc.buffer, buffer_, desc.instr_size);
1986 memmove(reloc_info_writer.pos() + rc_delta,
1987 reloc_info_writer.pos(), desc.reloc_size);
1991 buffer_ = desc.buffer;
1992 buffer_size_ = desc.buffer_size;
1994 reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
1995 reloc_info_writer.last_pc() + pc_delta);
1998 for (RelocIterator it(desc); !it.done(); it.next()) {
1999 RelocInfo::Mode rmode = it.rinfo()->rmode();
2000 if (rmode == RelocInfo::INTERNAL_REFERENCE) {
2001 byte* p =
reinterpret_cast<byte*
>(it.rinfo()->pc());
2012 *
reinterpret_cast<uint8_t*
>(pc_) = data;
2013 pc_ +=
sizeof(uint8_t);
2019 *
reinterpret_cast<uint32_t*
>(pc_) = data;
2020 pc_ +=
sizeof(uint32_t);
2024 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
2027 if (rmode >= RelocInfo::JS_RETURN && rmode <= RelocInfo::DEBUG_BREAK_SLOT) {
2029 ASSERT(RelocInfo::IsDebugBreakSlot(rmode)
2030 || RelocInfo::IsJSReturn(rmode)
2031 || RelocInfo::IsComment(rmode)
2032 || RelocInfo::IsPosition(rmode));
2037 if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
2048 if (rmode == RelocInfo::CODE_TARGET_WITH_ID) {
2051 reloc_info_writer.Write(&reloc_info_with_ast_id);
2053 reloc_info_writer.Write(&rinfo);
2070 if ((trampoline_pool_blocked_nesting_ > 0) ||
2071 (
pc_offset() < no_trampoline_pool_before_)) {
2074 if (trampoline_pool_blocked_nesting_ > 0) {
2077 next_buffer_check_ = no_trampoline_pool_before_;
2082 ASSERT(!trampoline_emitted_);
2083 ASSERT(unbound_labels_count_ >= 0);
2084 if (unbound_labels_count_ > 0) {
2092 for (
int i = 0; i < unbound_labels_count_; i++) {
2095 { BlockGrowBufferScope block_buf_growth(
this);
2099 RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
2101 ori(at, at, (imm32 & kImm16Mask));
2107 trampoline_ = Trampoline(pool_start, unbound_labels_count_);
2109 trampoline_emitted_ =
true;
2118 kMaxBranchOffset - kTrampolineSlotsSize * 16;
2130 return reinterpret_cast<Address>(
2159 uint32_t* p =
reinterpret_cast<uint32_t*
>(
pc);
2160 uint32_t itarget =
reinterpret_cast<uint32_t
>(target);
2172 *(p+1) =
ORI | rt_code | (rt_code << 5) | (itarget &
kImm16Mask);
2191 uint32_t ipc =
reinterpret_cast<uint32_t
>(pc + 3 *
kInstrSize);
2195 bool patched_jump =
false;
2197 #ifndef ALLOW_JAL_IN_BOUNDARY_REGION
2205 uint32_t segment_mask = ((256 *
MB) - 1) ^ ((32 *
KB) - 1);
2206 uint32_t ipc_segment_addr = ipc & segment_mask;
2207 if (ipc_segment_addr == 0 || ipc_segment_addr == segment_mask)
2214 if (in_range &&
GetRt(instr2) ==
GetRs(instr3)) {
2215 *(p+2) =
JAL | target_field;
2216 patched_jump =
true;
2218 }
else if (
IsJr(instr3)) {
2220 bool is_ret =
static_cast<int>(
GetRs(instr3)) == ra.code();
2221 if (in_range && !is_ret &&
GetRt(instr2) ==
GetRs(instr3)) {
2222 *(p+2) =
J | target_field;
2223 patched_jump =
true;
2225 }
else if (
IsJal(instr3)) {
2228 *(p+2) =
JAL | target_field;
2233 uint32_t rd_field = ra.code() <<
kRdShift;
2236 patched_jump =
true;
2237 }
else if (
IsJ(instr3)) {
2240 *(p+2) =
J | target_field;
2247 patched_jump =
true;
2256 uint32_t* p =
reinterpret_cast<uint32_t*
>(
pc);
2262 bool patched =
false;
2264 if (
IsJal(instr3)) {
2269 uint32_t rd_field = ra.code() <<
kRdShift;
2272 }
else if (
IsJ(instr3)) {
2288 #endif // V8_TARGET_ARCH_MIPS
void addu(Register rd, Register rs, Register rt)
static bool IsBranch(Instr instr)
Isolate * isolate() const
static const int kBranchPCOffset
void andi(Register rd, Register rs, int32_t j)
void beq(Register rs, Register rt, int16_t offset)
void cvt_l_d(FPURegister fd, FPURegister fs)
static int GetBranchOffset(Instr instr)
static uint32_t GetRt(Instr instr)
void ClearRecordedAstId()
void trunc_l_d(FPURegister fd, FPURegister fs)
static uint32_t GetOpcodeField(Instr instr)
void mtc1(Register rt, FPURegister fs)
static bool IsAddImmediate(Instr instr)
void PrintF(const char *format,...)
static Register GetRsReg(Instr instr)
void round_l_s(FPURegister fd, FPURegister fs)
void swc1(FPURegister fs, const MemOperand &dst)
void round_w_d(FPURegister fd, FPURegister fs)
void bgezal(Register rs, int16_t offset)
void instr_at_put(int pos, Instr instr)
void neg_d(FPURegister fd, FPURegister fs)
void blez(Register rs, int16_t offset)
void sw(Register rd, const MemOperand &rs)
void cvt_s_l(FPURegister fd, FPURegister fs)
void mov_d(FPURegister fd, FPURegister fs)
void rotr(Register rd, Register rt, uint16_t sa)
static uint32_t GetImmediate16(Instr instr)
void sqrt_d(FPURegister fd, FPURegister fs)
static bool IsSw(Instr instr)
static Instr SetAddImmediateOffset(Instr instr, int16_t offset)
static uint32_t GetFunctionField(Instr instr)
void tne(Register rs, Register rt, uint16_t code)
void or_(Register dst, int32_t imm32)
void round_w_s(FPURegister fd, FPURegister fs)
void b(int branch_offset, Condition cond=al)
const uint32_t kMaxWatchpointCode
void floor_l_s(FPURegister fd, FPURegister fs)
static uint32_t GetRsField(Instr instr)
void mul_d(FPURegister fd, FPURegister fs, FPURegister ft)
void clz(Register dst, Register src, Condition cond=al)
void bc1t(int16_t offset, uint16_t cc=0)
void div(Register rs, Register rt)
static uint32_t GetRs(Instr instr)
void j(Condition cc, Label *L, Label::Distance distance=Label::kFar)
static bool IsLwRegFpOffset(Instr instr)
const uint32_t kMaxStopCode
static const int kMinimalBufferSize
#define ASSERT(condition)
void swr(Register rd, const MemOperand &rs)
void ext_(Register rt, Register rs, uint16_t pos, uint16_t size)
const Instr kSwRegFpOffsetPattern
static uint32_t GetRdField(Instr instr)
void DoubleAsTwoUInt32(double d, uint32_t *lo, uint32_t *hi)
static Instr SetSwOffset(Instr instr, int16_t offset)
void sll(Register rd, Register rt, uint16_t sa, bool coming_from_nop=false)
void cvt_d_s(FPURegister fd, FPURegister fs)
static bool IsJalr(Instr instr)
void floor_w_s(FPURegister fd, FPURegister fs)
static bool IsJ(Instr instr)
void addiu(Register rd, Register rs, int32_t j)
void cvt_d_l(FPURegister fd, FPURegister fs)
StringInputBuffer *const buffer_
const int kFunctionFieldMask
static bool IsLwRegFpNegOffset(Instr instr)
void target_at_put(int pos, int target_pos)
void multu(Register rs, Register rt)
void add_d(FPURegister fd, FPURegister fs, FPURegister ft)
void CheckTrampolinePool()
const Instr kPopRegPattern
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 instructions(ARM only)") DEFINE_bool(enable_armv7
void ldc1(FPURegister fd, const MemOperand &src)
void cvt_d_w(FPURegister fd, FPURegister fs)
void cvt_w_d(FPURegister fd, FPURegister fs)
static void JumpLabelToJumpRegister(Address pc)
const Instr kPushRegPattern
void break_(uint32_t code, bool break_as_stop=false)
static bool IsPush(Instr instr)
void ceil_w_s(FPURegister fd, FPURegister fs)
void sh(Register rd, const MemOperand &rs)
static bool IsJr(Instr instr)
static bool IsOri(Instr instr)
void sra(Register rt, Register rd, uint16_t sa)
void slt(Register rd, Register rs, Register rt)
void swl(Register rd, const MemOperand &rs)
void lwr(Register rd, const MemOperand &rs)
void BlockTrampolinePoolBefore(int pc_offset)
void lbu(Register rd, const MemOperand &rs)
static bool IsJal(Instr instr)
void ceil_w_d(FPURegister fd, FPURegister fs)
void trunc_l_s(FPURegister fd, FPURegister fs)
const Instr kLwSwInstrTypeMask
void trunc_w_s(FPURegister fd, FPURegister fs)
void srlv(Register rd, Register rt, Register rs)
void div_d(FPURegister fd, FPURegister fs, FPURegister ft)
void abs_d(FPURegister fd, FPURegister fs)
void sltu(Register rd, Register rs, Register rt)
void GetCode(CodeDesc *desc)
void xori(Register rd, Register rs, int32_t j)
void jal_or_jalr(int32_t target, Register rs)
void teq(Register src1, const Operand &src2, Condition cond=al)
const Instr kLwRegFpOffsetPattern
int branch_offset(Label *L, bool jump_elimination_allowed)
const Instr kPushInstruction
static void set_target_address_at(Address pc, Address target)
static void TooLateToEnableNow()
static bool IsPop(Instr instr)
void movt(Register reg, uint32_t immediate, Condition cond=al)
void lui(Register rd, int32_t j)
const Instr kPopInstruction
static bool IsLw(Instr instr)
static uint32_t GetFunction(Instr instr)
void srl(Register rd, Register rt, uint16_t sa)
static Register GetRdReg(Instr instr)
void tlt(Register rs, Register rt, uint16_t code)
void slti(Register rd, Register rs, int32_t j)
void srav(Register rt, Register rd, Register rs)
static uint32_t GetRtField(Instr instr)
const int kRegister_fp_Code
void sltiu(Register rd, Register rs, int32_t j)
void jalr(Register rs, Register rd=ra)
void floor_l_d(FPURegister fd, FPURegister fs)
static bool MipsCpuHasFeature(CpuFeature feature)
void cfc1(Register rt, FPUControlRegister fs)
friend class BlockTrampolinePoolScope
void ins_(Register rt, Register rs, uint16_t pos, uint16_t size)
static Register GetRtReg(Instr instr)
#define UNIMPLEMENTED_MIPS()
void lw(Register rd, const MemOperand &rs)
void ceil_l_d(FPURegister fd, FPURegister fs)
static Register GetRd(Instr instr)
static bool IsNop(Instr instr, int type=NON_MARKING_NOP)
void RecordDebugBreakSlot()
static uint32_t GetLabelConst(Instr instr)
void ori(Register rd, Register rs, int32_t j)
void stop(const char *msg, Condition cond=al, int32_t code=kDefaultStopCode)
void cvt_s_w(FPURegister fd, FPURegister fs)
void movz(Register rd, Register rs, Register rt)
int ToNumber(Register reg)
void round_l_d(FPURegister fd, FPURegister fs)
static Address target_address_at(Address pc)
static HeapNumber * cast(Object *obj)
void set_value(double value)
static double nan_value()
void movf(Register rd, Register rs, uint16_t cc=0)
void RecordComment(const char *msg)
void fcmp(FPURegister src1, const double src2, FPUCondition cond)
static void QuietNaN(HeapObject *nan)
void bltzal(Register rs, int16_t offset)
void cvt_w_s(FPURegister fd, FPURegister fs)
void lwl(Register rd, const MemOperand &rs)
void bne(Register rs, Register rt, int16_t offset)
void xor_(Register dst, int32_t imm32)
void BlockTrampolinePoolFor(int instructions)
static bool IsSwRegFpOffset(Instr instr)
static const int kHeaderSize
static bool IsJump(Instr instr)
void mfc1(Register rt, FPURegister fs)
void mult(Register rs, Register rt)
void subu(Register rd, Register rs, Register rt)
static int RelocateInternalReference(byte *pc, intptr_t pc_delta)
void tgeu(Register rs, Register rt, uint16_t code)
Assembler(Isolate *isolate, void *buffer, int buffer_size)
static uint32_t GetSa(Instr instr)
bool MustUseReg(RelocInfo::Mode rmode)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
const Instr kLwSwInstrArgumentMask
void trunc_w_d(FPURegister fd, FPURegister fs)
void sllv(Register rd, Register rt, Register rs)
void ctc1(Register rt, FPUControlRegister fs)
void floor_w_d(FPURegister fd, FPURegister fs)
void sdc1(FPURegister fs, const MemOperand &dst)
void lh(Register rd, const MemOperand &rs)
static bool IsBne(Instr instr)
void bc1f(int16_t offset, uint16_t cc=0)
PositionsRecorder * positions_recorder()
static bool IsBeq(Instr instr)
static const int kInstrSize
MemOperand(Register rn, int32_t offset=0)
static uint64_t CpuFeaturesImpliedByPlatform()
const Instr kLwRegFpNegOffsetPattern
void ceil_l_s(FPURegister fd, FPURegister fs)
void tge(Register rs, Register rt, uint16_t code)
void cvt_s_d(FPURegister fd, FPURegister fs)
static void FlushICache(void *start, size_t size)
void and_(Register dst, Register src1, const Operand &src2, SBit s=LeaveCC, Condition cond=al)
void label_at_put(Label *L, int at_offset)
void bgtz(Register rs, int16_t offset)
void nor(Register rd, Register rs, Register rt)
static int16_t GetLwOffset(Instr instr)
const Instr kLwSwOffsetMask
const int kRegister_sp_Code
void DeleteArray(T *array)
static bool IsSwRegFpNegOffset(Instr instr)
void lb(Register rd, const MemOperand &rs)
Register ToRegister(int num)
uint32_t jump_address(Label *L)
void j_or_jr(int32_t target, Register rs)
void rotrv(Register rd, Register rt, Register rs)
void bgez(Register rs, int16_t offset)
void cvt_l_s(FPURegister fd, FPURegister fs)
void lhu(Register rd, const MemOperand &rs)
const Instr kSwRegFpNegOffsetPattern
void tltu(Register rs, Register rt, uint16_t code)
static Instr SetLwOffset(Instr instr, int16_t offset)
bool emit_debug_code() const
static uint32_t GetSaField(Instr instr)
void divu(Register rs, Register rt)
void bltz(Register rs, int16_t offset)
void lwc1(FPURegister fd, const MemOperand &src)
void sub_d(FPURegister fd, FPURegister fs, FPURegister ft)
void mul(Register dst, Register src1, Register src2, SBit s=LeaveCC, Condition cond=al)
static bool IsLui(Instr instr)
static bool IsAndImmediate(Instr instr)
void c(FPUCondition cond, SecondaryField fmt, FPURegister ft, FPURegister fs, uint16_t cc=0)
void movn(Register rd, Register rs, Register rt)
void sb(Register rd, const MemOperand &rs)