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

Side by Side Diff: runtime/vm/intermediate_language_arm.cc

Issue 606893002: Avoids vmovsr on ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 3604 matching lines...) Expand 10 before | Expand all | Expand 10 after
3615 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3615 void UnboxDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3616 CompileType* value_type = value()->Type(); 3616 CompileType* value_type = value()->Type();
3617 const intptr_t value_cid = value_type->ToCid(); 3617 const intptr_t value_cid = value_type->ToCid();
3618 const Register value = locs()->in(0).reg(); 3618 const Register value = locs()->in(0).reg();
3619 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); 3619 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
3620 3620
3621 if (value_cid == kDoubleCid) { 3621 if (value_cid == kDoubleCid) {
3622 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag); 3622 __ LoadDFromOffset(result, value, Double::value_offset() - kHeapObjectTag);
3623 } else if (value_cid == kSmiCid) { 3623 } else if (value_cid == kSmiCid) {
3624 __ SmiUntag(IP, value); 3624 __ SmiUntag(IP, value);
3625 __ vmovsr(STMP, IP); 3625 __ vmovdr(DTMP, 0, IP);
3626 __ vcvtdi(result, STMP); 3626 __ vcvtdi(result, STMP);
3627 } else { 3627 } else {
3628 Label* deopt = compiler->AddDeoptStub(deopt_id_, 3628 Label* deopt = compiler->AddDeoptStub(deopt_id_,
3629 ICData::kDeoptBinaryDoubleOp); 3629 ICData::kDeoptBinaryDoubleOp);
3630 const Register temp = locs()->temp(0).reg(); 3630 const Register temp = locs()->temp(0).reg();
3631 if (value_type->is_nullable() && 3631 if (value_type->is_nullable() &&
3632 (value_type->ToNullableCid() == kDoubleCid)) { 3632 (value_type->ToNullableCid() == kDoubleCid)) {
3633 __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null())); 3633 __ CompareImmediate(value, reinterpret_cast<intptr_t>(Object::null()));
3634 __ b(deopt, EQ); 3634 __ b(deopt, EQ);
3635 // It must be double now. 3635 // It must be double now.
3636 __ LoadDFromOffset(result, value, 3636 __ LoadDFromOffset(result, value,
3637 Double::value_offset() - kHeapObjectTag); 3637 Double::value_offset() - kHeapObjectTag);
3638 } else { 3638 } else {
3639 Label is_smi, done; 3639 Label is_smi, done;
3640 __ tst(value, Operand(kSmiTagMask)); 3640 __ tst(value, Operand(kSmiTagMask));
3641 __ b(&is_smi, EQ); 3641 __ b(&is_smi, EQ);
3642 __ CompareClassId(value, kDoubleCid, temp); 3642 __ CompareClassId(value, kDoubleCid, temp);
3643 __ b(deopt, NE); 3643 __ b(deopt, NE);
3644 __ LoadDFromOffset(result, value, 3644 __ LoadDFromOffset(result, value,
3645 Double::value_offset() - kHeapObjectTag); 3645 Double::value_offset() - kHeapObjectTag);
3646 __ b(&done); 3646 __ b(&done);
3647 __ Bind(&is_smi); 3647 __ Bind(&is_smi);
3648 __ SmiUntag(IP, value); 3648 __ SmiUntag(IP, value);
3649 __ vmovsr(STMP, IP); 3649 __ vmovdr(DTMP, 0, IP);
3650 __ vcvtdi(result, STMP); 3650 __ vcvtdi(result, STMP);
3651 __ Bind(&done); 3651 __ Bind(&done);
3652 } 3652 }
3653 } 3653 }
3654 } 3654 }
3655 3655
3656 3656
3657 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 3657 LocationSummary* BoxFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
3658 bool opt) const { 3658 bool opt) const {
3659 const intptr_t kNumInputs = 1; 3659 const intptr_t kNumInputs = 1;
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after
4787 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary( 4787 LocationSummary* Int32x4ConstructorInstr::MakeLocationSummary(
4788 Isolate* isolate, bool opt) const { 4788 Isolate* isolate, bool opt) const {
4789 const intptr_t kNumInputs = 4; 4789 const intptr_t kNumInputs = 4;
4790 const intptr_t kNumTemps = 0; 4790 const intptr_t kNumTemps = 0;
4791 LocationSummary* summary = new(isolate) LocationSummary( 4791 LocationSummary* summary = new(isolate) LocationSummary(
4792 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4792 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4793 summary->set_in(0, Location::RequiresRegister()); 4793 summary->set_in(0, Location::RequiresRegister());
4794 summary->set_in(1, Location::RequiresRegister()); 4794 summary->set_in(1, Location::RequiresRegister());
4795 summary->set_in(2, Location::RequiresRegister()); 4795 summary->set_in(2, Location::RequiresRegister());
4796 summary->set_in(3, Location::RequiresRegister()); 4796 summary->set_in(3, Location::RequiresRegister());
4797 // Low (< 7) Q register needed for the vmovsr instruction. 4797 summary->set_out(0, Location::RequiresRegister());
4798 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4799 return summary; 4798 return summary;
4800 } 4799 }
4801 4800
4802 4801
4803 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4802 void Int32x4ConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4804 const Register v0 = locs()->in(0).reg(); 4803 const Register v0 = locs()->in(0).reg();
4805 const Register v1 = locs()->in(1).reg(); 4804 const Register v1 = locs()->in(1).reg();
4806 const Register v2 = locs()->in(2).reg(); 4805 const Register v2 = locs()->in(2).reg();
4807 const Register v3 = locs()->in(3).reg(); 4806 const Register v3 = locs()->in(3).reg();
4808 const QRegister result = locs()->out(0).fpu_reg(); 4807 const QRegister result = locs()->out(0).fpu_reg();
4809 const DRegister dresult0 = EvenDRegisterOf(result); 4808 const DRegister dresult0 = EvenDRegisterOf(result);
4810 const DRegister dresult1 = OddDRegisterOf(result); 4809 const DRegister dresult1 = OddDRegisterOf(result);
4811 const SRegister sresult0 = EvenSRegisterOf(dresult0);
4812 const SRegister sresult1 = OddSRegisterOf(dresult0);
4813 const SRegister sresult2 = EvenSRegisterOf(dresult1);
4814 const SRegister sresult3 = OddSRegisterOf(dresult1);
4815 __ veorq(result, result, result); 4810 __ veorq(result, result, result);
4816 __ vmovsr(sresult0, v0); 4811 __ vmovdrr(dresult0, v0, v1);
4817 __ vmovsr(sresult1, v1); 4812 __ vmovdrr(dresult1, v2, v3);
4818 __ vmovsr(sresult2, v2);
4819 __ vmovsr(sresult3, v3);
4820 } 4813 }
4821 4814
4822 4815
4823 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary( 4816 LocationSummary* Int32x4BoolConstructorInstr::MakeLocationSummary(
4824 Isolate* isolate, bool opt) const { 4817 Isolate* isolate, bool opt) const {
4825 const intptr_t kNumInputs = 4; 4818 const intptr_t kNumInputs = 4;
4826 const intptr_t kNumTemps = 1; 4819 const intptr_t kNumTemps = 1;
4827 LocationSummary* summary = new(isolate) LocationSummary( 4820 LocationSummary* summary = new(isolate) LocationSummary(
4828 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4821 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4829 summary->set_in(0, Location::RequiresRegister()); 4822 summary->set_in(0, Location::RequiresRegister());
4830 summary->set_in(1, Location::RequiresRegister()); 4823 summary->set_in(1, Location::RequiresRegister());
4831 summary->set_in(2, Location::RequiresRegister()); 4824 summary->set_in(2, Location::RequiresRegister());
4832 summary->set_in(3, Location::RequiresRegister()); 4825 summary->set_in(3, Location::RequiresRegister());
4833 summary->set_temp(0, Location::RequiresRegister()); 4826 summary->set_temp(0, Location::RequiresRegister());
4834 // Low (< 7) Q register needed for the vmovsr instruction. 4827 summary->set_out(0, Location::RequiresRegister());
4835 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4836 return summary; 4828 return summary;
4837 } 4829 }
4838 4830
4839 4831
4840 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4832 void Int32x4BoolConstructorInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4841 const Register v0 = locs()->in(0).reg(); 4833 const Register v0 = locs()->in(0).reg();
4842 const Register v1 = locs()->in(1).reg(); 4834 const Register v1 = locs()->in(1).reg();
4843 const Register v2 = locs()->in(2).reg(); 4835 const Register v2 = locs()->in(2).reg();
4844 const Register v3 = locs()->in(3).reg(); 4836 const Register v3 = locs()->in(3).reg();
4845 const Register temp = locs()->temp(0).reg(); 4837 const Register temp = locs()->temp(0).reg();
4846 const QRegister result = locs()->out(0).fpu_reg(); 4838 const QRegister result = locs()->out(0).fpu_reg();
4847 const DRegister dresult0 = EvenDRegisterOf(result); 4839 const DRegister dresult0 = EvenDRegisterOf(result);
4848 const DRegister dresult1 = OddDRegisterOf(result); 4840 const DRegister dresult1 = OddDRegisterOf(result);
4849 const SRegister sresult0 = EvenSRegisterOf(dresult0);
4850 const SRegister sresult1 = OddSRegisterOf(dresult0);
4851 const SRegister sresult2 = EvenSRegisterOf(dresult1);
4852 const SRegister sresult3 = OddSRegisterOf(dresult1);
4853 4841
4854 __ veorq(result, result, result); 4842 __ veorq(result, result, result);
4855 __ LoadImmediate(temp, 0xffffffff); 4843 __ LoadImmediate(temp, 0xffffffff);
4856 4844
4857 __ CompareObject(v0, Bool::True()); 4845 __ LoadObject(IP, Bool::True());
4858 __ vmovsr(sresult0, temp, EQ); 4846 __ cmp(v0, Operand(IP));
4847 __ vmovdr(dresult0, 0, temp, EQ);
4859 4848
4860 __ CompareObject(v1, Bool::True()); 4849 __ cmp(v1, Operand(IP));
4861 __ vmovsr(sresult1, temp, EQ); 4850 __ vmovdr(dresult0, 1, temp, EQ);
4862 4851
4863 __ CompareObject(v2, Bool::True()); 4852 __ cmp(v2, Operand(IP));
4864 __ vmovsr(sresult2, temp, EQ); 4853 __ vmovdr(dresult1, 0, temp, EQ);
4865 4854
4866 __ CompareObject(v3, Bool::True()); 4855 __ cmp(v3, Operand(IP));
4867 __ vmovsr(sresult3, temp, EQ); 4856 __ vmovdr(dresult1, 1, temp, EQ);
4868 } 4857 }
4869 4858
4870 4859
4871 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Isolate* isolate, 4860 LocationSummary* Int32x4GetFlagInstr::MakeLocationSummary(Isolate* isolate,
4872 bool opt) const { 4861 bool opt) const {
4873 const intptr_t kNumInputs = 1; 4862 const intptr_t kNumInputs = 1;
4874 const intptr_t kNumTemps = 0; 4863 const intptr_t kNumTemps = 0;
4875 LocationSummary* summary = new(isolate) LocationSummary( 4864 LocationSummary* summary = new(isolate) LocationSummary(
4876 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4865 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4877 // Low (< 7) Q registers are needed for the vmovrs instruction. 4866 // Low (< 7) Q registers are needed for the vmovrs instruction.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
4950 4939
4951 4940
4952 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Isolate* isolate, 4941 LocationSummary* Int32x4SetFlagInstr::MakeLocationSummary(Isolate* isolate,
4953 bool opt) const { 4942 bool opt) const {
4954 const intptr_t kNumInputs = 2; 4943 const intptr_t kNumInputs = 2;
4955 const intptr_t kNumTemps = 0; 4944 const intptr_t kNumTemps = 0;
4956 LocationSummary* summary = new(isolate) LocationSummary( 4945 LocationSummary* summary = new(isolate) LocationSummary(
4957 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 4946 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
4958 summary->set_in(0, Location::RequiresFpuRegister()); 4947 summary->set_in(0, Location::RequiresFpuRegister());
4959 summary->set_in(1, Location::RequiresRegister()); 4948 summary->set_in(1, Location::RequiresRegister());
4960 // Low (< 7) Q register needed for the vmovsr instruction. 4949 summary->set_out(0, Location::RequiresFpuRegister());
4961 summary->set_out(0, Location::FpuRegisterLocation(Q6));
4962 return summary; 4950 return summary;
4963 } 4951 }
4964 4952
4965 4953
4966 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 4954 void Int32x4SetFlagInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
4967 const QRegister mask = locs()->in(0).fpu_reg(); 4955 const QRegister mask = locs()->in(0).fpu_reg();
4968 const Register flag = locs()->in(1).reg(); 4956 const Register flag = locs()->in(1).reg();
4969 const QRegister result = locs()->out(0).fpu_reg(); 4957 const QRegister result = locs()->out(0).fpu_reg();
4970 4958
4971 const DRegister dresult0 = EvenDRegisterOf(result); 4959 const DRegister dresult0 = EvenDRegisterOf(result);
4972 const DRegister dresult1 = OddDRegisterOf(result); 4960 const DRegister dresult1 = OddDRegisterOf(result);
4973 const SRegister sresult0 = EvenSRegisterOf(dresult0);
4974 const SRegister sresult1 = OddSRegisterOf(dresult0);
4975 const SRegister sresult2 = EvenSRegisterOf(dresult1);
4976 const SRegister sresult3 = OddSRegisterOf(dresult1);
4977 4961
4978 if (result != mask) { 4962 if (result != mask) {
4979 __ vmovq(result, mask); 4963 __ vmovq(result, mask);
4980 } 4964 }
4981 4965
4982 __ CompareObject(flag, Bool::True()); 4966 __ CompareObject(flag, Bool::True());
4983 __ LoadImmediate(TMP, 0xffffffff, EQ); 4967 __ LoadImmediate(TMP, 0xffffffff, EQ);
4984 __ LoadImmediate(TMP, 0, NE); 4968 __ LoadImmediate(TMP, 0, NE);
4985 switch (op_kind()) { 4969 switch (op_kind()) {
4986 case MethodRecognizer::kInt32x4WithFlagX: 4970 case MethodRecognizer::kInt32x4WithFlagX:
4987 __ vmovsr(sresult0, TMP); 4971 __ vmovdr(dresult0, 0, TMP);
4988 break; 4972 break;
4989 case MethodRecognizer::kInt32x4WithFlagY: 4973 case MethodRecognizer::kInt32x4WithFlagY:
4990 __ vmovsr(sresult1, TMP); 4974 __ vmovdr(dresult0, 1, TMP);
4991 break; 4975 break;
4992 case MethodRecognizer::kInt32x4WithFlagZ: 4976 case MethodRecognizer::kInt32x4WithFlagZ:
4993 __ vmovsr(sresult2, TMP); 4977 __ vmovdr(dresult1, 0, TMP);
4994 break; 4978 break;
4995 case MethodRecognizer::kInt32x4WithFlagW: 4979 case MethodRecognizer::kInt32x4WithFlagW:
4996 __ vmovsr(sresult3, TMP); 4980 __ vmovdr(dresult1, 1, TMP);
4997 break; 4981 break;
4998 default: UNREACHABLE(); 4982 default: UNREACHABLE();
4999 } 4983 }
5000 } 4984 }
5001 4985
5002 4986
5003 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Isolate* isolate, 4987 LocationSummary* Int32x4ToFloat32x4Instr::MakeLocationSummary(Isolate* isolate,
5004 bool opt) const { 4988 bool opt) const {
5005 const intptr_t kNumInputs = 1; 4989 const intptr_t kNumInputs = 1;
5006 const intptr_t kNumTemps = 0; 4990 const intptr_t kNumTemps = 0;
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
5255 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5239 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5256 result->set_in(0, Location::RequiresRegister()); 5240 result->set_in(0, Location::RequiresRegister());
5257 result->set_out(0, Location::RequiresFpuRegister()); 5241 result->set_out(0, Location::RequiresFpuRegister());
5258 return result; 5242 return result;
5259 } 5243 }
5260 5244
5261 5245
5262 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5246 void Int32ToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5263 const Register value = locs()->in(0).reg(); 5247 const Register value = locs()->in(0).reg();
5264 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); 5248 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
5265 __ vmovsr(STMP, value); 5249 __ vmovdr(DTMP, 0, value);
5266 __ vcvtdi(result, STMP); 5250 __ vcvtdi(result, STMP);
5267 } 5251 }
5268 5252
5269 5253
5270 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate, 5254 LocationSummary* SmiToDoubleInstr::MakeLocationSummary(Isolate* isolate,
5271 bool opt) const { 5255 bool opt) const {
5272 const intptr_t kNumInputs = 1; 5256 const intptr_t kNumInputs = 1;
5273 const intptr_t kNumTemps = 0; 5257 const intptr_t kNumTemps = 0;
5274 LocationSummary* result = new(isolate) LocationSummary( 5258 LocationSummary* result = new(isolate) LocationSummary(
5275 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); 5259 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall);
5276 result->set_in(0, Location::RequiresRegister()); 5260 result->set_in(0, Location::RequiresRegister());
5277 result->set_out(0, Location::RequiresFpuRegister()); 5261 result->set_out(0, Location::RequiresFpuRegister());
5278 return result; 5262 return result;
5279 } 5263 }
5280 5264
5281 5265
5282 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 5266 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
5283 const Register value = locs()->in(0).reg(); 5267 const Register value = locs()->in(0).reg();
5284 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); 5268 const DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg());
5285 __ SmiUntag(IP, value); 5269 __ SmiUntag(IP, value);
5286 __ vmovsr(STMP, IP); 5270 __ vmovdr(DTMP, 0, IP);
5287 __ vcvtdi(result, STMP); 5271 __ vcvtdi(result, STMP);
5288 } 5272 }
5289 5273
5290 5274
5291 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Isolate* isolate, 5275 LocationSummary* MintToDoubleInstr::MakeLocationSummary(Isolate* isolate,
5292 bool opt) const { 5276 bool opt) const {
5293 UNIMPLEMENTED(); 5277 UNIMPLEMENTED();
5294 return NULL; 5278 return NULL;
5295 } 5279 }
5296 5280
(...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after
7031 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); 7015 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs());
7032 #if defined(DEBUG) 7016 #if defined(DEBUG)
7033 __ LoadImmediate(R4, kInvalidObjectPointer); 7017 __ LoadImmediate(R4, kInvalidObjectPointer);
7034 __ LoadImmediate(R5, kInvalidObjectPointer); 7018 __ LoadImmediate(R5, kInvalidObjectPointer);
7035 #endif 7019 #endif
7036 } 7020 }
7037 7021
7038 } // namespace dart 7022 } // namespace dart
7039 7023
7040 #endif // defined TARGET_ARCH_ARM 7024 #endif // defined TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698