Commit a3f941ae authored by Miran.Karic's avatar Miran.Karic Committed by Commit bot

MIPS64: Replace JR/JALR with JIC/JIALC for r6.

Port of changes that replace JR and JALR instructions with JIC and JIALC
for mips64r6. Macroassembler Jump and Call functions now use JIC and
JIALC if branch delay slot is not used. Code patching is adjusted to
work with new changes. Jr and Jalr macroassembler functions are removed.
Other changes where mips32r6 uses jr/jalr are not done because mips64r6
uses j/jal instructions.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35141}
parent f954934d
...@@ -4062,7 +4062,9 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, ...@@ -4062,7 +4062,9 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code,
BackEdgeState target_state, BackEdgeState target_state,
Code* replacement_code) { Code* replacement_code) {
static const int kInstrSize = Assembler::kInstrSize; static const int kInstrSize = Assembler::kInstrSize;
Address branch_address = pc - 8 * kInstrSize; Address pc_immediate_load_address =
Assembler::target_address_from_return_address(pc);
Address branch_address = pc_immediate_load_address - 2 * kInstrSize;
Isolate* isolate = unoptimized_code->GetIsolate(); Isolate* isolate = unoptimized_code->GetIsolate();
CodePatcher patcher(isolate, branch_address, 1); CodePatcher patcher(isolate, branch_address, 1);
...@@ -4092,7 +4094,6 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code, ...@@ -4092,7 +4094,6 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code,
patcher.masm()->daddiu(at, zero_reg, 1); patcher.masm()->daddiu(at, zero_reg, 1);
break; break;
} }
Address pc_immediate_load_address = pc - 6 * kInstrSize;
// Replace the stack check address in the load-immediate (6-instr sequence) // Replace the stack check address in the load-immediate (6-instr sequence)
// with the entry address of the replacement code. // with the entry address of the replacement code.
Assembler::set_target_address_at(isolate, pc_immediate_load_address, Assembler::set_target_address_at(isolate, pc_immediate_load_address,
...@@ -4108,12 +4109,11 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( ...@@ -4108,12 +4109,11 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
Code* unoptimized_code, Code* unoptimized_code,
Address pc) { Address pc) {
static const int kInstrSize = Assembler::kInstrSize; static const int kInstrSize = Assembler::kInstrSize;
Address branch_address = pc - 8 * kInstrSize; Address pc_immediate_load_address =
#ifdef DEBUG Assembler::target_address_from_return_address(pc);
Address pc_immediate_load_address = pc - 6 * kInstrSize; Address branch_address = pc_immediate_load_address - 2 * kInstrSize;
#endif
DCHECK(Assembler::IsBeq(Assembler::instr_at(pc - 7 * kInstrSize))); DCHECK(Assembler::IsBeq(Assembler::instr_at(branch_address + kInstrSize)));
if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) { if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) {
DCHECK(reinterpret_cast<uint64_t>( DCHECK(reinterpret_cast<uint64_t>(
Assembler::target_address_at(pc_immediate_load_address)) == Assembler::target_address_at(pc_immediate_load_address)) ==
......
...@@ -535,7 +535,11 @@ class Assembler : public AssemblerBase { ...@@ -535,7 +535,11 @@ class Assembler : public AssemblerBase {
// Distance between the instruction referring to the address of the call // Distance between the instruction referring to the address of the call
// target and the return address. // target and the return address.
#ifdef _MIPS_ARCH_MIPS64R6
static const int kCallTargetAddressOffset = 5 * kInstrSize;
#else
static const int kCallTargetAddressOffset = 6 * kInstrSize; static const int kCallTargetAddressOffset = 6 * kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address // Distance between start of patched debug break slot and the emitted address
// to jump to. // to jump to.
...@@ -545,7 +549,11 @@ class Assembler : public AssemblerBase { ...@@ -545,7 +549,11 @@ class Assembler : public AssemblerBase {
// register. // register.
static const int kPcLoadDelta = 4; static const int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS64R6
static const int kDebugBreakSlotInstructions = 5;
#else
static const int kDebugBreakSlotInstructions = 6; static const int kDebugBreakSlotInstructions = 6;
#endif
static const int kDebugBreakSlotLength = static const int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize; kDebugBreakSlotInstructions * kInstrSize;
......
...@@ -3700,16 +3700,25 @@ void MacroAssembler::Jump(Register target, ...@@ -3700,16 +3700,25 @@ void MacroAssembler::Jump(Register target,
const Operand& rt, const Operand& rt,
BranchDelaySlot bd) { BranchDelaySlot bd) {
BlockTrampolinePoolScope block_trampoline_pool(this); BlockTrampolinePoolScope block_trampoline_pool(this);
if (cond == cc_always) { if (kArchVariant == kMips64r6 && bd == PROTECT) {
jr(target); if (cond == cc_always) {
jic(target, 0);
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jic(target, 0);
}
} else { } else {
BRANCH_ARGS_CHECK(cond, rs, rt); if (cond == cc_always) {
Branch(2, NegateCondition(cond), rs, rt); jr(target);
jr(target); } else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jr(target);
}
// Emit a nop in the branch delay slot if required.
if (bd == PROTECT) nop();
} }
// Emit a nop in the branch delay slot if required.
if (bd == PROTECT)
nop();
} }
...@@ -3767,8 +3776,7 @@ int MacroAssembler::CallSize(Register target, ...@@ -3767,8 +3776,7 @@ int MacroAssembler::CallSize(Register target,
size += 3; size += 3;
} }
if (bd == PROTECT) if (bd == PROTECT && kArchVariant != kMips64r6) size += 1;
size += 1;
return size * kInstrSize; return size * kInstrSize;
} }
...@@ -3787,16 +3795,25 @@ void MacroAssembler::Call(Register target, ...@@ -3787,16 +3795,25 @@ void MacroAssembler::Call(Register target,
BlockTrampolinePoolScope block_trampoline_pool(this); BlockTrampolinePoolScope block_trampoline_pool(this);
Label start; Label start;
bind(&start); bind(&start);
if (cond == cc_always) { if (kArchVariant == kMips64r6 && bd == PROTECT) {
jalr(target); if (cond == cc_always) {
jialc(target, 0);
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jialc(target, 0);
}
} else { } else {
BRANCH_ARGS_CHECK(cond, rs, rt); if (cond == cc_always) {
Branch(2, NegateCondition(cond), rs, rt); jalr(target);
jalr(target); } else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jalr(target);
}
// Emit a nop in the branch delay slot if required.
if (bd == PROTECT) nop();
} }
// Emit a nop in the branch delay slot if required.
if (bd == PROTECT)
nop();
#ifdef DEBUG #ifdef DEBUG
CHECK_EQ(size + CallSize(target, cond, rs, rt, bd), CHECK_EQ(size + CallSize(target, cond, rs, rt, bd),
...@@ -3919,44 +3936,6 @@ void MacroAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) { ...@@ -3919,44 +3936,6 @@ void MacroAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) {
} }
void MacroAssembler::Jr(Label* L, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
uint64_t imm64;
imm64 = jump_address(L);
{ BlockGrowBufferScope block_buf_growth(this);
// Buffer growth (and relocation) must be blocked for internal references
// until associated instructions are emitted and available to be patched.
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
li(at, Operand(imm64), ADDRESS_LOAD);
}
jr(at);
// Emit a nop in the branch delay slot if required.
if (bdslot == PROTECT)
nop();
}
void MacroAssembler::Jalr(Label* L, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
uint64_t imm64;
imm64 = jump_address(L);
{ BlockGrowBufferScope block_buf_growth(this);
// Buffer growth (and relocation) must be blocked for internal references
// until associated instructions are emitted and available to be patched.
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
li(at, Operand(imm64), ADDRESS_LOAD);
}
jalr(at);
// Emit a nop in the branch delay slot if required.
if (bdslot == PROTECT)
nop();
}
void MacroAssembler::DropAndRet(int drop) { void MacroAssembler::DropAndRet(int drop) {
DCHECK(is_int16(drop * kPointerSize)); DCHECK(is_int16(drop * kPointerSize));
Ret(USE_DELAY_SLOT); Ret(USE_DELAY_SLOT);
......
...@@ -1881,8 +1881,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT ...@@ -1881,8 +1881,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
BranchDelaySlot bdslot); BranchDelaySlot bdslot);
void BranchLong(Label* L, BranchDelaySlot bdslot); void BranchLong(Label* L, BranchDelaySlot bdslot);
void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot); void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot);
void Jr(Label* L, BranchDelaySlot bdslot);
void Jalr(Label* L, BranchDelaySlot bdslot);
// Common implementation of BranchF functions for the different formats. // Common implementation of BranchF functions for the different formats.
void BranchFCommon(SecondaryField sizeField, Label* target, Label* nan, void BranchFCommon(SecondaryField sizeField, Label* target, Label* nan,
......
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