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