| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 } | 430 } |
| 431 UNREACHABLE(); | 431 UNREACHABLE(); |
| 432 return NULL; | 432 return NULL; |
| 433 } | 433 } |
| 434 | 434 |
| 435 | 435 |
| 436 static void LoadValueCid(FlowGraphCompiler* compiler, | 436 static void LoadValueCid(FlowGraphCompiler* compiler, |
| 437 Register value_cid_reg, | 437 Register value_cid_reg, |
| 438 Register value_reg, | 438 Register value_reg, |
| 439 Label* value_is_smi = NULL) { | 439 Label* value_is_smi = NULL) { |
| 440 Label done; | |
| 441 if (value_is_smi == NULL) { | 440 if (value_is_smi == NULL) { |
| 442 __ mov(value_cid_reg, Operand(kSmiCid)); | 441 __ mov(value_cid_reg, Operand(kSmiCid)); |
| 443 } | 442 } |
| 444 __ tst(value_reg, Operand(kSmiTagMask)); | 443 __ tst(value_reg, Operand(kSmiTagMask)); |
| 445 if (value_is_smi == NULL) { | 444 if (value_is_smi == NULL) { |
| 446 __ b(&done, EQ); | 445 __ LoadClassId(value_cid_reg, value_reg, NE); |
| 447 } else { | 446 } else { |
| 448 __ b(value_is_smi, EQ); | 447 __ b(value_is_smi, EQ); |
| 448 __ LoadClassId(value_cid_reg, value_reg); |
| 449 } | 449 } |
| 450 __ LoadClassId(value_cid_reg, value_reg); | |
| 451 __ Bind(&done); | |
| 452 } | 450 } |
| 453 | 451 |
| 454 | 452 |
| 455 static Condition FlipCondition(Condition condition) { | 453 static Condition FlipCondition(Condition condition) { |
| 456 switch (condition) { | 454 switch (condition) { |
| 457 case EQ: return EQ; | 455 case EQ: return EQ; |
| 458 case NE: return NE; | 456 case NE: return NE; |
| 459 case LT: return GT; | 457 case LT: return GT; |
| 460 case LE: return GE; | 458 case LE: return GE; |
| 461 case GT: return LT; | 459 case GT: return LT; |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1048 return LocationSummary::Make(isolate, | 1046 return LocationSummary::Make(isolate, |
| 1049 kNumInputs, | 1047 kNumInputs, |
| 1050 Location::RequiresRegister(), | 1048 Location::RequiresRegister(), |
| 1051 LocationSummary::kNoCall); | 1049 LocationSummary::kNoCall); |
| 1052 } | 1050 } |
| 1053 | 1051 |
| 1054 | 1052 |
| 1055 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 1053 void LoadClassIdInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1056 const Register object = locs()->in(0).reg(); | 1054 const Register object = locs()->in(0).reg(); |
| 1057 const Register result = locs()->out(0).reg(); | 1055 const Register result = locs()->out(0).reg(); |
| 1058 Label load, done; | |
| 1059 __ tst(object, Operand(kSmiTagMask)); | 1056 __ tst(object, Operand(kSmiTagMask)); |
| 1060 __ b(&load, NE); | 1057 __ LoadImmediate(result, Smi::RawValue(kSmiCid), EQ); |
| 1061 __ LoadImmediate(result, Smi::RawValue(kSmiCid)); | 1058 __ LoadClassId(result, object, NE); |
| 1062 __ b(&done); | 1059 __ SmiTag(result, NE); |
| 1063 __ Bind(&load); | |
| 1064 __ LoadClassId(result, object); | |
| 1065 __ SmiTag(result); | |
| 1066 __ Bind(&done); | |
| 1067 } | 1060 } |
| 1068 | 1061 |
| 1069 | 1062 |
| 1070 CompileType LoadIndexedInstr::ComputeType() const { | 1063 CompileType LoadIndexedInstr::ComputeType() const { |
| 1071 switch (class_id_) { | 1064 switch (class_id_) { |
| 1072 case kArrayCid: | 1065 case kArrayCid: |
| 1073 case kImmutableArrayCid: | 1066 case kImmutableArrayCid: |
| 1074 return CompileType::Dynamic(); | 1067 return CompileType::Dynamic(); |
| 1075 | 1068 |
| 1076 case kTypedDataFloat32ArrayCid: | 1069 case kTypedDataFloat32ArrayCid: |
| (...skipping 4035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5112 } | 5105 } |
| 5113 | 5106 |
| 5114 | 5107 |
| 5115 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 5108 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5116 const Register result = locs()->out(0).reg(); | 5109 const Register result = locs()->out(0).reg(); |
| 5117 const Register value_obj = locs()->in(0).reg(); | 5110 const Register value_obj = locs()->in(0).reg(); |
| 5118 ASSERT(result == R0); | 5111 ASSERT(result == R0); |
| 5119 ASSERT(result != value_obj); | 5112 ASSERT(result != value_obj); |
| 5120 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); | 5113 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag); |
| 5121 | 5114 |
| 5122 Label do_call, done; | 5115 Label done, do_call; |
| 5123 // First check for NaN. Checking for minint after the conversion doesn't work | 5116 // First check for NaN. Checking for minint after the conversion doesn't work |
| 5124 // on ARM because vcvtid gives 0 for NaN. | 5117 // on ARM because vcvtid gives 0 for NaN. |
| 5125 __ vcmpd(DTMP, DTMP); | 5118 __ vcmpd(DTMP, DTMP); |
| 5126 __ vmstat(); | 5119 __ vmstat(); |
| 5127 __ b(&do_call, VS); | 5120 __ b(&do_call, VS); |
| 5128 | 5121 |
| 5129 __ vcvtid(STMP, DTMP); | 5122 __ vcvtid(STMP, DTMP); |
| 5130 __ vmovrs(result, STMP); | 5123 __ vmovrs(result, STMP); |
| 5131 // Overflow is signaled with minint. | 5124 // Overflow is signaled with minint. |
| 5132 | 5125 |
| 5133 // Check for overflow and that it fits into Smi. | 5126 // Check for overflow and that it fits into Smi. |
| 5134 __ CompareImmediate(result, 0xC0000000); | 5127 __ CompareImmediate(result, 0xC0000000); |
| 5135 __ b(&do_call, MI); | 5128 __ SmiTag(result, PL); |
| 5136 __ SmiTag(result); | 5129 __ b(&done, PL); |
| 5137 __ b(&done); | 5130 |
| 5138 __ Bind(&do_call); | 5131 __ Bind(&do_call); |
| 5139 __ Push(value_obj); | 5132 __ Push(value_obj); |
| 5140 ASSERT(instance_call()->HasICData()); | 5133 ASSERT(instance_call()->HasICData()); |
| 5141 const ICData& ic_data = *instance_call()->ic_data(); | 5134 const ICData& ic_data = *instance_call()->ic_data(); |
| 5142 ASSERT((ic_data.NumberOfChecks() == 1)); | 5135 ASSERT((ic_data.NumberOfChecks() == 1)); |
| 5143 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); | 5136 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0)); |
| 5144 | 5137 |
| 5145 const intptr_t kNumberOfArguments = 1; | 5138 const intptr_t kNumberOfArguments = 1; |
| 5146 compiler->GenerateStaticCall(deopt_id(), | 5139 compiler->GenerateStaticCall(deopt_id(), |
| 5147 instance_call()->token_pos(), | 5140 instance_call()->token_pos(), |
| (...skipping 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6357 compiler->GenerateCall(token_pos(), | 6350 compiler->GenerateCall(token_pos(), |
| 6358 &label, | 6351 &label, |
| 6359 PcDescriptors::kOther, | 6352 PcDescriptors::kOther, |
| 6360 locs()); | 6353 locs()); |
| 6361 __ Drop(ArgumentCount()); // Discard arguments. | 6354 __ Drop(ArgumentCount()); // Discard arguments. |
| 6362 } | 6355 } |
| 6363 | 6356 |
| 6364 } // namespace dart | 6357 } // namespace dart |
| 6365 | 6358 |
| 6366 #endif // defined TARGET_ARCH_ARM | 6359 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |