Commit 21733b6b authored by Miran.Karic's avatar Miran.Karic Committed by Commit bot

MIPS: Replace JR/JALR with JIC/JIALC for r6 part 2

This is another set of changes that replace JR and JALR instructions
with JIC and JIALC for mips32r6. 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 and few minor fixes are added.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#35071}
parent 47cce544
......@@ -4058,7 +4058,9 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code,
BackEdgeState target_state,
Code* replacement_code) {
static const int kInstrSize = Assembler::kInstrSize;
Address branch_address = pc - 6 * 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);
......@@ -4084,7 +4086,6 @@ void BackEdgeTable::PatchAt(Code* unoptimized_code,
patcher.masm()->addiu(at, zero_reg, 1);
break;
}
Address pc_immediate_load_address = pc - 4 * kInstrSize;
// Replace the stack check address in the load-immediate (lui/ori pair)
// with the entry address of the replacement code.
Assembler::set_target_address_at(isolate, pc_immediate_load_address,
......@@ -4100,12 +4101,11 @@ BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
Code* unoptimized_code,
Address pc) {
static const int kInstrSize = Assembler::kInstrSize;
Address branch_address = pc - 6 * kInstrSize;
#ifdef DEBUG
Address pc_immediate_load_address = pc - 4 * 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 - 5 * kInstrSize)));
DCHECK(Assembler::IsBeq(Assembler::instr_at(branch_address + kInstrSize)));
if (!Assembler::IsAddImmediate(Assembler::instr_at(branch_address))) {
DCHECK(reinterpret_cast<uint32_t>(
Assembler::target_address_at(pc_immediate_load_address)) ==
......
......@@ -528,7 +528,11 @@ class Assembler : public AssemblerBase {
// Distance between the instruction referring to the address of the call
// target and the return address.
#ifdef _MIPS_ARCH_MIPS32R6
static const int kCallTargetAddressOffset = 3 * kInstrSize;
#else
static const int kCallTargetAddressOffset = 4 * kInstrSize;
#endif
// Distance between start of patched debug break slot and the emitted address
// to jump to.
......@@ -538,7 +542,11 @@ class Assembler : public AssemblerBase {
// register.
static const int kPcLoadDelta = 4;
#ifdef _MIPS_ARCH_MIPS32R6
static const int kDebugBreakSlotInstructions = 3;
#else
static const int kDebugBreakSlotInstructions = 4;
#endif
static const int kDebugBreakSlotLength =
kDebugBreakSlotInstructions * kInstrSize;
......
......@@ -3052,16 +3052,25 @@ void MacroAssembler::Jump(Register target,
const Operand& rt,
BranchDelaySlot bd) {
BlockTrampolinePoolScope block_trampoline_pool(this);
if (cond == cc_always) {
jr(target);
if (IsMipsArchVariant(kMips32r6) && 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();
}
......@@ -3119,8 +3128,7 @@ int MacroAssembler::CallSize(Register target,
size += 3;
}
if (bd == PROTECT)
size += 1;
if (bd == PROTECT && !IsMipsArchVariant(kMips32r6)) size += 1;
return size * kInstrSize;
}
......@@ -3139,16 +3147,25 @@ void MacroAssembler::Call(Register target,
BlockTrampolinePoolScope block_trampoline_pool(this);
Label start;
bind(&start);
if (cond == cc_always) {
jalr(target);
if (IsMipsArchVariant(kMips32r6) && 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),
......@@ -3239,7 +3256,7 @@ void MacroAssembler::BranchLong(Label* L, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
uint32_t imm32;
imm32 = jump_address(L);
if (IsMipsArchVariant(kMips32r6) && bdslot != USE_DELAY_SLOT) {
if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) {
uint32_t lui_offset, jic_offset;
UnpackTargetAddressUnsigned(imm32, lui_offset, jic_offset);
{
......@@ -3280,7 +3297,7 @@ void MacroAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) {
BlockTrampolinePoolScope block_trampoline_pool(this);
uint32_t imm32;
imm32 = jump_address(L);
if (IsMipsArchVariant(kMips32r6) && bdslot != USE_DELAY_SLOT) {
if (IsMipsArchVariant(kMips32r6) && bdslot == PROTECT) {
uint32_t lui_offset, jic_offset;
UnpackTargetAddressUnsigned(imm32, lui_offset, jic_offset);
{
......@@ -3304,6 +3321,7 @@ void MacroAssembler::BranchAndLinkLong(Label* L, BranchDelaySlot bdslot) {
lui(at, (imm32 & kHiMask) >> kLuiShift);
ori(at, at, (imm32 & kImm16Mask));
}
CheckBuffer();
jalr(at);
// Emit a nop in the branch delay slot if required.
if (bdslot == PROTECT) nop();
......
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