Commit c91bcf71 authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Fix trampoline pool handling in MacroAssembler::BranchShort() for r6.

BUG=chromium:555543
LOG=N

Review URL: https://codereview.chromium.org/1446343002

Cr-Commit-Position: refs/heads/master@{#32094}
parent eb8a4238
...@@ -1367,10 +1367,12 @@ void Assembler::bgezalc(Register rt, int16_t offset) { ...@@ -1367,10 +1367,12 @@ void Assembler::bgezalc(Register rt, int16_t offset) {
void Assembler::bgezall(Register rs, int16_t offset) { void Assembler::bgezall(Register rs, int16_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(!IsMipsArchVariant(kMips32r6));
DCHECK(!(rs.is(zero_reg))); DCHECK(!(rs.is(zero_reg)));
BlockTrampolinePoolScope block_trampoline_pool(this);
positions_recorder()->WriteRecordedPositions(); positions_recorder()->WriteRecordedPositions();
GenInstrImmediate(REGIMM, rs, BGEZALL, offset); GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
...@@ -1453,7 +1455,9 @@ void Assembler::j(int32_t target) { ...@@ -1453,7 +1455,9 @@ void Assembler::j(int32_t target) {
(kImm26Bits + kImmFieldShift)) == 0; (kImm26Bits + kImmFieldShift)) == 0;
DCHECK(in_range && ((target & 3) == 0)); DCHECK(in_range && ((target & 3) == 0));
#endif #endif
BlockTrampolinePoolScope block_trampoline_pool(this);
GenInstrJump(J, (target >> 2) & kImm26Mask); GenInstrJump(J, (target >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
...@@ -1479,8 +1483,10 @@ void Assembler::jal(int32_t target) { ...@@ -1479,8 +1483,10 @@ void Assembler::jal(int32_t target) {
(kImm26Bits + kImmFieldShift)) == 0; (kImm26Bits + kImmFieldShift)) == 0;
DCHECK(in_range && ((target & 3) == 0)); DCHECK(in_range && ((target & 3) == 0));
#endif #endif
BlockTrampolinePoolScope block_trampoline_pool(this);
positions_recorder()->WriteRecordedPositions(); positions_recorder()->WriteRecordedPositions();
GenInstrJump(JAL, (target >> 2) & kImm26Mask); GenInstrJump(JAL, (target >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
......
...@@ -1208,6 +1208,8 @@ class Assembler : public AssemblerBase { ...@@ -1208,6 +1208,8 @@ class Assembler : public AssemblerBase {
return block_buffer_growth_; return block_buffer_growth_;
} }
inline void CheckTrampolinePoolQuick(int extra_instructions = 0);
private: private:
inline static void set_target_internal_reference_encoded_at(Address pc, inline static void set_target_internal_reference_encoded_at(Address pc,
Address target); Address target);
...@@ -1258,7 +1260,6 @@ class Assembler : public AssemblerBase { ...@@ -1258,7 +1260,6 @@ class Assembler : public AssemblerBase {
void GrowBuffer(); void GrowBuffer();
inline void emit(Instr x, inline void emit(Instr x,
CompactBranchType is_compact_branch = CompactBranchType::NO); CompactBranchType is_compact_branch = CompactBranchType::NO);
inline void CheckTrampolinePoolQuick(int extra_instructions = 0);
// Instruction generation. // Instruction generation.
// We have 3 different kind of encoding layout on MIPS. // We have 3 different kind of encoding layout on MIPS.
......
This diff is collapsed.
...@@ -1344,9 +1344,11 @@ void Assembler::bgezalc(Register rt, int16_t offset) { ...@@ -1344,9 +1344,11 @@ void Assembler::bgezalc(Register rt, int16_t offset) {
void Assembler::bgezall(Register rs, int16_t offset) { void Assembler::bgezall(Register rs, int16_t offset) {
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant != kMips64r6);
DCHECK(!(rs.is(zero_reg))); DCHECK(!(rs.is(zero_reg)));
BlockTrampolinePoolScope block_trampoline_pool(this);
GenInstrImmediate(REGIMM, rs, BGEZALL, offset); GenInstrImmediate(REGIMM, rs, BGEZALL, offset);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
...@@ -1409,15 +1411,19 @@ void Assembler::bnezc(Register rs, int32_t offset) { ...@@ -1409,15 +1411,19 @@ void Assembler::bnezc(Register rs, int32_t offset) {
void Assembler::j(int64_t target) { void Assembler::j(int64_t target) {
BlockTrampolinePoolScope block_trampoline_pool(this);
GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask); GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
void Assembler::j(Label* target) { void Assembler::j(Label* target) {
uint64_t imm = jump_offset(target); uint64_t imm = jump_offset(target);
if (target->is_bound()) { if (target->is_bound()) {
BlockTrampolinePoolScope block_trampoline_pool(this);
GenInstrJump(static_cast<Opcode>(kJRawMark), GenInstrJump(static_cast<Opcode>(kJRawMark),
static_cast<uint32_t>(imm >> 2) & kImm26Mask); static_cast<uint32_t>(imm >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} else { } else {
j(imm); j(imm);
} }
...@@ -1427,8 +1433,11 @@ void Assembler::j(Label* target) { ...@@ -1427,8 +1433,11 @@ void Assembler::j(Label* target) {
void Assembler::jal(Label* target) { void Assembler::jal(Label* target) {
uint64_t imm = jump_offset(target); uint64_t imm = jump_offset(target);
if (target->is_bound()) { if (target->is_bound()) {
BlockTrampolinePoolScope block_trampoline_pool(this);
positions_recorder()->WriteRecordedPositions();
GenInstrJump(static_cast<Opcode>(kJalRawMark), GenInstrJump(static_cast<Opcode>(kJalRawMark),
static_cast<uint32_t>(imm >> 2) & kImm26Mask); static_cast<uint32_t>(imm >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} else { } else {
jal(imm); jal(imm);
} }
...@@ -1450,8 +1459,10 @@ void Assembler::jr(Register rs) { ...@@ -1450,8 +1459,10 @@ void Assembler::jr(Register rs) {
void Assembler::jal(int64_t target) { void Assembler::jal(int64_t target) {
BlockTrampolinePoolScope block_trampoline_pool(this);
positions_recorder()->WriteRecordedPositions(); positions_recorder()->WriteRecordedPositions();
GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask); GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask);
BlockTrampolinePoolFor(1); // For associated delay slot.
} }
......
...@@ -5102,4 +5102,35 @@ TEST(bal) { ...@@ -5102,4 +5102,35 @@ TEST(bal) {
} }
TEST(Trampoline) {
// Private member of Assembler class.
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, nullptr, 0);
Label done;
size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2;
for (size_t i = 0; i < nr_calls; ++i) {
__ BranchShort(&done, eq, a0, Operand(a1));
}
__ bind(&done);
__ Ret(USE_DELAY_SLOT);
__ mov(v0, zero_reg);
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
int32_t res =
reinterpret_cast<int32_t>(CALL_GENERATED_CODE(f, 42, 42, 0, 0, 0));
CHECK_EQ(res, 0);
}
#undef __ #undef __
...@@ -5492,4 +5492,35 @@ TEST(bal) { ...@@ -5492,4 +5492,35 @@ TEST(bal) {
} }
TEST(Trampoline) {
// Private member of Assembler class.
static const int kMaxBranchOffset = (1 << (18 - 1)) - 1;
CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, nullptr, 0);
Label done;
size_t nr_calls = kMaxBranchOffset / (2 * Instruction::kInstrSize) + 2;
for (size_t i = 0; i < nr_calls; ++i) {
__ BranchShort(&done, eq, a0, Operand(a1));
}
__ bind(&done);
__ Ret(USE_DELAY_SLOT);
__ mov(v0, zero_reg);
CodeDesc desc;
assm.GetCode(&desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
int64_t res =
reinterpret_cast<int64_t>(CALL_GENERATED_CODE(f, 42, 42, 0, 0, 0));
CHECK_EQ(res, 0);
}
#undef __ #undef __
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment