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 4235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4246 | 4246 |
4247 | 4247 |
4248 void LCodeGen::DoMulConstIS(LMulConstIS* instr) { | 4248 void LCodeGen::DoMulConstIS(LMulConstIS* instr) { |
4249 ASSERT(instr->hydrogen()->representation().IsSmiOrInteger32()); | 4249 ASSERT(instr->hydrogen()->representation().IsSmiOrInteger32()); |
4250 bool is_smi = instr->hydrogen()->representation().IsSmi(); | 4250 bool is_smi = instr->hydrogen()->representation().IsSmi(); |
4251 Register result = | 4251 Register result = |
4252 is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result()); | 4252 is_smi ? ToRegister(instr->result()) : ToRegister32(instr->result()); |
4253 Register left = | 4253 Register left = |
4254 is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; | 4254 is_smi ? ToRegister(instr->left()) : ToRegister32(instr->left()) ; |
4255 int32_t right = ToInteger32(instr->right()); | 4255 int32_t right = ToInteger32(instr->right()); |
| 4256 ASSERT((right > -kMaxInt) || (right < kMaxInt)); |
4256 | 4257 |
4257 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4258 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
4258 bool bailout_on_minus_zero = | 4259 bool bailout_on_minus_zero = |
4259 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 4260 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
4260 | 4261 |
4261 if (bailout_on_minus_zero) { | 4262 if (bailout_on_minus_zero) { |
4262 if (right < 0) { | 4263 if (right < 0) { |
4263 // The result is -0 if right is negative and left is zero. | 4264 // The result is -0 if right is negative and left is zero. |
4264 DeoptimizeIfZero(left, instr->environment()); | 4265 DeoptimizeIfZero(left, instr->environment()); |
4265 } else if (right == 0) { | 4266 } else if (right == 0) { |
(...skipping 23 matching lines...) Expand all Loading... |
4289 break; | 4290 break; |
4290 case 2: | 4291 case 2: |
4291 if (can_overflow) { | 4292 if (can_overflow) { |
4292 __ Adds(result, left, left); | 4293 __ Adds(result, left, left); |
4293 DeoptimizeIf(vs, instr->environment()); | 4294 DeoptimizeIf(vs, instr->environment()); |
4294 } else { | 4295 } else { |
4295 __ Add(result, left, left); | 4296 __ Add(result, left, left); |
4296 } | 4297 } |
4297 break; | 4298 break; |
4298 | 4299 |
4299 // All other cases cannot detect overflow, because it would probably be no | |
4300 // faster than using the smull method in LMulI. | |
4301 // TODO(jbramley): Investigate this, and add overflow support if it would | |
4302 // be useful. | |
4303 default: | 4300 default: |
| 4301 // Multiplication by constant powers of two (and some related values) |
| 4302 // can be done efficiently with shifted operands. |
| 4303 int32_t right_abs = Abs(right); |
| 4304 |
| 4305 if (IsPowerOf2(right_abs)) { |
| 4306 int right_log2 = WhichPowerOf2(right_abs); |
| 4307 |
| 4308 if (can_overflow) { |
| 4309 Register scratch = result; |
| 4310 ASSERT(!AreAliased(scratch, left)); |
| 4311 __ Cls(scratch, left); |
| 4312 __ Cmp(scratch, right_log2); |
| 4313 DeoptimizeIf(lt, instr->environment()); |
| 4314 } |
| 4315 |
| 4316 if (right >= 0) { |
| 4317 // result = left << log2(right) |
| 4318 __ Lsl(result, left, right_log2); |
| 4319 } else { |
| 4320 // result = -left << log2(-right) |
| 4321 if (can_overflow) { |
| 4322 __ Negs(result, Operand(left, LSL, right_log2)); |
| 4323 DeoptimizeIf(vs, instr->environment()); |
| 4324 } else { |
| 4325 __ Neg(result, Operand(left, LSL, right_log2)); |
| 4326 } |
| 4327 } |
| 4328 return; |
| 4329 } |
| 4330 |
| 4331 |
| 4332 // For the following cases, we could perform a conservative overflow check |
| 4333 // with CLS as above. However the few cycles saved are likely not worth |
| 4334 // the risk of deoptimizing more often than required. |
4304 ASSERT(!can_overflow); | 4335 ASSERT(!can_overflow); |
4305 | 4336 |
4306 // Multiplication by constant powers of two (and some related values) | |
4307 // can be done efficiently with shifted operands. | |
4308 if (right >= 0) { | 4337 if (right >= 0) { |
4309 if (IsPowerOf2(right)) { | 4338 if (IsPowerOf2(right - 1)) { |
4310 // result = left << log2(right) | |
4311 __ Lsl(result, left, WhichPowerOf2(right)); | |
4312 } else if (IsPowerOf2(right - 1)) { | |
4313 // result = left + left << log2(right - 1) | 4339 // result = left + left << log2(right - 1) |
4314 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); | 4340 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(right - 1))); |
4315 } else if (IsPowerOf2(right + 1)) { | 4341 } else if (IsPowerOf2(right + 1)) { |
4316 // result = -left + left << log2(right + 1) | 4342 // result = -left + left << log2(right + 1) |
4317 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); | 4343 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(right + 1))); |
4318 __ Neg(result, result); | 4344 __ Neg(result, result); |
4319 } else { | 4345 } else { |
4320 UNREACHABLE(); | 4346 UNREACHABLE(); |
4321 } | 4347 } |
4322 } else { | 4348 } else { |
4323 if (IsPowerOf2(-right)) { | 4349 if (IsPowerOf2(-right + 1)) { |
4324 // result = -left << log2(-right) | |
4325 __ Neg(result, Operand(left, LSL, WhichPowerOf2(-right))); | |
4326 } else if (IsPowerOf2(-right + 1)) { | |
4327 // result = left - left << log2(-right + 1) | 4350 // result = left - left << log2(-right + 1) |
4328 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); | 4351 __ Sub(result, left, Operand(left, LSL, WhichPowerOf2(-right + 1))); |
4329 } else if (IsPowerOf2(-right - 1)) { | 4352 } else if (IsPowerOf2(-right - 1)) { |
4330 // result = -left - left << log2(-right - 1) | 4353 // result = -left - left << log2(-right - 1) |
4331 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); | 4354 __ Add(result, left, Operand(left, LSL, WhichPowerOf2(-right - 1))); |
4332 __ Neg(result, result); | 4355 __ Neg(result, result); |
4333 } else { | 4356 } else { |
4334 UNREACHABLE(); | 4357 UNREACHABLE(); |
4335 } | 4358 } |
4336 } | 4359 } |
4337 break; | |
4338 } | 4360 } |
4339 } | 4361 } |
4340 | 4362 |
4341 | 4363 |
4342 void LCodeGen::DoMulI(LMulI* instr) { | 4364 void LCodeGen::DoMulI(LMulI* instr) { |
4343 Register result = ToRegister32(instr->result()); | 4365 Register result = ToRegister32(instr->result()); |
4344 Register left = ToRegister32(instr->left()); | 4366 Register left = ToRegister32(instr->left()); |
4345 Register right = ToRegister32(instr->right()); | 4367 Register right = ToRegister32(instr->right()); |
4346 | 4368 |
4347 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4369 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5871 __ Bind(&out_of_object); | 5893 __ Bind(&out_of_object); |
5872 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5894 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
5873 // Index is equal to negated out of object property index plus 1. | 5895 // Index is equal to negated out of object property index plus 1. |
5874 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5896 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
5875 __ Ldr(result, FieldMemOperand(result, | 5897 __ Ldr(result, FieldMemOperand(result, |
5876 FixedArray::kHeaderSize - kPointerSize)); | 5898 FixedArray::kHeaderSize - kPointerSize)); |
5877 __ Bind(&done); | 5899 __ Bind(&done); |
5878 } | 5900 } |
5879 | 5901 |
5880 } } // namespace v8::internal | 5902 } } // namespace v8::internal |
OLD | NEW |