Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 601 // Nothing to do. | 601 // Nothing to do. |
| 602 } | 602 } |
| 603 | 603 |
| 604 | 604 |
| 605 void LCodeGen::DoModI(LModI* instr) { | 605 void LCodeGen::DoModI(LModI* instr) { |
| 606 Abort("Unimplemented: %s", "DoModI"); | 606 Abort("Unimplemented: %s", "DoModI"); |
| 607 } | 607 } |
| 608 | 608 |
| 609 | 609 |
| 610 void LCodeGen::DoDivI(LDivI* instr) { | 610 void LCodeGen::DoDivI(LDivI* instr) { |
| 611 Abort("Unimplemented: %s", "DoDivI");} | 611 LOperand* right = instr->InputAt(1); |
| 612 ASSERT(ToRegister(instr->result()).is(rax)); | |
| 613 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); | |
| 614 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); | |
| 615 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); | |
| 616 | |
| 617 Register left_reg = rax; | |
| 618 | |
| 619 // Check for x / 0. | |
| 620 Register right_reg = ToRegister(right); | |
| 621 if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { | |
| 622 __ testl(right_reg, right_reg); | |
| 623 DeoptimizeIf(zero, instr->environment()); | |
| 624 } | |
| 625 | |
| 626 // Check for (0 / -x) that will produce negative zero. | |
| 627 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 628 NearLabel left_not_zero; | |
|
William Hesse
2011/02/08 09:42:47
Should we combine the zero test and the Min-int te
Rico
2011/02/08 11:22:04
I guess combining these could cause us to deoptimi
| |
| 629 __ testl(left_reg, left_reg); | |
| 630 __ j(not_zero, &left_not_zero); | |
| 631 __ testl(right_reg, right_reg); | |
| 632 DeoptimizeIf(sign, instr->environment()); | |
| 633 __ bind(&left_not_zero); | |
| 634 } | |
| 635 | |
| 636 // Check for (-kMinInt / -1). | |
| 637 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | |
| 638 NearLabel left_not_min_int; | |
| 639 __ cmpl(left_reg, Immediate(kMinInt)); | |
| 640 __ j(not_zero, &left_not_min_int); | |
| 641 __ cmpl(right_reg, Immediate(-1)); | |
| 642 DeoptimizeIf(zero, instr->environment()); | |
| 643 __ bind(&left_not_min_int); | |
| 644 } | |
| 645 | |
| 646 // Sign extend to rdx. | |
| 647 __ cdq(); | |
| 648 __ idivl(right_reg); | |
| 649 | |
| 650 // Deoptimize if remainder is not 0. | |
| 651 __ testl(rdx, rdx); | |
| 652 DeoptimizeIf(not_zero, instr->environment()); | |
| 653 } | |
| 612 | 654 |
| 613 | 655 |
| 614 void LCodeGen::DoMulI(LMulI* instr) { | 656 void LCodeGen::DoMulI(LMulI* instr) { |
| 615 Abort("Unimplemented: %s", "DoMultI");} | 657 Register left = ToRegister(instr->InputAt(0)); |
| 658 LOperand* right = instr->InputAt(1); | |
| 659 | |
| 660 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 661 __ movl(kScratchRegister, left); | |
| 662 } | |
| 663 | |
| 664 if (right->IsConstantOperand()) { | |
| 665 int right_value = ToInteger32(LConstantOperand::cast(right)); | |
| 666 __ imull(left, left, Immediate(right_value)); | |
| 667 } else if (right->IsStackSlot()) { | |
| 668 __ imul(left, ToOperand(right)); | |
| 669 } else { | |
| 670 __ imull(left, ToRegister(right)); | |
| 671 } | |
| 672 | |
| 673 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | |
| 674 DeoptimizeIf(overflow, instr->environment()); | |
| 675 } | |
| 676 | |
| 677 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 678 // Bail out if the result is supposed to be negative zero. | |
| 679 NearLabel done; | |
| 680 __ testl(left, left); | |
| 681 __ j(not_zero, &done); | |
| 682 if (right->IsConstantOperand()) { | |
| 683 if (ToInteger32(LConstantOperand::cast(right)) < 0) { | |
|
William Hesse
2011/02/08 09:42:47
What about the case where right is constant 0? An
Rico
2011/02/08 11:22:04
Fixed - here and on ia32 and arm. Bug and regressi
| |
| 684 DeoptimizeIf(no_condition, instr->environment()); | |
| 685 } | |
| 686 } else if (right->IsStackSlot()) { | |
| 687 __ or_(kScratchRegister, ToOperand(right)); | |
| 688 DeoptimizeIf(sign, instr->environment()); | |
| 689 } else { | |
| 690 // Test the non-zero operand for negative sign. | |
| 691 __ or_(kScratchRegister, ToRegister(right)); | |
| 692 DeoptimizeIf(sign, instr->environment()); | |
| 693 } | |
| 694 __ bind(&done); | |
| 695 } | |
| 696 } | |
| 616 | 697 |
| 617 | 698 |
| 618 void LCodeGen::DoBitI(LBitI* instr) { | 699 void LCodeGen::DoBitI(LBitI* instr) { |
| 619 LOperand* left = instr->InputAt(0); | 700 LOperand* left = instr->InputAt(0); |
| 620 LOperand* right = instr->InputAt(1); | 701 LOperand* right = instr->InputAt(1); |
| 621 ASSERT(left->Equals(instr->result())); | 702 ASSERT(left->Equals(instr->result())); |
| 622 ASSERT(left->IsRegister()); | 703 ASSERT(left->IsRegister()); |
| 623 | 704 |
| 624 if (right->IsConstantOperand()) { | 705 if (right->IsConstantOperand()) { |
| 625 int right_operand = ToInteger32(LConstantOperand::cast(right)); | 706 int right_operand = ToInteger32(LConstantOperand::cast(right)); |
| (...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2395 | 2476 |
| 2396 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 2477 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
| 2397 Abort("Unimplemented: %s", "DoOsrEntry"); | 2478 Abort("Unimplemented: %s", "DoOsrEntry"); |
| 2398 } | 2479 } |
| 2399 | 2480 |
| 2400 #undef __ | 2481 #undef __ |
| 2401 | 2482 |
| 2402 } } // namespace v8::internal | 2483 } } // namespace v8::internal |
| 2403 | 2484 |
| 2404 #endif // V8_TARGET_ARCH_X64 | 2485 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |