OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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_ARM64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64. |
6 #if defined(TARGET_ARCH_ARM64) | 6 #if defined(TARGET_ARCH_ARM64) |
7 | 7 |
8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
9 | 9 |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 __ SmiTag(result); | 1140 __ SmiTag(result); |
1141 break; | 1141 break; |
1142 default: | 1142 default: |
1143 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1143 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1144 __ ldr(result, element_address); | 1144 __ ldr(result, element_address); |
1145 break; | 1145 break; |
1146 } | 1146 } |
1147 } | 1147 } |
1148 | 1148 |
1149 | 1149 |
| 1150 Representation LoadCodeUnitsInstr::representation() const { |
| 1151 switch (class_id()) { |
| 1152 case kOneByteStringCid: |
| 1153 case kTwoByteStringCid: |
| 1154 case kExternalOneByteStringCid: |
| 1155 case kExternalTwoByteStringCid: |
| 1156 return kTagged; |
| 1157 default: |
| 1158 UNIMPLEMENTED(); |
| 1159 return kTagged; |
| 1160 } |
| 1161 } |
| 1162 |
| 1163 |
| 1164 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, |
| 1165 bool opt) const { |
| 1166 const intptr_t kNumInputs = 2; |
| 1167 const intptr_t kNumTemps = 0; |
| 1168 LocationSummary* summary = new(isolate) LocationSummary( |
| 1169 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 1170 summary->set_in(0, Location::RequiresRegister()); |
| 1171 summary->set_in(1, Location::RequiresRegister()); |
| 1172 summary->set_out(0, Location::RequiresRegister()); |
| 1173 return summary; |
| 1174 } |
| 1175 |
| 1176 |
| 1177 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 1178 const Register array = locs()->in(0).reg(); |
| 1179 const Location index = locs()->in(1); |
| 1180 |
| 1181 Address element_address = __ ElementAddressForRegIndex( |
| 1182 true, IsExternal(), class_id(), index_scale(), array, index.reg()); |
| 1183 // Warning: element_address may use register TMP as base. |
| 1184 |
| 1185 Register result = locs()->out(0).reg(); |
| 1186 switch (class_id()) { |
| 1187 case kOneByteStringCid: |
| 1188 case kExternalOneByteStringCid: |
| 1189 switch (element_count()) { |
| 1190 case 1: __ ldr(result, element_address, kUnsignedByte); break; |
| 1191 case 2: __ ldr(result, element_address, kUnsignedHalfword); break; |
| 1192 case 4: __ ldr(result, element_address, kUnsignedWord); break; |
| 1193 default: UNREACHABLE(); |
| 1194 } |
| 1195 __ SmiTag(result); |
| 1196 break; |
| 1197 case kTwoByteStringCid: |
| 1198 case kExternalTwoByteStringCid: |
| 1199 switch (element_count()) { |
| 1200 case 1: __ ldr(result, element_address, kUnsignedHalfword); break; |
| 1201 case 2: __ ldr(result, element_address, kUnsignedWord); break; |
| 1202 default: UNREACHABLE(); |
| 1203 } |
| 1204 __ SmiTag(result); |
| 1205 break; |
| 1206 default: |
| 1207 UNREACHABLE(); |
| 1208 break; |
| 1209 } |
| 1210 } |
| 1211 |
| 1212 |
1150 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1213 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1151 intptr_t idx) const { | 1214 intptr_t idx) const { |
1152 // Array can be a Dart object or a pointer to external data. | 1215 // Array can be a Dart object or a pointer to external data. |
1153 if (idx == 0) return kNoRepresentation; // Flexible input representation. | 1216 if (idx == 0) return kNoRepresentation; // Flexible input representation. |
1154 if (idx == 1) return kTagged; // Index is a smi. | 1217 if (idx == 1) return kTagged; // Index is a smi. |
1155 ASSERT(idx == 2); | 1218 ASSERT(idx == 2); |
1156 switch (class_id_) { | 1219 switch (class_id_) { |
1157 case kArrayCid: | 1220 case kArrayCid: |
1158 case kOneByteStringCid: | 1221 case kOneByteStringCid: |
1159 case kTypedDataInt8ArrayCid: | 1222 case kTypedDataInt8ArrayCid: |
(...skipping 3175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4335 const VRegister result = locs()->out(0).fpu_reg(); | 4398 const VRegister result = locs()->out(0).fpu_reg(); |
4336 __ fmuld(result, val, val); | 4399 __ fmuld(result, val, val); |
4337 } else { | 4400 } else { |
4338 ASSERT((kind() == MathUnaryInstr::kSin) || | 4401 ASSERT((kind() == MathUnaryInstr::kSin) || |
4339 (kind() == MathUnaryInstr::kCos)); | 4402 (kind() == MathUnaryInstr::kCos)); |
4340 __ CallRuntime(TargetFunction(), InputCount()); | 4403 __ CallRuntime(TargetFunction(), InputCount()); |
4341 } | 4404 } |
4342 } | 4405 } |
4343 | 4406 |
4344 | 4407 |
| 4408 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( |
| 4409 Isolate* isolate, bool opt) const { |
| 4410 const intptr_t kNumTemps = 0; |
| 4411 LocationSummary* summary = new(isolate) LocationSummary( |
| 4412 isolate, InputCount(), kNumTemps, LocationSummary::kCall); |
| 4413 summary->set_in(0, Location::RegisterLocation(R0)); |
| 4414 summary->set_in(1, Location::RegisterLocation(R1)); |
| 4415 summary->set_in(2, Location::RegisterLocation(R2)); |
| 4416 summary->set_in(3, Location::RegisterLocation(R3)); |
| 4417 summary->set_out(0, Location::RegisterLocation(R0)); |
| 4418 return summary; |
| 4419 } |
| 4420 |
| 4421 |
| 4422 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( |
| 4423 FlowGraphCompiler* compiler) { |
| 4424 |
| 4425 // Call the function. |
| 4426 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); |
| 4427 } |
| 4428 |
| 4429 |
4345 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, | 4430 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, |
4346 bool opt) const { | 4431 bool opt) const { |
4347 if (result_cid() == kDoubleCid) { | 4432 if (result_cid() == kDoubleCid) { |
4348 const intptr_t kNumInputs = 2; | 4433 const intptr_t kNumInputs = 2; |
4349 const intptr_t kNumTemps = 0; | 4434 const intptr_t kNumTemps = 0; |
4350 LocationSummary* summary = new(isolate) LocationSummary( | 4435 LocationSummary* summary = new(isolate) LocationSummary( |
4351 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 4436 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
4352 summary->set_in(0, Location::RequiresFpuRegister()); | 4437 summary->set_in(0, Location::RequiresFpuRegister()); |
4353 summary->set_in(1, Location::RequiresFpuRegister()); | 4438 summary->set_in(1, Location::RequiresFpuRegister()); |
4354 // Reuse the left register so that code can be made shorter. | 4439 // Reuse the left register so that code can be made shorter. |
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5469 } | 5554 } |
5470 | 5555 |
5471 // We can fall through if the successor is the next block in the list. | 5556 // We can fall through if the successor is the next block in the list. |
5472 // Otherwise, we need a jump. | 5557 // Otherwise, we need a jump. |
5473 if (!compiler->CanFallThroughTo(successor())) { | 5558 if (!compiler->CanFallThroughTo(successor())) { |
5474 __ b(compiler->GetJumpLabel(successor())); | 5559 __ b(compiler->GetJumpLabel(successor())); |
5475 } | 5560 } |
5476 } | 5561 } |
5477 | 5562 |
5478 | 5563 |
| 5564 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, |
| 5565 bool opt) const { |
| 5566 const intptr_t kNumInputs = 1; |
| 5567 const intptr_t kNumTemps = 1; |
| 5568 |
| 5569 LocationSummary* summary = new(isolate) LocationSummary( |
| 5570 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| 5571 |
| 5572 summary->set_in(0, Location::RequiresRegister()); |
| 5573 summary->set_temp(0, Location::RequiresRegister()); |
| 5574 |
| 5575 return summary; |
| 5576 } |
| 5577 |
| 5578 |
| 5579 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 5580 Register target_address_reg = locs()->temp_slot(0)->reg(); |
| 5581 |
| 5582 // Load from [current frame pointer] + kPcMarkerSlotFromFp. |
| 5583 __ ldr(target_address_reg, Address(FP, kPcMarkerSlotFromFp * kWordSize)); |
| 5584 |
| 5585 // Add the offset. |
| 5586 Register offset_reg = locs()->in(0).reg(); |
| 5587 __ add(target_address_reg, |
| 5588 target_address_reg, |
| 5589 Operand(offset_reg, ASR, kSmiTagSize)); |
| 5590 |
| 5591 // Jump to the absolute address. |
| 5592 __ br(target_address_reg); |
| 5593 } |
| 5594 |
| 5595 |
5479 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, | 5596 LocationSummary* StrictCompareInstr::MakeLocationSummary(Isolate* isolate, |
5480 bool opt) const { | 5597 bool opt) const { |
5481 const intptr_t kNumInputs = 2; | 5598 const intptr_t kNumInputs = 2; |
5482 const intptr_t kNumTemps = 0; | 5599 const intptr_t kNumTemps = 0; |
5483 if (needs_number_check()) { | 5600 if (needs_number_check()) { |
5484 LocationSummary* locs = new(isolate) LocationSummary( | 5601 LocationSummary* locs = new(isolate) LocationSummary( |
5485 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); | 5602 isolate, kNumInputs, kNumTemps, LocationSummary::kCall); |
5486 locs->set_in(0, Location::RegisterLocation(R0)); | 5603 locs->set_in(0, Location::RegisterLocation(R0)); |
5487 locs->set_in(1, Location::RegisterLocation(R1)); | 5604 locs->set_in(1, Location::RegisterLocation(R1)); |
5488 locs->set_out(0, Location::RegisterLocation(R0)); | 5605 locs->set_out(0, Location::RegisterLocation(R0)); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5605 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 5722 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
5606 #if defined(DEBUG) | 5723 #if defined(DEBUG) |
5607 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); | 5724 __ LoadImmediate(R4, kInvalidObjectPointer, kNoPP); |
5608 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); | 5725 __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP); |
5609 #endif | 5726 #endif |
5610 } | 5727 } |
5611 | 5728 |
5612 } // namespace dart | 5729 } // namespace dart |
5613 | 5730 |
5614 #endif // defined TARGET_ARCH_ARM64 | 5731 #endif // defined TARGET_ARCH_ARM64 |
OLD | NEW |