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 |