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 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1198 __ jmp(&done, Label::kNear); | 1198 __ jmp(&done, Label::kNear); |
1199 __ bind(&needs_adjustment); | 1199 __ bind(&needs_adjustment); |
1200 __ leal(temp, Operand(dividend, divisor > 0 ? 1 : -1)); | 1200 __ leal(temp, Operand(dividend, divisor > 0 ? 1 : -1)); |
1201 __ TruncatingDiv(temp, Abs(divisor)); | 1201 __ TruncatingDiv(temp, Abs(divisor)); |
1202 if (divisor < 0) __ negl(rdx); | 1202 if (divisor < 0) __ negl(rdx); |
1203 __ decl(rdx); | 1203 __ decl(rdx); |
1204 __ bind(&done); | 1204 __ bind(&done); |
1205 } | 1205 } |
1206 | 1206 |
1207 | 1207 |
| 1208 // TODO(svenpanne) Refactor this to avoid code duplication with DoDivI. |
| 1209 void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { |
| 1210 HBinaryOperation* hdiv = instr->hydrogen(); |
| 1211 Register dividend = ToRegister(instr->dividend()); |
| 1212 Register divisor = ToRegister(instr->divisor()); |
| 1213 Register remainder = ToRegister(instr->temp()); |
| 1214 Register result = ToRegister(instr->result()); |
| 1215 ASSERT(dividend.is(rax)); |
| 1216 ASSERT(remainder.is(rdx)); |
| 1217 ASSERT(result.is(rax)); |
| 1218 ASSERT(!divisor.is(rax)); |
| 1219 ASSERT(!divisor.is(rdx)); |
| 1220 |
| 1221 // Check for x / 0. |
| 1222 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
| 1223 __ testl(divisor, divisor); |
| 1224 DeoptimizeIf(zero, instr->environment()); |
| 1225 } |
| 1226 |
| 1227 // Check for (0 / -x) that will produce negative zero. |
| 1228 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 1229 Label dividend_not_zero; |
| 1230 __ testl(dividend, dividend); |
| 1231 __ j(not_zero, ÷nd_not_zero, Label::kNear); |
| 1232 __ testl(divisor, divisor); |
| 1233 DeoptimizeIf(sign, instr->environment()); |
| 1234 __ bind(÷nd_not_zero); |
| 1235 } |
| 1236 |
| 1237 // Check for (kMinInt / -1). |
| 1238 if (hdiv->CheckFlag(HValue::kCanOverflow)) { |
| 1239 Label dividend_not_min_int; |
| 1240 __ cmpl(dividend, Immediate(kMinInt)); |
| 1241 __ j(not_zero, ÷nd_not_min_int, Label::kNear); |
| 1242 __ cmpl(divisor, Immediate(-1)); |
| 1243 DeoptimizeIf(zero, instr->environment()); |
| 1244 __ bind(÷nd_not_min_int); |
| 1245 } |
| 1246 |
| 1247 // Sign extend to rdx (= remainder). |
| 1248 __ cdq(); |
| 1249 __ idivl(divisor); |
| 1250 |
| 1251 Label done; |
| 1252 __ testl(remainder, remainder); |
| 1253 __ j(zero, &done, Label::kNear); |
| 1254 __ xorl(remainder, divisor); |
| 1255 __ sarl(remainder, Immediate(31)); |
| 1256 __ addl(result, remainder); |
| 1257 __ bind(&done); |
| 1258 } |
| 1259 |
| 1260 |
1208 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { | 1261 void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { |
1209 Register dividend = ToRegister(instr->dividend()); | 1262 Register dividend = ToRegister(instr->dividend()); |
1210 int32_t divisor = instr->divisor(); | 1263 int32_t divisor = instr->divisor(); |
1211 Register result = ToRegister(instr->result()); | 1264 Register result = ToRegister(instr->result()); |
1212 ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor))); | 1265 ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor))); |
1213 ASSERT(!result.is(dividend)); | 1266 ASSERT(!result.is(dividend)); |
1214 | 1267 |
1215 // Check for (0 / -x) that will produce negative zero. | 1268 // Check for (0 / -x) that will produce negative zero. |
1216 HDiv* hdiv = instr->hydrogen(); | 1269 HDiv* hdiv = instr->hydrogen(); |
1217 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { | 1270 if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1265 | 1318 |
1266 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { | 1319 if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
1267 __ movl(rax, rdx); | 1320 __ movl(rax, rdx); |
1268 __ imull(rax, rax, Immediate(divisor)); | 1321 __ imull(rax, rax, Immediate(divisor)); |
1269 __ subl(rax, dividend); | 1322 __ subl(rax, dividend); |
1270 DeoptimizeIf(not_equal, instr->environment()); | 1323 DeoptimizeIf(not_equal, instr->environment()); |
1271 } | 1324 } |
1272 } | 1325 } |
1273 | 1326 |
1274 | 1327 |
| 1328 // TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI. |
1275 void LCodeGen::DoDivI(LDivI* instr) { | 1329 void LCodeGen::DoDivI(LDivI* instr) { |
1276 HBinaryOperation* hdiv = instr->hydrogen(); | 1330 HBinaryOperation* hdiv = instr->hydrogen(); |
1277 Register dividend = ToRegister(instr->left()); | 1331 Register dividend = ToRegister(instr->dividend()); |
1278 Register divisor = ToRegister(instr->right()); | 1332 Register divisor = ToRegister(instr->divisor()); |
1279 Register remainder = ToRegister(instr->temp()); | 1333 Register remainder = ToRegister(instr->temp()); |
1280 Register result = ToRegister(instr->result()); | 1334 Register result = ToRegister(instr->result()); |
1281 ASSERT(dividend.is(rax)); | 1335 ASSERT(dividend.is(rax)); |
1282 ASSERT(remainder.is(rdx)); | 1336 ASSERT(remainder.is(rdx)); |
1283 ASSERT(result.is(rax)); | 1337 ASSERT(result.is(rax)); |
1284 ASSERT(!divisor.is(rax)); | 1338 ASSERT(!divisor.is(rax)); |
1285 ASSERT(!divisor.is(rdx)); | 1339 ASSERT(!divisor.is(rdx)); |
1286 | 1340 |
1287 // Check for x / 0. | 1341 // Check for x / 0. |
1288 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { | 1342 if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { |
(...skipping 18 matching lines...) Expand all Loading... |
1307 __ j(not_zero, ÷nd_not_min_int, Label::kNear); | 1361 __ j(not_zero, ÷nd_not_min_int, Label::kNear); |
1308 __ cmpl(divisor, Immediate(-1)); | 1362 __ cmpl(divisor, Immediate(-1)); |
1309 DeoptimizeIf(zero, instr->environment()); | 1363 DeoptimizeIf(zero, instr->environment()); |
1310 __ bind(÷nd_not_min_int); | 1364 __ bind(÷nd_not_min_int); |
1311 } | 1365 } |
1312 | 1366 |
1313 // Sign extend to rdx (= remainder). | 1367 // Sign extend to rdx (= remainder). |
1314 __ cdq(); | 1368 __ cdq(); |
1315 __ idivl(divisor); | 1369 __ idivl(divisor); |
1316 | 1370 |
1317 if (hdiv->IsMathFloorOfDiv()) { | 1371 if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { |
1318 Label done; | |
1319 __ testl(remainder, remainder); | |
1320 __ j(zero, &done, Label::kNear); | |
1321 __ xorl(remainder, divisor); | |
1322 __ sarl(remainder, Immediate(31)); | |
1323 __ addl(result, remainder); | |
1324 __ bind(&done); | |
1325 } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) { | |
1326 // Deoptimize if remainder is not 0. | 1372 // Deoptimize if remainder is not 0. |
1327 __ testl(remainder, remainder); | 1373 __ testl(remainder, remainder); |
1328 DeoptimizeIf(not_zero, instr->environment()); | 1374 DeoptimizeIf(not_zero, instr->environment()); |
1329 } | 1375 } |
1330 } | 1376 } |
1331 | 1377 |
1332 | 1378 |
1333 void LCodeGen::DoMulI(LMulI* instr) { | 1379 void LCodeGen::DoMulI(LMulI* instr) { |
1334 Register left = ToRegister(instr->left()); | 1380 Register left = ToRegister(instr->left()); |
1335 LOperand* right = instr->right(); | 1381 LOperand* right = instr->right(); |
(...skipping 4297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5633 __ bind(deferred->exit()); | 5679 __ bind(deferred->exit()); |
5634 __ bind(&done); | 5680 __ bind(&done); |
5635 } | 5681 } |
5636 | 5682 |
5637 | 5683 |
5638 #undef __ | 5684 #undef __ |
5639 | 5685 |
5640 } } // namespace v8::internal | 5686 } } // namespace v8::internal |
5641 | 5687 |
5642 #endif // V8_TARGET_ARCH_X64 | 5688 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |