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 "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 1111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |