Bug 1183842 - Use InvertCondition to expand the range of conditional branches. r=h4writer

This commit is contained in:
Sean Stangl 2015-07-14 12:20:02 -07:00
parent d9c7a266eb
commit 1c6d1661b1
5 changed files with 59 additions and 16 deletions

View File

@ -1557,15 +1557,12 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
Ret(vixl::ip0);
}
void j(Condition code, Label* dest) {
b(dest, code);
}
void j(Label* dest) {
b(dest, Always);
void j(Condition cond, Label* dest) {
B(dest, cond);
}
void branch(Condition cond, Label* label) {
b(label, cond);
B(label, cond);
}
void branch(JitCode* target) {
syncStackPtr();
@ -1576,20 +1573,20 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
void branch32(Condition cond, const Operand& lhs, Register rhs, Label* label) {
// since rhs is an operand, do the compare backwards
Cmp(ARMRegister(rhs, 32), lhs);
b(label, Assembler::InvertCmpCondition(cond));
B(label, Assembler::InvertCmpCondition(cond));
}
void branch32(Condition cond, const Operand& lhs, Imm32 rhs, Label* label) {
ARMRegister l = lhs.reg();
Cmp(l, Operand(rhs.value));
b(label, cond);
B(label, cond);
}
void branch32(Condition cond, Register lhs, Register rhs, Label* label) {
cmp32(lhs, rhs);
b(label, cond);
B(label, cond);
}
void branch32(Condition cond, Register lhs, Imm32 imm, Label* label) {
cmp32(lhs, imm);
b(label, cond);
B(label, cond);
}
void branch32(Condition cond, const Address& lhs, Register rhs, Label* label) {
vixl::UseScratchRegisterScope temps(this);
@ -1676,7 +1673,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
MOZ_ASSERT(!label->bound());
if (cond != Always) {
Label notTaken;
b(&notTaken, Assembler::InvertCondition(cond));
B(&notTaken, Assembler::InvertCondition(cond));
branch_bo = b(-1);
bind(&notTaken);
} else {
@ -2536,7 +2533,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
Label onFalse;
branch(Zero, &onFalse);
branch(Overflow, &onFalse);
b(label);
B(label);
bind(&onFalse);
}
}

View File

@ -211,6 +211,29 @@ LSDataSize CalcLSPairDataSize(LoadStorePairOp op) {
}
int Instruction::ImmBranchRangeBitwidth(ImmBranchType branch_type) {
switch (branch_type) {
case UncondBranchType:
return ImmUncondBranch_width;
case CondBranchType:
return ImmCondBranch_width;
case CompareBranchType:
return ImmCmpBranch_width;
case TestBranchType:
return ImmTestBranch_width;
default:
VIXL_UNREACHABLE();
return 0;
}
}
bool Instruction::IsValidImmPCOffset(ImmBranchType branch_type,
int32_t offset) {
return is_intn(ImmBranchRangeBitwidth(branch_type), offset);
}
const Instruction* Instruction::ImmPCOffsetTarget() const {
const Instruction * base = this;
ptrdiff_t offset;

View File

@ -271,6 +271,9 @@ class Instruction {
INSTRUCTION_FIELDS_LIST(DEFINE_SETTERS)
#undef DEFINE_SETTERS
static int ImmBranchRangeBitwidth(ImmBranchType branch_type);
static bool IsValidImmPCOffset(ImmBranchType branch_type, int32_t offset);
// Indicate whether Rd can be the stack pointer or the zero register. This
// does not check that the instruction actually has an Rd field.
Reg31Mode RdMode() const {

View File

@ -63,6 +63,25 @@ void MacroAssembler::B(Label* label, BranchType type, Register reg, int bit) {
}
void MacroAssembler::B(Label* label, Condition cond) {
VIXL_ASSERT((cond != al) && (cond != nv));
if (label->bound() && LabelIsOutOfRange(label, CondBranchType)) {
// If the label is out of range, invert the condition to use an
// unconditional branch, which has 26 bits instead of 19.
Label done;
b(&done, InvertCondition(cond));
b(label);
bind(&done);
} else {
// TODO: Need to register a slot in a literal pool, so that we can
// write a branch instruction there and use that to branch in case
// the unbound label winds up being out of range.
b(label, cond);
}
}
void MacroAssembler::And(const Register& rd, const Register& rn, const Operand& operand) {
LogicalMacro(rd, rn, operand, AND);
}

View File

@ -328,10 +328,7 @@ class MacroAssembler : public js::jit::Assembler {
void B(Label* label) {
b(label);
}
void B(Label* label, Condition cond) {
VIXL_ASSERT((cond != al) && (cond != nv));
b(label, cond);
}
void B(Label* label, Condition cond);
void B(Condition cond, Label* label) {
B(label, cond);
}
@ -1076,6 +1073,10 @@ class MacroAssembler : public js::jit::Assembler {
void PrepareForPush(int count, int size);
void PrepareForPop(int count, int size);
bool LabelIsOutOfRange(Label* label, ImmBranchType branch_type) {
return !Instruction::IsValidImmPCOffset(branch_type, nextOffset().diffB<int32_t>(label));
}
#if DEBUG
// Tell whether any of the macro instruction can be used. When false the
// MacroAssembler will assert if a method which can emit a variable number