Chromium Code Reviews| 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 |