Commit 738f4b69 authored by Clemens Backes's avatar Clemens Backes Committed by V8 LUCI CQ

[assembler] Remove the "no condition"

The no_condition / kNoCondition not only has the flaw that it's a
special case which represents an illegal / nonexisting condition, and
thus needs special handling in all methods which get a condition as
input (this check is often missing), it is also weird in that every
negative condition value must be considered a "no condition".

It turns out that this "no condition" is rarely used, and can easily be
avoided by duplicating methods, or storing a {base::Optional<Condition>}
instead (not needed anywhere yet).

This is a follow-up to https://crrev.com/c/3629553.

R=tebbi@chromium.org, pthier@chromium.org

Bug: v8:12425
Change-Id: Id2270b1660fcb0aff0a8460961b57068ed1c3c73
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3632102Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarPatrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80397}
parent e8cac377
......@@ -56,9 +56,6 @@ namespace internal {
class SafepointTableBuilder;
enum Condition {
// any value < 0 is considered no_condition
no_condition = -1,
overflow = 0,
no_overflow = 1,
below = 2,
......@@ -86,9 +83,6 @@ enum Condition {
};
// Returns the equivalent of !cc.
// Negation of the default no_condition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
return static_cast<Condition>(cc ^ 1);
}
......
......@@ -535,8 +535,6 @@ enum Opcode : uint32_t {
// On LOONG64 we use this enum to abstract from conditional branch instructions.
// The 'U' prefix is used to specify unsigned comparisons.
enum Condition {
// Any value < 0 is considered no_condition.
kNoCondition = -1,
overflow = 0,
no_overflow = 1,
Uless = 2,
......@@ -582,13 +580,9 @@ enum Condition {
uge = Ugreater_equal,
ule = Uless_equal,
ugt = Ugreater,
cc_default = kNoCondition
};
// Returns the equivalent of !cc.
// Negation of the default kNoCondition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
DCHECK(cc != cc_always);
return static_cast<Condition>(cc ^ 1);
......
......@@ -1006,8 +1006,6 @@ enum MSAMinorOpcode : uint32_t {
// Opposite conditions must be paired as odd/even numbers
// because 'NegateCondition' function flips LSB to negate condition.
enum Condition {
// Any value < 0 is considered no_condition.
kNoCondition = -1,
overflow = 0,
no_overflow = 1,
Uless = 2,
......@@ -1053,13 +1051,9 @@ enum Condition {
uge = Ugreater_equal,
ule = Uless_equal,
ugt = Ugreater,
cc_default = kNoCondition
};
// Returns the equivalent of !cc.
// Negation of the default kNoCondition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
DCHECK(cc != cc_always);
return static_cast<Condition>(cc ^ 1);
......
......@@ -1055,8 +1055,6 @@ enum MSAMinorOpcode : uint32_t {
// Opposite conditions must be paired as odd/even numbers
// because 'NegateCondition' function flips LSB to negate condition.
enum Condition {
// Any value < 0 is considered no_condition.
kNoCondition = -1,
overflow = 0,
no_overflow = 1,
Uless = 2,
......@@ -1102,13 +1100,9 @@ enum Condition {
uge = Ugreater_equal,
ule = Uless_equal,
ugt = Ugreater,
cc_default = kNoCondition
};
// Returns the equivalent of !cc.
// Negation of the default kNoCondition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
DCHECK(cc != cc_always);
return static_cast<Condition>(cc ^ 1);
......
......@@ -1115,8 +1115,7 @@ enum Opcode : uint32_t {
// The 'U' prefix is used to specify unsigned comparisons.
// Opposite conditions must be paired as odd/even numbers
// because 'NegateCondition' function flips LSB to negate condition.
enum Condition { // Any value < 0 is considered no_condition.
kNoCondition = -1,
enum Condition {
overflow = 0,
no_overflow = 1,
Uless = 2,
......@@ -1146,9 +1145,6 @@ enum Condition { // Any value < 0 is considered no_condition.
};
// Returns the equivalent of !cc.
// Negation of the default kNoCondition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
DCHECK(cc != cc_always);
return static_cast<Condition>(cc ^ 1);
......
......@@ -1068,8 +1068,6 @@ void Assembler::cdq() {
}
void Assembler::cmovq(Condition cc, Register dst, Register src) {
DCHECK_LE(0, cc); // Check for standard and degenerate 'no_condition'.
EnsureSpace ensure_space(this);
// Opcode: REX.W 0f 40 + cc /r.
emit_rex_64(dst, src);
......@@ -1079,8 +1077,6 @@ void Assembler::cmovq(Condition cc, Register dst, Register src) {
}
void Assembler::cmovq(Condition cc, Register dst, Operand src) {
DCHECK_LE(0, cc); // Check for standard and degenerate 'no_condition'.
EnsureSpace ensure_space(this);
// Opcode: REX.W 0f 40 + cc /r.
emit_rex_64(dst, src);
......@@ -1090,8 +1086,6 @@ void Assembler::cmovq(Condition cc, Register dst, Operand src) {
}
void Assembler::cmovl(Condition cc, Register dst, Register src) {
DCHECK_LE(0, cc); // Check for standard and degenerate 'no_condition'.
EnsureSpace ensure_space(this);
// Opcode: 0f 40 + cc /r.
emit_optional_rex_32(dst, src);
......@@ -1101,8 +1095,6 @@ void Assembler::cmovl(Condition cc, Register dst, Register src) {
}
void Assembler::cmovl(Condition cc, Register dst, Operand src) {
DCHECK_LE(0, cc); // Check for standard and degenerate 'no_condition'.
EnsureSpace ensure_space(this);
// Opcode: 0f 40 + cc /r.
emit_optional_rex_32(dst, src);
......
......@@ -63,9 +63,6 @@ class SafepointTableBuilder;
// Utility functions
enum Condition {
// any value < 0 is considered no_condition
no_condition = -1,
overflow = 0,
no_overflow = 1,
below = 2,
......@@ -93,9 +90,6 @@ enum Condition {
};
// Returns the equivalent of !cc.
// Negation of the default no_condition (-1) results in a non-default
// no_condition value (-2). As long as tests for no_condition check
// for condition < 0, this will work as expected.
inline Condition NegateCondition(Condition cc) {
return static_cast<Condition>(cc ^ 1);
}
......
......@@ -1852,7 +1852,6 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
#define __ tasm->
Loong64OperandConverter i(gen, instr);
Condition cc = kNoCondition;
// LOONG64 does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit loong64 pseudo-instructions, which are handled here by branch
......@@ -1861,14 +1860,14 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
// they are tested here.
if (instr->arch_opcode() == kLoong64Tst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
__ Branch(tlabel, cc, t8, Operand(zero_reg));
} else if (instr->arch_opcode() == kLoong64Add_d ||
instr->arch_opcode() == kLoong64Sub_d) {
UseScratchRegisterScope temps(tasm);
Register scratch = temps.Acquire();
Register scratch2 = temps.Acquire();
cc = FlagsConditionToConditionOvf(condition);
Condition cc = FlagsConditionToConditionOvf(condition);
__ srai_d(scratch, i.OutputRegister(), 32);
__ srai_w(scratch2, i.OutputRegister(), 31);
__ Branch(tlabel, cc, scratch2, Operand(scratch));
......@@ -1898,10 +1897,10 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
UNSUPPORTED_COND(kLoong64MulOvf_w, condition);
}
} else if (instr->arch_opcode() == kLoong64Cmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.TempRegister(0), i.TempRegister(0), 1);
......@@ -2009,13 +2008,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// last output of the instruction.
DCHECK_NE(0u, instr->OutputCount());
Register result = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = kNoCondition;
// Loong64 does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit loong64 pseudo-instructions, which are checked and handled here.
if (instr->arch_opcode() == kLoong64Tst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
if (cc == eq) {
__ Sltu(result, t8, 1);
} else {
......@@ -2026,7 +2024,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
instr->arch_opcode() == kLoong64Sub_d) {
UseScratchRegisterScope temps(tasm());
Register scratch = temps.Acquire();
cc = FlagsConditionToConditionOvf(condition);
Condition cc = FlagsConditionToConditionOvf(condition);
// Check for overflow creates 1 or 0 for result.
__ srli_d(scratch, i.OutputRegister(), 63);
__ srli_w(result, i.OutputRegister(), 31);
......@@ -2042,7 +2040,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// Overflow occurs if overflow register is not zero
__ Sgtu(result, t8, zero_reg);
} else if (instr->arch_opcode() == kLoong64Cmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
switch (cc) {
case eq:
case ne: {
......@@ -2139,7 +2137,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.OutputRegister(), i.TempRegister(0), 1);
......
......@@ -3602,7 +3602,6 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
#undef __
#define __ tasm->
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips pseudo-instructions, which are handled here by branch
......@@ -3612,7 +3611,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
MipsOperandConverter i(gen, instr);
if (instr->arch_opcode() == kMipsTst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
__ Branch(tlabel, cc, kScratchReg, Operand(zero_reg));
} else if (instr->arch_opcode() == kMipsAddOvf ||
instr->arch_opcode() == kMipsSubOvf) {
......@@ -3640,10 +3639,10 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
UNSUPPORTED_COND(kMipsMulOvf, condition);
}
} else if (instr->arch_opcode() == kMipsCmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.TempRegister(0), i.TempRegister(0), 1);
......@@ -3749,13 +3748,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// last output of the instruction.
DCHECK_NE(0u, instr->OutputCount());
Register result = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips pseudo-instructions, which are checked and handled here.
if (instr->arch_opcode() == kMipsTst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
if (cc == eq) {
__ Sltu(result, kScratchReg, 1);
} else {
......@@ -3770,7 +3768,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// Overflow occurs if overflow register is not zero
__ Sgtu(result, kScratchReg, zero_reg);
} else if (instr->arch_opcode() == kMipsCmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
switch (cc) {
case eq:
case ne: {
......@@ -3881,7 +3879,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.OutputRegister(), i.TempRegister(0), 1);
......
......@@ -3785,7 +3785,6 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
#define __ tasm->
MipsOperandConverter i(gen, instr);
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips pseudo-instructions, which are handled here by branch
......@@ -3794,11 +3793,11 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
// they are tested here.
if (instr->arch_opcode() == kMips64Tst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
__ Branch(tlabel, cc, kScratchReg, Operand(zero_reg));
} else if (instr->arch_opcode() == kMips64Dadd ||
instr->arch_opcode() == kMips64Dsub) {
cc = FlagsConditionToConditionOvf(condition);
Condition cc = FlagsConditionToConditionOvf(condition);
__ dsra32(kScratchReg, i.OutputRegister(), 0);
__ sra(kScratchReg2, i.OutputRegister(), 31);
__ Branch(tlabel, cc, kScratchReg2, Operand(kScratchReg));
......@@ -3828,10 +3827,10 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
UNSUPPORTED_COND(kMipsMulOvf, condition);
}
} else if (instr->arch_opcode() == kMips64Cmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.TempRegister(0), i.TempRegister(0), 1);
......@@ -3939,13 +3938,12 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// last output of the instruction.
DCHECK_NE(0u, instr->OutputCount());
Register result = i.OutputRegister(instr->OutputCount() - 1);
Condition cc = kNoCondition;
// MIPS does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit mips pseudo-instructions, which are checked and handled here.
if (instr->arch_opcode() == kMips64Tst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
if (cc == eq) {
__ Sltu(result, kScratchReg, 1);
} else {
......@@ -3954,7 +3952,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
return;
} else if (instr->arch_opcode() == kMips64Dadd ||
instr->arch_opcode() == kMips64Dsub) {
cc = FlagsConditionToConditionOvf(condition);
Condition cc = FlagsConditionToConditionOvf(condition);
// Check for overflow creates 1 or 0 for result.
__ dsrl32(kScratchReg, i.OutputRegister(), 31);
__ srl(kScratchReg2, i.OutputRegister(), 31);
......@@ -3970,7 +3968,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
// Overflow occurs if overflow register is not zero
__ Sgtu(result, kScratchReg, zero_reg);
} else if (instr->arch_opcode() == kMips64Cmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
switch (cc) {
case eq:
case ne: {
......@@ -4086,7 +4084,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
return;
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
if (cc == ls) {
__ xori(i.OutputRegister(), i.TempRegister(0), 1);
......
......@@ -3444,7 +3444,6 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
#define __ tasm->
RiscvOperandConverter i(gen, instr);
Condition cc = kNoCondition;
// RISC-V does not have condition code flags, so compare and branch are
// implemented differently than on the other arch's. The compare operations
// emit riscv64 pseudo-instructions, which are handled here by branch
......@@ -3453,11 +3452,11 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
// they are tested here.
if (instr->arch_opcode() == kRiscvTst) {
cc = FlagsConditionToConditionTst(condition);
Condition cc = FlagsConditionToConditionTst(condition);
__ Branch(tlabel, cc, kScratchReg, Operand(zero_reg));
} else if (instr->arch_opcode() == kRiscvAdd64 ||
instr->arch_opcode() == kRiscvSub64) {
cc = FlagsConditionToConditionOvf(condition);
Condition cc = FlagsConditionToConditionOvf(condition);
__ Sra64(kScratchReg, i.OutputRegister(), 32);
__ Sra64(kScratchReg2, i.OutputRegister(), 31);
__ Branch(tlabel, cc, kScratchReg2, Operand(kScratchReg));
......@@ -3487,17 +3486,17 @@ void AssembleBranchToLabels(CodeGenerator* gen, TurboAssembler* tasm,
UNSUPPORTED_COND(kRiscvMulOvf32, condition);
}
} else if (instr->arch_opcode() == kRiscvCmp) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
__ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
} else if (instr->arch_opcode() == kRiscvCmpZero) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
if (i.InputOrZeroRegister(0) == zero_reg && IsInludeEqual(cc)) {
__ Branch(tlabel);
} else if (i.InputOrZeroRegister(0) != zero_reg) {
__ Branch(tlabel, cc, i.InputRegister(0), Operand(zero_reg));
}
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
cc = FlagsConditionToConditionCmp(condition);
Condition cc = FlagsConditionToConditionCmp(condition);
Register lhs_register = sp;
uint32_t offset;
if (gen->ShouldApplyOffsetToStackCheck(instr, &offset)) {
......
......@@ -201,7 +201,7 @@ void RegExpMacroAssemblerIA32::CheckGreedyLoop(Label* on_equal) {
__ cmp(edi, Operand(backtrack_stackpointer(), 0));
__ j(not_equal, &fallthrough);
__ add(backtrack_stackpointer(), Immediate(kSystemPointerSize)); // Pop.
BranchOrBacktrack(no_condition, on_equal);
BranchOrBacktrack(on_equal);
__ bind(&fallthrough);
}
......@@ -296,7 +296,7 @@ void RegExpMacroAssemblerIA32::CheckNotBackReferenceIgnoreCase(
// Restore original values before failing.
__ pop(backtrack_stackpointer());
__ pop(edi);
BranchOrBacktrack(no_condition, on_no_match);
BranchOrBacktrack(on_no_match);
__ bind(&success);
// Restore original value before continuing.
......@@ -434,7 +434,7 @@ void RegExpMacroAssemblerIA32::CheckNotBackReference(int start_reg,
__ bind(&fail);
// Restore backtrack stackpointer.
__ pop(backtrack_stackpointer());
BranchOrBacktrack(no_condition, on_no_match);
BranchOrBacktrack(on_no_match);
__ bind(&success);
// Move current character position to position after match.
......@@ -1053,11 +1053,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
return Handle<HeapObject>::cast(code);
}
void RegExpMacroAssemblerIA32::GoTo(Label* to) {
BranchOrBacktrack(no_condition, to);
}
void RegExpMacroAssemblerIA32::GoTo(Label* to) { BranchOrBacktrack(to); }
void RegExpMacroAssemblerIA32::IfRegisterGE(int reg,
int comparand,
......@@ -1252,24 +1248,18 @@ void RegExpMacroAssemblerIA32::CheckPosition(int cp_offset,
}
}
void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
Label* to) {
if (condition < 0) { // No condition
if (to == nullptr) {
Backtrack();
return;
}
__ jmp(to);
return;
}
void RegExpMacroAssemblerIA32::BranchOrBacktrack(Label* to) {
if (to == nullptr) {
__ j(condition, &backtrack_label_);
Backtrack();
return;
}
__ j(condition, to);
__ jmp(to);
}
void RegExpMacroAssemblerIA32::BranchOrBacktrack(Condition condition,
Label* to) {
__ j(condition, to ? to : &backtrack_label_);
}
void RegExpMacroAssemblerIA32::SafeCall(Label* to) {
Label return_to;
......
......@@ -159,6 +159,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerIA32
// Byte size of chars in the string to match (decided by the Mode argument)
inline int char_size() const { return static_cast<int>(mode_); }
// Equivalent to an unconditional branch to the label, unless the label
// is nullptr, in which case it is a Backtrack.
void BranchOrBacktrack(Label* to);
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(Condition condition, Label* to);
......
......@@ -212,7 +212,7 @@ void RegExpMacroAssemblerX64::CheckGreedyLoop(Label* on_equal) {
__ cmpl(rdi, Operand(backtrack_stackpointer(), 0));
__ j(not_equal, &fallthrough);
Drop();
BranchOrBacktrack(no_condition, on_equal);
BranchOrBacktrack(on_equal);
__ bind(&fallthrough);
}
......@@ -1104,11 +1104,7 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
return Handle<HeapObject>::cast(code);
}
void RegExpMacroAssemblerX64::GoTo(Label* to) {
BranchOrBacktrack(no_condition, to);
}
void RegExpMacroAssemblerX64::GoTo(Label* to) { BranchOrBacktrack(to); }
void RegExpMacroAssemblerX64::IfRegisterGE(int reg,
int comparand,
......@@ -1318,24 +1314,18 @@ void RegExpMacroAssemblerX64::CheckPosition(int cp_offset,
}
}
void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition,
Label* to) {
if (condition < 0) { // No condition
if (to == nullptr) {
Backtrack();
return;
}
__ jmp(to);
return;
}
void RegExpMacroAssemblerX64::BranchOrBacktrack(Label* to) {
if (to == nullptr) {
__ j(condition, &backtrack_label_);
Backtrack();
return;
}
__ j(condition, to);
__ jmp(to);
}
void RegExpMacroAssemblerX64::BranchOrBacktrack(Condition condition,
Label* to) {
__ j(condition, to ? to : &backtrack_label_);
}
void RegExpMacroAssemblerX64::SafeCall(Label* to) {
__ call(to);
......
......@@ -195,6 +195,10 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64
// Byte size of chars in the string to match (decided by the Mode argument)
inline int char_size() { return static_cast<int>(mode_); }
// Equivalent to an unconditional branch to the label, unless the label
// is nullptr, in which case it is a Backtrack.
void BranchOrBacktrack(Label* to);
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(Condition condition, Label* to);
......
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