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 857 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 | 868 |
869 void LCodeGen::DoMulI(LMulI* instr) { | 869 void LCodeGen::DoMulI(LMulI* instr) { |
870 Register left = ToRegister(instr->InputAt(0)); | 870 Register left = ToRegister(instr->InputAt(0)); |
871 LOperand* right = instr->InputAt(1); | 871 LOperand* right = instr->InputAt(1); |
872 | 872 |
873 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 873 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
874 __ mov(ToRegister(instr->TempAt(0)), left); | 874 __ mov(ToRegister(instr->TempAt(0)), left); |
875 } | 875 } |
876 | 876 |
877 if (right->IsConstantOperand()) { | 877 if (right->IsConstantOperand()) { |
878 __ imul(left, left, ToInteger32(LConstantOperand::cast(right))); | 878 // Try strength reductions on the multiplication. |
| 879 // All replacement instructions are at most as long as the imul |
| 880 // and have better latency. |
| 881 int constant = ToInteger32(LConstantOperand::cast(right)); |
| 882 if (constant == -1) { |
| 883 __ neg(left); |
| 884 } else if (constant == 0) { |
| 885 __ xor_(left, Operand(left)); |
| 886 } else if (constant == 2) { |
| 887 __ add(left, Operand(left)); |
| 888 } else if (!instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| 889 // If we know that the multiplication can't overflow, it's safe to |
| 890 // use instructions that don't set the overflow flag for the |
| 891 // multiplication. |
| 892 switch (constant) { |
| 893 case 1: |
| 894 // Do nothing. |
| 895 break; |
| 896 case 3: |
| 897 __ lea(left, Operand(left, left, times_2, 0)); |
| 898 break; |
| 899 case 4: |
| 900 __ shl(left, 2); |
| 901 break; |
| 902 case 5: |
| 903 __ lea(left, Operand(left, left, times_4, 0)); |
| 904 break; |
| 905 case 8: |
| 906 __ shl(left, 3); |
| 907 break; |
| 908 case 9: |
| 909 __ lea(left, Operand(left, left, times_8, 0)); |
| 910 break; |
| 911 case 16: |
| 912 __ shl(left, 4); |
| 913 break; |
| 914 default: |
| 915 __ imul(left, left, constant); |
| 916 break; |
| 917 } |
| 918 } else { |
| 919 __ imul(left, left, constant); |
| 920 } |
879 } else { | 921 } else { |
880 __ imul(left, ToOperand(right)); | 922 __ imul(left, ToOperand(right)); |
881 } | 923 } |
882 | 924 |
883 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | 925 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
884 DeoptimizeIf(overflow, instr->environment()); | 926 DeoptimizeIf(overflow, instr->environment()); |
885 } | 927 } |
886 | 928 |
887 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 929 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
888 // Bail out if the result is supposed to be negative zero. | 930 // Bail out if the result is supposed to be negative zero. |
(...skipping 2981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3870 ASSERT(osr_pc_offset_ == -1); | 3912 ASSERT(osr_pc_offset_ == -1); |
3871 osr_pc_offset_ = masm()->pc_offset(); | 3913 osr_pc_offset_ = masm()->pc_offset(); |
3872 } | 3914 } |
3873 | 3915 |
3874 | 3916 |
3875 #undef __ | 3917 #undef __ |
3876 | 3918 |
3877 } } // namespace v8::internal | 3919 } } // namespace v8::internal |
3878 | 3920 |
3879 #endif // V8_TARGET_ARCH_IA32 | 3921 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |