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

Side by Side Diff: src/arm/lithium-codegen-arm.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/arm/lithium-codegen-arm.h ('k') | src/ia32/lithium-codegen-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3736 matching lines...) Expand 10 before | Expand all | Expand 10 after
3747 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { 3747 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) {
3748 ASSERT(ToRegister(instr->result()).is(r0)); 3748 ASSERT(ToRegister(instr->result()).is(r0));
3749 CallKnownFunction(instr->function(), 3749 CallKnownFunction(instr->function(),
3750 instr->arity(), 3750 instr->arity(),
3751 instr, 3751 instr,
3752 CALL_AS_METHOD, 3752 CALL_AS_METHOD,
3753 R1_UNINITIALIZED); 3753 R1_UNINITIALIZED);
3754 } 3754 }
3755 3755
3756 3756
3757 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { 3757 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
3758 Register input = ToRegister(instr->value()); 3758 Register input = ToRegister(instr->value());
3759 Register result = ToRegister(instr->result()); 3759 Register result = ToRegister(instr->result());
3760 Register scratch = scratch0(); 3760 Register scratch = scratch0();
3761 3761
3762 // Deoptimize if not a heap number. 3762 // Deoptimize if not a heap number.
3763 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); 3763 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
3764 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 3764 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
3765 __ cmp(scratch, Operand(ip)); 3765 __ cmp(scratch, Operand(ip));
3766 DeoptimizeIf(ne, instr->environment()); 3766 DeoptimizeIf(ne, instr->environment());
3767 3767
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3813 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); 3813 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
3814 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); 3814 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
3815 3815
3816 __ StoreToSafepointRegisterSlot(tmp1, result); 3816 __ StoreToSafepointRegisterSlot(tmp1, result);
3817 } 3817 }
3818 3818
3819 __ bind(&done); 3819 __ bind(&done);
3820 } 3820 }
3821 3821
3822 3822
3823 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { 3823 void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
3824 Register input = ToRegister(instr->value()); 3824 Register input = ToRegister(instr->value());
3825 Register result = ToRegister(instr->result()); 3825 Register result = ToRegister(instr->result());
3826 __ cmp(input, Operand::Zero()); 3826 __ cmp(input, Operand::Zero());
3827 __ Move(result, input, pl); 3827 __ Move(result, input, pl);
3828 // We can make rsb conditional because the previous cmp instruction 3828 // We can make rsb conditional because the previous cmp instruction
3829 // will clear the V (overflow) flag and rsb won't set this flag 3829 // will clear the V (overflow) flag and rsb won't set this flag
3830 // if input is positive. 3830 // if input is positive.
3831 __ rsb(result, input, Operand::Zero(), SetCC, mi); 3831 __ rsb(result, input, Operand::Zero(), SetCC, mi);
3832 // Deoptimize on overflow. 3832 // Deoptimize on overflow.
3833 DeoptimizeIf(vs, instr->environment()); 3833 DeoptimizeIf(vs, instr->environment());
3834 } 3834 }
3835 3835
3836 3836
3837 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3837 void LCodeGen::DoMathAbs(LMathAbs* instr) {
3838 // Class for deferred case. 3838 // Class for deferred case.
3839 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3839 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3840 public: 3840 public:
3841 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3841 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
3842 LUnaryMathOperation* instr)
3843 : LDeferredCode(codegen), instr_(instr) { } 3842 : LDeferredCode(codegen), instr_(instr) { }
3844 virtual void Generate() { 3843 virtual void Generate() {
3845 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3844 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3846 } 3845 }
3847 virtual LInstruction* instr() { return instr_; } 3846 virtual LInstruction* instr() { return instr_; }
3848 private: 3847 private:
3849 LUnaryMathOperation* instr_; 3848 LMathAbs* instr_;
3850 }; 3849 };
3851 3850
3852 Representation r = instr->hydrogen()->value()->representation(); 3851 Representation r = instr->hydrogen()->value()->representation();
3853 if (r.IsDouble()) { 3852 if (r.IsDouble()) {
3854 DwVfpRegister input = ToDoubleRegister(instr->value()); 3853 DwVfpRegister input = ToDoubleRegister(instr->value());
3855 DwVfpRegister result = ToDoubleRegister(instr->result()); 3854 DwVfpRegister result = ToDoubleRegister(instr->result());
3856 __ vabs(result, input); 3855 __ vabs(result, input);
3857 } else if (r.IsInteger32()) { 3856 } else if (r.IsInteger32()) {
3858 EmitIntegerMathAbs(instr); 3857 EmitIntegerMathAbs(instr);
3859 } else { 3858 } else {
3860 // Representation is tagged. 3859 // Representation is tagged.
3861 DeferredMathAbsTaggedHeapNumber* deferred = 3860 DeferredMathAbsTaggedHeapNumber* deferred =
3862 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); 3861 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
3863 Register input = ToRegister(instr->value()); 3862 Register input = ToRegister(instr->value());
3864 // Smi check. 3863 // Smi check.
3865 __ JumpIfNotSmi(input, deferred->entry()); 3864 __ JumpIfNotSmi(input, deferred->entry());
3866 // If smi, handle it directly. 3865 // If smi, handle it directly.
3867 EmitIntegerMathAbs(instr); 3866 EmitIntegerMathAbs(instr);
3868 __ bind(deferred->exit()); 3867 __ bind(deferred->exit());
3869 } 3868 }
3870 } 3869 }
3871 3870
3872 3871
3873 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3872 void LCodeGen::DoMathFloor(LMathFloor* instr) {
3874 DwVfpRegister input = ToDoubleRegister(instr->value()); 3873 DwVfpRegister input = ToDoubleRegister(instr->value());
3875 Register result = ToRegister(instr->result()); 3874 Register result = ToRegister(instr->result());
3876 Register input_high = scratch0(); 3875 Register input_high = scratch0();
3877 Label done, exact; 3876 Label done, exact;
3878 3877
3879 __ vmov(input_high, input.high()); 3878 __ vmov(input_high, input.high());
3880 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); 3879 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
3881 DeoptimizeIf(al, instr->environment()); 3880 DeoptimizeIf(al, instr->environment());
3882 3881
3883 __ bind(&exact); 3882 __ bind(&exact);
3884 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3883 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3885 // Test for -0. 3884 // Test for -0.
3886 __ cmp(result, Operand::Zero()); 3885 __ cmp(result, Operand::Zero());
3887 __ b(ne, &done); 3886 __ b(ne, &done);
3888 __ cmp(input_high, Operand::Zero()); 3887 __ cmp(input_high, Operand::Zero());
3889 DeoptimizeIf(mi, instr->environment()); 3888 DeoptimizeIf(mi, instr->environment());
3890 } 3889 }
3891 __ bind(&done); 3890 __ bind(&done);
3892 } 3891 }
3893 3892
3894 3893
3895 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3894 void LCodeGen::DoMathRound(LMathRound* instr) {
3896 DwVfpRegister input = ToDoubleRegister(instr->value()); 3895 DwVfpRegister input = ToDoubleRegister(instr->value());
3897 Register result = ToRegister(instr->result()); 3896 Register result = ToRegister(instr->result());
3898 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3897 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
3899 DwVfpRegister input_plus_dot_five = double_scratch1; 3898 DwVfpRegister input_plus_dot_five = double_scratch1;
3900 Register input_high = scratch0(); 3899 Register input_high = scratch0();
3901 DwVfpRegister dot_five = double_scratch0(); 3900 DwVfpRegister dot_five = double_scratch0();
3902 Label convert, done; 3901 Label convert, done;
3903 3902
3904 __ Vmov(dot_five, 0.5, scratch0()); 3903 __ Vmov(dot_five, 0.5, scratch0());
3905 __ vabs(double_scratch1, input); 3904 __ vabs(double_scratch1, input);
(...skipping 18 matching lines...) Expand all
3924 __ vadd(input_plus_dot_five, input, dot_five); 3923 __ vadd(input_plus_dot_five, input, dot_five);
3925 __ vmov(input_high, input_plus_dot_five.high()); 3924 __ vmov(input_high, input_plus_dot_five.high());
3926 // Reuse dot_five (double_scratch0) as we no longer need this value. 3925 // Reuse dot_five (double_scratch0) as we no longer need this value.
3927 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), 3926 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
3928 &done, &done); 3927 &done, &done);
3929 DeoptimizeIf(al, instr->environment()); 3928 DeoptimizeIf(al, instr->environment());
3930 __ bind(&done); 3929 __ bind(&done);
3931 } 3930 }
3932 3931
3933 3932
3934 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3933 void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
3935 DwVfpRegister input = ToDoubleRegister(instr->value()); 3934 DwVfpRegister input = ToDoubleRegister(instr->value());
3936 DwVfpRegister result = ToDoubleRegister(instr->result()); 3935 DwVfpRegister result = ToDoubleRegister(instr->result());
3937 __ vsqrt(result, input); 3936 __ vsqrt(result, input);
3938 } 3937 }
3939 3938
3940 3939
3941 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3940 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
3942 DwVfpRegister input = ToDoubleRegister(instr->value()); 3941 DwVfpRegister input = ToDoubleRegister(instr->value());
3943 DwVfpRegister result = ToDoubleRegister(instr->result()); 3942 DwVfpRegister result = ToDoubleRegister(instr->result());
3944 DwVfpRegister temp = ToDoubleRegister(instr->temp()); 3943 DwVfpRegister temp = ToDoubleRegister(instr->temp());
3945 3944
3946 // Note that according to ECMA-262 15.8.2.13: 3945 // Note that according to ECMA-262 15.8.2.13:
3947 // Math.pow(-Infinity, 0.5) == Infinity 3946 // Math.pow(-Infinity, 0.5) == Infinity
3948 // Math.sqrt(-Infinity) == NaN 3947 // Math.sqrt(-Infinity) == NaN
3949 Label done; 3948 Label done;
3950 __ vmov(temp, -V8_INFINITY, scratch0()); 3949 __ vmov(temp, -V8_INFINITY, scratch0());
3951 __ VFPCompareAndSetFlags(input, temp); 3950 __ VFPCompareAndSetFlags(input, temp);
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
4076 DwVfpRegister double_scratch2 = double_scratch0(); 4075 DwVfpRegister double_scratch2 = double_scratch0();
4077 Register temp1 = ToRegister(instr->temp1()); 4076 Register temp1 = ToRegister(instr->temp1());
4078 Register temp2 = ToRegister(instr->temp2()); 4077 Register temp2 = ToRegister(instr->temp2());
4079 4078
4080 MathExpGenerator::EmitMathExp( 4079 MathExpGenerator::EmitMathExp(
4081 masm(), input, result, double_scratch1, double_scratch2, 4080 masm(), input, result, double_scratch1, double_scratch2,
4082 temp1, temp2, scratch0()); 4081 temp1, temp2, scratch0());
4083 } 4082 }
4084 4083
4085 4084
4086 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 4085 void LCodeGen::DoMathLog(LMathLog* instr) {
4087 ASSERT(ToDoubleRegister(instr->result()).is(d2)); 4086 ASSERT(ToDoubleRegister(instr->result()).is(d2));
4088 TranscendentalCacheStub stub(TranscendentalCache::LOG, 4087 TranscendentalCacheStub stub(TranscendentalCache::LOG,
4089 TranscendentalCacheStub::UNTAGGED); 4088 TranscendentalCacheStub::UNTAGGED);
4090 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4089 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4091 } 4090 }
4092 4091
4093 4092
4094 void LCodeGen::DoMathTan(LUnaryMathOperation* instr) { 4093 void LCodeGen::DoMathTan(LMathTan* instr) {
4095 ASSERT(ToDoubleRegister(instr->result()).is(d2)); 4094 ASSERT(ToDoubleRegister(instr->result()).is(d2));
4096 TranscendentalCacheStub stub(TranscendentalCache::TAN, 4095 TranscendentalCacheStub stub(TranscendentalCache::TAN,
4097 TranscendentalCacheStub::UNTAGGED); 4096 TranscendentalCacheStub::UNTAGGED);
4098 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4097 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4099 } 4098 }
4100 4099
4101 4100
4102 void LCodeGen::DoMathCos(LUnaryMathOperation* instr) { 4101 void LCodeGen::DoMathCos(LMathCos* instr) {
4103 ASSERT(ToDoubleRegister(instr->result()).is(d2)); 4102 ASSERT(ToDoubleRegister(instr->result()).is(d2));
4104 TranscendentalCacheStub stub(TranscendentalCache::COS, 4103 TranscendentalCacheStub stub(TranscendentalCache::COS,
4105 TranscendentalCacheStub::UNTAGGED); 4104 TranscendentalCacheStub::UNTAGGED);
4106 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4105 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4107 } 4106 }
4108 4107
4109 4108
4110 void LCodeGen::DoMathSin(LUnaryMathOperation* instr) { 4109 void LCodeGen::DoMathSin(LMathSin* instr) {
4111 ASSERT(ToDoubleRegister(instr->result()).is(d2)); 4110 ASSERT(ToDoubleRegister(instr->result()).is(d2));
4112 TranscendentalCacheStub stub(TranscendentalCache::SIN, 4111 TranscendentalCacheStub stub(TranscendentalCache::SIN,
4113 TranscendentalCacheStub::UNTAGGED); 4112 TranscendentalCacheStub::UNTAGGED);
4114 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4113 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4115 } 4114 }
4116 4115
4117 4116
4118 void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) {
4119 switch (instr->op()) {
4120 case kMathAbs:
4121 DoMathAbs(instr);
4122 break;
4123 case kMathFloor:
4124 DoMathFloor(instr);
4125 break;
4126 case kMathRound:
4127 DoMathRound(instr);
4128 break;
4129 case kMathSqrt:
4130 DoMathSqrt(instr);
4131 break;
4132 case kMathPowHalf:
4133 DoMathPowHalf(instr);
4134 break;
4135 case kMathCos:
4136 DoMathCos(instr);
4137 break;
4138 case kMathSin:
4139 DoMathSin(instr);
4140 break;
4141 case kMathTan:
4142 DoMathTan(instr);
4143 break;
4144 case kMathLog:
4145 DoMathLog(instr);
4146 break;
4147 default:
4148 Abort("Unimplemented type of LUnaryMathOperation.");
4149 UNREACHABLE();
4150 }
4151 }
4152
4153
4154 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { 4117 void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
4155 ASSERT(ToRegister(instr->function()).is(r1)); 4118 ASSERT(ToRegister(instr->function()).is(r1));
4156 ASSERT(instr->HasPointerMap()); 4119 ASSERT(instr->HasPointerMap());
4157 4120
4158 if (instr->known_function().is_null()) { 4121 if (instr->known_function().is_null()) {
4159 LPointerMap* pointers = instr->pointer_map(); 4122 LPointerMap* pointers = instr->pointer_map();
4160 RecordPosition(pointers->position()); 4123 RecordPosition(pointers->position());
4161 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); 4124 SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
4162 ParameterCount count(instr->arity()); 4125 ParameterCount count(instr->arity());
4163 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD); 4126 __ InvokeFunction(r1, count, CALL_FUNCTION, generator, CALL_AS_METHOD);
(...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after
6042 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 6005 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
6043 __ ldr(result, FieldMemOperand(scratch, 6006 __ ldr(result, FieldMemOperand(scratch,
6044 FixedArray::kHeaderSize - kPointerSize)); 6007 FixedArray::kHeaderSize - kPointerSize));
6045 __ bind(&done); 6008 __ bind(&done);
6046 } 6009 }
6047 6010
6048 6011
6049 #undef __ 6012 #undef __
6050 6013
6051 } } // namespace v8::internal 6014 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698