Commit 515105a7 authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS64: Use BOVC/BNVC for overflow checking on r6.

Port 21b331e3

BUG=

Review URL: https://codereview.chromium.org/1784353003

Cr-Commit-Position: refs/heads/master@{#34731}
parent 90eb6341
......@@ -1338,9 +1338,10 @@ void LCodeGen::DoMulS(LMulS* instr) {
switch (constant) {
case -1:
if (overflow) {
__ DsubuAndCheckForOverflow(result, zero_reg, left, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, scratch,
Operand(zero_reg));
Label no_overflow;
__ DsubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow);
DeoptimizeIf(al, instr);
__ bind(&no_overflow);
} else {
__ Dsubu(result, zero_reg, left);
}
......@@ -1439,9 +1440,10 @@ void LCodeGen::DoMulI(LMulI* instr) {
switch (constant) {
case -1:
if (overflow) {
__ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, scratch,
Operand(zero_reg));
Label no_overflow;
__ SubBranchNoOvf(result, zero_reg, Operand(left), &no_overflow);
DeoptimizeIf(al, instr);
__ bind(&no_overflow);
} else {
__ Subu(result, zero_reg, left);
}
......@@ -1647,13 +1649,13 @@ void LCodeGen::DoSubS(LSubS* instr) {
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Dsubu(ToRegister(result), ToRegister(left), ToOperand(right));
} else { // can_overflow.
Register overflow = scratch0();
Register scratch = scratch1();
Register scratch = scratch0();
Label no_overflow_label;
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ DsubuAndCheckForOverflow(ToRegister(result), ToRegister(left),
ToOperand(right), overflow, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow,
Operand(zero_reg));
__ DsubBranchNoOvf(ToRegister(result), ToRegister(left), ToOperand(right),
&no_overflow_label, scratch);
DeoptimizeIf(al, instr);
__ bind(&no_overflow_label);
}
}
......@@ -1668,13 +1670,13 @@ void LCodeGen::DoSubI(LSubI* instr) {
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Subu(ToRegister(result), ToRegister(left), ToOperand(right));
} else { // can_overflow.
Register overflow = scratch0();
Register scratch = scratch1();
Register scratch = scratch0();
Label no_overflow_label;
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ SubuAndCheckForOverflow(ToRegister(result), ToRegister(left),
ToOperand(right), overflow, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow,
Operand(zero_reg));
__ SubBranchNoOvf(ToRegister(result), ToRegister(left), ToOperand(right),
&no_overflow_label, scratch);
DeoptimizeIf(al, instr);
__ bind(&no_overflow_label);
}
}
......@@ -1808,13 +1810,13 @@ void LCodeGen::DoAddS(LAddS* instr) {
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Daddu(ToRegister(result), ToRegister(left), ToOperand(right));
} else { // can_overflow.
Register overflow = scratch0();
Label no_overflow_label;
Register scratch = scratch1();
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ DadduAndCheckForOverflow(ToRegister(result), ToRegister(left),
ToOperand(right), overflow, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow,
Operand(zero_reg));
__ DaddBranchNoOvf(ToRegister(result), ToRegister(left), ToOperand(right),
&no_overflow_label, scratch);
DeoptimizeIf(al, instr);
__ bind(&no_overflow_label);
}
}
......@@ -1829,13 +1831,13 @@ void LCodeGen::DoAddI(LAddI* instr) {
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Addu(ToRegister(result), ToRegister(left), ToOperand(right));
} else { // can_overflow.
Register overflow = scratch0();
Label no_overflow_label;
Register scratch = scratch1();
DCHECK(right->IsRegister() || right->IsConstantOperand());
__ AdduAndCheckForOverflow(ToRegister(result), ToRegister(left),
ToOperand(right), overflow, scratch);
DeoptimizeIf(lt, instr, Deoptimizer::kOverflow, overflow,
Operand(zero_reg));
__ AddBranchNoOvf(ToRegister(result), ToRegister(left), ToOperand(right),
&no_overflow_label, scratch);
DeoptimizeIf(al, instr);
__ bind(&no_overflow_label);
}
}
......
......@@ -2083,12 +2083,10 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
break;
}
case Token::ADD:
__ DadduAndCheckForOverflow(v0, left, right, scratch1);
__ BranchOnOverflow(&stub_call, scratch1);
__ DaddBranchOvf(v0, left, Operand(right), &stub_call);
break;
case Token::SUB:
__ DsubuAndCheckForOverflow(v0, left, right, scratch1);
__ BranchOnOverflow(&stub_call, scratch1);
__ DsubBranchOvf(v0, left, Operand(right), &stub_call);
break;
case Token::MUL: {
__ Dmulh(v0, left, right);
......@@ -3672,10 +3670,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
}
Register scratch1 = a1;
Register scratch2 = a4;
__ li(scratch1, Operand(Smi::FromInt(count_value)));
__ DadduAndCheckForOverflow(v0, v0, scratch1, scratch2);
__ BranchOnNoOverflow(&done, scratch2);
__ DaddBranchNoOvf(v0, v0, Operand(scratch1), &done);
// Call stub. Undo operation first.
__ Move(v0, a0);
__ jmp(&stub_call);
......
......@@ -1387,7 +1387,6 @@ void Assembler::bne(Register rs, Register rt, int16_t offset) {
void Assembler::bovc(Register rs, Register rt, int16_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK(!rs.is(zero_reg));
if (rs.code() >= rt.code()) {
GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
} else {
......@@ -1398,7 +1397,6 @@ void Assembler::bovc(Register rs, Register rt, int16_t offset) {
void Assembler::bnvc(Register rs, Register rt, int16_t offset) {
DCHECK(IsMipsArchVariant(kMips32r6));
DCHECK(!rs.is(zero_reg));
if (rs.code() >= rt.code()) {
GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
} else {
......
......@@ -1372,17 +1372,21 @@ void Assembler::bne(Register rs, Register rt, int16_t offset) {
void Assembler::bovc(Register rs, Register rt, int16_t offset) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(!(rs.is(zero_reg)));
DCHECK(rs.code() >= rt.code());
GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
if (rs.code() >= rt.code()) {
GenInstrImmediate(ADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
} else {
GenInstrImmediate(ADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
}
}
void Assembler::bnvc(Register rs, Register rt, int16_t offset) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(!(rs.is(zero_reg)));
DCHECK(rs.code() >= rt.code());
GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
if (rs.code() >= rt.code()) {
GenInstrImmediate(DADDI, rs, rt, offset, CompactBranchType::COMPACT_BRANCH);
} else {
GenInstrImmediate(DADDI, rt, rs, offset, CompactBranchType::COMPACT_BRANCH);
}
}
......
This diff is collapsed.
......@@ -1298,32 +1298,41 @@ class MacroAssembler: public Assembler {
// Usage: first call the appropriate arithmetic function, then call one of the
// jump functions with the overflow_dst register as the second parameter.
void AdduAndCheckForOverflow(Register dst,
Register left,
Register right,
Register overflow_dst,
Register scratch = at);
inline void AddBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Register scratch = at) {
AddBranchOvf(dst, left, right, overflow_label, nullptr, scratch);
}
inline void AddBranchNoOvf(Register dst, Register left, const Operand& right,
Label* no_overflow_label, Register scratch = at) {
AddBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch);
}
void AddBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Label* no_overflow_label,
Register scratch = at);
void AdduAndCheckForOverflow(Register dst, Register left,
const Operand& right, Register overflow_dst,
Register scratch);
void AddBranchOvf(Register dst, Register left, Register right,
Label* overflow_label, Label* no_overflow_label,
Register scratch = at);
void SubuAndCheckForOverflow(Register dst,
Register left,
Register right,
Register overflow_dst,
Register scratch = at);
inline void SubBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Register scratch = at) {
SubBranchOvf(dst, left, right, overflow_label, nullptr, scratch);
}
void SubuAndCheckForOverflow(Register dst, Register left,
const Operand& right, Register overflow_dst,
Register scratch);
inline void SubBranchNoOvf(Register dst, Register left, const Operand& right,
Label* no_overflow_label, Register scratch = at) {
SubBranchOvf(dst, left, right, nullptr, no_overflow_label, scratch);
}
void DadduAndCheckForOverflow(Register dst, Register left, Register right,
Register overflow_dst, Register scratch = at);
void SubBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Label* no_overflow_label,
Register scratch = at);
void DadduAndCheckForOverflow(Register dst, Register left,
const Operand& right, Register overflow_dst,
Register scratch);
void SubBranchOvf(Register dst, Register left, Register right,
Label* overflow_label, Label* no_overflow_label,
Register scratch = at);
inline void DaddBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Register scratch = at) {
......@@ -1343,13 +1352,6 @@ class MacroAssembler: public Assembler {
Label* overflow_label, Label* no_overflow_label,
Register scratch = at);
void DsubuAndCheckForOverflow(Register dst, Register left, Register right,
Register overflow_dst, Register scratch = at);
void DsubuAndCheckForOverflow(Register dst, Register left,
const Operand& right, Register overflow_dst,
Register scratch);
inline void DsubBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Register scratch = at) {
DsubBranchOvf(dst, left, right, overflow_label, nullptr, scratch);
......
......@@ -4330,11 +4330,8 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
if (kArchVariant == kMips64r6) {
if (rs_reg >= rt_reg) { // BOVC
if (HaveSameSign(rs, rt)) {
if (rs > 0) {
BranchCompactHelper(rs > Registers::kMaxValue - rt, 16);
} else if (rs < 0) {
BranchCompactHelper(rs < Registers::kMinValue - rt, 16);
}
int64_t sum = rs + rt;
BranchCompactHelper(sum < INT32_MIN || sum > INT32_MAX, 16);
}
} else {
if (rs_reg == 0) { // BEQZALC
......@@ -4364,11 +4361,8 @@ void Simulator::DecodeTypeImmediate(Instruction* instr) {
if (!HaveSameSign(rs, rt) || rs == 0 || rt == 0) {
BranchCompactHelper(true, 16);
} else {
if (rs > 0) {
BranchCompactHelper(rs <= Registers::kMaxValue - rt, 16);
} else if (rs < 0) {
BranchCompactHelper(rs >= Registers::kMinValue - rt, 16);
}
int64_t sum = rs + rt;
BranchCompactHelper(sum >= INT32_MIN && sum <= INT32_MAX, 16);
}
} else {
if (rs_reg == 0) { // BNEZALC
......
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