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_MIPS. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. |
6 #if defined(TARGET_ARCH_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
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 1242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1253 } | 1253 } |
1254 break; | 1254 break; |
1255 default: | 1255 default: |
1256 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); | 1256 ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid)); |
1257 __ lw(result, element_address); | 1257 __ lw(result, element_address); |
1258 break; | 1258 break; |
1259 } | 1259 } |
1260 } | 1260 } |
1261 | 1261 |
1262 | 1262 |
1263 CompileType LoadCodeUnitsInstr::ComputeType() const { | |
1264 switch (class_id()) { | |
1265 case kOneByteStringCid: | |
1266 case kTwoByteStringCid: | |
1267 return CompileType::FromCid(kSmiCid); | |
1268 default: | |
1269 UNIMPLEMENTED(); | |
1270 return CompileType::Dynamic(); | |
1271 } | |
1272 } | |
1273 | |
1274 | |
1275 Representation LoadCodeUnitsInstr::representation() const { | |
1276 switch (class_id()) { | |
1277 case kOneByteStringCid: | |
1278 case kTwoByteStringCid: | |
1279 return kTagged; | |
1280 default: | |
1281 UNIMPLEMENTED(); | |
1282 return kTagged; | |
1283 } | |
1284 } | |
1285 | |
1286 | |
1287 LocationSummary* LoadCodeUnitsInstr::MakeLocationSummary(Isolate* isolate, | |
1288 bool opt) const { | |
1289 const intptr_t kNumInputs = 2; | |
1290 const intptr_t kNumTemps = 0; | |
1291 LocationSummary* locs = new(isolate) LocationSummary( | |
1292 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
1293 locs->set_in(0, Location::RequiresRegister()); | |
1294 if (CanBeImmediateIndex(index(), class_id(), IsExternal())) { | |
1295 locs->set_in(1, Location::Constant(index()->definition()->AsConstant())); | |
1296 } else { | |
1297 locs->set_in(1, Location::RequiresRegister()); | |
1298 } | |
1299 | |
1300 // TODO(jgruber): Handle mints properly once possible. | |
1301 ASSERT(representation() == kTagged); | |
1302 locs->set_out(0, Location::RequiresRegister()); | |
1303 | |
1304 return locs; | |
1305 } | |
1306 | |
1307 | |
1308 void LoadCodeUnitsInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
1309 const Register array = locs()->in(0).reg(); | |
1310 const Location index = locs()->in(1); | |
1311 | |
1312 Address element_address = index.IsRegister() | |
1313 ? __ ElementAddressForRegIndex(true, // Load. | |
1314 IsExternal(), class_id(), index_scale(), | |
1315 array, index.reg()) | |
1316 : __ ElementAddressForIntIndex( | |
1317 IsExternal(), class_id(), index_scale(), | |
1318 array, Smi::Cast(index.constant()).Value()); | |
1319 // Warning: element_address may use register TMP as base. | |
1320 | |
1321 ASSERT(representation() == kTagged); | |
1322 Register result = locs()->out(0).reg(); | |
1323 switch (class_id()) { | |
1324 case kOneByteStringCid: | |
1325 switch (element_count()) { | |
1326 case 1: __ lbu(result, element_address); break; | |
1327 case 2: __ lhu(result, element_address); break; | |
1328 case 4: // Loading multiple code units is disabled on MIPS. | |
Florian Schneider
2014/10/01 17:04:13
Maybe add a TODO for supporting this?
jgruber1
2014/10/03 18:59:51
The associated TODO is for kEnableUnalignedAccesse
| |
1329 default: UNREACHABLE(); | |
1330 } | |
1331 __ SmiTag(result); | |
1332 break; | |
1333 case kTwoByteStringCid: | |
1334 switch (element_count()) { | |
1335 case 1: __ lhu(result, element_address); break; | |
1336 case 2: // Loading multiple code units is disabled on MIPS. | |
1337 default: UNREACHABLE(); | |
1338 } | |
1339 __ SmiTag(result); | |
1340 break; | |
1341 default: | |
1342 UNREACHABLE(); | |
1343 break; | |
1344 } | |
1345 } | |
1346 | |
1347 | |
1263 Representation StoreIndexedInstr::RequiredInputRepresentation( | 1348 Representation StoreIndexedInstr::RequiredInputRepresentation( |
1264 intptr_t idx) const { | 1349 intptr_t idx) const { |
1265 // Array can be a Dart object or a pointer to external data. | 1350 // Array can be a Dart object or a pointer to external data. |
1266 if (idx == 0) return kNoRepresentation; // Flexible input representation. | 1351 if (idx == 0) return kNoRepresentation; // Flexible input representation. |
1267 if (idx == 1) return kTagged; // Index is a smi. | 1352 if (idx == 1) return kTagged; // Index is a smi. |
1268 ASSERT(idx == 2); | 1353 ASSERT(idx == 2); |
1269 switch (class_id_) { | 1354 switch (class_id_) { |
1270 case kArrayCid: | 1355 case kArrayCid: |
1271 case kOneByteStringCid: | 1356 case kOneByteStringCid: |
1272 case kTypedDataInt8ArrayCid: | 1357 case kTypedDataInt8ArrayCid: |
(...skipping 2377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3650 } else if (kind() == MathUnaryInstr::kDoubleSquare) { | 3735 } else if (kind() == MathUnaryInstr::kDoubleSquare) { |
3651 DRegister val = locs()->in(0).fpu_reg(); | 3736 DRegister val = locs()->in(0).fpu_reg(); |
3652 DRegister result = locs()->out(0).fpu_reg(); | 3737 DRegister result = locs()->out(0).fpu_reg(); |
3653 __ muld(result, val, val); | 3738 __ muld(result, val, val); |
3654 } else { | 3739 } else { |
3655 __ CallRuntime(TargetFunction(), InputCount()); | 3740 __ CallRuntime(TargetFunction(), InputCount()); |
3656 } | 3741 } |
3657 } | 3742 } |
3658 | 3743 |
3659 | 3744 |
3745 LocationSummary* CaseInsensitiveCompareUC16Instr::MakeLocationSummary( | |
3746 Isolate* isolate, bool opt) const { | |
3747 const intptr_t kNumTemps = 0; | |
3748 LocationSummary* summary = new(isolate) LocationSummary( | |
3749 isolate, InputCount(), kNumTemps, LocationSummary::kCall); | |
3750 summary->set_in(0, Location::RegisterLocation(A0)); | |
3751 summary->set_in(1, Location::RegisterLocation(A1)); | |
3752 summary->set_in(2, Location::RegisterLocation(A2)); | |
3753 summary->set_in(3, Location::RegisterLocation(A3)); | |
3754 summary->set_out(0, Location::RegisterLocation(V0)); | |
3755 return summary; | |
3756 } | |
3757 | |
3758 | |
3759 void CaseInsensitiveCompareUC16Instr::EmitNativeCode( | |
3760 FlowGraphCompiler* compiler) { | |
3761 | |
3762 // Call the function. | |
3763 __ CallRuntime(TargetFunction(), TargetFunction().argument_count()); | |
3764 } | |
3765 | |
3766 | |
3660 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, | 3767 LocationSummary* MathMinMaxInstr::MakeLocationSummary(Isolate* isolate, |
3661 bool opt) const { | 3768 bool opt) const { |
3662 if (result_cid() == kDoubleCid) { | 3769 if (result_cid() == kDoubleCid) { |
3663 const intptr_t kNumInputs = 2; | 3770 const intptr_t kNumInputs = 2; |
3664 const intptr_t kNumTemps = 1; | 3771 const intptr_t kNumTemps = 1; |
3665 LocationSummary* summary = new(isolate) LocationSummary( | 3772 LocationSummary* summary = new(isolate) LocationSummary( |
3666 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | 3773 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); |
3667 summary->set_in(0, Location::RequiresFpuRegister()); | 3774 summary->set_in(0, Location::RequiresFpuRegister()); |
3668 summary->set_in(1, Location::RequiresFpuRegister()); | 3775 summary->set_in(1, Location::RequiresFpuRegister()); |
3669 // Reuse the left register so that code can be made shorter. | 3776 // Reuse the left register so that code can be made shorter. |
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4740 } | 4847 } |
4741 | 4848 |
4742 | 4849 |
4743 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4850 void GraphEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4744 if (!compiler->CanFallThroughTo(normal_entry())) { | 4851 if (!compiler->CanFallThroughTo(normal_entry())) { |
4745 __ b(compiler->GetJumpLabel(normal_entry())); | 4852 __ b(compiler->GetJumpLabel(normal_entry())); |
4746 } | 4853 } |
4747 } | 4854 } |
4748 | 4855 |
4749 | 4856 |
4857 void IndirectEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4858 __ Bind(compiler->GetJumpLabel(this)); | |
4859 if (!compiler->is_optimizing()) { | |
4860 compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, | |
4861 deopt_id_, | |
4862 Scanner::kNoSourcePos); | |
4863 } | |
4864 if (HasParallelMove()) { | |
4865 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); | |
4866 } | |
4867 } | |
4868 | |
4869 | |
4750 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate, | 4870 LocationSummary* GotoInstr::MakeLocationSummary(Isolate* isolate, |
4751 bool opt) const { | 4871 bool opt) const { |
4752 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall); | 4872 return new(isolate) LocationSummary(isolate, 0, 0, LocationSummary::kNoCall); |
4753 } | 4873 } |
4754 | 4874 |
4755 | 4875 |
4756 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4876 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
4757 __ TraceSimMsg("GotoInstr"); | 4877 __ TraceSimMsg("GotoInstr"); |
4758 if (!compiler->is_optimizing()) { | 4878 if (!compiler->is_optimizing()) { |
4759 if (FLAG_emit_edge_counters) { | 4879 if (FLAG_emit_edge_counters) { |
(...skipping 13 matching lines...) Expand all Loading... | |
4773 } | 4893 } |
4774 | 4894 |
4775 // We can fall through if the successor is the next block in the list. | 4895 // We can fall through if the successor is the next block in the list. |
4776 // Otherwise, we need a jump. | 4896 // Otherwise, we need a jump. |
4777 if (!compiler->CanFallThroughTo(successor())) { | 4897 if (!compiler->CanFallThroughTo(successor())) { |
4778 __ b(compiler->GetJumpLabel(successor())); | 4898 __ b(compiler->GetJumpLabel(successor())); |
4779 } | 4899 } |
4780 } | 4900 } |
4781 | 4901 |
4782 | 4902 |
4903 LocationSummary* IndirectGotoInstr::MakeLocationSummary(Isolate* isolate, | |
4904 bool opt) const { | |
4905 const intptr_t kNumInputs = 1; | |
4906 const intptr_t kNumTemps = 1; | |
4907 | |
4908 LocationSummary* locs = new(isolate) LocationSummary( | |
4909 isolate, kNumInputs, kNumTemps, LocationSummary::kNoCall); | |
4910 | |
4911 locs->set_in(0, Location::RequiresRegister()); | |
4912 locs->set_temp(0, Location::RequiresRegister()); | |
4913 | |
4914 return locs; | |
4915 } | |
4916 | |
4917 | |
4918 void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | |
4919 Register sum_reg = locs()->temp_slot(0)->reg(); | |
4920 | |
4921 // Load from [current frame pointer] + kPcMarkerSlotFromFp. | |
4922 __ lw(sum_reg, Address(FP, kPcMarkerSlotFromFp * kWordSize)); | |
4923 | |
4924 // Subtract the entrypoint offset. | |
4925 __ AddImmediate(sum_reg, -Assembler::EntryPointToPcMarkerOffset()); | |
4926 | |
4927 // Add the offset. | |
4928 Register offset_reg = locs()->in(0).reg(); | |
4929 __ SmiUntag(offset_reg); | |
4930 __ addu(sum_reg, sum_reg, offset_reg); | |
4931 | |
4932 // Jump to the absolute address. | |
4933 __ jr(sum_reg); | |
4934 } | |
4935 | |
4936 | |
4783 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, | 4937 LocationSummary* CurrentContextInstr::MakeLocationSummary(Isolate* isolate, |
4784 bool opt) const { | 4938 bool opt) const { |
4785 return LocationSummary::Make(isolate, | 4939 return LocationSummary::Make(isolate, |
4786 0, | 4940 0, |
4787 Location::RequiresRegister(), | 4941 Location::RequiresRegister(), |
4788 LocationSummary::kNoCall); | 4942 LocationSummary::kNoCall); |
4789 } | 4943 } |
4790 | 4944 |
4791 | 4945 |
4792 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { | 4946 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4926 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); | 5080 compiler->GenerateCall(token_pos(), &label, stub_kind_, locs()); |
4927 #if defined(DEBUG) | 5081 #if defined(DEBUG) |
4928 __ LoadImmediate(S4, kInvalidObjectPointer); | 5082 __ LoadImmediate(S4, kInvalidObjectPointer); |
4929 __ LoadImmediate(S5, kInvalidObjectPointer); | 5083 __ LoadImmediate(S5, kInvalidObjectPointer); |
4930 #endif | 5084 #endif |
4931 } | 5085 } |
4932 | 5086 |
4933 } // namespace dart | 5087 } // namespace dart |
4934 | 5088 |
4935 #endif // defined TARGET_ARCH_MIPS | 5089 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |