OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
976 UNREACHABLE(); | 976 UNREACHABLE(); |
977 } | 977 } |
978 } | 978 } |
979 | 979 |
980 | 980 |
981 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 981 void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
982 GenerateOsrPrologue(); | 982 GenerateOsrPrologue(); |
983 } | 983 } |
984 | 984 |
985 | 985 |
| 986 void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { |
| 987 Register dividend = ToRegister(instr->dividend()); |
| 988 int32_t divisor = instr->divisor(); |
| 989 ASSERT(dividend.is(ToRegister(instr->result()))); |
| 990 |
| 991 // Theoretically, a variation of the branch-free code for integer division by |
| 992 // a power of 2 (calculating the remainder via an additional multiplication |
| 993 // (which gets simplified to an 'and') and subtraction) should be faster, and |
| 994 // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to |
| 995 // indicate that positive dividends are heavily favored, so the branching |
| 996 // version performs better. |
| 997 HMod* hmod = instr->hydrogen(); |
| 998 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); |
| 999 Label dividend_is_not_negative, done; |
| 1000 if (hmod->left()->CanBeNegative()) { |
| 1001 __ testl(dividend, dividend); |
| 1002 __ j(not_sign, ÷nd_is_not_negative, Label::kNear); |
| 1003 // Note that this is correct even for kMinInt operands. |
| 1004 __ negl(dividend); |
| 1005 __ andl(dividend, Immediate(mask)); |
| 1006 __ negl(dividend); |
| 1007 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1008 DeoptimizeIf(zero, instr->environment()); |
| 1009 } |
| 1010 __ jmp(&done, Label::kNear); |
| 1011 } |
| 1012 |
| 1013 __ bind(÷nd_is_not_negative); |
| 1014 __ andl(dividend, Immediate(mask)); |
| 1015 __ bind(&done); |
| 1016 } |
| 1017 |
| 1018 |
986 void LCodeGen::DoModI(LModI* instr) { | 1019 void LCodeGen::DoModI(LModI* instr) { |
| 1020 if (instr->hydrogen()->RightIsPowerOf2()) { |
| 1021 return DoModByPowerOf2I(reinterpret_cast<LModByPowerOf2I*>(instr)); |
| 1022 } |
987 HMod* hmod = instr->hydrogen(); | 1023 HMod* hmod = instr->hydrogen(); |
988 HValue* left = hmod->left(); | 1024 HValue* left = hmod->left(); |
989 HValue* right = hmod->right(); | 1025 HValue* right = hmod->right(); |
990 if (hmod->RightIsPowerOf2()) { | 1026 |
991 // TODO(svenpanne) We should really do the strength reduction on the | 1027 Register left_reg = ToRegister(instr->left()); |
992 // Hydrogen level. | 1028 ASSERT(left_reg.is(rax)); |
993 Register left_reg = ToRegister(instr->left()); | 1029 Register right_reg = ToRegister(instr->right()); |
994 ASSERT(left_reg.is(ToRegister(instr->result()))); | 1030 ASSERT(!right_reg.is(rax)); |
995 | 1031 ASSERT(!right_reg.is(rdx)); |
996 // Note: The code below even works when right contains kMinInt. | 1032 Register result_reg = ToRegister(instr->result()); |
997 int32_t divisor = Abs(right->GetInteger32Constant()); | 1033 ASSERT(result_reg.is(rdx)); |
998 | 1034 |
999 Label left_is_not_negative, done; | 1035 Label done; |
1000 if (left->CanBeNegative()) { | 1036 // Check for x % 0, idiv would signal a divide error. We have to |
1001 __ testl(left_reg, left_reg); | 1037 // deopt in this case because we can't return a NaN. |
1002 __ j(not_sign, &left_is_not_negative, Label::kNear); | 1038 if (right->CanBeZero()) { |
1003 __ negl(left_reg); | 1039 __ testl(right_reg, right_reg); |
1004 __ andl(left_reg, Immediate(divisor - 1)); | 1040 DeoptimizeIf(zero, instr->environment()); |
1005 __ negl(left_reg); | 1041 } |
1006 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1042 |
1007 DeoptimizeIf(zero, instr->environment()); | 1043 // Check for kMinInt % -1, idiv would signal a divide error. We |
1008 } | 1044 // have to deopt if we care about -0, because we can't return that. |
| 1045 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { |
| 1046 Label no_overflow_possible; |
| 1047 __ cmpl(left_reg, Immediate(kMinInt)); |
| 1048 __ j(not_zero, &no_overflow_possible, Label::kNear); |
| 1049 __ cmpl(right_reg, Immediate(-1)); |
| 1050 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1051 DeoptimizeIf(equal, instr->environment()); |
| 1052 } else { |
| 1053 __ j(not_equal, &no_overflow_possible, Label::kNear); |
| 1054 __ Set(result_reg, 0); |
1009 __ jmp(&done, Label::kNear); | 1055 __ jmp(&done, Label::kNear); |
1010 } | 1056 } |
1011 | 1057 __ bind(&no_overflow_possible); |
1012 __ bind(&left_is_not_negative); | 1058 } |
1013 __ andl(left_reg, Immediate(divisor - 1)); | 1059 |
1014 __ bind(&done); | 1060 // Sign extend dividend in eax into edx:eax, since we are using only the low |
1015 } else { | 1061 // 32 bits of the values. |
1016 Register left_reg = ToRegister(instr->left()); | 1062 __ cdq(); |
1017 ASSERT(left_reg.is(rax)); | 1063 |
1018 Register right_reg = ToRegister(instr->right()); | 1064 // If we care about -0, test if the dividend is <0 and the result is 0. |
1019 ASSERT(!right_reg.is(rax)); | 1065 if (left->CanBeNegative() && |
1020 ASSERT(!right_reg.is(rdx)); | 1066 hmod->CanBeZero() && |
1021 Register result_reg = ToRegister(instr->result()); | 1067 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1022 ASSERT(result_reg.is(rdx)); | 1068 Label positive_left; |
1023 | 1069 __ testl(left_reg, left_reg); |
1024 Label done; | 1070 __ j(not_sign, &positive_left, Label::kNear); |
1025 // Check for x % 0, idiv would signal a divide error. We have to | 1071 __ idivl(right_reg); |
1026 // deopt in this case because we can't return a NaN. | 1072 __ testl(result_reg, result_reg); |
1027 if (right->CanBeZero()) { | 1073 DeoptimizeIf(zero, instr->environment()); |
1028 __ testl(right_reg, right_reg); | 1074 __ jmp(&done, Label::kNear); |
1029 DeoptimizeIf(zero, instr->environment()); | 1075 __ bind(&positive_left); |
| 1076 } |
| 1077 __ idivl(right_reg); |
| 1078 __ bind(&done); |
| 1079 } |
| 1080 |
| 1081 |
| 1082 void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { |
| 1083 Register dividend = ToRegister(instr->dividend()); |
| 1084 int32_t divisor = instr->divisor(); |
| 1085 ASSERT(dividend.is(ToRegister(instr->result()))); |
| 1086 |
| 1087 // If the divisor is positive, things are easy: There can be no deopts and we |
| 1088 // can simply do an arithmetic right shift. |
| 1089 if (divisor == 1) return; |
| 1090 int32_t shift = WhichPowerOf2Abs(divisor); |
| 1091 if (divisor > 1) { |
| 1092 __ sarl(dividend, Immediate(shift)); |
| 1093 return; |
| 1094 } |
| 1095 |
| 1096 // If the divisor is negative, we have to negate and handle edge cases. |
| 1097 Label not_kmin_int, done; |
| 1098 __ negl(dividend); |
| 1099 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1100 DeoptimizeIf(zero, instr->environment()); |
| 1101 } |
| 1102 if (instr->hydrogen()->left()->RangeCanInclude(kMinInt)) { |
| 1103 // Note that we could emit branch-free code, but that would need one more |
| 1104 // register. |
| 1105 __ j(no_overflow, ¬_kmin_int, Label::kNear); |
| 1106 if (divisor == -1) { |
| 1107 DeoptimizeIf(no_condition, instr->environment()); |
| 1108 } else { |
| 1109 __ movl(dividend, Immediate(kMinInt / divisor)); |
| 1110 __ jmp(&done, Label::kNear); |
1030 } | 1111 } |
1031 | 1112 } |
1032 // Check for kMinInt % -1, idiv would signal a divide error. We | 1113 __ bind(¬_kmin_int); |
1033 // have to deopt if we care about -0, because we can't return that. | 1114 __ sarl(dividend, Immediate(shift)); |
1034 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { | 1115 __ bind(&done); |
1035 Label no_overflow_possible; | 1116 } |
1036 __ cmpl(left_reg, Immediate(kMinInt)); | 1117 |
1037 __ j(not_zero, &no_overflow_possible, Label::kNear); | 1118 |
1038 __ cmpl(right_reg, Immediate(-1)); | 1119 void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { |
1039 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1120 Register dividend = ToRegister(instr->dividend()); |
1040 DeoptimizeIf(equal, instr->environment()); | 1121 int32_t divisor = instr->divisor(); |
1041 } else { | 1122 Register temp = ToRegister(instr->temp()); |
1042 __ j(not_equal, &no_overflow_possible, Label::kNear); | 1123 Register result = ToRegister(instr->result()); |
1043 __ Set(result_reg, 0); | 1124 |
1044 __ jmp(&done, Label::kNear); | 1125 if (divisor == 0) { |
1045 } | |
1046 __ bind(&no_overflow_possible); | |
1047 } | |
1048 | |
1049 // Sign extend dividend in eax into edx:eax, since we are using only the low | |
1050 // 32 bits of the values. | |
1051 __ cdq(); | |
1052 | |
1053 // If we care about -0, test if the dividend is <0 and the result is 0. | |
1054 if (left->CanBeNegative() && | |
1055 hmod->CanBeZero() && | |
1056 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
1057 Label positive_left; | |
1058 __ testl(left_reg, left_reg); | |
1059 __ j(not_sign, &positive_left, Label::kNear); | |
1060 __ idivl(right_reg); | |
1061 __ testl(result_reg, result_reg); | |
1062 DeoptimizeIf(zero, instr->environment()); | |
1063 __ jmp(&done, Label::kNear); | |
1064 __ bind(&positive_left); | |
1065 } | |
1066 __ idivl(right_reg); | |
1067 __ bind(&done); | |
1068 } | |
1069 } | |
1070 | |
1071 | |
1072 void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { | |
1073 ASSERT(instr->right()->IsConstantOperand()); | |
1074 | |
1075 const Register dividend = ToRegister(instr->left()); | |
1076 int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right())); | |
1077 const Register result = ToRegister(instr->result()); | |
1078 | |
1079 switch (divisor) { | |
1080 case 0: | |
1081 DeoptimizeIf(no_condition, instr->environment()); | 1126 DeoptimizeIf(no_condition, instr->environment()); |
1082 return; | 1127 return; |
1083 | 1128 } |
1084 case 1: | 1129 |
1085 if (!result.is(dividend)) { | 1130 // Find b which: 2^b < divisor_abs < 2^(b+1). |
1086 __ movl(result, dividend); | |
1087 } | |
1088 return; | |
1089 | |
1090 case -1: | |
1091 if (!result.is(dividend)) { | |
1092 __ movl(result, dividend); | |
1093 } | |
1094 __ negl(result); | |
1095 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
1096 DeoptimizeIf(zero, instr->environment()); | |
1097 } | |
1098 if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { | |
1099 DeoptimizeIf(overflow, instr->environment()); | |
1100 } | |
1101 return; | |
1102 } | |
1103 | |
1104 uint32_t divisor_abs = abs(divisor); | 1131 uint32_t divisor_abs = abs(divisor); |
1105 if (IsPowerOf2(divisor_abs)) { | 1132 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); |
1106 int32_t power = WhichPowerOf2(divisor_abs); | 1133 unsigned shift = 32 + b; // Precision +1bit (effectively). |
1107 if (divisor < 0) { | 1134 double multiplier_f = |
1108 __ movsxlq(result, dividend); | 1135 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; |
1109 __ neg(result); | 1136 int64_t multiplier; |
1110 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1137 if (multiplier_f - std::floor(multiplier_f) < 0.5) { |
1111 DeoptimizeIf(zero, instr->environment()); | 1138 multiplier = static_cast<int64_t>(std::floor(multiplier_f)); |
1112 } | |
1113 __ sar(result, Immediate(power)); | |
1114 } else { | |
1115 if (!result.is(dividend)) { | |
1116 __ movl(result, dividend); | |
1117 } | |
1118 __ sarl(result, Immediate(power)); | |
1119 } | |
1120 } else { | 1139 } else { |
1121 Register reg1 = ToRegister(instr->temp()); | 1140 multiplier = static_cast<int64_t>(std::floor(multiplier_f)) + 1; |
1122 Register reg2 = ToRegister(instr->result()); | 1141 } |
1123 | 1142 // The multiplier is a uint32. |
1124 // Find b which: 2^b < divisor_abs < 2^(b+1). | 1143 ASSERT(multiplier > 0 && |
1125 unsigned b = 31 - CompilerIntrinsics::CountLeadingZeros(divisor_abs); | 1144 multiplier < (static_cast<int64_t>(1) << 32)); |
1126 unsigned shift = 32 + b; // Precision +1bit (effectively). | 1145 // The multiply is int64, so sign-extend to r64. |
1127 double multiplier_f = | 1146 __ movsxlq(temp, dividend); |
1128 static_cast<double>(static_cast<uint64_t>(1) << shift) / divisor_abs; | 1147 if (divisor < 0 && |
1129 int64_t multiplier; | 1148 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1130 if (multiplier_f - std::floor(multiplier_f) < 0.5) { | 1149 __ neg(temp); |
1131 multiplier = static_cast<int64_t>(std::floor(multiplier_f)); | 1150 DeoptimizeIf(zero, instr->environment()); |
1132 } else { | 1151 } |
1133 multiplier = static_cast<int64_t>(std::floor(multiplier_f)) + 1; | 1152 __ Set(result, multiplier); |
1134 } | 1153 // Result just fit in r64, because it's int32 * uint32. |
1135 // The multiplier is a uint32. | 1154 __ imul(result, temp); |
1136 ASSERT(multiplier > 0 && | 1155 |
1137 multiplier < (static_cast<int64_t>(1) << 32)); | 1156 __ addq(result, Immediate(1 << 30)); |
1138 // The multiply is int64, so sign-extend to r64. | 1157 __ sar(result, Immediate(shift)); |
1139 __ movsxlq(reg1, dividend); | 1158 } |
1140 if (divisor < 0 && | 1159 |
1141 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1160 |
1142 __ neg(reg1); | 1161 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { |
1143 DeoptimizeIf(zero, instr->environment()); | 1162 Register dividend = ToRegister(instr->dividend()); |
1144 } | 1163 int32_t divisor = instr->divisor(); |
1145 __ Set(reg2, multiplier); | 1164 Register result = ToRegister(instr->result()); |
1146 // Result just fit in r64, because it's int32 * uint32. | 1165 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor)))); |
1147 __ imul(reg2, reg1); | 1166 ASSERT(!result.is(dividend)); |
1148 | 1167 |
1149 __ addq(reg2, Immediate(1 << 30)); | 1168 // Check for (0 / -x) that will produce negative zero. |
1150 __ sar(reg2, Immediate(shift)); | 1169 HDiv* hdiv = instr->hydrogen(); |
1151 } | 1170 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && |
| 1171 hdiv->left()->RangeCanInclude(0) && divisor < 0) { |
| 1172 __ testl(dividend, dividend); |
| 1173 DeoptimizeIf(zero, instr->environment()); |
| 1174 } |
| 1175 // Check for (kMinInt / -1). |
| 1176 if (hdiv->CheckFlag(HValue::kCanOverflow) && |
| 1177 hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) { |
| 1178 __ cmpl(dividend, Immediate(kMinInt)); |
| 1179 DeoptimizeIf(zero, instr->environment()); |
| 1180 } |
| 1181 // Deoptimize if remainder will not be 0. |
| 1182 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1183 divisor != 1 && divisor != -1) { |
| 1184 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); |
| 1185 __ testl(dividend, Immediate(mask)); |
| 1186 DeoptimizeIf(not_zero, instr->environment()); |
| 1187 } |
| 1188 __ Move(result, dividend); |
| 1189 int32_t shift = WhichPowerOf2Abs(divisor); |
| 1190 if (shift > 0) { |
| 1191 // The arithmetic shift is always OK, the 'if' is an optimization only. |
| 1192 if (shift > 1) __ sarl(result, Immediate(31)); |
| 1193 __ shrl(result, Immediate(32 - shift)); |
| 1194 __ addl(result, dividend); |
| 1195 __ sarl(result, Immediate(shift)); |
| 1196 } |
| 1197 if (divisor < 0) __ negl(result); |
1152 } | 1198 } |
1153 | 1199 |
1154 | 1200 |
1155 void LCodeGen::DoDivI(LDivI* instr) { | 1201 void LCodeGen::DoDivI(LDivI* instr) { |
1156 if (!instr->is_flooring() && instr->hydrogen()->RightIsPowerOf2()) { | 1202 Register dividend = ToRegister(instr->left()); |
1157 Register dividend = ToRegister(instr->left()); | 1203 Register divisor = ToRegister(instr->right()); |
1158 HDiv* hdiv = instr->hydrogen(); | 1204 Register remainder = ToRegister(instr->temp()); |
1159 int32_t divisor = hdiv->right()->GetInteger32Constant(); | 1205 Register result = ToRegister(instr->result()); |
1160 Register result = ToRegister(instr->result()); | 1206 ASSERT(dividend.is(rax)); |
1161 ASSERT(!result.is(dividend)); | 1207 ASSERT(remainder.is(rdx)); |
1162 | 1208 ASSERT(result.is(rax)); |
1163 // Check for (0 / -x) that will produce negative zero. | 1209 ASSERT(!divisor.is(rax)); |
1164 if (hdiv->left()->RangeCanInclude(0) && divisor < 0 && | 1210 ASSERT(!divisor.is(rdx)); |
1165 hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
1166 __ testl(dividend, dividend); | |
1167 DeoptimizeIf(zero, instr->environment()); | |
1168 } | |
1169 // Check for (kMinInt / -1). | |
1170 if (hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1 && | |
1171 hdiv->CheckFlag(HValue::kCanOverflow)) { | |
1172 __ cmpl(dividend, Immediate(kMinInt)); | |
1173 DeoptimizeIf(zero, instr->environment()); | |
1174 } | |
1175 // Deoptimize if remainder will not be 0. | |
1176 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | |
1177 __ testl(dividend, Immediate(Abs(divisor) - 1)); | |
1178 DeoptimizeIf(not_zero, instr->environment()); | |
1179 } | |
1180 __ Move(result, dividend); | |
1181 int32_t shift = WhichPowerOf2(Abs(divisor)); | |
1182 if (shift > 0) { | |
1183 // The arithmetic shift is always OK, the 'if' is an optimization only. | |
1184 if (shift > 1) __ sarl(result, Immediate(31)); | |
1185 __ shrl(result, Immediate(32 - shift)); | |
1186 __ addl(result, dividend); | |
1187 __ sarl(result, Immediate(shift)); | |
1188 } | |
1189 if (divisor < 0) __ negl(result); | |
1190 return; | |
1191 } | |
1192 | |
1193 LOperand* right = instr->right(); | |
1194 ASSERT(ToRegister(instr->result()).is(rax)); | |
1195 ASSERT(ToRegister(instr->left()).is(rax)); | |
1196 ASSERT(!ToRegister(instr->right()).is(rax)); | |
1197 ASSERT(!ToRegister(instr->right()).is(rdx)); | |
1198 | |
1199 Register left_reg = rax; | |
1200 | 1211 |
1201 // Check for x / 0. | 1212 // Check for x / 0. |
1202 Register right_reg = ToRegister(right); | 1213 HBinaryOperation* hdiv = instr->hydrogen(); |
1203 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { | 1214 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
1204 __ testl(right_reg, right_reg); | 1215 __ testl(divisor, divisor); |
1205 DeoptimizeIf(zero, instr->environment()); | 1216 DeoptimizeIf(zero, instr->environment()); |
1206 } | 1217 } |
1207 | 1218 |
1208 // Check for (0 / -x) that will produce negative zero. | 1219 // Check for (0 / -x) that will produce negative zero. |
1209 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1220 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { |
1210 Label left_not_zero; | 1221 Label dividend_not_zero; |
1211 __ testl(left_reg, left_reg); | 1222 __ testl(dividend, dividend); |
1212 __ j(not_zero, &left_not_zero, Label::kNear); | 1223 __ j(not_zero, ÷nd_not_zero, Label::kNear); |
1213 __ testl(right_reg, right_reg); | 1224 __ testl(divisor, divisor); |
1214 DeoptimizeIf(sign, instr->environment()); | 1225 DeoptimizeIf(sign, instr->environment()); |
1215 __ bind(&left_not_zero); | 1226 __ bind(÷nd_not_zero); |
1216 } | 1227 } |
1217 | 1228 |
1218 // Check for (kMinInt / -1). | 1229 // Check for (kMinInt / -1). |
1219 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)) { | 1230 if (hdiv->CheckFlag(HValue::kCanOverflow)) { |
1220 Label left_not_min_int; | 1231 Label dividend_not_min_int; |
1221 __ cmpl(left_reg, Immediate(kMinInt)); | 1232 __ cmpl(dividend, Immediate(kMinInt)); |
1222 __ j(not_zero, &left_not_min_int, Label::kNear); | 1233 __ j(not_zero, ÷nd_not_min_int, Label::kNear); |
1223 __ cmpl(right_reg, Immediate(-1)); | 1234 __ cmpl(divisor, Immediate(-1)); |
1224 DeoptimizeIf(zero, instr->environment()); | 1235 DeoptimizeIf(zero, instr->environment()); |
1225 __ bind(&left_not_min_int); | 1236 __ bind(÷nd_not_min_int); |
1226 } | 1237 } |
1227 | 1238 |
1228 // Sign extend to rdx. | 1239 // Sign extend to rdx (= remainder). |
1229 __ cdq(); | 1240 __ cdq(); |
1230 __ idivl(right_reg); | 1241 __ idivl(divisor); |
1231 | 1242 |
1232 if (instr->is_flooring()) { | 1243 if (instr->is_flooring()) { |
1233 Label done; | 1244 Label done; |
1234 __ testl(rdx, rdx); | 1245 __ testl(remainder, remainder); |
1235 __ j(zero, &done, Label::kNear); | 1246 __ j(zero, &done, Label::kNear); |
1236 __ xorl(rdx, right_reg); | 1247 __ xorl(remainder, divisor); |
1237 __ sarl(rdx, Immediate(31)); | 1248 __ sarl(remainder, Immediate(31)); |
1238 __ addl(rax, rdx); | 1249 __ addl(result, remainder); |
1239 __ bind(&done); | 1250 __ bind(&done); |
1240 } else if (!instr->hydrogen()->CheckFlag( | 1251 } else if (!instr->hydrogen()->CheckFlag( |
1241 HInstruction::kAllUsesTruncatingToInt32)) { | 1252 HInstruction::kAllUsesTruncatingToInt32)) { |
1242 // Deoptimize if remainder is not 0. | 1253 // Deoptimize if remainder is not 0. |
1243 __ testl(rdx, rdx); | 1254 __ testl(remainder, remainder); |
1244 DeoptimizeIf(not_zero, instr->environment()); | 1255 DeoptimizeIf(not_zero, instr->environment()); |
1245 } | 1256 } |
1246 } | 1257 } |
1247 | 1258 |
1248 | 1259 |
1249 void LCodeGen::DoMulI(LMulI* instr) { | 1260 void LCodeGen::DoMulI(LMulI* instr) { |
1250 Register left = ToRegister(instr->left()); | 1261 Register left = ToRegister(instr->left()); |
1251 LOperand* right = instr->right(); | 1262 LOperand* right = instr->right(); |
1252 | 1263 |
1253 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1264 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
(...skipping 4333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5587 FixedArray::kHeaderSize - kPointerSize)); | 5598 FixedArray::kHeaderSize - kPointerSize)); |
5588 __ bind(&done); | 5599 __ bind(&done); |
5589 } | 5600 } |
5590 | 5601 |
5591 | 5602 |
5592 #undef __ | 5603 #undef __ |
5593 | 5604 |
5594 } } // namespace v8::internal | 5605 } } // namespace v8::internal |
5595 | 5606 |
5596 #endif // V8_TARGET_ARCH_X64 | 5607 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |