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,
BackEdgeState target_state,
Code* replacement_code) {
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();
CodePatcher patcher(isolate, branch_address, 1);
......@@ -4092,7 +4094,6 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code,
patcher.masm()->daddiu(at, zero_reg, 1);
break;
}
Address pc_immediate_load_address = pc - 6 * kInstrSize;
// Replace the stack check address in the load-immediate (6-instr sequence)
// with the entry address of the replacement code.
Assembler::set_target_address_at(isolate, pc_immediate_load_address,
......@@ -4108,12 +4109,11 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
Code* unoptimized_code,
Address pc) {
static const int kInstrSize = Assembler::kInstrSize;
Address branch_address = pc - 8 * kInstrSize;
#ifdef DEBUG
Address pc_immediate_load_address = pc - 6 * kInstrSize;
#endif
Address pc_immediate_load_address =
Assembler::target_address_from_return_address(pc);
Address branch_address = pc_immediate_load_address - 2 * kInstrSize;
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))) {
DCHECK(reinterpret_cast<uint64_t>(
Assembler::target_address_at(pc_immediate_load_address)) ==
......
......@@ -535,7 +535,11 @@ class Assembler : public AssemblerBase {
// Distance between the instruction referring to the address of the call
// target and the return address.
#ifdef _MIPS_ARCH_MIPS64R6
static const int kCallTargetAddressOffset = 5 * kInstrSize;
#else
static const int kCallTargetAddressOffset = 6 * kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address
// to jump to.
......@@ -545,7 +549,11 @@ class Assembler : public AssemblerBase {
// register.
static const int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS64R6
static const int kDebugBreakSlotInstructions = 5;
#else
static const int kDebugBreakSlotInstructions = 6;
#endif
static const int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize;
......
......@@ -3700,16 +3700,25 @@ void MacroAssembler::Jump(Register target,
const Operand& rt,
BranchDelaySlot bd) {
BlockTrampolinePoolScope block_trampoline_pool(this);
if (cond == cc_always) {
jr(target);
if (kArchVariant == kMips64r6 && bd == PROTECT) {
if (cond == cc_always) {
jic(target, 0);
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jic(target, 0);
}
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jr(target);
if (cond == cc_always) {
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,
size += 3;
}
if (bd == PROTECT)
size += 1;
if (bd == PROTECT && kArchVariant != kMips64r6) size += 1;
return size * kInstrSize;
}
......@@ -3787,16 +3795,25 @@ void MacroAssembler::Call(Register target,
BlockTrampolinePoolScope block_trampoline_pool(this);
Label start;
bind(&start);
if (cond == cc_always) {
jalr(target);
if (kArchVariant == kMips64r6 && bd == PROTECT) {
if (cond == cc_always) {
jialc(target, 0);
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jialc(target, 0);
}
} else {
BRANCH_ARGS_CHECK(cond, rs, rt);
Branch(2, NegateCondition(cond), rs, rt);
jalr(target);
if (cond == cc_always) {
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
CHECK_EQ(size + CallSize(target, cond, rs, rt, bd),
......@@ -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) {
DCHECK(is_int16(drop * kPointerSize));
Ret(USE_DELAY_SLOT);
......
......@@ -1881,8 +1881,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
BranchDelaySlot bdslot);
void BranchLong(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.
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