OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 6199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6210 case Token::SUB: | 6210 case Token::SUB: |
6211 if (Smi::IsValid(left - right)) { | 6211 if (Smi::IsValid(left - right)) { |
6212 answer_object = Smi::FromInt(left - right); | 6212 answer_object = Smi::FromInt(left - right); |
6213 } | 6213 } |
6214 break; | 6214 break; |
6215 case Token::MUL: { | 6215 case Token::MUL: { |
6216 double answer = static_cast<double>(left) * right; | 6216 double answer = static_cast<double>(left) * right; |
6217 if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) { | 6217 if (answer >= Smi::kMinValue && answer <= Smi::kMaxValue) { |
6218 // If the product is zero and the non-zero factor is negative, | 6218 // If the product is zero and the non-zero factor is negative, |
6219 // the spec requires us to return floating point negative zero. | 6219 // the spec requires us to return floating point negative zero. |
6220 if (answer != 0 || (left >= 0 && right >= 0)) { | 6220 if (answer != 0 || (left + right) >= 0) { |
6221 answer_object = Smi::FromInt(static_cast<int>(answer)); | 6221 answer_object = Smi::FromInt(static_cast<int>(answer)); |
6222 } | 6222 } |
6223 } | 6223 } |
6224 } | 6224 } |
6225 break; | 6225 break; |
6226 case Token::DIV: | 6226 case Token::DIV: |
6227 case Token::MOD: | 6227 case Token::MOD: |
6228 break; | 6228 break; |
6229 case Token::BIT_OR: | 6229 case Token::BIT_OR: |
6230 answer_object = Smi::FromInt(left | right); | 6230 answer_object = Smi::FromInt(left | right); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6278 frame_->Push(Handle<Object>(answer_object)); | 6278 frame_->Push(Handle<Object>(answer_object)); |
6279 return true; | 6279 return true; |
6280 } | 6280 } |
6281 | 6281 |
6282 | 6282 |
6283 // End of CodeGenerator implementation. | 6283 // End of CodeGenerator implementation. |
6284 | 6284 |
6285 void UnarySubStub::Generate(MacroAssembler* masm) { | 6285 void UnarySubStub::Generate(MacroAssembler* masm) { |
6286 Label slow; | 6286 Label slow; |
6287 Label done; | 6287 Label done; |
6288 | 6288 Label try_float; |
| 6289 Label special; |
6289 // Check whether the value is a smi. | 6290 // Check whether the value is a smi. |
6290 __ testl(rax, Immediate(kSmiTagMask)); | 6291 __ testl(rax, Immediate(kSmiTagMask)); |
6291 // TODO(X64): Add inline code that handles floats, as on ia32 platform. | 6292 __ j(not_zero, &try_float); |
6292 __ j(not_zero, &slow); | 6293 |
6293 // Enter runtime system if the value of the smi is zero | 6294 // Enter runtime system if the value of the smi is zero |
6294 // to make sure that we switch between 0 and -0. | 6295 // to make sure that we switch between 0 and -0. |
6295 // Also enter it if the value of the smi is Smi::kMinValue | 6296 // Also enter it if the value of the smi is Smi::kMinValue |
6296 __ testl(rax, Immediate(0x7FFFFFFE)); | 6297 __ testl(rax, Immediate(0x7FFFFFFE)); |
6297 __ j(zero, &slow); | 6298 __ j(zero, &special); |
6298 __ neg(rax); | 6299 __ neg(rax); |
6299 __ jmp(&done); | 6300 __ jmp(&done); |
| 6301 |
| 6302 __ bind(&special); |
| 6303 // Either zero or -0x4000000, neither of which become a smi when negated. |
| 6304 __ testl(rax, rax); |
| 6305 __ j(not_zero, &slow); |
| 6306 __ Move(rax, Factory::minus_zero_value()); |
| 6307 __ jmp(&done); |
| 6308 |
6300 // Enter runtime system. | 6309 // Enter runtime system. |
6301 __ bind(&slow); | 6310 __ bind(&slow); |
6302 __ pop(rcx); // pop return address | 6311 __ pop(rcx); // pop return address |
6303 __ push(rax); | 6312 __ push(rax); |
6304 __ push(rcx); // push return address | 6313 __ push(rcx); // push return address |
6305 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION); | 6314 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION); |
| 6315 __ jmp(&done); |
| 6316 |
| 6317 // Try floating point case. |
| 6318 __ bind(&try_float); |
| 6319 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); |
| 6320 __ Cmp(rdx, Factory::heap_number_map()); |
| 6321 __ j(not_equal, &slow); |
| 6322 // Operand is a float, negate its value by flipping sign bit. |
| 6323 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); |
| 6324 __ movq(kScratchRegister, Immediate(0x01)); |
| 6325 __ shl(kScratchRegister, Immediate(63)); |
| 6326 __ xor_(rdx, kScratchRegister); // Flip sign. |
| 6327 // rdx is value to store. |
| 6328 if (overwrite_) { |
| 6329 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); |
| 6330 } else { |
| 6331 FloatingPointHelper::AllocateHeapNumber(masm, &slow, rbx, rcx); |
| 6332 // rcx: allocated 'empty' number |
| 6333 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); |
| 6334 __ movq(rax, rcx); |
| 6335 } |
6306 | 6336 |
6307 __ bind(&done); | 6337 __ bind(&done); |
6308 __ StubReturn(1); | 6338 __ StubReturn(1); |
6309 } | 6339 } |
6310 | 6340 |
6311 | 6341 |
6312 void CompareStub::Generate(MacroAssembler* masm) { | 6342 void CompareStub::Generate(MacroAssembler* masm) { |
6313 Label call_builtin, done; | 6343 Label call_builtin, done; |
6314 | 6344 |
6315 // NOTICE! This code is only reached after a smi-fast-case check, so | 6345 // NOTICE! This code is only reached after a smi-fast-case check, so |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7698 int CompareStub::MinorKey() { | 7728 int CompareStub::MinorKey() { |
7699 // Encode the two parameters in a unique 16 bit value. | 7729 // Encode the two parameters in a unique 16 bit value. |
7700 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); | 7730 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); |
7701 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); | 7731 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); |
7702 } | 7732 } |
7703 | 7733 |
7704 | 7734 |
7705 #undef __ | 7735 #undef __ |
7706 | 7736 |
7707 } } // namespace v8::internal | 7737 } } // namespace v8::internal |
OLD | NEW |