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:
balazs.kilvady 2015-11-16 09:21:49 -08:00 committed by Commit bot
parent 462cc3c6f0
commit bb332195d3

View File

@ -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();