| 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 |