| Index: src/mips/lithium-mips.cc
|
| diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
|
| index 3d5d663e6716e391d71ac8130e27a493b872474e..8ce576da0a3a9c252b3b18c1846ab9a8b387166e 100644
|
| --- a/src/mips/lithium-mips.cc
|
| +++ b/src/mips/lithium-mips.cc
|
| @@ -1283,8 +1283,22 @@ LInstruction* LChunkBuilder::DoMul(HMul* instr) {
|
| return DefineAsRegister(mul);
|
|
|
| } else if (instr->representation().IsDouble()) {
|
| + if (kArchVariant == kMips32r2) {
|
| + if (instr->UseCount() == 1 && instr->uses().value()->IsAdd()) {
|
| + HAdd* add = HAdd::cast(instr->uses().value());
|
| + if (instr == add->left()) {
|
| + // This mul is the lhs of an add. The add and mul will be folded
|
| + // into a multiply-add.
|
| + return NULL;
|
| + }
|
| + if (instr == add->right() && !add->left()->IsMul()) {
|
| + // This mul is the rhs of an add, where the lhs is not another mul.
|
| + // The add and mul will be folded into a multiply-add.
|
| + return NULL;
|
| + }
|
| + }
|
| + }
|
| return DoArithmeticD(Token::MUL, instr);
|
| -
|
| } else {
|
| return DoArithmeticT(Token::MUL, instr);
|
| }
|
| @@ -1311,6 +1325,15 @@ LInstruction* LChunkBuilder::DoSub(HSub* instr) {
|
| }
|
|
|
|
|
| +LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
|
| + LOperand* multiplier_op = UseRegisterAtStart(mul->left());
|
| + LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
|
| + LOperand* addend_op = UseRegisterAtStart(addend);
|
| + return DefineSameAsFirst(new(zone()) LMultiplyAddD(addend_op, multiplier_op,
|
| + multiplicand_op));
|
| +}
|
| +
|
| +
|
| LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| if (instr->representation().IsInteger32()) {
|
| ASSERT(instr->left()->representation().IsInteger32());
|
| @@ -1324,6 +1347,15 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
|
| }
|
| return result;
|
| } else if (instr->representation().IsDouble()) {
|
| + if (kArchVariant == kMips32r2) {
|
| + if (instr->left()->IsMul())
|
| + return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
|
| +
|
| + if (instr->right()->IsMul()) {
|
| + ASSERT(!instr->left()->IsMul());
|
| + return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
|
| + }
|
| + }
|
| return DoArithmeticD(Token::ADD, instr);
|
| } else {
|
| ASSERT(instr->representation().IsTagged());
|
|
|