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