| Index: src/compiler/mips64/code-generator-mips64.cc
|
| diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc
|
| index 8bc7deb35b21ff944052ffbea976e6aee5a484f4..a8a9457cf4eb89cd1355186b662cca61f70d67d4 100644
|
| --- a/src/compiler/mips64/code-generator-mips64.cc
|
| +++ b/src/compiler/mips64/code-generator-mips64.cc
|
| @@ -641,12 +641,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| case kMips64Dadd:
|
| __ Daddu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| break;
|
| + case kMips64DaddOvf:
|
| + // Pseudo-instruction used for overflow/branch. No opcode emitted here.
|
| + break;
|
| case kMips64Sub:
|
| __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| break;
|
| case kMips64Dsub:
|
| __ Dsubu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| break;
|
| + case kMips64DsubOvf:
|
| + // Pseudo-instruction used for overflow/branch. No opcode emitted here.
|
| + break;
|
| case kMips64Mul:
|
| __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
|
| break;
|
| @@ -1388,6 +1394,34 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
|
| __ dsra32(kScratchReg, i.OutputRegister(), 0);
|
| __ sra(at, i.OutputRegister(), 31);
|
| __ Branch(tlabel, cc, at, Operand(kScratchReg));
|
| + } else if (instr->arch_opcode() == kMips64DaddOvf) {
|
| + switch (branch->condition) {
|
| + case kOverflow:
|
| + __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), tlabel, flabel);
|
| + break;
|
| + case kNotOverflow:
|
| + __ DaddBranchOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), flabel, tlabel);
|
| + break;
|
| + default:
|
| + UNSUPPORTED_COND(kMips64DaddOvf, branch->condition);
|
| + break;
|
| + }
|
| + } else if (instr->arch_opcode() == kMips64DsubOvf) {
|
| + switch (branch->condition) {
|
| + case kOverflow:
|
| + __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), tlabel, flabel);
|
| + break;
|
| + case kNotOverflow:
|
| + __ DsubBranchOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), flabel, tlabel);
|
| + break;
|
| + default:
|
| + UNSUPPORTED_COND(kMips64DsubOvf, branch->condition);
|
| + break;
|
| + }
|
| } else if (instr->arch_opcode() == kMips64Cmp) {
|
| cc = FlagsConditionToConditionCmp(branch->condition);
|
| __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
|
| @@ -1462,6 +1496,28 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
|
| if (cc == eq) // Toggle result for not overflow.
|
| __ xori(result, result, 1);
|
| return;
|
| + } else if (instr->arch_opcode() == kMips64DaddOvf ||
|
| + instr->arch_opcode() == kMips64DsubOvf) {
|
| + Label flabel, tlabel;
|
| + switch (instr->arch_opcode()) {
|
| + case kMips64DaddOvf:
|
| + __ DaddBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), &flabel);
|
| +
|
| + break;
|
| + case kMips64DsubOvf:
|
| + __ DsubBranchNoOvf(i.OutputRegister(), i.InputRegister(0),
|
| + i.InputOperand(1), &flabel);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + __ li(result, 1);
|
| + __ Branch(&tlabel);
|
| + __ bind(&flabel);
|
| + __ li(result, 0);
|
| + __ bind(&tlabel);
|
| } else if (instr->arch_opcode() == kMips64Cmp) {
|
| cc = FlagsConditionToConditionCmp(condition);
|
| switch (cc) {
|
|
|