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 |