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

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, 5 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 | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intrinsifier_arm.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 __ LoadFromOffset(result, object, offset() - kHeapObjectTag);
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. 1298 // If the data offset doesn't fit into the 18 bits we get for the addressing
1264 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays 1299 // mode, then we must load the offset into a register and add it to the
1265 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the 1300 // index.
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(), 1301 element_address = Address(index.reg(),
1293 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1302 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1294 } 1303 }
1295 1304
1296 if ((representation() == kUnboxedDouble) || 1305 if ((representation() == kUnboxedDouble) ||
1297 (representation() == kUnboxedMint) || 1306 (representation() == kUnboxedMint) ||
1298 (representation() == kUnboxedFloat32x4)) { 1307 (representation() == kUnboxedFloat32x4)) {
1299 DRegister result = locs()->out().fpu_reg(); 1308 DRegister result = locs()->out().fpu_reg();
1300 switch (class_id()) { 1309 switch (class_id()) {
1301 case kTypedDataInt32ArrayCid: 1310 case kTypedDataInt32ArrayCid:
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
1447 return locs; 1456 return locs;
1448 } 1457 }
1449 1458
1450 1459
1451 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1460 void StoreIndexedInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1452 __ TraceSimMsg("StoreIndexedInstr"); 1461 __ TraceSimMsg("StoreIndexedInstr");
1453 Register array = locs()->in(0).reg(); 1462 Register array = locs()->in(0).reg();
1454 Location index = locs()->in(1); 1463 Location index = locs()->in(1);
1455 1464
1456 Address element_address(kNoRegister, 0); 1465 Address element_address(kNoRegister, 0);
1466 ASSERT(index.IsRegister()); // TODO(regis): Revisit.
1467 // Note that index is expected smi-tagged, (i.e, times 2) for all arrays
1468 // with index scale factor > 1. E.g., for Uint8Array and OneByteString the
1469 // index is expected to be untagged before accessing.
1470 ASSERT(kSmiTagShift == 1);
1471 switch (index_scale()) {
1472 case 1: {
1473 __ SmiUntag(index.reg());
1474 break;
1475 }
1476 case 2: {
1477 break;
1478 }
1479 case 4: {
1480 __ sll(index.reg(), index.reg(), 1);
1481 break;
1482 }
1483 case 8: {
1484 __ sll(index.reg(), index.reg(), 2);
1485 break;
1486 }
1487 case 16: {
1488 __ sll(index.reg(), index.reg(), 3);
1489 break;
1490 }
1491 default:
1492 UNREACHABLE();
1493 }
1494 __ addu(index.reg(), array, index.reg());
1495
1457 if (IsExternal()) { 1496 if (IsExternal()) {
1458 UNIMPLEMENTED(); 1497 element_address = Address(index.reg(), 0);
1459 } else { 1498 } else {
1460 ASSERT(this->array()->definition()->representation() == kTagged); 1499 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(), 1500 element_address = Address(index.reg(),
1491 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag); 1501 FlowGraphCompiler::DataOffsetFor(class_id()) - kHeapObjectTag);
1492 } 1502 }
1493 1503
1494 switch (class_id()) { 1504 switch (class_id()) {
1495 case kArrayCid: 1505 case kArrayCid:
1496 if (ShouldEmitStoreBarrier()) { 1506 if (ShouldEmitStoreBarrier()) {
1497 Register value = locs()->in(2).reg(); 1507 Register value = locs()->in(2).reg();
1498 __ StoreIntoObject(array, element_address, value); 1508 __ StoreIntoObject(array, element_address, value);
1499 } else if (locs()->in(2).IsConstant()) { 1509 } else if (locs()->in(2).IsConstant()) {
(...skipping 1600 matching lines...) Expand 10 before | Expand all | Expand 10 after
3100 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3110 void SmiToDoubleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3101 Register value = locs()->in(0).reg(); 3111 Register value = locs()->in(0).reg();
3102 FpuRegister result = locs()->out().fpu_reg(); 3112 FpuRegister result = locs()->out().fpu_reg();
3103 __ SmiUntag(value); 3113 __ SmiUntag(value);
3104 __ mtc1(value, STMP1); 3114 __ mtc1(value, STMP1);
3105 __ cvtdw(result, STMP1); 3115 __ cvtdw(result, STMP1);
3106 } 3116 }
3107 3117
3108 3118
3109 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const { 3119 LocationSummary* DoubleToIntegerInstr::MakeLocationSummary() const {
3110 UNIMPLEMENTED(); 3120 const intptr_t kNumInputs = 1;
3111 return NULL; 3121 const intptr_t kNumTemps = 0;
3122 LocationSummary* result =
3123 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
3124 result->set_in(0, Location::RegisterLocation(T1));
3125 result->set_out(Location::RegisterLocation(V0));
3126 return result;
3112 } 3127 }
3113 3128
3114 3129
3115 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 3130 void DoubleToIntegerInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
3116 UNIMPLEMENTED(); 3131 Register result = locs()->out().reg();
3132 Register value_obj = locs()->in(0).reg();
3133 ASSERT(result == V0);
3134 ASSERT(result != value_obj);
3135 __ LoadDFromOffset(DTMP, value_obj, Double::value_offset() - kHeapObjectTag);
3136 __ cvtwd(STMP1, DTMP);
3137 __ mfc1(result, STMP1);
3138
3139 // Overflow is signaled with minint.
3140 Label do_call, done;
3141 // Check for overflow and that it fits into Smi.
3142 __ LoadImmediate(TMP, 0xC0000000);
3143 __ subu(CMPRES, result, TMP);
3144 __ bltz(CMPRES, &do_call);
3145 __ SmiTag(result);
3146 __ b(&done);
3147 __ Bind(&do_call);
3148 __ Push(value_obj);
3149 ASSERT(instance_call()->HasICData());
3150 const ICData& ic_data = *instance_call()->ic_data();
3151 ASSERT((ic_data.NumberOfChecks() == 1));
3152 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
3153
3154 const intptr_t kNumberOfArguments = 1;
3155 compiler->GenerateStaticCall(deopt_id(),
3156 instance_call()->token_pos(),
3157 target,
3158 kNumberOfArguments,
3159 Object::null_array(), // No argument names.,
3160 locs());
3161 __ Bind(&done);
3117 } 3162 }
3118 3163
3119 3164
3120 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const { 3165 LocationSummary* DoubleToSmiInstr::MakeLocationSummary() const {
3121 const intptr_t kNumInputs = 1; 3166 const intptr_t kNumInputs = 1;
3122 const intptr_t kNumTemps = 0; 3167 const intptr_t kNumTemps = 0;
3123 LocationSummary* result = new LocationSummary( 3168 LocationSummary* result = new LocationSummary(
3124 kNumInputs, kNumTemps, LocationSummary::kNoCall); 3169 kNumInputs, kNumTemps, LocationSummary::kNoCall);
3125 result->set_in(0, Location::RequiresFpuRegister()); 3170 result->set_in(0, Location::RequiresFpuRegister());
3126 result->set_out(Location::RequiresRegister()); 3171 result->set_out(Location::RequiresRegister());
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after
3724 compiler->GenerateCall(token_pos(), 3769 compiler->GenerateCall(token_pos(),
3725 &label, 3770 &label,
3726 PcDescriptors::kOther, 3771 PcDescriptors::kOther,
3727 locs()); 3772 locs());
3728 __ Drop(2); // Discard type arguments and receiver. 3773 __ Drop(2); // Discard type arguments and receiver.
3729 } 3774 }
3730 3775
3731 } // namespace dart 3776 } // namespace dart
3732 3777
3733 #endif // defined TARGET_ARCH_MIPS 3778 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm.cc ('k') | runtime/vm/intrinsifier_arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698