| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 8869a3e98d1b9d9fe89836d731b6e59ac3b94af2..9f336e5b57a722222c221045136db65b567bee2e 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -1497,6 +1497,67 @@ void LCodeGen::DoAddI(LAddI* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
|
| + LOperand* left = instr->InputAt(0);
|
| + LOperand* right = instr->InputAt(1);
|
| + ASSERT(left->Equals(instr->result()));
|
| + HMathMinMax::Operation operation = instr->hydrogen()->operation();
|
| + if (instr->hydrogen()->representation().IsInteger32()) {
|
| + Label return_left;
|
| + Condition condition = (operation == HMathMinMax::kMathMin)
|
| + ? less_equal
|
| + : greater_equal;
|
| + if (right->IsConstantOperand()) {
|
| + Operand left_op = ToOperand(left);
|
| + Immediate right_imm = ToInteger32Immediate(right);
|
| + __ cmp(left_op, right_imm);
|
| + __ j(condition, &return_left, Label::kNear);
|
| + __ mov(left_op, right_imm);
|
| + } else {
|
| + Register left_reg = ToRegister(left);
|
| + Operand right_op = ToOperand(right);
|
| + __ cmp(left_reg, right_op);
|
| + __ j(condition, &return_left, Label::kNear);
|
| + __ mov(left_reg, right_op);
|
| + }
|
| + __ bind(&return_left);
|
| + } else {
|
| + ASSERT(instr->hydrogen()->representation().IsDouble());
|
| + Label check_nan_left, check_zero, return_left, return_right;
|
| + Condition condition = (operation == HMathMinMax::kMathMin) ? below : above;
|
| + XMMRegister left_reg = ToDoubleRegister(left);
|
| + XMMRegister right_reg = ToDoubleRegister(right);
|
| + __ ucomisd(left_reg, right_reg);
|
| + __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN.
|
| + __ j(equal, &check_zero, Label::kNear); // left == right.
|
| + __ j(condition, &return_left, Label::kNear);
|
| + __ jmp(&return_right, Label::kNear);
|
| +
|
| + __ bind(&check_zero);
|
| + XMMRegister xmm_scratch = xmm0;
|
| + __ xorps(xmm_scratch, xmm_scratch);
|
| + __ ucomisd(left_reg, xmm_scratch);
|
| + __ j(not_equal, &return_left, Label::kNear); // left == right != 0.
|
| + // At this point, both left and right are either 0 or -0.
|
| + if (operation == HMathMinMax::kMathMin) {
|
| + __ orpd(left_reg, right_reg);
|
| + } else {
|
| + // Since we operate on +0 and/or -0, addsd and andsd have the same effect.
|
| + __ addsd(left_reg, right_reg);
|
| + }
|
| + __ jmp(&return_left, Label::kNear);
|
| +
|
| + __ bind(&check_nan_left);
|
| + __ ucomisd(left_reg, left_reg); // NaN check.
|
| + __ j(parity_even, &return_left, Label::kNear); // left == NaN.
|
| + __ bind(&return_right);
|
| + __ movsd(left_reg, right_reg);
|
| +
|
| + __ bind(&return_left);
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
|
| XMMRegister left = ToDoubleRegister(instr->InputAt(0));
|
| XMMRegister right = ToDoubleRegister(instr->InputAt(1));
|
|
|