| Index: src/arm/lithium-codegen-arm.cc
|
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
|
| index a0da25c2b1d561a4203556d46f02b5be4d8e933c..698b6db2bdbd8222384f9612b0ec648f512de8cb 100644
|
| --- a/src/arm/lithium-codegen-arm.cc
|
| +++ b/src/arm/lithium-codegen-arm.cc
|
| @@ -1649,6 +1649,68 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
|
| + LOperand* left = instr->InputAt(0);
|
| + LOperand* right = instr->InputAt(1);
|
| + HMathMinMax::Operation operation = instr->hydrogen()->operation();
|
| + Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
|
| + if (instr->hydrogen()->representation().IsInteger32()) {
|
| + Register left_reg = ToRegister(left);
|
| + Operand right_op = (right->IsRegister() || right->IsConstantOperand())
|
| + ? ToOperand(right)
|
| + : Operand(EmitLoadRegister(right, ip));
|
| + Register result_reg = ToRegister(instr->result());
|
| + __ cmp(left_reg, right_op);
|
| + if (!result_reg.is(left_reg)) {
|
| + __ mov(result_reg, left_reg, LeaveCC, condition);
|
| + }
|
| + __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
|
| + } else {
|
| + ASSERT(instr->hydrogen()->representation().IsDouble());
|
| + DoubleRegister left_reg = ToDoubleRegister(left);
|
| + DoubleRegister right_reg = ToDoubleRegister(right);
|
| + DoubleRegister result_reg = ToDoubleRegister(instr->result());
|
| + Label check_nan_left, check_zero, return_left, return_right, done;
|
| + __ VFPCompareAndSetFlags(left_reg, right_reg);
|
| + __ b(vs, &check_nan_left);
|
| + __ b(eq, &check_zero);
|
| + __ b(condition, &return_left);
|
| + __ b(al, &return_right);
|
| +
|
| + __ bind(&check_zero);
|
| + __ VFPCompareAndSetFlags(left_reg, 0.0);
|
| + __ b(ne, &return_left); // left == right != 0.
|
| + // At this point, both left and right are either 0 or -0.
|
| + if (operation == HMathMinMax::kMathMin) {
|
| + // We could use a single 'vorr' instruction here if we had NEON support.
|
| + __ vneg(left_reg, left_reg);
|
| + __ vsub(result_reg, left_reg, right_reg);
|
| + __ vneg(result_reg, result_reg);
|
| + } else {
|
| + // Since we operate on +0 and/or -0, vadd and vand have the same effect;
|
| + // the decision for vadd is easy because vand is a NEON instruction.
|
| + __ vadd(result_reg, left_reg, right_reg);
|
| + }
|
| + __ b(al, &done);
|
| +
|
| + __ bind(&check_nan_left);
|
| + __ VFPCompareAndSetFlags(left_reg, left_reg);
|
| + __ b(vs, &return_left); // left == NaN.
|
| + __ bind(&return_right);
|
| + if (!right_reg.is(result_reg)) {
|
| + __ vmov(result_reg, right_reg);
|
| + }
|
| + __ b(al, &done);
|
| +
|
| + __ bind(&return_left);
|
| + if (!left_reg.is(result_reg)) {
|
| + __ vmov(result_reg, left_reg);
|
| + }
|
| + __ bind(&done);
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
|
| DoubleRegister left = ToDoubleRegister(instr->InputAt(0));
|
| DoubleRegister right = ToDoubleRegister(instr->InputAt(1));
|
|
|