| 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 3311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3322 RDI_UNINITIALIZED); | 3322 RDI_UNINITIALIZED); |
| 3323 } | 3323 } |
| 3324 | 3324 |
| 3325 | 3325 |
| 3326 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { | 3326 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { |
| 3327 Register input_reg = ToRegister(instr->value()); | 3327 Register input_reg = ToRegister(instr->value()); |
| 3328 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), | 3328 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 3329 Heap::kHeapNumberMapRootIndex); | 3329 Heap::kHeapNumberMapRootIndex); |
| 3330 DeoptimizeIf(not_equal, instr->environment()); | 3330 DeoptimizeIf(not_equal, instr->environment()); |
| 3331 | 3331 |
| 3332 Label done; | 3332 Label slow, allocated, done; |
| 3333 Register tmp = input_reg.is(rax) ? rcx : rax; | 3333 Register tmp = input_reg.is(rax) ? rcx : rax; |
| 3334 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; | 3334 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; |
| 3335 | 3335 |
| 3336 // Preserve the value of all registers. | 3336 // Preserve the value of all registers. |
| 3337 PushSafepointRegistersScope scope(this); | 3337 PushSafepointRegistersScope scope(this); |
| 3338 | 3338 |
| 3339 Label negative; | |
| 3340 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3339 __ movl(tmp, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 3341 // Check the sign of the argument. If the argument is positive, just | 3340 // Check the sign of the argument. If the argument is positive, just |
| 3342 // return it. We do not need to patch the stack since |input| and | 3341 // return it. We do not need to patch the stack since |input| and |
| 3343 // |result| are the same register and |input| will be restored | 3342 // |result| are the same register and |input| will be restored |
| 3344 // unchanged by popping safepoint registers. | 3343 // unchanged by popping safepoint registers. |
| 3345 __ testl(tmp, Immediate(HeapNumber::kSignMask)); | 3344 __ testl(tmp, Immediate(HeapNumber::kSignMask)); |
| 3346 __ j(not_zero, &negative); | 3345 __ j(zero, &done); |
| 3347 __ jmp(&done); | |
| 3348 | 3346 |
| 3349 __ bind(&negative); | |
| 3350 | |
| 3351 Label allocated, slow; | |
| 3352 __ AllocateHeapNumber(tmp, tmp2, &slow); | 3347 __ AllocateHeapNumber(tmp, tmp2, &slow); |
| 3353 __ jmp(&allocated); | 3348 __ jmp(&allocated, Label::kNear); |
| 3354 | 3349 |
| 3355 // Slow case: Call the runtime system to do the number allocation. | 3350 // Slow case: Call the runtime system to do the number allocation. |
| 3356 __ bind(&slow); | 3351 __ bind(&slow); |
| 3357 | |
| 3358 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); | 3352 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); |
| 3359 // Set the pointer to the new heap number in tmp. | 3353 // Set the pointer to the new heap number in tmp. |
| 3360 if (!tmp.is(rax)) { | 3354 if (!tmp.is(rax)) __ movq(tmp, rax); |
| 3361 __ movq(tmp, rax); | |
| 3362 } | |
| 3363 | |
| 3364 // Restore input_reg after call to runtime. | 3355 // Restore input_reg after call to runtime. |
| 3365 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); | 3356 __ LoadFromSafepointRegisterSlot(input_reg, input_reg); |
| 3366 | 3357 |
| 3367 __ bind(&allocated); | 3358 __ bind(&allocated); |
| 3368 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3359 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3369 __ shl(tmp2, Immediate(1)); | 3360 __ shl(tmp2, Immediate(1)); |
| 3370 __ shr(tmp2, Immediate(1)); | 3361 __ shr(tmp2, Immediate(1)); |
| 3371 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); | 3362 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); |
| 3372 __ StoreToSafepointRegisterSlot(input_reg, tmp); | 3363 __ StoreToSafepointRegisterSlot(input_reg, tmp); |
| 3373 | 3364 |
| 3374 __ bind(&done); | 3365 __ bind(&done); |
| 3375 } | 3366 } |
| 3376 | 3367 |
| 3377 | 3368 |
| 3378 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { | 3369 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) { |
| 3379 Register input_reg = ToRegister(instr->value()); | 3370 Register input_reg = ToRegister(instr->value()); |
| 3380 __ testl(input_reg, input_reg); | 3371 __ testl(input_reg, input_reg); |
| 3381 Label is_positive; | 3372 Label is_positive; |
| 3382 __ j(not_sign, &is_positive); | 3373 __ j(not_sign, &is_positive, Label::kNear); |
| 3383 __ negl(input_reg); // Sets flags. | 3374 __ negl(input_reg); // Sets flags. |
| 3384 DeoptimizeIf(negative, instr->environment()); | 3375 DeoptimizeIf(negative, instr->environment()); |
| 3385 __ bind(&is_positive); | 3376 __ bind(&is_positive); |
| 3386 } | 3377 } |
| 3387 | 3378 |
| 3388 | 3379 |
| 3389 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3380 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
| 3390 // Class for deferred case. | 3381 // Class for deferred case. |
| 3391 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 3382 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
| 3392 public: | 3383 public: |
| (...skipping 2135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5528 FixedArray::kHeaderSize - kPointerSize)); | 5519 FixedArray::kHeaderSize - kPointerSize)); |
| 5529 __ bind(&done); | 5520 __ bind(&done); |
| 5530 } | 5521 } |
| 5531 | 5522 |
| 5532 | 5523 |
| 5533 #undef __ | 5524 #undef __ |
| 5534 | 5525 |
| 5535 } } // namespace v8::internal | 5526 } } // namespace v8::internal |
| 5536 | 5527 |
| 5537 #endif // V8_TARGET_ARCH_X64 | 5528 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |