| 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 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1206 LOperand* dividend = UseFixed(instr->left(), a0); | 1206 LOperand* dividend = UseFixed(instr->left(), a0); |
| 1207 LOperand* divisor = UseFixed(instr->right(), a1); | 1207 LOperand* divisor = UseFixed(instr->right(), a1); |
| 1208 return AssignEnvironment(AssignPointerMap( | 1208 return AssignEnvironment(AssignPointerMap( |
| 1209 DefineFixed(new(zone()) LDivI(dividend, divisor), v0))); | 1209 DefineFixed(new(zone()) LDivI(dividend, divisor), v0))); |
| 1210 } else { | 1210 } else { |
| 1211 return DoArithmeticT(Token::DIV, instr); | 1211 return DoArithmeticT(Token::DIV, instr); |
| 1212 } | 1212 } |
| 1213 } | 1213 } |
| 1214 | 1214 |
| 1215 | 1215 |
| 1216 bool LChunkBuilder::HasMagicNumberForDivisor(int32_t divisor) { |
| 1217 uint32_t divisor_abs = abs(divisor); |
| 1218 // Dividing by 0, 1, and powers of 2 is easy. |
| 1219 // Note that IsPowerOf2(0) returns true; |
| 1220 ASSERT(IsPowerOf2(0) == true); |
| 1221 if (IsPowerOf2(divisor_abs)) return true; |
| 1222 |
| 1223 // We have magic numbers for a few specific divisors. |
| 1224 // Details and proofs can be found in: |
| 1225 // - Hacker's Delight, Henry S. Warren, Jr. |
| 1226 // - The PowerPC Compiler Writer's Guide |
| 1227 // and probably many others. |
| 1228 // |
| 1229 // We handle |
| 1230 // <divisor with magic numbers> * <power of 2> |
| 1231 // but not |
| 1232 // <divisor with magic numbers> * <other divisor with magic numbers> |
| 1233 int32_t power_of_2_factor = |
| 1234 CompilerIntrinsics::CountTrailingZeros(divisor_abs); |
| 1235 DivMagicNumbers magic_numbers = |
| 1236 DivMagicNumberFor(divisor_abs >> power_of_2_factor); |
| 1237 if (magic_numbers.M != InvalidDivMagicNumber.M) return true; |
| 1238 |
| 1239 return false; |
| 1240 } |
| 1241 |
| 1242 |
| 1243 HValue* LChunkBuilder::SimplifiedDividendForMathFloorOfDiv(HValue* dividend) { |
| 1244 // A value with an integer representation does not need to be transformed. |
| 1245 if (dividend->representation().IsInteger32()) { |
| 1246 return dividend; |
| 1247 // A change from an integer32 can be replaced by the integer32 value. |
| 1248 } else if (dividend->IsChange() && |
| 1249 HChange::cast(dividend)->from().IsInteger32()) { |
| 1250 return HChange::cast(dividend)->value(); |
| 1251 } |
| 1252 return NULL; |
| 1253 } |
| 1254 |
| 1255 |
| 1256 HValue* LChunkBuilder::SimplifiedDivisorForMathFloorOfDiv(HValue* divisor) { |
| 1257 // Only optimize when we have magic numbers for the divisor. |
| 1258 // The standard integer division routine is usually slower than transitionning |
| 1259 // to FPU. |
| 1260 if (divisor->IsConstant() && |
| 1261 HConstant::cast(divisor)->HasInteger32Value()) { |
| 1262 HConstant* constant_val = HConstant::cast(divisor); |
| 1263 return constant_val->CopyToRepresentation(Representation::Integer32(), |
| 1264 divisor->block()->zone()); |
| 1265 } |
| 1266 return NULL; |
| 1267 } |
| 1268 |
| 1269 |
| 1216 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { | 1270 LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) { |
| 1217 UNIMPLEMENTED(); | 1271 HValue* right = instr->right(); |
| 1218 return NULL; | 1272 LOperand* dividend = UseRegister(instr->left()); |
| 1273 LOperand* divisor = UseRegisterOrConstant(right); |
| 1274 LOperand* remainder = TempRegister(); |
| 1275 ASSERT(right->IsConstant() && |
| 1276 HConstant::cast(right)->HasInteger32Value()); |
| 1277 return AssignEnvironment(DefineAsRegister( |
| 1278 new(zone()) LMathFloorOfDiv(dividend, divisor, remainder))); |
| 1219 } | 1279 } |
| 1220 | 1280 |
| 1221 | 1281 |
| 1222 LInstruction* LChunkBuilder::DoMod(HMod* instr) { | 1282 LInstruction* LChunkBuilder::DoMod(HMod* instr) { |
| 1223 if (instr->representation().IsInteger32()) { | 1283 if (instr->representation().IsInteger32()) { |
| 1224 ASSERT(instr->left()->representation().IsInteger32()); | 1284 ASSERT(instr->left()->representation().IsInteger32()); |
| 1225 ASSERT(instr->right()->representation().IsInteger32()); | 1285 ASSERT(instr->right()->representation().IsInteger32()); |
| 1226 | 1286 |
| 1227 LModI* mod; | 1287 LModI* mod; |
| 1228 if (instr->HasPowerOf2Divisor()) { | 1288 if (instr->HasPowerOf2Divisor()) { |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2317 | 2377 |
| 2318 | 2378 |
| 2319 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { | 2379 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { |
| 2320 LOperand* object = UseRegister(instr->object()); | 2380 LOperand* object = UseRegister(instr->object()); |
| 2321 LOperand* index = UseRegister(instr->index()); | 2381 LOperand* index = UseRegister(instr->index()); |
| 2322 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); | 2382 return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index)); |
| 2323 } | 2383 } |
| 2324 | 2384 |
| 2325 | 2385 |
| 2326 } } // namespace v8::internal | 2386 } } // namespace v8::internal |
| OLD | NEW |