MIPS: Fix trampoline pool handling in MacroAssembler::BranchShort()
BUG=chromium:555543 LOG=N Review URL: https://codereview.chromium.org/1448033002 Cr-Commit-Position: refs/heads/master@{#32017}
This commit is contained in:
parent
462cc3c6f0
commit
bb332195d3
@ -2374,121 +2374,122 @@ bool MacroAssembler::BranchShortHelper(int16_t offset, Label* L, Condition cond,
|
|||||||
// Be careful to always use shifted_branch_offset only just before the
|
// Be careful to always use shifted_branch_offset only just before the
|
||||||
// branch instruction, as the location will be remember for patching the
|
// branch instruction, as the location will be remember for patching the
|
||||||
// target.
|
// target.
|
||||||
BlockTrampolinePoolScope block_trampoline_pool(this);
|
{
|
||||||
switch (cond) {
|
BlockTrampolinePoolScope block_trampoline_pool(this);
|
||||||
case cc_always:
|
switch (cond) {
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
case cc_always:
|
||||||
b(offset32);
|
|
||||||
break;
|
|
||||||
case eq:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
beq(rs, zero_reg, offset32);
|
|
||||||
} else {
|
|
||||||
// We don't want any other register but scratch clobbered.
|
|
||||||
scratch = GetRtAsRegisterHelper(rt, scratch);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
beq(rs, scratch, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ne:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(rs, zero_reg, offset32);
|
|
||||||
} else {
|
|
||||||
// We don't want any other register but scratch clobbered.
|
|
||||||
scratch = GetRtAsRegisterHelper(rt, scratch);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(rs, scratch, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Signed comparison.
|
|
||||||
case greater:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bgtz(rs, offset32);
|
|
||||||
} else {
|
|
||||||
Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(scratch, zero_reg, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case greater_equal:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bgez(rs, offset32);
|
|
||||||
} else {
|
|
||||||
Slt(scratch, rs, rt);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
beq(scratch, zero_reg, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case less:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bltz(rs, offset32);
|
|
||||||
} else {
|
|
||||||
Slt(scratch, rs, rt);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(scratch, zero_reg, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case less_equal:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
blez(rs, offset32);
|
|
||||||
} else {
|
|
||||||
Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
beq(scratch, zero_reg, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Unsigned comparison.
|
|
||||||
case Ugreater:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(rs, zero_reg, offset32);
|
|
||||||
} else {
|
|
||||||
Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
|
||||||
bne(scratch, zero_reg, offset32);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Ugreater_equal:
|
|
||||||
if (IsZero(rt)) {
|
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
b(offset32);
|
b(offset32);
|
||||||
} else {
|
break;
|
||||||
Sltu(scratch, rs, rt);
|
case eq:
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
if (IsZero(rt)) {
|
||||||
beq(scratch, zero_reg, offset32);
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
}
|
beq(rs, zero_reg, offset32);
|
||||||
break;
|
} else {
|
||||||
case Uless:
|
// We don't want any other register but scratch clobbered.
|
||||||
if (IsZero(rt)) {
|
scratch = GetRtAsRegisterHelper(rt, scratch);
|
||||||
return true; // No code needs to be emitted.
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
} else {
|
beq(rs, scratch, offset32);
|
||||||
Sltu(scratch, rs, rt);
|
}
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
break;
|
||||||
bne(scratch, zero_reg, offset32);
|
case ne:
|
||||||
}
|
if (IsZero(rt)) {
|
||||||
break;
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
case Uless_equal:
|
bne(rs, zero_reg, offset32);
|
||||||
if (IsZero(rt)) {
|
} else {
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
// We don't want any other register but scratch clobbered.
|
||||||
beq(rs, zero_reg, offset32);
|
scratch = GetRtAsRegisterHelper(rt, scratch);
|
||||||
} else {
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
bne(rs, scratch, offset32);
|
||||||
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
}
|
||||||
beq(scratch, zero_reg, offset32);
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Signed comparison.
|
||||||
|
case greater:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bgtz(rs, offset32);
|
||||||
|
} else {
|
||||||
|
Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bne(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case greater_equal:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bgez(rs, offset32);
|
||||||
|
} else {
|
||||||
|
Slt(scratch, rs, rt);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
beq(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case less:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bltz(rs, offset32);
|
||||||
|
} else {
|
||||||
|
Slt(scratch, rs, rt);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bne(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case less_equal:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
blez(rs, offset32);
|
||||||
|
} else {
|
||||||
|
Slt(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
beq(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Unsigned comparison.
|
||||||
|
case Ugreater:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bne(rs, zero_reg, offset32);
|
||||||
|
} else {
|
||||||
|
Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bne(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Ugreater_equal:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
b(offset32);
|
||||||
|
} else {
|
||||||
|
Sltu(scratch, rs, rt);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
beq(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Uless:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
return true; // No code needs to be emitted.
|
||||||
|
} else {
|
||||||
|
Sltu(scratch, rs, rt);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
bne(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Uless_equal:
|
||||||
|
if (IsZero(rt)) {
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
beq(rs, zero_reg, offset32);
|
||||||
|
} else {
|
||||||
|
Sltu(scratch, GetRtAsRegisterHelper(rt, scratch), rs);
|
||||||
|
offset32 = GetOffset(offset, L, OffsetSize::kOffset16);
|
||||||
|
beq(scratch, zero_reg, offset32);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
// Emit a nop in the branch delay slot if required.
|
// Emit a nop in the branch delay slot if required.
|
||||||
if (bdslot == PROTECT)
|
if (bdslot == PROTECT)
|
||||||
nop();
|
nop();
|
||||||
|
Loading…
Reference in New Issue
Block a user