Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: runtime/vm/intermediate_language_mips.cc

Issue 17907005: Implements external array access for mips. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "lib/error.h" 10 #include "lib/error.h"
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 __ LoadImmediate(result, 1122 __ LoadImmediate(result,
1123 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 1123 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1124 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1124 __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1125 __ sll(TMP1, char_code, 1); // Char code is a smi. 1125 __ sll(TMP1, char_code, 1); // Char code is a smi.
1126 __ addu(TMP1, TMP1, result); 1126 __ addu(TMP1, TMP1, result);
1127 __ lw(result, Address(TMP1)); 1127 __ lw(result, Address(TMP1));
1128 } 1128 }
1129 1129
1130 1130
1131 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const { 1131 LocationSummary* LoadUntaggedInstr::MakeLocationSummary() const {
1132 UNIMPLEMENTED(); 1132 const intptr_t kNumInputs = 1;
1133 return NULL; 1133 return LocationSummary::Make(kNumInputs,
1134 Location::RequiresRegister(),
1135 LocationSummary::kNoCall);
1134 } 1136 }
1135 1137
1136 1138
1137 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1139 void LoadUntaggedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1138 UNIMPLEMENTED(); 1140 Register object = locs()->in(0).reg();
1141 Register result = locs()->out().reg();
1142 __ lw(result, FieldAddress(object, offset()));
regis 2013/06/27 01:34:04 On ARM, we use LoadFromOffset here, in case offset
zra 2013/06/27 16:20:12 Added LoadFromOffset to MIPS assembler, and used i
1139 } 1143 }
1140 1144
1141 1145
1142 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const { 1146 LocationSummary* LoadClassIdInstr::MakeLocationSummary() const {
1143 const intptr_t kNumInputs = 1; 1147 const intptr_t kNumInputs = 1;
1144 return LocationSummary::Make(kNumInputs, 1148 return LocationSummary::Make(kNumInputs,
1145 Location::RequiresRegister(), 1149 Location::RequiresRegister(),
1146 LocationSummary::kNoCall); 1150 LocationSummary::kNoCall);
1147 } 1151 }
1148 1152
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 return locs; 1253 return locs;
1250 } 1254 }
1251 1255
1252 1256
1253 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1257 void LoadIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1254 __ TraceSimMsg("LoadIndexedInstr"); 1258 __ TraceSimMsg("LoadIndexedInstr");
1255 Register array = locs()->in(0).reg(); 1259 Register array = locs()->in(0).reg();
1256 Location index = locs()->in(1); 1260 Location index = locs()->in(1);
1257 1261
1258 Address element_address(kNoRegister, 0); 1262 Address element_address(kNoRegister, 0);
1263
1264 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1265 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1266 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1267 // index is expected to be untagged before accessing.
1268 ASSERT(kSmiTagShift == 1);
1269 switch (index_scale()) {
1270 case 1: {
1271 __ SmiUntag(index.reg());
1272 break;
1273 }
1274 case 2: {
1275 break;
1276 }
1277 case 4: {
1278 __ sll(index.reg(), index.reg(), 1);
1279 break;
1280 }
1281 case 8: {
1282 __ sll(index.reg(), index.reg(), 2);
1283 break;
1284 }
1285 case 16: {
1286 __ sll(index.reg(), index.reg(), 3);
1287 break;
1288 }
1289 default:
1290 UNREACHABLE();
1291 }
1292 __ addu(index.reg(), array, index.reg());
1293
1259 if (IsExternal()) { 1294 if (IsExternal()) {
1260 UNIMPLEMENTED(); 1295 element_address = Address(index.reg(), 0);
1261 } else { 1296 } else {
1262 ASSERT(this->array()->definition()->representation() == kTagged); 1297 ASSERT(this->array()->definition()->representation() == kTagged);
1263 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1264 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1265 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1266 // index is expected to be untagged before accessing.
1267 ASSERT(kSmiTagShift == 1);
1268 switch (index_scale()) {
1269 case 1: {
1270 __ SmiUntag(index.reg());
1271 break;
1272 }
1273 case 2: {
1274 break;
1275 }
1276 case 4: {
1277 __ sll(index.reg(), index.reg(), 1);
1278 break;
1279 }
1280 case 8: {
1281 __ sll(index.reg(), index.reg(), 2);
1282 break;
1283 }
1284 case 16: {
1285 __ sll(index.reg(), index.reg(), 3);
1286 break;
1287 }
1288 default:
1289 UNREACHABLE();
1290 }
1291 __ addu(index.reg(), array, index.reg());
1292 element_address = Address(index.reg(), 1298 element_address = Address(index.reg(),
1293 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1299 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1294 } 1300 }
1295 1301
1296 if ((representation() == kUnboxedDouble) || 1302 if ((representation() == kUnboxedDouble) ||
1297 (representation() == kUnboxedMint) || 1303 (representation() == kUnboxedMint) ||
1298 (representation() == kUnboxedFloat32x4)) { 1304 (representation() == kUnboxedFloat32x4)) {
1299 DRegister result = locs()->out().fpu_reg(); 1305 DRegister result = locs()->out().fpu_reg();
1300 switch (class_id()) { 1306 switch (class_id()) {
1301 case kTypedDataInt32ArrayCid: 1307 case kTypedDataInt32ArrayCid:
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 return locs; 1453 return locs;
1448 } 1454 }
1449 1455
1450 1456
1451 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1457 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1452 __ TraceSimMsg("StoreIndexedInstr"); 1458 __ TraceSimMsg("StoreIndexedInstr");
1453 Register array = locs()->in(0).reg(); 1459 Register array = locs()->in(0).reg();
1454 Location index = locs()->in(1); 1460 Location index = locs()->in(1);
1455 1461
1456 Address element_address(kNoRegister, 0); 1462 Address element_address(kNoRegister, 0);
1463 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1464 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1465 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1466 // index is expected to be untagged before accessing.
1467 ASSERT(kSmiTagShift == 1);
1468 switch (index_scale()) {
1469 case 1: {
1470 __ SmiUntag(index.reg());
1471 break;
1472 }
1473 case 2: {
1474 break;
1475 }
1476 case 4: {
1477 __ sll(index.reg(), index.reg(), 1);
1478 break;
1479 }
1480 case 8: {
1481 __ sll(index.reg(), index.reg(), 2);
1482 break;
1483 }
1484 case 16: {
1485 __ sll(index.reg(), index.reg(), 3);
1486 break;
1487 }
1488 default:
1489 UNREACHABLE();
1490 }
1491 __ addu(index.reg(), array, index.reg());
1492
1457 if (IsExternal()) { 1493 if (IsExternal()) {
1458 UNIMPLEMENTED(); 1494 element_address = Address(index.reg(), 0);
1459 } else { 1495 } else {
1460 ASSERT(this->array()->definition()->representation() == kTagged); 1496 ASSERT(this->array()->definition()->representation() == kTagged);
1461 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1462 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1463 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1464 // index is expected to be untagged before accessing.
1465 ASSERT(kSmiTagShift == 1);
1466 switch (index_scale()) {
1467 case 1: {
1468 __ SmiUntag(index.reg());
1469 break;
1470 }
1471 case 2: {
1472 break;
1473 }
1474 case 4: {
1475 __ sll(index.reg(), index.reg(), 1);
1476 break;
1477 }
1478 case 8: {
1479 __ sll(index.reg(), index.reg(), 2);
1480 break;
1481 }
1482 case 16: {
1483 __ sll(index.reg(), index.reg(), 3);
1484 break;
1485 }
1486 default:
1487 UNREACHABLE();
1488 }
1489 __ addu(index.reg(), array, index.reg());
1490 element_address = Address(index.reg(), 1497 element_address = Address(index.reg(),
1491 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1498 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1492 } 1499 }
1493 1500
1494 switch (class_id()) { 1501 switch (class_id()) {
1495 case kArrayCid: 1502 case kArrayCid:
1496 if (ShouldEmitStoreBarrier()) { 1503 if (ShouldEmitStoreBarrier()) {
1497 Register value = locs()->in(2).reg(); 1504 Register value = locs()->in(2).reg();
1498 __ StoreIntoObject(array, element_address, value); 1505 __ StoreIntoObject(array, element_address, value);
1499 } else if (locs()->in(2).IsConstant()) { 1506 } else if (locs()->in(2).IsConstant()) {
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3107 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3101 Register value = locs()->in(0).reg(); 3108 Register value = locs()->in(0).reg();
3102 FpuRegister result = locs()->out().fpu_reg(); 3109 FpuRegister result = locs()->out().fpu_reg();
3103 __ SmiUntag(value); 3110 __ SmiUntag(value);
3104 __ mtc1(value, STMP1); 3111 __ mtc1(value, STMP1);
3105 __ cvtdw(result, STMP1); 3112 __ cvtdw(result, STMP1);
3106 } 3113 }
3107 3114
3108 3115
3109 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 3116 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const {
3110 UNIMPLEMENTED(); 3117 const intptr_t kNumInputs = 1;
3111 return NULL; 3118 const intptr_t kNumTemps = 0;
3119 LocationSummary* result =
3120 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3121 result->set_in(0, Location::RegisterLocation(T1));
3122 result->set_out(Location::RegisterLocation(V0));
3123 return result;
3112 } 3124 }
3113 3125
3114 3126
3115 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3127 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3116 UNIMPLEMENTED(); 3128 Register result = locs()->out().reg();
3129 Register value_obj = locs()->in(0).reg();
3130 ASSERT(result == V0);
3131 ASSERT(result != value_obj);
3132 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag);
3133 __ cvtwd(STMP1, DTMP);
3134 __ mfc1(result, STMP1);
3135
3136 // Overflow is signaled with minint.
3137 Label do_call, done;
3138 // Check for overflow and that it fits into Smi.
3139 __ LoadImmediate(TMP, 0xC0000000);
3140 __ subu(CMPRES, result, TMP);
3141 __ bltz(CMPRES, &do_call);
3142 __ SmiTag(result);
3143 __ b(&done);
3144 __ Bind(&do_call);
3145 __ Push(value_obj);
3146 ASSERT(instance_call()->HasICData());
3147 const ICData& ic_data = *instance_call()->ic_data();
3148 ASSERT((ic_data.NumberOfChecks() == 1));
3149 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
3150
3151 const intptr_t kNumberOfArguments = 1;
3152 compiler->GenerateStaticCall(deopt_id(),
3153 instance_call()->token_pos(),
3154 target,
3155 kNumberOfArguments,
3156 Object::null_array(), // No argument names.,
3157 locs());
3158 __ Bind(&done);
3117 } 3159 }
3118 3160
3119 3161
3120 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 3162 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
3121 const intptr_t kNumInputs = 1; 3163 const intptr_t kNumInputs = 1;
3122 const intptr_t kNumTemps = 0; 3164 const intptr_t kNumTemps = 0;
3123 LocationSummary* result = new LocationSummary( 3165 LocationSummary* result = new LocationSummary(
3124 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3166 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3125 result->set_in(0, Location::RequiresFpuRegister()); 3167 result->set_in(0, Location::RequiresFpuRegister());
3126 result->set_out(Location::RequiresRegister()); 3168 result->set_out(Location::RequiresRegister());
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 compiler->GenerateCall(token_pos(), 3766 compiler->GenerateCall(token_pos(),
3725 &label, 3767 &label,
3726 PcDescriptors::kOther, 3768 PcDescriptors::kOther,
3727 locs()); 3769 locs());
3728 __ Drop(2); // Discard type arguments and receiver. 3770 __ Drop(2); // Discard type arguments and receiver.
3729 } 3771 }
3730 3772
3731 } // namespace dart 3773 } // namespace dart
3732 3774
3733 #endif // defined TARGET_ARCH_MIPS 3775 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intrinsifier_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698