Chromium Code Reviews| 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 4214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4225 | 4225 |
| 4226 void LCodeGen::DoMulI(LMulI* instr) { | 4226 void LCodeGen::DoMulI(LMulI* instr) { |
| 4227 Register result = ToRegister32(instr->result()); | 4227 Register result = ToRegister32(instr->result()); |
| 4228 Register left = ToRegister32(instr->left()); | 4228 Register left = ToRegister32(instr->left()); |
| 4229 Register right = ToRegister32(instr->right()); | 4229 Register right = ToRegister32(instr->right()); |
| 4230 | 4230 |
| 4231 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4231 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 4232 bool bailout_on_minus_zero = | 4232 bool bailout_on_minus_zero = |
| 4233 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 4233 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
| 4234 | 4234 |
| 4235 if (bailout_on_minus_zero) { | 4235 if (bailout_on_minus_zero && !left.Is(right)) { |
| 4236 // If one operand is zero and the other is negative, the result is -0. | 4236 // If one operand is zero and the other is negative, the result is -0. |
| 4237 // - Set Z (eq) if either left or right, or both, are 0. | 4237 // - Set Z (eq) if either left or right, or both, are 0. |
| 4238 __ Cmp(left, 0); | 4238 __ Cmp(left, 0); |
| 4239 __ Ccmp(right, 0, ZFlag, ne); | 4239 __ Ccmp(right, 0, ZFlag, ne); |
| 4240 // - If so (eq), set N (mi) if left + right is negative. | 4240 // - If so (eq), set N (mi) if left + right is negative. |
| 4241 // - Otherwise, clear N. | 4241 // - Otherwise, clear N. |
| 4242 __ Ccmn(left, right, NoFlag, eq); | 4242 __ Ccmn(left, right, NoFlag, eq); |
| 4243 DeoptimizeIf(mi, instr->environment()); | 4243 DeoptimizeIf(mi, instr->environment()); |
| 4244 } | 4244 } |
| 4245 | 4245 |
| 4246 if (can_overflow) { | 4246 if (can_overflow) { |
| 4247 __ Smull(result.X(), left, right); | 4247 __ Smull(result.X(), left, right); |
| 4248 __ Cmp(result.X(), Operand(result, SXTW)); | 4248 __ Cmp(result.X(), Operand(result, SXTW)); |
| 4249 DeoptimizeIf(ne, instr->environment()); | 4249 DeoptimizeIf(ne, instr->environment()); |
| 4250 } else { | 4250 } else { |
| 4251 __ Mul(result, left, right); | 4251 __ Mul(result, left, right); |
| 4252 } | 4252 } |
| 4253 } | 4253 } |
| 4254 | 4254 |
| 4255 | 4255 |
| 4256 void LCodeGen::DoMulS(LMulS* instr) { | 4256 void LCodeGen::DoMulS(LMulS* instr) { |
| 4257 Register result = ToRegister(instr->result()); | 4257 Register result = ToRegister(instr->result()); |
| 4258 Register left = ToRegister(instr->left()); | 4258 Register left = ToRegister(instr->left()); |
| 4259 Register right = ToRegister(instr->right()); | 4259 Register right = ToRegister(instr->right()); |
| 4260 | 4260 |
| 4261 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 4261 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| 4262 bool bailout_on_minus_zero = | 4262 bool bailout_on_minus_zero = |
| 4263 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); | 4263 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); |
| 4264 | 4264 |
| 4265 if (bailout_on_minus_zero) { | 4265 if (bailout_on_minus_zero && !left.Is(right)) { |
| 4266 // If one operand is zero and the other is negative, the result is -0. | 4266 // If one operand is zero and the other is negative, the result is -0. |
| 4267 // - Set Z (eq) if either left or right, or both, are 0. | 4267 // - Set Z (eq) if either left or right, or both, are 0. |
| 4268 __ Cmp(left, 0); | 4268 __ Cmp(left, 0); |
| 4269 __ Ccmp(right, 0, ZFlag, ne); | 4269 __ Ccmp(right, 0, ZFlag, ne); |
| 4270 // - If so (eq), set N (mi) if left + right is negative. | 4270 // - If so (eq), set N (mi) if left + right is negative. |
| 4271 // - Otherwise, clear N. | 4271 // - Otherwise, clear N. |
| 4272 __ Ccmn(left, right, NoFlag, eq); | 4272 __ Ccmn(left, right, NoFlag, eq); |
| 4273 DeoptimizeIf(mi, instr->environment()); | 4273 DeoptimizeIf(mi, instr->environment()); |
| 4274 } | 4274 } |
| 4275 | 4275 |
| 4276 STATIC_ASSERT((kSmiShift == 32) && (kSmiTag == 0)); | 4276 STATIC_ASSERT((kSmiShift == 32) && (kSmiTag == 0)); |
| 4277 if (can_overflow) { | 4277 if (can_overflow) { |
| 4278 __ Smulh(result, left, right); | 4278 __ Smulh(result, left, right); |
| 4279 __ Cmp(result, Operand(result.W(), SXTW)); | 4279 __ Cmp(result, Operand(result.W(), SXTW)); |
| 4280 __ SmiTag(result); | 4280 __ SmiTag(result); |
| 4281 DeoptimizeIf(ne, instr->environment()); | 4281 DeoptimizeIf(ne, instr->environment()); |
| 4282 } else { | 4282 } else { |
| 4283 // TODO(jbramley): This could be rewritten to support UseRegisterAtStart. | 4283 if (AreAliased(result, left, right)) { |
| 4284 ASSERT(!AreAliased(result, right)); | 4284 // All three registers are the same: half untag the input and then |
| 4285 __ SmiUntag(result, left); | 4285 // multiply, giving a tagged result. |
| 4286 __ Mul(result, result, right); | 4286 STATIC_ASSERT((kSmiShift % 2) == 0); |
| 4287 __ Asr(result, left, kSmiShift / 2); | |
| 4288 __ Mul(result, result, result); | |
| 4289 } else if (result.Is(left) && !left.Is(right)) { | |
| 4290 // Registers result and left alias, right is distinct: untag left into | |
| 4291 // result, and then multiply by right, giving a tagged result. | |
| 4292 __ SmiUntag(result, left); | |
| 4293 __ Mul(result, result, right); | |
| 4294 } else { | |
|
ulan
2014/03/11 13:39:13
ASSERT(!left.Is(result));
| |
| 4295 // Registers result and right alias, left is distinct, or all registers | |
| 4296 // are distinct: untag right into result, and then multiply by left, | |
| 4297 // giving a tagged result. | |
| 4298 __ SmiUntag(result, right); | |
| 4299 __ Mul(result, left, result); | |
| 4300 } | |
| 4287 } | 4301 } |
| 4288 } | 4302 } |
| 4289 | 4303 |
| 4290 | 4304 |
| 4291 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 4305 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
| 4292 // TODO(3095996): Get rid of this. For now, we need to make the | 4306 // TODO(3095996): Get rid of this. For now, we need to make the |
| 4293 // result register contain a valid pointer because it is already | 4307 // result register contain a valid pointer because it is already |
| 4294 // contained in the register pointer map. | 4308 // contained in the register pointer map. |
| 4295 Register result = ToRegister(instr->result()); | 4309 Register result = ToRegister(instr->result()); |
| 4296 __ Mov(result, 0); | 4310 __ Mov(result, 0); |
| (...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5741 __ Bind(&out_of_object); | 5755 __ Bind(&out_of_object); |
| 5742 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); | 5756 __ Ldr(result, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
| 5743 // Index is equal to negated out of object property index plus 1. | 5757 // Index is equal to negated out of object property index plus 1. |
| 5744 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); | 5758 __ Sub(result, result, Operand::UntagSmiAndScale(index, kPointerSizeLog2)); |
| 5745 __ Ldr(result, FieldMemOperand(result, | 5759 __ Ldr(result, FieldMemOperand(result, |
| 5746 FixedArray::kHeaderSize - kPointerSize)); | 5760 FixedArray::kHeaderSize - kPointerSize)); |
| 5747 __ Bind(&done); | 5761 __ Bind(&done); |
| 5748 } | 5762 } |
| 5749 | 5763 |
| 5750 } } // namespace v8::internal | 5764 } } // namespace v8::internal |
| OLD | NEW |