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 |