Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 13841003: Separate Math Lithium operations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 3350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3361 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3361 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3362 ASSERT(ToRegister(instr->result()).is(rax)); 3362 ASSERT(ToRegister(instr->result()).is(rax));
3363 CallKnownFunction(instr->function(), 3363 CallKnownFunction(instr->function(),
3364 instr->arity(), 3364 instr->arity(),
3365 instr, 3365 instr,
3366 CALL_AS_METHOD, 3366 CALL_AS_METHOD,
3367 RDI_UNINITIALIZED); 3367 RDI_UNINITIALIZED);
3368 } 3368 }
3369 3369
3370 3370
3371 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3371 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3372 Register input_reg = ToRegister(instr->value()); 3372 Register input_reg = ToRegister(instr->value());
3373 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset), 3373 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
3374 Heap::kHeapNumberMapRootIndex); 3374 Heap::kHeapNumberMapRootIndex);
3375 DeoptimizeIf(not_equal, instr->environment()); 3375 DeoptimizeIf(not_equal, instr->environment());
3376 3376
3377 Label done; 3377 Label done;
3378 Register tmp = input_reg.is(rax) ? rcx : rax; 3378 Register tmp = input_reg.is(rax) ? rcx : rax;
3379 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx; 3379 Register tmp2 = tmp.is(rcx) ? rdx : input_reg.is(rcx) ? rdx : rcx;
3380 3380
3381 // Preserve the value of all registers. 3381 // Preserve the value of all registers.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3413 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3413 __ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
3414 __ shl(tmp2, Immediate(1)); 3414 __ shl(tmp2, Immediate(1));
3415 __ shr(tmp2, Immediate(1)); 3415 __ shr(tmp2, Immediate(1));
3416 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2); 3416 __ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
3417 __ StoreToSafepointRegisterSlot(input_reg, tmp); 3417 __ StoreToSafepointRegisterSlot(input_reg, tmp);
3418 3418
3419 __ bind(&done); 3419 __ bind(&done);
3420 } 3420 }
3421 3421
3422 3422
3423 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3423 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3424 Register input_reg = ToRegister(instr->value()); 3424 Register input_reg = ToRegister(instr->value());
3425 __ testl(input_reg, input_reg); 3425 __ testl(input_reg, input_reg);
3426 Label is_positive; 3426 Label is_positive;
3427 __ j(not_sign, &is_positive); 3427 __ j(not_sign, &is_positive);
3428 __ negl(input_reg); // Sets flags. 3428 __ negl(input_reg); // Sets flags.
3429 DeoptimizeIf(negative, instr->environment()); 3429 DeoptimizeIf(negative, instr->environment());
3430 __ bind(&is_positive); 3430 __ bind(&is_positive);
3431 } 3431 }
3432 3432
3433 3433
3434 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3434 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3435 // Class for deferred case. 3435 // Class for deferred case.
3436 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3436 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3437 public: 3437 public:
3438 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3438 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3439 LUnaryMathOperation* instr)
3440 : LDeferredCode(codegen), instr_(instr) { } 3439 : LDeferredCode(codegen), instr_(instr) { }
3441 virtual void Generate() { 3440 virtual void Generate() {
3442 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3441 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3443 } 3442 }
3444 virtual LInstruction* instr() { return instr_; } 3443 virtual LInstruction* instr() { return instr_; }
3445 private: 3444 private:
3446 LUnaryMathOperation* instr_; 3445 LMathAbs* instr_;
3447 }; 3446 };
3448 3447
3449 ASSERT(instr->value()->Equals(instr->result())); 3448 ASSERT(instr->value()->Equals(instr->result()));
3450 Representation r = instr->hydrogen()->value()->representation(); 3449 Representation r = instr->hydrogen()->value()->representation();
3451 3450
3452 if (r.IsDouble()) { 3451 if (r.IsDouble()) {
3453 XMMRegister scratch = xmm0; 3452 XMMRegister scratch = xmm0;
3454 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3453 XMMRegister input_reg = ToDoubleRegister(instr->value());
3455 __ xorps(scratch, scratch); 3454 __ xorps(scratch, scratch);
3456 __ subsd(scratch, input_reg); 3455 __ subsd(scratch, input_reg);
3457 __ andpd(input_reg, scratch); 3456 __ andpd(input_reg, scratch);
3458 } else if (r.IsInteger32()) { 3457 } else if (r.IsInteger32()) {
3459 EmitIntegerMathAbs(instr); 3458 EmitIntegerMathAbs(instr);
3460 } else { // Tagged case. 3459 } else { // Tagged case.
3461 DeferredMathAbsTaggedHeapNumber* deferred = 3460 DeferredMathAbsTaggedHeapNumber* deferred =
3462 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3461 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3463 Register input_reg = ToRegister(instr->value()); 3462 Register input_reg = ToRegister(instr->value());
3464 // Smi check. 3463 // Smi check.
3465 __ JumpIfNotSmi(input_reg, deferred->entry()); 3464 __ JumpIfNotSmi(input_reg, deferred->entry());
3466 __ SmiToInteger32(input_reg, input_reg); 3465 __ SmiToInteger32(input_reg, input_reg);
3467 EmitIntegerMathAbs(instr); 3466 EmitIntegerMathAbs(instr);
3468 __ Integer32ToSmi(input_reg, input_reg); 3467 __ Integer32ToSmi(input_reg, input_reg);
3469 __ bind(deferred->exit()); 3468 __ bind(deferred->exit());
3470 } 3469 }
3471 } 3470 }
3472 3471
3473 3472
3474 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3473 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3475 XMMRegister xmm_scratch = xmm0; 3474 XMMRegister xmm_scratch = xmm0;
3476 Register output_reg = ToRegister(instr->result()); 3475 Register output_reg = ToRegister(instr->result());
3477 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3476 XMMRegister input_reg = ToDoubleRegister(instr->value());
3478 3477
3479 if (CpuFeatures::IsSupported(SSE4_1)) { 3478 if (CpuFeatures::IsSupported(SSE4_1)) {
3480 CpuFeatureScope scope(masm(), SSE4_1); 3479 CpuFeatureScope scope(masm(), SSE4_1);
3481 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3480 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3482 // Deoptimize if minus zero. 3481 // Deoptimize if minus zero.
3483 __ movq(output_reg, input_reg); 3482 __ movq(output_reg, input_reg);
3484 __ subq(output_reg, Immediate(1)); 3483 __ subq(output_reg, Immediate(1));
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3523 __ ucomisd(input_reg, xmm_scratch); 3522 __ ucomisd(input_reg, xmm_scratch);
3524 __ j(equal, &done, Label::kNear); 3523 __ j(equal, &done, Label::kNear);
3525 __ subl(output_reg, Immediate(1)); 3524 __ subl(output_reg, Immediate(1));
3526 DeoptimizeIf(overflow, instr->environment()); 3525 DeoptimizeIf(overflow, instr->environment());
3527 3526
3528 __ bind(&done); 3527 __ bind(&done);
3529 } 3528 }
3530 } 3529 }
3531 3530
3532 3531
3533 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3532 void LCodeGen::DoMathRound(LMathRound* instr) {
3534 const XMMRegister xmm_scratch = xmm0; 3533 const XMMRegister xmm_scratch = xmm0;
3535 Register output_reg = ToRegister(instr->result()); 3534 Register output_reg = ToRegister(instr->result());
3536 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3535 XMMRegister input_reg = ToDoubleRegister(instr->value());
3537 static int64_t one_half = V8_INT64_C(0x3FE0000000000000); // 0.5 3536 static int64_t one_half = V8_INT64_C(0x3FE0000000000000); // 0.5
3538 static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5 3537 static int64_t minus_one_half = V8_INT64_C(0xBFE0000000000000); // -0.5
3539 3538
3540 Label done, round_to_zero, below_one_half, do_not_compensate, restore; 3539 Label done, round_to_zero, below_one_half, do_not_compensate, restore;
3541 __ movq(kScratchRegister, one_half, RelocInfo::NONE64); 3540 __ movq(kScratchRegister, one_half, RelocInfo::NONE64);
3542 __ movq(xmm_scratch, kScratchRegister); 3541 __ movq(xmm_scratch, kScratchRegister);
3543 __ ucomisd(xmm_scratch, input_reg); 3542 __ ucomisd(xmm_scratch, input_reg);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3584 __ movq(output_reg, input_reg); 3583 __ movq(output_reg, input_reg);
3585 __ testq(output_reg, output_reg); 3584 __ testq(output_reg, output_reg);
3586 __ RecordComment("Minus zero"); 3585 __ RecordComment("Minus zero");
3587 DeoptimizeIf(negative, instr->environment()); 3586 DeoptimizeIf(negative, instr->environment());
3588 } 3587 }
3589 __ Set(output_reg, 0); 3588 __ Set(output_reg, 0);
3590 __ bind(&done); 3589 __ bind(&done);
3591 } 3590 }
3592 3591
3593 3592
3594 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3593 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3595 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3594 XMMRegister input_reg = ToDoubleRegister(instr->value());
3596 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3595 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3597 __ sqrtsd(input_reg, input_reg); 3596 __ sqrtsd(input_reg, input_reg);
3598 } 3597 }
3599 3598
3600 3599
3601 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3600 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3602 XMMRegister xmm_scratch = xmm0; 3601 XMMRegister xmm_scratch = xmm0;
3603 XMMRegister input_reg = ToDoubleRegister(instr->value()); 3602 XMMRegister input_reg = ToDoubleRegister(instr->value());
3604 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); 3603 ASSERT(ToDoubleRegister(instr->result()).is(input_reg));
3605 3604
3606 // Note that according to ECMA-262 15.8.2.13: 3605 // Note that according to ECMA-262 15.8.2.13:
3607 // Math.pow(-Infinity, 0.5) == Infinity 3606 // Math.pow(-Infinity, 0.5) == Infinity
3608 // Math.sqrt(-Infinity) == NaN 3607 // Math.sqrt(-Infinity) == NaN
3609 Label done, sqrt; 3608 Label done, sqrt;
3610 // Check base for -Infinity. According to IEEE-754, double-precision 3609 // Check base for -Infinity. According to IEEE-754, double-precision
3611 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared. 3610 // -Infinity has the highest 12 bits set and the lowest 52 bits cleared.
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
3758 void LCodeGen::DoMathExp(LMathExp* instr) { 3757 void LCodeGen::DoMathExp(LMathExp* instr) {
3759 XMMRegister input = ToDoubleRegister(instr->value()); 3758 XMMRegister input = ToDoubleRegister(instr->value());
3760 XMMRegister result = ToDoubleRegister(instr->result()); 3759 XMMRegister result = ToDoubleRegister(instr->result());
3761 Register temp1 = ToRegister(instr->temp1()); 3760 Register temp1 = ToRegister(instr->temp1());
3762 Register temp2 = ToRegister(instr->temp2()); 3761 Register temp2 = ToRegister(instr->temp2());
3763 3762
3764 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); 3763 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2);
3765 } 3764 }
3766 3765
3767 3766
3768 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 3767 void LCodeGen::DoMathLog(LMathLog* instr) {
3769 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3768 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3770 TranscendentalCacheStub stub(TranscendentalCache::LOG, 3769 TranscendentalCacheStub stub(TranscendentalCache::LOG,
3771 TranscendentalCacheStub::UNTAGGED); 3770 TranscendentalCacheStub::UNTAGGED);
3772 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3771 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3773 } 3772 }
3774 3773
3775 3774
3776 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { 3775 void LCodeGen::DoMathTan(LMathTan* instr) {
3777 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3776 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3778 TranscendentalCacheStub stub(TranscendentalCache::TAN, 3777 TranscendentalCacheStub stub(TranscendentalCache::TAN,
3779 TranscendentalCacheStub::UNTAGGED); 3778 TranscendentalCacheStub::UNTAGGED);
3780 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3779 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3781 } 3780 }
3782 3781
3783 3782
3784 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { 3783 void LCodeGen::DoMathCos(LMathCos* instr) {
3785 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3784 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3786 TranscendentalCacheStub stub(TranscendentalCache::COS, 3785 TranscendentalCacheStub stub(TranscendentalCache::COS,
3787 TranscendentalCacheStub::UNTAGGED); 3786 TranscendentalCacheStub::UNTAGGED);
3788 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3787 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3789 } 3788 }
3790 3789
3791 3790
3792 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { 3791 void LCodeGen::DoMathSin(LMathSin* instr) {
3793 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); 3792 ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
3794 TranscendentalCacheStub stub(TranscendentalCache::SIN, 3793 TranscendentalCacheStub stub(TranscendentalCache::SIN,
3795 TranscendentalCacheStub::UNTAGGED); 3794 TranscendentalCacheStub::UNTAGGED);
3796 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 3795 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
3797 } 3796 }
3798 3797
3799 3798
3800 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
3801 switch (instr->op()) {
3802 case kMathAbs:
3803 DoMathAbs(instr);
3804 break;
3805 case kMathFloor:
3806 DoMathFloor(instr);
3807 break;
3808 case kMathRound:
3809 DoMathRound(instr);
3810 break;
3811 case kMathSqrt:
3812 DoMathSqrt(instr);
3813 break;
3814 case kMathPowHalf:
3815 DoMathPowHalf(instr);
3816 break;
3817 case kMathCos:
3818 DoMathCos(instr);
3819 break;
3820 case kMathSin:
3821 DoMathSin(instr);
3822 break;
3823 case kMathTan:
3824 DoMathTan(instr);
3825 break;
3826 case kMathLog:
3827 DoMathLog(instr);
3828 break;
3829
3830 default:
3831 UNREACHABLE();
3832 }
3833 }
3834
3835
3836 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 3799 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
3837 ASSERT(ToRegister(instr->function()).is(rdi)); 3800 ASSERT(ToRegister(instr->function()).is(rdi));
3838 ASSERT(instr->HasPointerMap()); 3801 ASSERT(instr->HasPointerMap());
3839 3802
3840 if (instr->known_function().is_null()) { 3803 if (instr->known_function().is_null()) {
3841 LPointerMap* pointers = instr->pointer_map(); 3804 LPointerMap* pointers = instr->pointer_map();
3842 RecordPosition(pointers->position()); 3805 RecordPosition(pointers->position());
3843 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 3806 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
3844 ParameterCount count(instr->arity()); 3807 ParameterCount count(instr->arity());
3845 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 3808 __ InvokeFunction(rdi, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
(...skipping 1844 matching lines...) Expand 10 before | Expand all | Expand 10 after
5690 FixedArray::kHeaderSize - kPointerSize)); 5653 FixedArray::kHeaderSize - kPointerSize));
5691 __ bind(&done); 5654 __ bind(&done);
5692 } 5655 }
5693 5656
5694 5657
5695 #undef __ 5658 #undef __
5696 5659
5697 } } // namespace v8::internal 5660 } } // namespace v8::internal
5698 5661
5699 #endif // V8_TARGET_ARCH_X64 5662 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698