зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1183842 - Use InvertCondition to expand the range of conditional branches. r=h4writer
This commit is contained in:
Родитель
5d2028c280
Коммит
d738aed0de
|
@ -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(¬Taken, Assembler::InvertCondition(cond));
|
||||
B(¬Taken, Assembler::InvertCondition(cond));
|
||||
branch_bo = b(-1);
|
||||
bind(¬Taken);
|
||||
} else {
|
||||
|
@ -2536,7 +2533,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
|
|||
Label onFalse;
|
||||
branch(Zero, &onFalse);
|
||||
branch(Overflow, &onFalse);
|
||||
b(label);
|
||||
B(label);
|
||||
bind(&onFalse);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче