OLD | NEW |
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 4878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4889 | 4889 |
4890 | 4890 |
4891 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { | 4891 LocationSummary* MathUnaryInstr::MakeLocationSummary(bool opt) const { |
4892 if ((kind() == MathUnaryInstr::kSin) || (kind() == MathUnaryInstr::kCos)) { | 4892 if ((kind() == MathUnaryInstr::kSin) || (kind() == MathUnaryInstr::kCos)) { |
4893 const intptr_t kNumInputs = 1; | 4893 const intptr_t kNumInputs = 1; |
4894 const intptr_t kNumTemps = 0; | 4894 const intptr_t kNumTemps = 0; |
4895 LocationSummary* summary = | 4895 LocationSummary* summary = |
4896 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 4896 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
4897 summary->set_in(0, Location::FpuRegisterLocation(Q0)); | 4897 summary->set_in(0, Location::FpuRegisterLocation(Q0)); |
4898 summary->set_out(0, Location::FpuRegisterLocation(Q0)); | 4898 summary->set_out(0, Location::FpuRegisterLocation(Q0)); |
4899 #if !defined(ARM_FLOAT_ABI_HARD) | 4899 if (!TargetCPUFeatures::hardfp_supported()) { |
4900 summary->AddTemp(Location::RegisterLocation(R0)); | 4900 summary->AddTemp(Location::RegisterLocation(R0)); |
4901 summary->AddTemp(Location::RegisterLocation(R1)); | 4901 summary->AddTemp(Location::RegisterLocation(R1)); |
4902 summary->AddTemp(Location::RegisterLocation(R2)); | 4902 summary->AddTemp(Location::RegisterLocation(R2)); |
4903 summary->AddTemp(Location::RegisterLocation(R3)); | 4903 summary->AddTemp(Location::RegisterLocation(R3)); |
4904 #endif | 4904 } |
4905 return summary; | 4905 return summary; |
4906 } | 4906 } |
4907 ASSERT((kind() == MathUnaryInstr::kSqrt) || | 4907 ASSERT((kind() == MathUnaryInstr::kSqrt) || |
4908 (kind() == MathUnaryInstr::kDoubleSquare)); | 4908 (kind() == MathUnaryInstr::kDoubleSquare)); |
4909 const intptr_t kNumInputs = 1; | 4909 const intptr_t kNumInputs = 1; |
4910 const intptr_t kNumTemps = 0; | 4910 const intptr_t kNumTemps = 0; |
4911 LocationSummary* summary = | 4911 LocationSummary* summary = |
4912 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4912 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4913 summary->set_in(0, Location::RequiresFpuRegister()); | 4913 summary->set_in(0, Location::RequiresFpuRegister()); |
4914 summary->set_out(0, Location::RequiresFpuRegister()); | 4914 summary->set_out(0, Location::RequiresFpuRegister()); |
4915 return summary; | 4915 return summary; |
4916 } | 4916 } |
4917 | 4917 |
4918 | 4918 |
4919 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4919 void MathUnaryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4920 if (kind() == MathUnaryInstr::kSqrt) { | 4920 if (kind() == MathUnaryInstr::kSqrt) { |
4921 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4921 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
4922 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 4922 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
4923 __ vsqrtd(result, val); | 4923 __ vsqrtd(result, val); |
4924 } else if (kind() == MathUnaryInstr::kDoubleSquare) { | 4924 } else if (kind() == MathUnaryInstr::kDoubleSquare) { |
4925 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); | 4925 DRegister val = EvenDRegisterOf(locs()->in(0).fpu_reg()); |
4926 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); | 4926 DRegister result = EvenDRegisterOf(locs()->out(0).fpu_reg()); |
4927 __ vmuld(result, val, val); | 4927 __ vmuld(result, val, val); |
4928 } else { | 4928 } else { |
4929 ASSERT((kind() == MathUnaryInstr::kSin) || | 4929 ASSERT((kind() == MathUnaryInstr::kSin) || |
4930 (kind() == MathUnaryInstr::kCos)); | 4930 (kind() == MathUnaryInstr::kCos)); |
4931 #if defined(ARM_FLOAT_ABI_HARD) | 4931 if (TargetCPUFeatures::hardfp_supported()) { |
4932 __ CallRuntime(TargetFunction(), InputCount()); | 4932 __ CallRuntime(TargetFunction(), InputCount()); |
4933 #else | 4933 } else { |
4934 // If we aren't doing "hardfp", then we have to move the double arguments | 4934 // If we aren't doing "hardfp", then we have to move the double arguments |
4935 // to the integer registers, and take the results from the integer | 4935 // to the integer registers, and take the results from the integer |
4936 // registers. | 4936 // registers. |
4937 __ vmovrrd(R0, R1, D0); | 4937 __ vmovrrd(R0, R1, D0); |
4938 __ vmovrrd(R2, R3, D1); | 4938 __ vmovrrd(R2, R3, D1); |
4939 __ CallRuntime(TargetFunction(), InputCount()); | 4939 __ CallRuntime(TargetFunction(), InputCount()); |
4940 __ vmovdrr(D0, R0, R1); | 4940 __ vmovdrr(D0, R0, R1); |
4941 __ vmovdrr(D1, R2, R3); | 4941 __ vmovdrr(D1, R2, R3); |
4942 #endif | 4942 } |
4943 } | 4943 } |
4944 } | 4944 } |
4945 | 4945 |
4946 | 4946 |
4947 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { | 4947 LocationSummary* MathMinMaxInstr::MakeLocationSummary(bool opt) const { |
4948 if (result_cid() == kDoubleCid) { | 4948 if (result_cid() == kDoubleCid) { |
4949 const intptr_t kNumInputs = 2; | 4949 const intptr_t kNumInputs = 2; |
4950 const intptr_t kNumTemps = 1; | 4950 const intptr_t kNumTemps = 1; |
4951 LocationSummary* summary = | 4951 LocationSummary* summary = |
4952 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4952 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5237 const intptr_t kNumTemps = 0; | 5237 const intptr_t kNumTemps = 0; |
5238 LocationSummary* result = | 5238 LocationSummary* result = |
5239 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); | 5239 new LocationSummary(InputCount(), kNumTemps, LocationSummary::kCall); |
5240 result->set_in(0, Location::FpuRegisterLocation(Q0)); | 5240 result->set_in(0, Location::FpuRegisterLocation(Q0)); |
5241 if (InputCount() == 2) { | 5241 if (InputCount() == 2) { |
5242 result->set_in(1, Location::FpuRegisterLocation(Q1)); | 5242 result->set_in(1, Location::FpuRegisterLocation(Q1)); |
5243 } | 5243 } |
5244 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 5244 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
5245 result->AddTemp(Location::RegisterLocation(R2)); | 5245 result->AddTemp(Location::RegisterLocation(R2)); |
5246 } | 5246 } |
5247 #if !defined(ARM_FLOAT_ABI_HARD) | 5247 if (!TargetCPUFeatures::hardfp_supported()) { |
5248 result->AddTemp(Location::RegisterLocation(R0)); | 5248 result->AddTemp(Location::RegisterLocation(R0)); |
5249 result->AddTemp(Location::RegisterLocation(R1)); | 5249 result->AddTemp(Location::RegisterLocation(R1)); |
5250 // Check if R2 is already added. | 5250 // Check if R2 is already added. |
5251 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { | 5251 if (recognized_kind() != MethodRecognizer::kMathDoublePow) { |
5252 result->AddTemp(Location::RegisterLocation(R2)); | 5252 result->AddTemp(Location::RegisterLocation(R2)); |
| 5253 } |
| 5254 result->AddTemp(Location::RegisterLocation(R3)); |
5253 } | 5255 } |
5254 result->AddTemp(Location::RegisterLocation(R3)); | |
5255 #endif | |
5256 result->set_out(0, Location::FpuRegisterLocation(Q0)); | 5256 result->set_out(0, Location::FpuRegisterLocation(Q0)); |
5257 return result; | 5257 return result; |
5258 } | 5258 } |
5259 | 5259 |
5260 | 5260 |
5261 // Pseudo code: | 5261 // Pseudo code: |
5262 // if (exponent == 0.0) return 1.0; | 5262 // if (exponent == 0.0) return 1.0; |
5263 // // Speed up simple cases. | 5263 // // Speed up simple cases. |
5264 // if (exponent == 1.0) return base; | 5264 // if (exponent == 1.0) return base; |
5265 // if (exponent == 2.0) return base * base; | 5265 // if (exponent == 2.0) return base * base; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5367 | 5367 |
5368 __ Bind(&return_zero); | 5368 __ Bind(&return_zero); |
5369 __ LoadDImmediate(result, 0.0, temp); | 5369 __ LoadDImmediate(result, 0.0, temp); |
5370 __ b(&skip_call); | 5370 __ b(&skip_call); |
5371 | 5371 |
5372 __ Bind(&do_pow); | 5372 __ Bind(&do_pow); |
5373 __ vmovd(base, saved_base); // Restore base. | 5373 __ vmovd(base, saved_base); // Restore base. |
5374 | 5374 |
5375 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 5375 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
5376 __ vmovd(D1, D2); | 5376 __ vmovd(D1, D2); |
5377 #if defined(ARM_FLOAT_ABI_HARD) | 5377 if (TargetCPUFeatures::hardfp_supported()) { |
5378 __ CallRuntime(instr->TargetFunction(), kInputCount); | 5378 __ CallRuntime(instr->TargetFunction(), kInputCount); |
5379 #else | 5379 } else { |
5380 // If the ABI is not "hardfp", then we have to move the double arguments | 5380 // If the ABI is not "hardfp", then we have to move the double arguments |
5381 // to the integer registers, and take the results from the integer | 5381 // to the integer registers, and take the results from the integer |
5382 // registers. | 5382 // registers. |
5383 __ vmovrrd(R0, R1, D0); | 5383 __ vmovrrd(R0, R1, D0); |
5384 __ vmovrrd(R2, R3, D1); | 5384 __ vmovrrd(R2, R3, D1); |
5385 __ CallRuntime(instr->TargetFunction(), kInputCount); | 5385 __ CallRuntime(instr->TargetFunction(), kInputCount); |
5386 __ vmovdrr(D0, R0, R1); | 5386 __ vmovdrr(D0, R0, R1); |
5387 __ vmovdrr(D1, R2, R3); | 5387 __ vmovdrr(D1, R2, R3); |
5388 #endif | 5388 } |
5389 __ Bind(&skip_call); | 5389 __ Bind(&skip_call); |
5390 } | 5390 } |
5391 | 5391 |
5392 | 5392 |
5393 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5393 void InvokeMathCFunctionInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
5394 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { | 5394 if (recognized_kind() == MethodRecognizer::kMathDoublePow) { |
5395 InvokeDoublePow(compiler, this); | 5395 InvokeDoublePow(compiler, this); |
5396 return; | 5396 return; |
5397 } | 5397 } |
5398 | 5398 |
5399 if (InputCount() == 2) { | 5399 if (InputCount() == 2) { |
5400 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. | 5400 // Args must be in D0 and D1, so move arg from Q1(== D3:D2) to D1. |
5401 __ vmovd(D1, D2); | 5401 __ vmovd(D1, D2); |
5402 } | 5402 } |
5403 #if defined(ARM_FLOAT_ABI_HARD) | 5403 if (TargetCPUFeatures::hardfp_supported()) { |
5404 __ CallRuntime(TargetFunction(), InputCount()); | 5404 __ CallRuntime(TargetFunction(), InputCount()); |
5405 #else | 5405 } else { |
5406 // If the ABI is not "hardfp", then we have to move the double arguments | 5406 // If the ABI is not "hardfp", then we have to move the double arguments |
5407 // to the integer registers, and take the results from the integer | 5407 // to the integer registers, and take the results from the integer |
5408 // registers. | 5408 // registers. |
5409 __ vmovrrd(R0, R1, D0); | 5409 __ vmovrrd(R0, R1, D0); |
5410 __ vmovrrd(R2, R3, D1); | 5410 __ vmovrrd(R2, R3, D1); |
5411 __ CallRuntime(TargetFunction(), InputCount()); | 5411 __ CallRuntime(TargetFunction(), InputCount()); |
5412 __ vmovdrr(D0, R0, R1); | 5412 __ vmovdrr(D0, R0, R1); |
5413 __ vmovdrr(D1, R2, R3); | 5413 __ vmovdrr(D1, R2, R3); |
5414 #endif | 5414 } |
5415 } | 5415 } |
5416 | 5416 |
5417 | 5417 |
5418 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { | 5418 LocationSummary* ExtractNthOutputInstr::MakeLocationSummary(bool opt) const { |
5419 // Only use this instruction in optimized code. | 5419 // Only use this instruction in optimized code. |
5420 ASSERT(opt); | 5420 ASSERT(opt); |
5421 const intptr_t kNumInputs = 1; | 5421 const intptr_t kNumInputs = 1; |
5422 LocationSummary* summary = | 5422 LocationSummary* summary = |
5423 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); | 5423 new LocationSummary(kNumInputs, 0, LocationSummary::kNoCall); |
5424 if (representation() == kUnboxedDouble) { | 5424 if (representation() == kUnboxedDouble) { |
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6288 compiler->GenerateCall(token_pos(), | 6288 compiler->GenerateCall(token_pos(), |
6289 &label, | 6289 &label, |
6290 PcDescriptors::kOther, | 6290 PcDescriptors::kOther, |
6291 locs()); | 6291 locs()); |
6292 __ Drop(ArgumentCount()); // Discard arguments. | 6292 __ Drop(ArgumentCount()); // Discard arguments. |
6293 } | 6293 } |
6294 | 6294 |
6295 } // namespace dart | 6295 } // namespace dart |
6296 | 6296 |
6297 #endif // defined TARGET_ARCH_ARM | 6297 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |