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 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
875 __ jmp(&done, Label::kNear); | 875 __ jmp(&done, Label::kNear); |
876 | 876 |
877 __ bind(&remainder_eq_dividend); | 877 __ bind(&remainder_eq_dividend); |
878 __ movl(result_reg, left_reg); | 878 __ movl(result_reg, left_reg); |
879 | 879 |
880 __ bind(&done); | 880 __ bind(&done); |
881 } | 881 } |
882 } | 882 } |
883 | 883 |
884 | 884 |
885 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { | |
886 ASSERT(instr->InputAt(1)->IsConstantOperand()); | |
887 | |
888 const Register dividend = ToRegister(instr->InputAt(0)); | |
889 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); | |
890 const Register result = ToRegister(instr->result()); | |
891 | |
892 switch (divisor) { | |
893 case 0: | |
894 DeoptimizeIf(no_condition, instr->environment()); | |
895 return; | |
896 | |
897 case 1: | |
898 if (!result.is(dividend)) { | |
899 __ movl(result, dividend); | |
900 } | |
901 return; | |
902 | |
903 case -1: | |
904 if (!result.is(dividend)) { | |
905 __ movl(result, dividend); | |
906 } | |
907 __ negl(result); | |
908 // FIXME: set & check HValue::kBailoutOnMinusZero | |
Yang
2012/06/19 15:41:38
Any changes here?
| |
909 DeoptimizeIf(zero, instr->environment()); | |
910 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | |
911 DeoptimizeIf(overflow, instr->environment()); | |
912 } | |
913 return; | |
914 } | |
915 | |
916 uint32_t divisor_abs = abs(divisor); | |
917 if (IsPowerOf2(divisor_abs)) { | |
918 int32_t power = WhichPowerOf2(divisor_abs); | |
919 if (divisor < 0) { | |
920 __ movsxlq(result, dividend); | |
921 __ neg(result); | |
922 // FIXME: set & check HValue::kBailoutOnMinusZero | |
Yang
2012/06/19 15:41:38
Ditto.
| |
923 DeoptimizeIf(zero, instr->environment()); | |
924 __ sar(result, Immediate(power)); | |
925 } else { | |
926 if (!result.is(dividend)) { | |
927 __ movl(result, dividend); | |
928 } | |
929 __ sarl(result, Immediate(power)); | |
930 } | |
931 } else { | |
932 Register reg1 = ToRegister(instr->TempAt(0)); | |
933 Register reg2 = ToRegister(instr->result()); | |
934 | |
935 // b: 2^b < divisor_abs < 2^(b+1) | |
936 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); | |
937 unsigned shift = 32 + b; // precision +1bit (effectively) | |
938 double multiplier_f = static_cast<double>((uint64_t)1 << shift) | |
Yang
2012/06/19 15:41:38
Use static_cast please.
| |
939 / divisor_abs; | |
940 int64_t multiplier; | |
941 if (multiplier_f - floor(multiplier_f) < 0.5) { | |
942 multiplier = floor(multiplier_f); | |
943 } else { | |
944 multiplier = floor(multiplier_f) + 1; | |
945 } | |
946 // multiplier is a uint32 | |
947 ASSERT(multiplier > 0 && multiplier < ((int64_t)1<<32)); | |
Yang
2012/06/19 15:41:38
Use static_cast please.
| |
948 // the multiply is int64, so sign-extend to r64 | |
949 __ movsxlq(reg1, dividend); | |
950 if (divisor < 0) { | |
951 __ neg(reg1); | |
952 // FIXME: set & check HValue::kBailoutOnMinusZero | |
Yang
2012/06/19 15:41:38
Ditto.
| |
953 DeoptimizeIf(zero, instr->environment()); | |
954 } | |
955 __ movq(reg2, multiplier, RelocInfo::NONE); | |
956 // result just fit in r64: because it's int32 * uint32 | |
957 __ imul(reg2, reg1); | |
958 | |
959 __ addq(reg2, Immediate(1<<30)); // effectively +1/2d | |
960 __ sar(reg2, Immediate(shift)); | |
961 } | |
962 } | |
963 | |
964 | |
885 void LCodeGen::DoDivI(LDivI* instr) { | 965 void LCodeGen::DoDivI(LDivI* instr) { |
886 LOperand* right = instr->InputAt(1); | 966 LOperand* right = instr->InputAt(1); |
887 ASSERT(ToRegister(instr->result()).is(rax)); | 967 ASSERT(ToRegister(instr->result()).is(rax)); |
888 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); | 968 ASSERT(ToRegister(instr->InputAt(0)).is(rax)); |
889 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); | 969 ASSERT(!ToRegister(instr->InputAt(1)).is(rax)); |
890 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); | 970 ASSERT(!ToRegister(instr->InputAt(1)).is(rdx)); |
891 | 971 |
892 Register left_reg = rax; | 972 Register left_reg = rax; |
893 | 973 |
894 // Check for x / 0. | 974 // Check for x / 0. |
(...skipping 3916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4811 FixedArray::kHeaderSize - kPointerSize)); | 4891 FixedArray::kHeaderSize - kPointerSize)); |
4812 __ bind(&done); | 4892 __ bind(&done); |
4813 } | 4893 } |
4814 | 4894 |
4815 | 4895 |
4816 #undef __ | 4896 #undef __ |
4817 | 4897 |
4818 } } // namespace v8::internal | 4898 } } // namespace v8::internal |
4819 | 4899 |
4820 #endif // V8_TARGET_ARCH_X64 | 4900 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |