Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 191293013: Cleanup some of the range uses in ModI/DivI. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 __ FlooringDiv(dividend, Abs(divisor)); 1029 __ FlooringDiv(dividend, Abs(divisor));
1030 __ movl(rax, dividend); 1030 __ movl(rax, dividend);
1031 __ shrl(rax, Immediate(31)); 1031 __ shrl(rax, Immediate(31));
1032 __ addl(rdx, rax); 1032 __ addl(rdx, rax);
1033 __ imull(rdx, rdx, Immediate(Abs(divisor))); 1033 __ imull(rdx, rdx, Immediate(Abs(divisor)));
1034 __ movl(rax, dividend); 1034 __ movl(rax, dividend);
1035 __ subl(rax, rdx); 1035 __ subl(rax, rdx);
1036 1036
1037 // Check for negative zero. 1037 // Check for negative zero.
1038 HMod* hmod = instr->hydrogen(); 1038 HMod* hmod = instr->hydrogen();
1039 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && 1039 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1040 hmod->left()->CanBeNegative()) {
1041 Label remainder_not_zero; 1040 Label remainder_not_zero;
1042 __ j(not_zero, &remainder_not_zero, Label::kNear); 1041 __ j(not_zero, &remainder_not_zero, Label::kNear);
1043 __ cmpl(dividend, Immediate(0)); 1042 __ cmpl(dividend, Immediate(0));
1044 DeoptimizeIf(less, instr->environment()); 1043 DeoptimizeIf(less, instr->environment());
1045 __ bind(&remainder_not_zero); 1044 __ bind(&remainder_not_zero);
1046 } 1045 }
1047 } 1046 }
1048 1047
1049 1048
1050 void LCodeGen::DoModI(LModI* instr) { 1049 void LCodeGen::DoModI(LModI* instr) {
1051 if (instr->hydrogen()->RightIsPowerOf2()) {
1052 return DoModByPowerOf2I(reinterpret_cast<LModByPowerOf2I*>(instr));
1053 }
1054 HMod* hmod = instr->hydrogen(); 1050 HMod* hmod = instr->hydrogen();
1055 HValue* left = hmod->left();
1056 HValue* right = hmod->right();
1057 1051
1058 Register left_reg = ToRegister(instr->left()); 1052 Register left_reg = ToRegister(instr->left());
1059 ASSERT(left_reg.is(rax)); 1053 ASSERT(left_reg.is(rax));
1060 Register right_reg = ToRegister(instr->right()); 1054 Register right_reg = ToRegister(instr->right());
1061 ASSERT(!right_reg.is(rax)); 1055 ASSERT(!right_reg.is(rax));
1062 ASSERT(!right_reg.is(rdx)); 1056 ASSERT(!right_reg.is(rdx));
1063 Register result_reg = ToRegister(instr->result()); 1057 Register result_reg = ToRegister(instr->result());
1064 ASSERT(result_reg.is(rdx)); 1058 ASSERT(result_reg.is(rdx));
1065 1059
1066 Label done; 1060 Label done;
1067 // Check for x % 0, idiv would signal a divide error. We have to 1061 // Check for x % 0, idiv would signal a divide error. We have to
1068 // deopt in this case because we can't return a NaN. 1062 // deopt in this case because we can't return a NaN.
1069 if (right->CanBeZero()) { 1063 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
1070 __ testl(right_reg, right_reg); 1064 __ testl(right_reg, right_reg);
1071 DeoptimizeIf(zero, instr->environment()); 1065 DeoptimizeIf(zero, instr->environment());
1072 } 1066 }
1073 1067
1074 // Check for kMinInt % -1, idiv would signal a divide error. We 1068 // Check for kMinInt % -1, idiv would signal a divide error. We
1075 // have to deopt if we care about -0, because we can't return that. 1069 // have to deopt if we care about -0, because we can't return that.
1076 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { 1070 if (hmod->CheckFlag(HValue::kCanOverflow)) {
1077 Label no_overflow_possible; 1071 Label no_overflow_possible;
1078 __ cmpl(left_reg, Immediate(kMinInt)); 1072 __ cmpl(left_reg, Immediate(kMinInt));
1079 __ j(not_zero, &no_overflow_possible, Label::kNear); 1073 __ j(not_zero, &no_overflow_possible, Label::kNear);
1080 __ cmpl(right_reg, Immediate(-1)); 1074 __ cmpl(right_reg, Immediate(-1));
1081 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { 1075 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1082 DeoptimizeIf(equal, instr->environment()); 1076 DeoptimizeIf(equal, instr->environment());
1083 } else { 1077 } else {
1084 __ j(not_equal, &no_overflow_possible, Label::kNear); 1078 __ j(not_equal, &no_overflow_possible, Label::kNear);
1085 __ Set(result_reg, 0); 1079 __ Set(result_reg, 0);
1086 __ jmp(&done, Label::kNear); 1080 __ jmp(&done, Label::kNear);
1087 } 1081 }
1088 __ bind(&no_overflow_possible); 1082 __ bind(&no_overflow_possible);
1089 } 1083 }
1090 1084
1091 // Sign extend dividend in eax into edx:eax, since we are using only the low 1085 // Sign extend dividend in eax into edx:eax, since we are using only the low
1092 // 32 bits of the values. 1086 // 32 bits of the values.
1093 __ cdq(); 1087 __ cdq();
1094 1088
1095 // If we care about -0, test if the dividend is <0 and the result is 0. 1089 // If we care about -0, test if the dividend is <0 and the result is 0.
1096 if (left->CanBeNegative() && 1090 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1097 hmod->CanBeZero() &&
1098 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
1099 Label positive_left; 1091 Label positive_left;
1100 __ testl(left_reg, left_reg); 1092 __ testl(left_reg, left_reg);
1101 __ j(not_sign, &positive_left, Label::kNear); 1093 __ j(not_sign, &positive_left, Label::kNear);
1102 __ idivl(right_reg); 1094 __ idivl(right_reg);
1103 __ testl(result_reg, result_reg); 1095 __ testl(result_reg, result_reg);
1104 DeoptimizeIf(zero, instr->environment()); 1096 DeoptimizeIf(zero, instr->environment());
1105 __ jmp(&done, Label::kNear); 1097 __ jmp(&done, Label::kNear);
1106 __ bind(&positive_left); 1098 __ bind(&positive_left);
1107 } 1099 }
1108 __ idivl(right_reg); 1100 __ idivl(right_reg);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1152 int32_t divisor = instr->divisor(); 1144 int32_t divisor = instr->divisor();
1153 ASSERT(ToRegister(instr->result()).is(rdx)); 1145 ASSERT(ToRegister(instr->result()).is(rdx));
1154 1146
1155 if (divisor == 0) { 1147 if (divisor == 0) {
1156 DeoptimizeIf(no_condition, instr->environment()); 1148 DeoptimizeIf(no_condition, instr->environment());
1157 return; 1149 return;
1158 } 1150 }
1159 1151
1160 // Check for (0 / -x) that will produce negative zero. 1152 // Check for (0 / -x) that will produce negative zero.
1161 HMathFloorOfDiv* hdiv = instr->hydrogen(); 1153 HMathFloorOfDiv* hdiv = instr->hydrogen();
1162 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && 1154 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1163 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
1164 __ testl(dividend, dividend); 1155 __ testl(dividend, dividend);
1165 DeoptimizeIf(zero, instr->environment()); 1156 DeoptimizeIf(zero, instr->environment());
1166 } 1157 }
1167 1158
1168 __ FlooringDiv(dividend, divisor); 1159 __ FlooringDiv(dividend, divisor);
1169 } 1160 }
1170 1161
1171 1162
1172 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { 1163 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
1173 Register dividend = ToRegister(instr->dividend()); 1164 Register dividend = ToRegister(instr->dividend());
1174 int32_t divisor = instr->divisor(); 1165 int32_t divisor = instr->divisor();
1175 Register result = ToRegister(instr->result()); 1166 Register result = ToRegister(instr->result());
1176 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor)))); 1167 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor))));
1177 ASSERT(!result.is(dividend)); 1168 ASSERT(!result.is(dividend));
1178 1169
1179 // Check for (0 / -x) that will produce negative zero. 1170 // Check for (0 / -x) that will produce negative zero.
1180 HDiv* hdiv = instr->hydrogen(); 1171 HDiv* hdiv = instr->hydrogen();
1181 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && 1172 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1182 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
1183 __ testl(dividend, dividend); 1173 __ testl(dividend, dividend);
1184 DeoptimizeIf(zero, instr->environment()); 1174 DeoptimizeIf(zero, instr->environment());
1185 } 1175 }
1186 // Check for (kMinInt / -1). 1176 // Check for (kMinInt / -1).
1187 if (hdiv->CheckFlag(HValue::kCanOverflow) && 1177 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
1188 hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) {
1189 __ cmpl(dividend, Immediate(kMinInt)); 1178 __ cmpl(dividend, Immediate(kMinInt));
1190 DeoptimizeIf(zero, instr->environment()); 1179 DeoptimizeIf(zero, instr->environment());
1191 } 1180 }
1192 // Deoptimize if remainder will not be 0. 1181 // Deoptimize if remainder will not be 0.
1193 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && 1182 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
1194 divisor != 1 && divisor != -1) { 1183 divisor != 1 && divisor != -1) {
1195 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); 1184 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
1196 __ testl(dividend, Immediate(mask)); 1185 __ testl(dividend, Immediate(mask));
1197 DeoptimizeIf(not_zero, instr->environment()); 1186 DeoptimizeIf(not_zero, instr->environment());
1198 } 1187 }
(...skipping 15 matching lines...) Expand all
1214 int32_t divisor = instr->divisor(); 1203 int32_t divisor = instr->divisor();
1215 ASSERT(ToRegister(instr->result()).is(rdx)); 1204 ASSERT(ToRegister(instr->result()).is(rdx));
1216 1205
1217 if (divisor == 0) { 1206 if (divisor == 0) {
1218 DeoptimizeIf(no_condition, instr->environment()); 1207 DeoptimizeIf(no_condition, instr->environment());
1219 return; 1208 return;
1220 } 1209 }
1221 1210
1222 // Check for (0 / -x) that will produce negative zero. 1211 // Check for (0 / -x) that will produce negative zero.
1223 HDiv* hdiv = instr->hydrogen(); 1212 HDiv* hdiv = instr->hydrogen();
1224 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && 1213 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
1225 hdiv->left()->RangeCanInclude(0) && divisor < 0) {
1226 __ testl(dividend, dividend); 1214 __ testl(dividend, dividend);
1227 DeoptimizeIf(zero, instr->environment()); 1215 DeoptimizeIf(zero, instr->environment());
1228 } 1216 }
1229 1217
1230 __ FlooringDiv(dividend, Abs(divisor)); 1218 __ FlooringDiv(dividend, Abs(divisor));
1231 __ movl(rax, dividend); 1219 __ movl(rax, dividend);
1232 __ shrl(rax, Immediate(31)); 1220 __ shrl(rax, Immediate(31));
1233 __ addl(rdx, rax); 1221 __ addl(rdx, rax);
1234 if (divisor < 0) __ neg(rdx); 1222 if (divisor < 0) __ neg(rdx);
1235 1223
1236 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { 1224 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
1237 __ movl(rax, rdx); 1225 __ movl(rax, rdx);
1238 __ imull(rax, rax, Immediate(divisor)); 1226 __ imull(rax, rax, Immediate(divisor));
1239 __ subl(rax, dividend); 1227 __ subl(rax, dividend);
1240 DeoptimizeIf(not_equal, instr->environment()); 1228 DeoptimizeIf(not_equal, instr->environment());
1241 } 1229 }
1242 } 1230 }
1243 1231
1244 1232
1245 void LCodeGen::DoDivI(LDivI* instr) { 1233 void LCodeGen::DoDivI(LDivI* instr) {
1234 HBinaryOperation* hdiv = instr->hydrogen();
1246 Register dividend = ToRegister(instr->left()); 1235 Register dividend = ToRegister(instr->left());
1247 Register divisor = ToRegister(instr->right()); 1236 Register divisor = ToRegister(instr->right());
1248 Register remainder = ToRegister(instr->temp()); 1237 Register remainder = ToRegister(instr->temp());
1249 Register result = ToRegister(instr->result()); 1238 Register result = ToRegister(instr->result());
1250 ASSERT(dividend.is(rax)); 1239 ASSERT(dividend.is(rax));
1251 ASSERT(remainder.is(rdx)); 1240 ASSERT(remainder.is(rdx));
1252 ASSERT(result.is(rax)); 1241 ASSERT(result.is(rax));
1253 ASSERT(!divisor.is(rax)); 1242 ASSERT(!divisor.is(rax));
1254 ASSERT(!divisor.is(rdx)); 1243 ASSERT(!divisor.is(rdx));
1255 1244
1256 // Check for x / 0. 1245 // Check for x / 0.
1257 HBinaryOperation* hdiv = instr->hydrogen();
1258 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { 1246 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
1259 __ testl(divisor, divisor); 1247 __ testl(divisor, divisor);
1260 DeoptimizeIf(zero, instr->environment()); 1248 DeoptimizeIf(zero, instr->environment());
1261 } 1249 }
1262 1250
1263 // Check for (0 / -x) that will produce negative zero. 1251 // Check for (0 / -x) that will produce negative zero.
1264 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { 1252 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
1265 Label dividend_not_zero; 1253 Label dividend_not_zero;
1266 __ testl(dividend, dividend); 1254 __ testl(dividend, dividend);
1267 __ j(not_zero, &dividend_not_zero, Label::kNear); 1255 __ j(not_zero, &dividend_not_zero, Label::kNear);
1268 __ testl(divisor, divisor); 1256 __ testl(divisor, divisor);
1269 DeoptimizeIf(sign, instr->environment()); 1257 DeoptimizeIf(sign, instr->environment());
1270 __ bind(&dividend_not_zero); 1258 __ bind(&dividend_not_zero);
1271 } 1259 }
1272 1260
1273 // Check for (kMinInt / -1). 1261 // Check for (kMinInt / -1).
1274 if (hdiv->CheckFlag(HValue::kCanOverflow)) { 1262 if (hdiv->CheckFlag(HValue::kCanOverflow)) {
1275 Label dividend_not_min_int; 1263 Label dividend_not_min_int;
1276 __ cmpl(dividend, Immediate(kMinInt)); 1264 __ cmpl(dividend, Immediate(kMinInt));
1277 __ j(not_zero, &dividend_not_min_int, Label::kNear); 1265 __ j(not_zero, &dividend_not_min_int, Label::kNear);
1278 __ cmpl(divisor, Immediate(-1)); 1266 __ cmpl(divisor, Immediate(-1));
1279 DeoptimizeIf(zero, instr->environment()); 1267 DeoptimizeIf(zero, instr->environment());
1280 __ bind(&dividend_not_min_int); 1268 __ bind(&dividend_not_min_int);
1281 } 1269 }
1282 1270
1283 // Sign extend to rdx (= remainder). 1271 // Sign extend to rdx (= remainder).
1284 __ cdq(); 1272 __ cdq();
1285 __ idivl(divisor); 1273 __ idivl(divisor);
1286 1274
1287 if (instr->is_flooring()) { 1275 if (hdiv->IsMathFloorOfDiv()) {
1288 Label done; 1276 Label done;
1289 __ testl(remainder, remainder); 1277 __ testl(remainder, remainder);
1290 __ j(zero, &done, Label::kNear); 1278 __ j(zero, &done, Label::kNear);
1291 __ xorl(remainder, divisor); 1279 __ xorl(remainder, divisor);
1292 __ sarl(remainder, Immediate(31)); 1280 __ sarl(remainder, Immediate(31));
1293 __ addl(result, remainder); 1281 __ addl(result, remainder);
1294 __ bind(&done); 1282 __ bind(&done);
1295 } else if (!instr->hydrogen()->CheckFlag( 1283 } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
1296 HInstruction::kAllUsesTruncatingToInt32)) {
1297 // Deoptimize if remainder is not 0. 1284 // Deoptimize if remainder is not 0.
1298 __ testl(remainder, remainder); 1285 __ testl(remainder, remainder);
1299 DeoptimizeIf(not_zero, instr->environment()); 1286 DeoptimizeIf(not_zero, instr->environment());
1300 } 1287 }
1301 } 1288 }
1302 1289
1303 1290
1304 void LCodeGen::DoMulI(LMulI* instr) { 1291 void LCodeGen::DoMulI(LMulI* instr) {
1305 Register left = ToRegister(instr->left()); 1292 Register left = ToRegister(instr->left());
1306 LOperand* right = instr->right(); 1293 LOperand* right = instr->right();
(...skipping 4359 matching lines...) Expand 10 before | Expand all | Expand 10 after
5666 FixedArray::kHeaderSize - kPointerSize)); 5653 FixedArray::kHeaderSize - kPointerSize));
5667 __ bind(&done); 5654 __ bind(&done);
5668 } 5655 }
5669 5656
5670 5657
5671 #undef __ 5658 #undef __
5672 5659
5673 } } // namespace v8::internal 5660 } } // namespace v8::internal
5674 5661
5675 #endif // V8_TARGET_ARCH_X64 5662 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698