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);
}
}
......
......@@ -5022,153 +5022,194 @@ void MacroAssembler::SmiToDoubleFPURegister(Register smi,
cvt_d_w(value, value);
}
static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst,
Label* overflow_label,
Label* no_overflow_label) {
DCHECK(overflow_label || no_overflow_label);
if (!overflow_label) {
DCHECK(no_overflow_label);
masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg));
} else {
masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg));
if (no_overflow_label) masm->Branch(no_overflow_label);
}
}
void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
const Operand& right,
Register overflow_dst,
Register scratch) {
void MacroAssembler::AddBranchOvf(Register dst, Register left,
const Operand& right, Label* overflow_label,
Label* no_overflow_label, Register scratch) {
if (right.is_reg()) {
AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
AddBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label,
scratch);
} else {
if (dst.is(left)) {
li(t9, right); // Load right.
mov(scratch, left); // Preserve left.
addu(dst, left, t9); // Left is overwritten.
xor_(scratch, dst, scratch); // Original left.
xor_(overflow_dst, dst, t9);
and_(overflow_dst, overflow_dst, scratch);
if (kArchVariant == kMips64r6) {
Register right_reg = t9;
DCHECK(!left.is(right_reg));
li(right_reg, Operand(right));
AddBranchOvf(dst, left, right_reg, overflow_label, no_overflow_label);
} else {
li(t9, right);
addu(dst, left, t9);
xor_(overflow_dst, dst, left);
xor_(scratch, dst, t9);
and_(overflow_dst, scratch, overflow_dst);
Register overflow_dst = t9;
DCHECK(!dst.is(scratch));
DCHECK(!dst.is(overflow_dst));
DCHECK(!scratch.is(overflow_dst));
DCHECK(!left.is(overflow_dst));
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
// Left is overwritten.
Addu(dst, left, static_cast<int32_t>(right.immediate()));
xor_(scratch, dst, scratch); // Original left.
// Load right since xori takes uint16 as immediate.
Addu(overflow_dst, zero_reg, right);
xor_(overflow_dst, dst, overflow_dst);
and_(overflow_dst, overflow_dst, scratch);
} else {
Addu(dst, left, static_cast<int32_t>(right.immediate()));
xor_(overflow_dst, dst, left);
// Load right since xori takes uint16 as immediate.
Addu(scratch, zero_reg, right);
xor_(scratch, dst, scratch);
and_(overflow_dst, scratch, overflow_dst);
}
BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label);
}
}
}
void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
Register right,
Register overflow_dst,
Register scratch) {
DCHECK(!dst.is(overflow_dst));
DCHECK(!dst.is(scratch));
DCHECK(!overflow_dst.is(scratch));
DCHECK(!overflow_dst.is(left));
DCHECK(!overflow_dst.is(right));
if (left.is(right) && dst.is(left)) {
DCHECK(!dst.is(t9));
DCHECK(!scratch.is(t9));
DCHECK(!left.is(t9));
DCHECK(!right.is(t9));
DCHECK(!overflow_dst.is(t9));
mov(t9, right);
right = t9;
}
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
addu(dst, left, right); // Left is overwritten.
xor_(scratch, dst, scratch); // Original left.
xor_(overflow_dst, dst, right);
and_(overflow_dst, overflow_dst, scratch);
} else if (dst.is(right)) {
mov(scratch, right); // Preserve right.
addu(dst, left, right); // Right is overwritten.
xor_(scratch, dst, scratch); // Original right.
xor_(overflow_dst, dst, left);
and_(overflow_dst, overflow_dst, scratch);
void MacroAssembler::AddBranchOvf(Register dst, Register left, Register right,
Label* overflow_label,
Label* no_overflow_label, Register scratch) {
if (kArchVariant == kMips64r6) {
if (!overflow_label) {
DCHECK(no_overflow_label);
DCHECK(!dst.is(scratch));
Register left_reg = left.is(dst) ? scratch : left;
Register right_reg = right.is(dst) ? t9 : right;
DCHECK(!dst.is(left_reg));
DCHECK(!dst.is(right_reg));
Move(left_reg, left);
Move(right_reg, right);
addu(dst, left, right);
bnvc(left_reg, right_reg, no_overflow_label);
} else {
bovc(left, right, overflow_label);
addu(dst, left, right);
if (no_overflow_label) bc(no_overflow_label);
}
} else {
addu(dst, left, right);
xor_(overflow_dst, dst, left);
xor_(scratch, dst, right);
and_(overflow_dst, scratch, overflow_dst);
}
}
Register overflow_dst = t9;
DCHECK(!dst.is(scratch));
DCHECK(!dst.is(overflow_dst));
DCHECK(!scratch.is(overflow_dst));
DCHECK(!left.is(overflow_dst));
DCHECK(!right.is(overflow_dst));
DCHECK(!left.is(scratch));
DCHECK(!right.is(scratch));
if (left.is(right) && dst.is(left)) {
mov(overflow_dst, right);
right = overflow_dst;
}
void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left,
const Operand& right,
Register overflow_dst,
Register scratch) {
if (right.is_reg()) {
DadduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
} else {
if (dst.is(left)) {
li(t9, right); // Load right.
mov(scratch, left); // Preserve left.
daddu(dst, left, t9); // Left is overwritten.
addu(dst, left, right); // Left is overwritten.
xor_(scratch, dst, scratch); // Original left.
xor_(overflow_dst, dst, t9);
xor_(overflow_dst, dst, right);
and_(overflow_dst, overflow_dst, scratch);
} else if (dst.is(right)) {
mov(scratch, right); // Preserve right.
addu(dst, left, right); // Right is overwritten.
xor_(scratch, dst, scratch); // Original right.
xor_(overflow_dst, dst, left);
and_(overflow_dst, overflow_dst, scratch);
} else {
li(t9, right); // Load right.
Daddu(dst, left, t9);
addu(dst, left, right);
xor_(overflow_dst, dst, left);
xor_(scratch, dst, t9);
xor_(scratch, dst, right);
and_(overflow_dst, scratch, overflow_dst);
}
BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label);
}
}
void MacroAssembler::SubBranchOvf(Register dst, Register left,
const Operand& right, Label* overflow_label,
Label* no_overflow_label, Register scratch) {
DCHECK(overflow_label || no_overflow_label);
if (right.is_reg()) {
SubBranchOvf(dst, left, right.rm(), overflow_label, no_overflow_label,
scratch);
} else {
Register overflow_dst = t9;
DCHECK(!dst.is(scratch));
DCHECK(!dst.is(overflow_dst));
DCHECK(!scratch.is(overflow_dst));
DCHECK(!left.is(overflow_dst));
DCHECK(!left.is(scratch));
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
// Left is overwritten.
Subu(dst, left, static_cast<int32_t>(right.immediate()));
// Load right since xori takes uint16 as immediate.
Addu(overflow_dst, zero_reg, right);
xor_(overflow_dst, scratch, overflow_dst); // scratch is original left.
xor_(scratch, dst, scratch); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else {
Subu(dst, left, right);
xor_(overflow_dst, dst, left);
// Load right since xori takes uint16 as immediate.
Addu(scratch, zero_reg, right);
xor_(scratch, left, scratch);
and_(overflow_dst, scratch, overflow_dst);
}
BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label);
}
}
void MacroAssembler::DadduAndCheckForOverflow(Register dst, Register left,
Register right,
Register overflow_dst,
Register scratch) {
DCHECK(!dst.is(overflow_dst));
void MacroAssembler::SubBranchOvf(Register dst, Register left, Register right,
Label* overflow_label,
Label* no_overflow_label, Register scratch) {
DCHECK(overflow_label || no_overflow_label);
Register overflow_dst = t9;
DCHECK(!dst.is(scratch));
DCHECK(!overflow_dst.is(scratch));
DCHECK(!dst.is(overflow_dst));
DCHECK(!scratch.is(overflow_dst));
DCHECK(!overflow_dst.is(left));
DCHECK(!overflow_dst.is(right));
DCHECK(!scratch.is(left));
DCHECK(!scratch.is(right));
if (left.is(right) && dst.is(left)) {
DCHECK(!dst.is(t9));
DCHECK(!scratch.is(t9));
DCHECK(!left.is(t9));
DCHECK(!right.is(t9));
DCHECK(!overflow_dst.is(t9));
mov(t9, right);
right = t9;
// This happens with some crankshaft code. Since Subu works fine if
// left == right, let's not make that restriction here.
if (left.is(right)) {
mov(dst, zero_reg);
if (no_overflow_label) {
Branch(no_overflow_label);
}
}
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
daddu(dst, left, right); // Left is overwritten.
xor_(scratch, dst, scratch); // Original left.
xor_(overflow_dst, dst, right);
and_(overflow_dst, overflow_dst, scratch);
subu(dst, left, right); // Left is overwritten.
xor_(overflow_dst, dst, scratch); // scratch is original left.
xor_(scratch, scratch, right); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else if (dst.is(right)) {
mov(scratch, right); // Preserve right.
daddu(dst, left, right); // Right is overwritten.
xor_(scratch, dst, scratch); // Original right.
subu(dst, left, right); // Right is overwritten.
xor_(overflow_dst, dst, left);
and_(overflow_dst, overflow_dst, scratch);
xor_(scratch, left, scratch); // Original right.
and_(overflow_dst, scratch, overflow_dst);
} else {
daddu(dst, left, right);
subu(dst, left, right);
xor_(overflow_dst, dst, left);
xor_(scratch, dst, right);
xor_(scratch, left, right);
and_(overflow_dst, scratch, overflow_dst);
}
BranchOvfHelper(this, overflow_dst, overflow_label, no_overflow_label);
}
static inline void BranchOvfHelper(MacroAssembler* masm, Register overflow_dst,
Label* overflow_label,
Label* no_overflow_label) {
DCHECK(overflow_label || no_overflow_label);
if (!overflow_label) {
DCHECK(no_overflow_label);
masm->Branch(no_overflow_label, ge, overflow_dst, Operand(zero_reg));
} else {
masm->Branch(overflow_label, lt, overflow_dst, Operand(zero_reg));
if (no_overflow_label) masm->Branch(no_overflow_label);
}
}
void MacroAssembler::DaddBranchOvf(Register dst, Register left,
const Operand& right, Label* overflow_label,
Label* no_overflow_label, Register scratch) {
......@@ -5238,138 +5279,6 @@ void MacroAssembler::DaddBranchOvf(Register dst, Register left, Register right,
}
void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
const Operand& right,
Register overflow_dst,
Register scratch) {
if (right.is_reg()) {
SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
} else {
if (dst.is(left)) {
li(t9, right); // Load right.
mov(scratch, left); // Preserve left.
Subu(dst, left, t9); // Left is overwritten.
xor_(overflow_dst, dst, scratch); // scratch is original left.
xor_(scratch, scratch, t9); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else {
li(t9, right);
subu(dst, left, t9);
xor_(overflow_dst, dst, left);
xor_(scratch, left, t9);
and_(overflow_dst, scratch, overflow_dst);
}
}
}
void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
Register right,
Register overflow_dst,
Register scratch) {
DCHECK(!dst.is(overflow_dst));
DCHECK(!dst.is(scratch));
DCHECK(!overflow_dst.is(scratch));
DCHECK(!overflow_dst.is(left));
DCHECK(!overflow_dst.is(right));
DCHECK(!scratch.is(left));
DCHECK(!scratch.is(right));
// This happens with some crankshaft code. Since Subu works fine if
// left == right, let's not make that restriction here.
if (left.is(right)) {
mov(dst, zero_reg);
mov(overflow_dst, zero_reg);
return;
}
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
subu(dst, left, right); // Left is overwritten.
xor_(overflow_dst, dst, scratch); // scratch is original left.
xor_(scratch, scratch, right); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else if (dst.is(right)) {
mov(scratch, right); // Preserve right.
subu(dst, left, right); // Right is overwritten.
xor_(overflow_dst, dst, left);
xor_(scratch, left, scratch); // Original right.
and_(overflow_dst, scratch, overflow_dst);
} else {
subu(dst, left, right);
xor_(overflow_dst, dst, left);
xor_(scratch, left, right);
and_(overflow_dst, scratch, overflow_dst);
}
}
void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left,
const Operand& right,
Register overflow_dst,
Register scratch) {
if (right.is_reg()) {
DsubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
} else {
if (dst.is(left)) {
li(t9, right); // Load right.
mov(scratch, left); // Preserve left.
dsubu(dst, left, t9); // Left is overwritten.
xor_(overflow_dst, dst, scratch); // scratch is original left.
xor_(scratch, scratch, t9); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else {
li(t9, right);
dsubu(dst, left, t9);
xor_(overflow_dst, dst, left);
xor_(scratch, left, t9);
and_(overflow_dst, scratch, overflow_dst);
}
}
}
void MacroAssembler::DsubuAndCheckForOverflow(Register dst, Register left,
Register right,
Register overflow_dst,
Register scratch) {
DCHECK(!dst.is(overflow_dst));
DCHECK(!dst.is(scratch));
DCHECK(!overflow_dst.is(scratch));
DCHECK(!overflow_dst.is(left));
DCHECK(!overflow_dst.is(right));
DCHECK(!scratch.is(left));
DCHECK(!scratch.is(right));
// This happens with some crankshaft code. Since Subu works fine if
// left == right, let's not make that restriction here.
if (left.is(right)) {
mov(dst, zero_reg);
mov(overflow_dst, zero_reg);
return;
}
if (dst.is(left)) {
mov(scratch, left); // Preserve left.
dsubu(dst, left, right); // Left is overwritten.
xor_(overflow_dst, dst, scratch); // scratch is original left.
xor_(scratch, scratch, right); // scratch is original left.
and_(overflow_dst, scratch, overflow_dst);
} else if (dst.is(right)) {
mov(scratch, right); // Preserve right.
dsubu(dst, left, right); // Right is overwritten.
xor_(overflow_dst, dst, left);
xor_(scratch, left, scratch); // Original right.
and_(overflow_dst, scratch, overflow_dst);
} else {
dsubu(dst, left, right);
xor_(overflow_dst, dst, left);
xor_(scratch, left, right);
and_(overflow_dst, scratch, overflow_dst);
}
}
void MacroAssembler::DsubBranchOvf(Register dst, Register left,
const Operand& right, Label* overflow_label,
Label* no_overflow_label, Register scratch) {
......
......@@ -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