OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1386 } else { | 1386 } else { |
1387 __ addl(ToRegister(left), ToOperand(right)); | 1387 __ addl(ToRegister(left), ToOperand(right)); |
1388 } | 1388 } |
1389 | 1389 |
1390 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 1390 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
1391 DeoptimizeIf(overflow, instr->environment()); | 1391 DeoptimizeIf(overflow, instr->environment()); |
1392 } | 1392 } |
1393 } | 1393 } |
1394 | 1394 |
1395 | 1395 |
| 1396 void LCodeGen::DoMathMinMax(LMathMinMax* instr) { |
| 1397 LOperand* left = instr->InputAt(0); |
| 1398 LOperand* right = instr->InputAt(1); |
| 1399 ASSERT(left->Equals(instr->result())); |
| 1400 HMathMinMax::Operation operation = instr->hydrogen()->operation(); |
| 1401 if (instr->hydrogen()->representation().IsInteger32()) { |
| 1402 Label return_left; |
| 1403 Condition condition = (operation == HMathMinMax::kMathMin) |
| 1404 ? less_equal |
| 1405 : greater_equal; |
| 1406 Register left_reg = ToRegister(left); |
| 1407 if (right->IsConstantOperand()) { |
| 1408 Immediate right_imm = |
| 1409 Immediate(ToInteger32(LConstantOperand::cast(right))); |
| 1410 __ cmpq(left_reg, right_imm); |
| 1411 __ j(condition, &return_left, Label::kNear); |
| 1412 __ movq(left_reg, right_imm); |
| 1413 } else { |
| 1414 Operand right_op = ToOperand(right); |
| 1415 __ cmpq(left_reg, right_op); |
| 1416 __ j(condition, &return_left, Label::kNear); |
| 1417 __ movq(left_reg, right_op); |
| 1418 } |
| 1419 __ bind(&return_left); |
| 1420 } else { |
| 1421 ASSERT(instr->hydrogen()->representation().IsDouble()); |
| 1422 Label check_nan_left, check_zero, return_left, return_right; |
| 1423 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; |
| 1424 XMMRegister left_reg = ToDoubleRegister(left); |
| 1425 XMMRegister right_reg = ToDoubleRegister(right); |
| 1426 __ ucomisd(left_reg, right_reg); |
| 1427 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. |
| 1428 __ j(equal, &check_zero, Label::kNear); // left == right. |
| 1429 __ j(condition, &return_left, Label::kNear); |
| 1430 __ jmp(&return_right, Label::kNear); |
| 1431 |
| 1432 __ bind(&check_zero); |
| 1433 XMMRegister xmm_scratch = xmm0; |
| 1434 __ xorps(xmm_scratch, xmm_scratch); |
| 1435 __ ucomisd(left_reg, xmm_scratch); |
| 1436 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. |
| 1437 // At this point, both left and right are either 0 or -0. |
| 1438 if (operation == HMathMinMax::kMathMin) { |
| 1439 __ orpd(left_reg, right_reg); |
| 1440 } else { |
| 1441 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. |
| 1442 __ addsd(left_reg, right_reg); |
| 1443 } |
| 1444 __ jmp(&return_left, Label::kNear); |
| 1445 |
| 1446 __ bind(&check_nan_left); |
| 1447 __ ucomisd(left_reg, left_reg); // NaN check. |
| 1448 __ j(parity_even, &return_left, Label::kNear); |
| 1449 __ bind(&return_right); |
| 1450 __ movsd(left_reg, right_reg); |
| 1451 |
| 1452 __ bind(&return_left); |
| 1453 } |
| 1454 } |
| 1455 |
| 1456 |
1396 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 1457 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
1397 XMMRegister left = ToDoubleRegister(instr->InputAt(0)); | 1458 XMMRegister left = ToDoubleRegister(instr->InputAt(0)); |
1398 XMMRegister right = ToDoubleRegister(instr->InputAt(1)); | 1459 XMMRegister right = ToDoubleRegister(instr->InputAt(1)); |
1399 XMMRegister result = ToDoubleRegister(instr->result()); | 1460 XMMRegister result = ToDoubleRegister(instr->result()); |
1400 // All operations except MOD are computed in-place. | 1461 // All operations except MOD are computed in-place. |
1401 ASSERT(instr->op() == Token::MOD || left.is(result)); | 1462 ASSERT(instr->op() == Token::MOD || left.is(result)); |
1402 switch (instr->op()) { | 1463 switch (instr->op()) { |
1403 case Token::ADD: | 1464 case Token::ADD: |
1404 __ addsd(left, right); | 1465 __ addsd(left, right); |
1405 break; | 1466 break; |
(...skipping 3694 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5100 FixedArray::kHeaderSize - kPointerSize)); | 5161 FixedArray::kHeaderSize - kPointerSize)); |
5101 __ bind(&done); | 5162 __ bind(&done); |
5102 } | 5163 } |
5103 | 5164 |
5104 | 5165 |
5105 #undef __ | 5166 #undef __ |
5106 | 5167 |
5107 } } // namespace v8::internal | 5168 } } // namespace v8::internal |
5108 | 5169 |
5109 #endif // V8_TARGET_ARCH_X64 | 5170 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |