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 4220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4231 | 4231 |
4232 | 4232 |
4233 void LCodeGen::DoMulConstIS(LMulConstIS* instr) { | 4233 void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
4234 ASSERT(instr->hydrogen()->representation().IsSmiOrInteger32()); | 4234 ASSERT(instr->hydrogen()->representation().IsSmiOrInteger32()); |
4235 bool is_smi = instr->hydrogen()->representation().IsSmi(); | 4235 bool is_smi = instr->hydrogen()->representation().IsSmi(); |
4236 Register result = | 4236 Register result = |
4237 is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result()); | 4237 is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result()); |
4238 Register left = | 4238 Register left = |
4239 is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; | 4239 is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; |
4240 int32_t right = ToInteger32(instr->right()); | 4240 int32_t right = ToInteger32(instr->right()); |
| 4241 ASSERT((right > -kMaxInt) || (right < kMaxInt)); |
4241 | 4242 |
4242 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4243 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
4243 bool bailout_on_minus_zero = | 4244 bool bailout_on_minus_zero = |
4244 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 4245 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
4245 | 4246 |
4246 if (bailout_on_minus_zero) { | 4247 if (bailout_on_minus_zero) { |
4247 if (right < 0) { | 4248 if (right < 0) { |
4248 // The result is -0 if right is negative and left is zero. | 4249 // The result is -0 if right is negative and left is zero. |
4249 DeoptimizeIfZero(left, instr->environment()); | 4250 DeoptimizeIfZero(left, instr->environment()); |
4250 } else if (right == 0) { | 4251 } else if (right == 0) { |
(...skipping 23 matching lines...) Expand all Loading... |
4274 break; | 4275 break; |
4275 case 2: | 4276 case 2: |
4276 if (can_overflow) { | 4277 if (can_overflow) { |
4277 __ Adds(result, left, left); | 4278 __ Adds(result, left, left); |
4278 DeoptimizeIf(vs, instr->environment()); | 4279 DeoptimizeIf(vs, instr->environment()); |
4279 } else { | 4280 } else { |
4280 __ Add(result, left, left); | 4281 __ Add(result, left, left); |
4281 } | 4282 } |
4282 break; | 4283 break; |
4283 | 4284 |
4284 // All other cases cannot detect overflow, because it would probably be no | |
4285 // faster than using the smull method in LMulI. | |
4286 // TODO(jbramley): Investigate this, and add overflow support if it would | |
4287 // be useful. | |
4288 default: | 4285 default: |
| 4286 // Multiplication by constant powers of two (and some related values) |
| 4287 // can be done efficiently with shifted operands. |
| 4288 int32_t right_abs = Abs(right); |
| 4289 |
| 4290 if (IsPowerOf2(right_abs)) { |
| 4291 int right_log2 = WhichPowerOf2(right_abs); |
| 4292 |
| 4293 if (can_overflow) { |
| 4294 Register scratch = result; |
| 4295 ASSERT(!AreAliased(scratch, left)); |
| 4296 __ Cls(scratch, left); |
| 4297 __ Cmp(scratch, right_log2); |
| 4298 DeoptimizeIf(lt, instr->environment()); |
| 4299 } |
| 4300 |
| 4301 if (right >= 0) { |
| 4302 // result = left << log2(right) |
| 4303 __ Lsl(result, left, right_log2); |
| 4304 } else { |
| 4305 // result = -left << log2(-right) |
| 4306 __ Neg(result, Operand(left, LSL, right_log2)); |
| 4307 } |
| 4308 return; |
| 4309 } |
| 4310 |
| 4311 |
| 4312 // For the following cases, we could perform a conservative overflow check |
| 4313 // with CLS as above. However the few cycles saved are likely not worth |
| 4314 // the risk of deoptimizing more often than required. |
4289 ASSERT(!can_overflow); | 4315 ASSERT(!can_overflow); |
4290 | 4316 |
4291 // Multiplication by constant powers of two (and some related values) | |
4292 // can be done efficiently with shifted operands. | |
4293 if (right >= 0) { | 4317 if (right >= 0) { |
4294 if (IsPowerOf2(right)) { | 4318 if (IsPowerOf2(right - 1)) { |
4295 // result = left << log2(right) | |
4296 __ Lsl(result, left, WhichPowerOf2(right)); | |
4297 } else if (IsPowerOf2(right - 1)) { | |
4298 // result = left + left << log2(right - 1) | 4319 // result = left + left << log2(right - 1) |
4299 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); | 4320 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); |
4300 } else if (IsPowerOf2(right + 1)) { | 4321 } else if (IsPowerOf2(right + 1)) { |
4301 // result = -left + left << log2(right + 1) | 4322 // result = -left + left << log2(right + 1) |
4302 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); | 4323 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); |
4303 __ Neg(result, result); | 4324 __ Neg(result, result); |
4304 } else { | 4325 } else { |
4305 UNREACHABLE(); | 4326 UNREACHABLE(); |
4306 } | 4327 } |
4307 } else { | 4328 } else { |
4308 if (IsPowerOf2(-right)) { | 4329 if (IsPowerOf2(-right + 1)) { |
4309 // result = -left << log2(-right) | |
4310 __ Neg(result, Operand(left, LSL, WhichPowerOf2(-right))); | |
4311 } else if (IsPowerOf2(-right + 1)) { | |
4312 // result = left - left << log2(-right + 1) | 4330 // result = left - left << log2(-right + 1) |
4313 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); | 4331 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); |
4314 } else if (IsPowerOf2(-right - 1)) { | 4332 } else if (IsPowerOf2(-right - 1)) { |
4315 // result = -left - left << log2(-right - 1) | 4333 // result = -left - left << log2(-right - 1) |
4316 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); | 4334 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); |
4317 __ Neg(result, result); | 4335 __ Neg(result, result); |
4318 } else { | 4336 } else { |
4319 UNREACHABLE(); | 4337 UNREACHABLE(); |
4320 } | 4338 } |
4321 } | 4339 } |
4322 break; | |
4323 } | 4340 } |
4324 } | 4341 } |
4325 | 4342 |
4326 | 4343 |
4327 void LCodeGen::DoMulI(LMulI* instr) { | 4344 void LCodeGen::DoMulI(LMulI* instr) { |
4328 Register result = ToRegister32(instr->result()); | 4345 Register result = ToRegister32(instr->result()); |
4329 Register left = ToRegister32(instr->left()); | 4346 Register left = ToRegister32(instr->left()); |
4330 Register right = ToRegister32(instr->right()); | 4347 Register right = ToRegister32(instr->right()); |
4331 | 4348 |
4332 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4349 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5856 __ Bind(&out_of_object); | 5873 __ Bind(&out_of_object); |
5857 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5874 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5858 // Index is equal to negated out of object property index plus 1. | 5875 // Index is equal to negated out of object property index plus 1. |
5859 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5876 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5860 __ Ldr(result, FieldMemOperand(result, | 5877 __ Ldr(result, FieldMemOperand(result, |
5861 FixedArray::kHeaderSize - kPointerSize)); | 5878 FixedArray::kHeaderSize - kPointerSize)); |
5862 __ Bind(&done); | 5879 __ Bind(&done); |
5863 } | 5880 } |
5864 | 5881 |
5865 } } // namespace v8::internal | 5882 } } // namespace v8::internal |
OLD | NEW |