| 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 1145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 } | 1156 } |
| 1157 | 1157 |
| 1158 __ FlooringDiv(result, dividend, Abs(divisor)); | 1158 __ FlooringDiv(result, dividend, Abs(divisor)); |
| 1159 __ add(result, result, Operand(dividend, LSR, 31)); | 1159 __ add(result, result, Operand(dividend, LSR, 31)); |
| 1160 __ mov(ip, Operand(Abs(divisor))); | 1160 __ mov(ip, Operand(Abs(divisor))); |
| 1161 __ smull(result, ip, result, ip); | 1161 __ smull(result, ip, result, ip); |
| 1162 __ sub(result, dividend, result, SetCC); | 1162 __ sub(result, dividend, result, SetCC); |
| 1163 | 1163 |
| 1164 // Check for negative zero. | 1164 // Check for negative zero. |
| 1165 HMod* hmod = instr->hydrogen(); | 1165 HMod* hmod = instr->hydrogen(); |
| 1166 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && | 1166 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1167 hmod->left()->CanBeNegative()) { | |
| 1168 Label remainder_not_zero; | 1167 Label remainder_not_zero; |
| 1169 __ b(ne, &remainder_not_zero); | 1168 __ b(ne, &remainder_not_zero); |
| 1170 __ cmp(dividend, Operand::Zero()); | 1169 __ cmp(dividend, Operand::Zero()); |
| 1171 DeoptimizeIf(lt, instr->environment()); | 1170 DeoptimizeIf(lt, instr->environment()); |
| 1172 __ bind(&remainder_not_zero); | 1171 __ bind(&remainder_not_zero); |
| 1173 } | 1172 } |
| 1174 } | 1173 } |
| 1175 | 1174 |
| 1176 | 1175 |
| 1177 void LCodeGen::DoModI(LModI* instr) { | 1176 void LCodeGen::DoModI(LModI* instr) { |
| 1178 HMod* hmod = instr->hydrogen(); | 1177 HMod* hmod = instr->hydrogen(); |
| 1179 HValue* left = hmod->left(); | |
| 1180 HValue* right = hmod->right(); | |
| 1181 if (CpuFeatures::IsSupported(SUDIV)) { | 1178 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1182 CpuFeatureScope scope(masm(), SUDIV); | 1179 CpuFeatureScope scope(masm(), SUDIV); |
| 1183 | 1180 |
| 1184 Register left_reg = ToRegister(instr->left()); | 1181 Register left_reg = ToRegister(instr->left()); |
| 1185 Register right_reg = ToRegister(instr->right()); | 1182 Register right_reg = ToRegister(instr->right()); |
| 1186 Register result_reg = ToRegister(instr->result()); | 1183 Register result_reg = ToRegister(instr->result()); |
| 1187 | 1184 |
| 1188 Label done; | 1185 Label done; |
| 1189 // Check for x % 0, sdiv might signal an exception. We have to deopt in this | 1186 // Check for x % 0, sdiv might signal an exception. We have to deopt in this |
| 1190 // case because we can't return a NaN. | 1187 // case because we can't return a NaN. |
| 1191 if (right->CanBeZero()) { | 1188 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1192 __ cmp(right_reg, Operand::Zero()); | 1189 __ cmp(right_reg, Operand::Zero()); |
| 1193 DeoptimizeIf(eq, instr->environment()); | 1190 DeoptimizeIf(eq, instr->environment()); |
| 1194 } | 1191 } |
| 1195 | 1192 |
| 1196 // Check for kMinInt % -1, sdiv will return kMinInt, which is not what we | 1193 // Check for kMinInt % -1, sdiv will return kMinInt, which is not what we |
| 1197 // want. We have to deopt if we care about -0, because we can't return that. | 1194 // want. We have to deopt if we care about -0, because we can't return that. |
| 1198 if (left->RangeCanInclude(kMinInt) && right->RangeCanInclude(-1)) { | 1195 if (hmod->CheckFlag(HValue::kCanOverflow)) { |
| 1199 Label no_overflow_possible; | 1196 Label no_overflow_possible; |
| 1200 __ cmp(left_reg, Operand(kMinInt)); | 1197 __ cmp(left_reg, Operand(kMinInt)); |
| 1201 __ b(ne, &no_overflow_possible); | 1198 __ b(ne, &no_overflow_possible); |
| 1202 __ cmp(right_reg, Operand(-1)); | 1199 __ cmp(right_reg, Operand(-1)); |
| 1203 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1200 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1204 DeoptimizeIf(eq, instr->environment()); | 1201 DeoptimizeIf(eq, instr->environment()); |
| 1205 } else { | 1202 } else { |
| 1206 __ b(ne, &no_overflow_possible); | 1203 __ b(ne, &no_overflow_possible); |
| 1207 __ mov(result_reg, Operand::Zero()); | 1204 __ mov(result_reg, Operand::Zero()); |
| 1208 __ jmp(&done); | 1205 __ jmp(&done); |
| 1209 } | 1206 } |
| 1210 __ bind(&no_overflow_possible); | 1207 __ bind(&no_overflow_possible); |
| 1211 } | 1208 } |
| 1212 | 1209 |
| 1213 // For 'r3 = r1 % r2' we can have the following ARM code: | 1210 // For 'r3 = r1 % r2' we can have the following ARM code: |
| 1214 // sdiv r3, r1, r2 | 1211 // sdiv r3, r1, r2 |
| 1215 // mls r3, r3, r2, r1 | 1212 // mls r3, r3, r2, r1 |
| 1216 | 1213 |
| 1217 __ sdiv(result_reg, left_reg, right_reg); | 1214 __ sdiv(result_reg, left_reg, right_reg); |
| 1218 __ mls(result_reg, result_reg, right_reg, left_reg); | 1215 __ mls(result_reg, result_reg, right_reg, left_reg); |
| 1219 | 1216 |
| 1220 // If we care about -0, test if the dividend is <0 and the result is 0. | 1217 // If we care about -0, test if the dividend is <0 and the result is 0. |
| 1221 if (left->CanBeNegative() && | 1218 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1222 hmod->CanBeZero() && | |
| 1223 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 1224 __ cmp(result_reg, Operand::Zero()); | 1219 __ cmp(result_reg, Operand::Zero()); |
| 1225 __ b(ne, &done); | 1220 __ b(ne, &done); |
| 1226 __ cmp(left_reg, Operand::Zero()); | 1221 __ cmp(left_reg, Operand::Zero()); |
| 1227 DeoptimizeIf(lt, instr->environment()); | 1222 DeoptimizeIf(lt, instr->environment()); |
| 1228 } | 1223 } |
| 1229 __ bind(&done); | 1224 __ bind(&done); |
| 1230 | 1225 |
| 1231 } else { | 1226 } else { |
| 1232 // General case, without any SDIV support. | 1227 // General case, without any SDIV support. |
| 1233 Register left_reg = ToRegister(instr->left()); | 1228 Register left_reg = ToRegister(instr->left()); |
| 1234 Register right_reg = ToRegister(instr->right()); | 1229 Register right_reg = ToRegister(instr->right()); |
| 1235 Register result_reg = ToRegister(instr->result()); | 1230 Register result_reg = ToRegister(instr->result()); |
| 1236 Register scratch = scratch0(); | 1231 Register scratch = scratch0(); |
| 1237 ASSERT(!scratch.is(left_reg)); | 1232 ASSERT(!scratch.is(left_reg)); |
| 1238 ASSERT(!scratch.is(right_reg)); | 1233 ASSERT(!scratch.is(right_reg)); |
| 1239 ASSERT(!scratch.is(result_reg)); | 1234 ASSERT(!scratch.is(result_reg)); |
| 1240 DwVfpRegister dividend = ToDoubleRegister(instr->temp()); | 1235 DwVfpRegister dividend = ToDoubleRegister(instr->temp()); |
| 1241 DwVfpRegister divisor = ToDoubleRegister(instr->temp2()); | 1236 DwVfpRegister divisor = ToDoubleRegister(instr->temp2()); |
| 1242 ASSERT(!divisor.is(dividend)); | 1237 ASSERT(!divisor.is(dividend)); |
| 1243 LowDwVfpRegister quotient = double_scratch0(); | 1238 LowDwVfpRegister quotient = double_scratch0(); |
| 1244 ASSERT(!quotient.is(dividend)); | 1239 ASSERT(!quotient.is(dividend)); |
| 1245 ASSERT(!quotient.is(divisor)); | 1240 ASSERT(!quotient.is(divisor)); |
| 1246 | 1241 |
| 1247 Label done; | 1242 Label done; |
| 1248 // Check for x % 0, we have to deopt in this case because we can't return a | 1243 // Check for x % 0, we have to deopt in this case because we can't return a |
| 1249 // NaN. | 1244 // NaN. |
| 1250 if (right->CanBeZero()) { | 1245 if (hmod->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1251 __ cmp(right_reg, Operand::Zero()); | 1246 __ cmp(right_reg, Operand::Zero()); |
| 1252 DeoptimizeIf(eq, instr->environment()); | 1247 DeoptimizeIf(eq, instr->environment()); |
| 1253 } | 1248 } |
| 1254 | 1249 |
| 1255 __ Move(result_reg, left_reg); | 1250 __ Move(result_reg, left_reg); |
| 1256 // Load the arguments in VFP registers. The divisor value is preloaded | 1251 // Load the arguments in VFP registers. The divisor value is preloaded |
| 1257 // before. Be careful that 'right_reg' is only live on entry. | 1252 // before. Be careful that 'right_reg' is only live on entry. |
| 1258 // TODO(svenpanne) The last comments seems to be wrong nowadays. | 1253 // TODO(svenpanne) The last comments seems to be wrong nowadays. |
| 1259 __ vmov(double_scratch0().low(), left_reg); | 1254 __ vmov(double_scratch0().low(), left_reg); |
| 1260 __ vcvt_f64_s32(dividend, double_scratch0().low()); | 1255 __ vcvt_f64_s32(dividend, double_scratch0().low()); |
| 1261 __ vmov(double_scratch0().low(), right_reg); | 1256 __ vmov(double_scratch0().low(), right_reg); |
| 1262 __ vcvt_f64_s32(divisor, double_scratch0().low()); | 1257 __ vcvt_f64_s32(divisor, double_scratch0().low()); |
| 1263 | 1258 |
| 1264 // We do not care about the sign of the divisor. Note that we still handle | 1259 // We do not care about the sign of the divisor. Note that we still handle |
| 1265 // the kMinInt % -1 case correctly, though. | 1260 // the kMinInt % -1 case correctly, though. |
| 1266 __ vabs(divisor, divisor); | 1261 __ vabs(divisor, divisor); |
| 1267 // Compute the quotient and round it to a 32bit integer. | 1262 // Compute the quotient and round it to a 32bit integer. |
| 1268 __ vdiv(quotient, dividend, divisor); | 1263 __ vdiv(quotient, dividend, divisor); |
| 1269 __ vcvt_s32_f64(quotient.low(), quotient); | 1264 __ vcvt_s32_f64(quotient.low(), quotient); |
| 1270 __ vcvt_f64_s32(quotient, quotient.low()); | 1265 __ vcvt_f64_s32(quotient, quotient.low()); |
| 1271 | 1266 |
| 1272 // Compute the remainder in result. | 1267 // Compute the remainder in result. |
| 1273 __ vmul(double_scratch0(), divisor, quotient); | 1268 __ vmul(double_scratch0(), divisor, quotient); |
| 1274 __ vcvt_s32_f64(double_scratch0().low(), double_scratch0()); | 1269 __ vcvt_s32_f64(double_scratch0().low(), double_scratch0()); |
| 1275 __ vmov(scratch, double_scratch0().low()); | 1270 __ vmov(scratch, double_scratch0().low()); |
| 1276 __ sub(result_reg, left_reg, scratch, SetCC); | 1271 __ sub(result_reg, left_reg, scratch, SetCC); |
| 1277 | 1272 |
| 1278 // If we care about -0, test if the dividend is <0 and the result is 0. | 1273 // If we care about -0, test if the dividend is <0 and the result is 0. |
| 1279 if (left->CanBeNegative() && | 1274 if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1280 hmod->CanBeZero() && | |
| 1281 hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 1282 __ b(ne, &done); | 1275 __ b(ne, &done); |
| 1283 __ cmp(left_reg, Operand::Zero()); | 1276 __ cmp(left_reg, Operand::Zero()); |
| 1284 DeoptimizeIf(mi, instr->environment()); | 1277 DeoptimizeIf(mi, instr->environment()); |
| 1285 } | 1278 } |
| 1286 __ bind(&done); | 1279 __ bind(&done); |
| 1287 } | 1280 } |
| 1288 } | 1281 } |
| 1289 | 1282 |
| 1290 | 1283 |
| 1291 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { | 1284 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { |
| 1292 Register dividend = ToRegister(instr->dividend()); | 1285 Register dividend = ToRegister(instr->dividend()); |
| 1293 int32_t divisor = instr->divisor(); | 1286 int32_t divisor = instr->divisor(); |
| 1294 Register result = ToRegister(instr->result()); | 1287 Register result = ToRegister(instr->result()); |
| 1295 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor)))); | 1288 ASSERT(divisor == kMinInt || (divisor != 0 && IsPowerOf2(Abs(divisor)))); |
| 1296 ASSERT(!result.is(dividend)); | 1289 ASSERT(!result.is(dividend)); |
| 1297 | 1290 |
| 1298 // Check for (0 / -x) that will produce negative zero. | 1291 // Check for (0 / -x) that will produce negative zero. |
| 1299 HDiv* hdiv = instr->hydrogen(); | 1292 HDiv* hdiv = instr->hydrogen(); |
| 1300 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && | 1293 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
| 1301 hdiv->left()->RangeCanInclude(0) && divisor < 0) { | |
| 1302 __ cmp(dividend, Operand::Zero()); | 1294 __ cmp(dividend, Operand::Zero()); |
| 1303 DeoptimizeIf(eq, instr->environment()); | 1295 DeoptimizeIf(eq, instr->environment()); |
| 1304 } | 1296 } |
| 1305 // Check for (kMinInt / -1). | 1297 // Check for (kMinInt / -1). |
| 1306 if (hdiv->CheckFlag(HValue::kCanOverflow) && | 1298 if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) { |
| 1307 hdiv->left()->RangeCanInclude(kMinInt) && divisor == -1) { | |
| 1308 __ cmp(dividend, Operand(kMinInt)); | 1299 __ cmp(dividend, Operand(kMinInt)); |
| 1309 DeoptimizeIf(eq, instr->environment()); | 1300 DeoptimizeIf(eq, instr->environment()); |
| 1310 } | 1301 } |
| 1311 // Deoptimize if remainder will not be 0. | 1302 // Deoptimize if remainder will not be 0. |
| 1312 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && | 1303 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && |
| 1313 divisor != 1 && divisor != -1) { | 1304 divisor != 1 && divisor != -1) { |
| 1314 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); | 1305 int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1); |
| 1315 __ tst(dividend, Operand(mask)); | 1306 __ tst(dividend, Operand(mask)); |
| 1316 DeoptimizeIf(ne, instr->environment()); | 1307 DeoptimizeIf(ne, instr->environment()); |
| 1317 } | 1308 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1340 Register result = ToRegister(instr->result()); | 1331 Register result = ToRegister(instr->result()); |
| 1341 ASSERT(!dividend.is(result)); | 1332 ASSERT(!dividend.is(result)); |
| 1342 | 1333 |
| 1343 if (divisor == 0) { | 1334 if (divisor == 0) { |
| 1344 DeoptimizeIf(al, instr->environment()); | 1335 DeoptimizeIf(al, instr->environment()); |
| 1345 return; | 1336 return; |
| 1346 } | 1337 } |
| 1347 | 1338 |
| 1348 // Check for (0 / -x) that will produce negative zero. | 1339 // Check for (0 / -x) that will produce negative zero. |
| 1349 HDiv* hdiv = instr->hydrogen(); | 1340 HDiv* hdiv = instr->hydrogen(); |
| 1350 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && | 1341 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
| 1351 hdiv->left()->RangeCanInclude(0) && divisor < 0) { | |
| 1352 __ cmp(dividend, Operand::Zero()); | 1342 __ cmp(dividend, Operand::Zero()); |
| 1353 DeoptimizeIf(eq, instr->environment()); | 1343 DeoptimizeIf(eq, instr->environment()); |
| 1354 } | 1344 } |
| 1355 | 1345 |
| 1356 __ FlooringDiv(result, dividend, Abs(divisor)); | 1346 __ FlooringDiv(result, dividend, Abs(divisor)); |
| 1357 __ add(result, result, Operand(dividend, LSR, 31)); | 1347 __ add(result, result, Operand(dividend, LSR, 31)); |
| 1358 if (divisor < 0) __ rsb(result, result, Operand::Zero()); | 1348 if (divisor < 0) __ rsb(result, result, Operand::Zero()); |
| 1359 | 1349 |
| 1360 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1350 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| 1361 __ mov(ip, Operand(divisor)); | 1351 __ mov(ip, Operand(divisor)); |
| 1362 __ smull(scratch0(), ip, result, ip); | 1352 __ smull(scratch0(), ip, result, ip); |
| 1363 __ sub(scratch0(), scratch0(), dividend, SetCC); | 1353 __ sub(scratch0(), scratch0(), dividend, SetCC); |
| 1364 DeoptimizeIf(ne, instr->environment()); | 1354 DeoptimizeIf(ne, instr->environment()); |
| 1365 } | 1355 } |
| 1366 } | 1356 } |
| 1367 | 1357 |
| 1368 | 1358 |
| 1369 void LCodeGen::DoDivI(LDivI* instr) { | 1359 void LCodeGen::DoDivI(LDivI* instr) { |
| 1360 HBinaryOperation* hdiv = instr->hydrogen(); |
| 1370 const Register left = ToRegister(instr->left()); | 1361 const Register left = ToRegister(instr->left()); |
| 1371 const Register right = ToRegister(instr->right()); | 1362 const Register right = ToRegister(instr->right()); |
| 1372 const Register result = ToRegister(instr->result()); | 1363 const Register result = ToRegister(instr->result()); |
| 1373 | 1364 |
| 1374 // Check for x / 0. | 1365 // Check for x / 0. |
| 1375 if (instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { | 1366 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1376 __ cmp(right, Operand::Zero()); | 1367 __ cmp(right, Operand::Zero()); |
| 1377 DeoptimizeIf(eq, instr->environment()); | 1368 DeoptimizeIf(eq, instr->environment()); |
| 1378 } | 1369 } |
| 1379 | 1370 |
| 1380 // Check for (0 / -x) that will produce negative zero. | 1371 // Check for (0 / -x) that will produce negative zero. |
| 1381 if (instr->hydrogen_value()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 1372 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1382 Label positive; | 1373 Label positive; |
| 1383 if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { | 1374 if (!instr->hydrogen_value()->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1384 // Do the test only if it hadn't be done above. | 1375 // Do the test only if it hadn't be done above. |
| 1385 __ cmp(right, Operand::Zero()); | 1376 __ cmp(right, Operand::Zero()); |
| 1386 } | 1377 } |
| 1387 __ b(pl, &positive); | 1378 __ b(pl, &positive); |
| 1388 __ cmp(left, Operand::Zero()); | 1379 __ cmp(left, Operand::Zero()); |
| 1389 DeoptimizeIf(eq, instr->environment()); | 1380 DeoptimizeIf(eq, instr->environment()); |
| 1390 __ bind(&positive); | 1381 __ bind(&positive); |
| 1391 } | 1382 } |
| 1392 | 1383 |
| 1393 // Check for (kMinInt / -1). | 1384 // Check for (kMinInt / -1). |
| 1394 if (instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow) && | 1385 if (hdiv->CheckFlag(HValue::kCanOverflow) && |
| 1395 (!CpuFeatures::IsSupported(SUDIV) || | 1386 (!CpuFeatures::IsSupported(SUDIV) || |
| 1396 !instr->hydrogen_value()->CheckFlag( | 1387 !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32))) { |
| 1397 HValue::kAllUsesTruncatingToInt32))) { | |
| 1398 // We don't need to check for overflow when truncating with sdiv | 1388 // We don't need to check for overflow when truncating with sdiv |
| 1399 // support because, on ARM, sdiv kMinInt, -1 -> kMinInt. | 1389 // support because, on ARM, sdiv kMinInt, -1 -> kMinInt. |
| 1400 __ cmp(left, Operand(kMinInt)); | 1390 __ cmp(left, Operand(kMinInt)); |
| 1401 __ cmp(right, Operand(-1), eq); | 1391 __ cmp(right, Operand(-1), eq); |
| 1402 DeoptimizeIf(eq, instr->environment()); | 1392 DeoptimizeIf(eq, instr->environment()); |
| 1403 } | 1393 } |
| 1404 | 1394 |
| 1405 if (CpuFeatures::IsSupported(SUDIV)) { | 1395 if (CpuFeatures::IsSupported(SUDIV)) { |
| 1406 CpuFeatureScope scope(masm(), SUDIV); | 1396 CpuFeatureScope scope(masm(), SUDIV); |
| 1407 __ sdiv(result, left, right); | 1397 __ sdiv(result, left, right); |
| 1408 | 1398 |
| 1409 if (!instr->hydrogen_value()->CheckFlag( | 1399 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1410 HInstruction::kAllUsesTruncatingToInt32)) { | |
| 1411 // Compute remainder and deopt if it's not zero. | 1400 // Compute remainder and deopt if it's not zero. |
| 1412 const Register remainder = scratch0(); | 1401 const Register remainder = scratch0(); |
| 1413 __ mls(remainder, result, right, left); | 1402 __ mls(remainder, result, right, left); |
| 1414 __ cmp(remainder, Operand::Zero()); | 1403 __ cmp(remainder, Operand::Zero()); |
| 1415 DeoptimizeIf(ne, instr->environment()); | 1404 DeoptimizeIf(ne, instr->environment()); |
| 1416 } | 1405 } |
| 1417 } else { | 1406 } else { |
| 1418 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); | 1407 const DoubleRegister vleft = ToDoubleRegister(instr->temp()); |
| 1419 const DoubleRegister vright = double_scratch0(); | 1408 const DoubleRegister vright = double_scratch0(); |
| 1420 __ vmov(double_scratch0().low(), left); | 1409 __ vmov(double_scratch0().low(), left); |
| 1421 __ vcvt_f64_s32(vleft, double_scratch0().low()); | 1410 __ vcvt_f64_s32(vleft, double_scratch0().low()); |
| 1422 __ vmov(double_scratch0().low(), right); | 1411 __ vmov(double_scratch0().low(), right); |
| 1423 __ vcvt_f64_s32(vright, double_scratch0().low()); | 1412 __ vcvt_f64_s32(vright, double_scratch0().low()); |
| 1424 __ vdiv(vleft, vleft, vright); // vleft now contains the result. | 1413 __ vdiv(vleft, vleft, vright); // vleft now contains the result. |
| 1425 __ vcvt_s32_f64(double_scratch0().low(), vleft); | 1414 __ vcvt_s32_f64(double_scratch0().low(), vleft); |
| 1426 __ vmov(result, double_scratch0().low()); | 1415 __ vmov(result, double_scratch0().low()); |
| 1427 | 1416 |
| 1428 if (!instr->hydrogen_value()->CheckFlag( | 1417 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
| 1429 HInstruction::kAllUsesTruncatingToInt32)) { | |
| 1430 // Deopt if exact conversion to integer was not possible. | 1418 // Deopt if exact conversion to integer was not possible. |
| 1431 // Use vright as scratch register. | 1419 // Use vright as scratch register. |
| 1432 __ vcvt_f64_s32(double_scratch0(), double_scratch0().low()); | 1420 __ vcvt_f64_s32(double_scratch0(), double_scratch0().low()); |
| 1433 __ VFPCompareAndSetFlags(vleft, double_scratch0()); | 1421 __ VFPCompareAndSetFlags(vleft, double_scratch0()); |
| 1434 DeoptimizeIf(ne, instr->environment()); | 1422 DeoptimizeIf(ne, instr->environment()); |
| 1435 } | 1423 } |
| 1436 } | 1424 } |
| 1437 } | 1425 } |
| 1438 | 1426 |
| 1439 | 1427 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1504 Register result = ToRegister(instr->result()); | 1492 Register result = ToRegister(instr->result()); |
| 1505 ASSERT(!dividend.is(result)); | 1493 ASSERT(!dividend.is(result)); |
| 1506 | 1494 |
| 1507 if (divisor == 0) { | 1495 if (divisor == 0) { |
| 1508 DeoptimizeIf(al, instr->environment()); | 1496 DeoptimizeIf(al, instr->environment()); |
| 1509 return; | 1497 return; |
| 1510 } | 1498 } |
| 1511 | 1499 |
| 1512 // Check for (0 / -x) that will produce negative zero. | 1500 // Check for (0 / -x) that will produce negative zero. |
| 1513 HMathFloorOfDiv* hdiv = instr->hydrogen(); | 1501 HMathFloorOfDiv* hdiv = instr->hydrogen(); |
| 1514 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && | 1502 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
| 1515 hdiv->left()->RangeCanInclude(0) && divisor < 0) { | |
| 1516 __ cmp(dividend, Operand::Zero()); | 1503 __ cmp(dividend, Operand::Zero()); |
| 1517 DeoptimizeIf(eq, instr->environment()); | 1504 DeoptimizeIf(eq, instr->environment()); |
| 1518 } | 1505 } |
| 1519 | 1506 |
| 1520 __ FlooringDiv(result, dividend, divisor); | 1507 __ FlooringDiv(result, dividend, divisor); |
| 1521 } | 1508 } |
| 1522 | 1509 |
| 1523 | 1510 |
| 1524 void LCodeGen::DoMulI(LMulI* instr) { | 1511 void LCodeGen::DoMulI(LMulI* instr) { |
| 1525 Register result = ToRegister(instr->result()); | 1512 Register result = ToRegister(instr->result()); |
| (...skipping 4207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5733 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5720 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
| 5734 __ ldr(result, FieldMemOperand(scratch, | 5721 __ ldr(result, FieldMemOperand(scratch, |
| 5735 FixedArray::kHeaderSize - kPointerSize)); | 5722 FixedArray::kHeaderSize - kPointerSize)); |
| 5736 __ bind(&done); | 5723 __ bind(&done); |
| 5737 } | 5724 } |
| 5738 | 5725 |
| 5739 | 5726 |
| 5740 #undef __ | 5727 #undef __ |
| 5741 | 5728 |
| 5742 } } // namespace v8::internal | 5729 } } // namespace v8::internal |
| OLD | NEW |