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

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

Issue 253623003: Enables all startup code for arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 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/flow_graph_compiler_arm64.cc ('k') | runtime/vm/intrinsifier_arm64.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 16 matching lines...) Expand all
27 // Generic summary for call instructions that have all arguments pushed 27 // Generic summary for call instructions that have all arguments pushed
28 // on the stack and return the result in a fixed register R0. 28 // on the stack and return the result in a fixed register R0.
29 LocationSummary* Instruction::MakeCallSummary() { 29 LocationSummary* Instruction::MakeCallSummary() {
30 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall); 30 LocationSummary* result = new LocationSummary(0, 0, LocationSummary::kCall);
31 result->set_out(0, Location::RegisterLocation(R0)); 31 result->set_out(0, Location::RegisterLocation(R0));
32 return result; 32 return result;
33 } 33 }
34 34
35 35
36 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const { 36 LocationSummary* PushArgumentInstr::MakeLocationSummary(bool opt) const {
37 UNIMPLEMENTED(); 37 const intptr_t kNumInputs = 1;
38 return NULL; 38 const intptr_t kNumTemps= 0;
39 LocationSummary* locs =
40 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
41 locs->set_in(0, Location::AnyOrConstant(value()));
42 return locs;
39 } 43 }
40 44
41 45
42 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 46 void PushArgumentInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
43 UNIMPLEMENTED(); 47 // In SSA mode, we need an explicit push. Nothing to do in non-SSA mode
48 // where PushArgument is handled by BindInstr::EmitNativeCode.
49 if (compiler->is_optimizing()) {
50 Location value = locs()->in(0);
51 if (value.IsRegister()) {
52 __ Push(value.reg());
53 } else if (value.IsConstant()) {
54 __ PushObject(value.constant(), PP);
55 } else {
56 ASSERT(value.IsStackSlot());
57 const intptr_t value_offset = value.ToStackSlotOffset();
58 __ LoadFromOffset(TMP, FP, value_offset);
59 __ Push(TMP);
60 }
61 }
44 } 62 }
45 63
46 64
47 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const { 65 LocationSummary* ReturnInstr::MakeLocationSummary(bool opt) const {
48 const intptr_t kNumInputs = 1; 66 const intptr_t kNumInputs = 1;
49 const intptr_t kNumTemps = 0; 67 const intptr_t kNumTemps = 0;
50 LocationSummary* locs = 68 LocationSummary* locs =
51 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); 69 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
52 locs->set_in(0, Location::RegisterLocation(R0)); 70 locs->set_in(0, Location::RegisterLocation(R0));
53 return locs; 71 return locs;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 return NULL; 113 return NULL;
96 } 114 }
97 115
98 116
99 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 117 void ClosureCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
100 UNIMPLEMENTED(); 118 UNIMPLEMENTED();
101 } 119 }
102 120
103 121
104 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const { 122 LocationSummary* LoadLocalInstr::MakeLocationSummary(bool opt) const {
105 UNIMPLEMENTED(); 123 return LocationSummary::Make(0,
106 return NULL; 124 Location::RequiresRegister(),
125 LocationSummary::kNoCall);
107 } 126 }
108 127
109 128
110 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 129 void LoadLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
111 UNIMPLEMENTED(); 130 Register result = locs()->out(0).reg();
131 __ LoadFromOffset(result, FP, local().index() * kWordSize);
112 } 132 }
113 133
114 134
115 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const { 135 LocationSummary* StoreLocalInstr::MakeLocationSummary(bool opt) const {
116 UNIMPLEMENTED(); 136 return LocationSummary::Make(1,
117 return NULL; 137 Location::SameAsFirstInput(),
138 LocationSummary::kNoCall);
118 } 139 }
119 140
120 141
121 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 142 void StoreLocalInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
122 UNIMPLEMENTED(); 143 Register value = locs()->in(0).reg();
144 Register result = locs()->out(0).reg();
145 ASSERT(result == value); // Assert that register assignment is correct.
146 __ StoreToOffset(value, FP, local().index() * kWordSize);
123 } 147 }
124 148
125 149
126 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const { 150 LocationSummary* ConstantInstr::MakeLocationSummary(bool opt) const {
127 return LocationSummary::Make(0, 151 return LocationSummary::Make(0,
128 Location::RequiresRegister(), 152 Location::RequiresRegister(),
129 LocationSummary::kNoCall); 153 LocationSummary::kNoCall);
130 } 154 }
131 155
132 156
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 } 245 }
222 246
223 247
224 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler, 248 void RelationalOpInstr::EmitBranchCode(FlowGraphCompiler* compiler,
225 BranchInstr* branch) { 249 BranchInstr* branch) {
226 UNIMPLEMENTED(); 250 UNIMPLEMENTED();
227 } 251 }
228 252
229 253
230 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const { 254 LocationSummary* NativeCallInstr::MakeLocationSummary(bool opt) const {
231 UNIMPLEMENTED(); 255 const intptr_t kNumInputs = 0;
232 return NULL; 256 const intptr_t kNumTemps = 3;
257 LocationSummary* locs =
258 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
259 locs->set_temp(0, Location::RegisterLocation(R1));
260 locs->set_temp(1, Location::RegisterLocation(R2));
261 locs->set_temp(2, Location::RegisterLocation(R5));
262 locs->set_out(0, Location::RegisterLocation(R0));
263 return locs;
233 } 264 }
234 265
235 266
236 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 267 void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
237 UNIMPLEMENTED(); 268 ASSERT(locs()->temp(0).reg() == R1);
269 ASSERT(locs()->temp(1).reg() == R2);
270 ASSERT(locs()->temp(2).reg() == R5);
271 Register result = locs()->out(0).reg();
272
273 // Push the result place holder initialized to NULL.
274 __ PushObject(Object::ZoneHandle(), PP);
275 // Pass a pointer to the first argument in R2.
276 if (!function().HasOptionalParameters()) {
277 __ AddImmediate(R2, FP, (kParamEndSlotFromFp +
278 function().NumParameters()) * kWordSize, PP);
279 } else {
280 __ AddImmediate(R2, FP, kFirstLocalSlotFromFp * kWordSize, PP);
281 }
282 // Compute the effective address. When running under the simulator,
283 // this is a redirection address that forces the simulator to call
284 // into the runtime system.
285 uword entry = reinterpret_cast<uword>(native_c_function());
286 const ExternalLabel* stub_entry;
287 if (is_bootstrap_native()) {
288 stub_entry = &StubCode::CallBootstrapCFunctionLabel();
289 #if defined(USING_SIMULATOR)
290 entry = Simulator::RedirectExternalReference(
291 entry, Simulator::kBootstrapNativeCall, function().NumParameters());
292 #endif
293 } else {
294 // In the case of non bootstrap native methods the CallNativeCFunction
295 // stub generates the redirection address when running under the simulator
296 // and hence we do not change 'entry' here.
297 stub_entry = &StubCode::CallNativeCFunctionLabel();
298 #if defined(USING_SIMULATOR)
299 if (!function().IsNativeAutoSetupScope()) {
300 entry = Simulator::RedirectExternalReference(
301 entry, Simulator::kBootstrapNativeCall, function().NumParameters());
302 }
303 #endif
304 }
305 __ LoadImmediate(R5, entry, PP);
306 __ LoadImmediate(R1, NativeArguments::ComputeArgcTag(function()), PP);
307 compiler->GenerateCall(token_pos(),
308 stub_entry,
309 PcDescriptors::kOther,
310 locs());
311 __ Pop(result);
238 } 312 }
239 313
240 314
241 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const { 315 LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(bool opt) const {
242 UNIMPLEMENTED(); 316 UNIMPLEMENTED();
243 return NULL; 317 return NULL;
244 } 318 }
245 319
246 320
247 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 321 void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 return NULL; 1237 return NULL;
1164 } 1238 }
1165 1239
1166 1240
1167 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1241 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1168 UNIMPLEMENTED(); 1242 UNIMPLEMENTED();
1169 } 1243 }
1170 1244
1171 1245
1172 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const { 1246 LocationSummary* BranchInstr::MakeLocationSummary(bool opt) const {
1173 UNIMPLEMENTED(); 1247 comparison()->InitializeLocationSummary(opt);
1174 return NULL; 1248 // Branches don't produce a result.
1249 comparison()->locs()->set_out(0, Location::NoLocation());
1250 return comparison()->locs();
1175 } 1251 }
1176 1252
1177 1253
1178 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1254 void BranchInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1179 UNIMPLEMENTED(); 1255 comparison()->EmitBranchCode(compiler, this);
1180 } 1256 }
1181 1257
1182 1258
1183 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const { 1259 LocationSummary* CheckClassInstr::MakeLocationSummary(bool opt) const {
1184 UNIMPLEMENTED(); 1260 UNIMPLEMENTED();
1185 return NULL; 1261 return NULL;
1186 } 1262 }
1187 1263
1188 1264
1189 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1265 void CheckClassInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 deopt_id_, 1385 deopt_id_,
1310 Scanner::kNoSourcePos); 1386 Scanner::kNoSourcePos);
1311 } 1387 }
1312 if (HasParallelMove()) { 1388 if (HasParallelMove()) {
1313 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 1389 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1314 } 1390 }
1315 } 1391 }
1316 1392
1317 1393
1318 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const { 1394 LocationSummary* GotoInstr::MakeLocationSummary(bool opt) const {
1319 UNIMPLEMENTED(); 1395 return new LocationSummary(0, 0, LocationSummary::kNoCall);
1320 return NULL;
1321 } 1396 }
1322 1397
1323 1398
1324 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1399 void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1325 UNIMPLEMENTED(); 1400 if (!compiler->is_optimizing()) {
1401 compiler->EmitEdgeCounter();
1402 // Add a deoptimization descriptor for deoptimizing instructions that
1403 // may be inserted before this instruction. On ARM64 this descriptor
1404 // points after the edge counter code so that we can reuse the same
1405 // pattern matching code as at call sites, which matches backwards from
1406 // the end of the pattern.
1407 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
1408 GetDeoptId(),
1409 Scanner::kNoSourcePos);
1410 }
1411 if (HasParallelMove()) {
1412 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
1413 }
1414
1415 // We can fall through if the successor is the next block in the list.
1416 // Otherwise, we need a jump.
1417 if (!compiler->CanFallThroughTo(successor())) {
1418 __ b(compiler->GetJumpLabel(successor()));
1419 }
1326 } 1420 }
1327 1421
1328 1422
1329 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const { 1423 LocationSummary* CurrentContextInstr::MakeLocationSummary(bool opt) const {
1330 UNIMPLEMENTED(); 1424 UNIMPLEMENTED();
1331 return NULL; 1425 return NULL;
1332 } 1426 }
1333 1427
1334 1428
1335 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1429 void CurrentContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1336 UNIMPLEMENTED(); 1430 UNIMPLEMENTED();
1337 } 1431 }
1338 1432
1339 1433
1434 static Condition NegateCondition(Condition condition) {
1435 switch (condition) {
1436 case EQ: return NE;
1437 case NE: return EQ;
1438 case LT: return GE;
1439 case LE: return GT;
1440 case GT: return LE;
1441 case GE: return LT;
1442 case CC: return CS;
1443 case LS: return HI;
1444 case HI: return LS;
1445 case CS: return CC;
1446 default:
1447 UNREACHABLE();
1448 return EQ;
1449 }
1450 }
1451
1452
1453 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
1454 Condition true_condition,
1455 BranchLabels labels) {
1456 if (labels.fall_through == labels.false_label) {
1457 // If the next block is the false successor we will fall through to it.
1458 __ b(labels.true_label, true_condition);
1459 } else {
1460 // If the next block is not the false successor we will branch to it.
1461 Condition false_condition = NegateCondition(true_condition);
1462 __ b(labels.false_label, false_condition);
1463
1464 // Fall through or jump to the true successor.
1465 if (labels.fall_through != labels.true_label) {
1466 __ b(labels.true_label);
1467 }
1468 }
1469 }
1470
1471
1340 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const { 1472 LocationSummary* StrictCompareInstr::MakeLocationSummary(bool opt) const {
1341 UNIMPLEMENTED(); 1473 const intptr_t kNumInputs = 2;
1342 return NULL; 1474 const intptr_t kNumTemps = 0;
1475 if (needs_number_check()) {
1476 LocationSummary* locs =
1477 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
1478 locs->set_in(0, Location::RegisterLocation(R0));
1479 locs->set_in(1, Location::RegisterLocation(R1));
1480 locs->set_out(0, Location::RegisterLocation(R0));
1481 return locs;
1482 }
1483 LocationSummary* locs =
1484 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
1485 locs->set_in(0, Location::RegisterOrConstant(left()));
1486 // Only one of the inputs can be a constant. Choose register if the first one
1487 // is a constant.
1488 locs->set_in(1, locs->in(0).IsConstant()
1489 ? Location::RequiresRegister()
1490 : Location::RegisterOrConstant(right()));
1491 locs->set_out(0, Location::RequiresRegister());
1492 return locs;
1343 } 1493 }
1344 1494
1345 1495
1346 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 1496 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
1347 BranchLabels labels) { 1497 BranchLabels labels) {
1348 UNIMPLEMENTED(); 1498 Location left = locs()->in(0);
1349 return VS; 1499 Location right = locs()->in(1);
1500 ASSERT(!left.IsConstant() || !right.IsConstant());
1501 if (left.IsConstant()) {
1502 compiler->EmitEqualityRegConstCompare(right.reg(),
1503 left.constant(),
1504 needs_number_check(),
1505 token_pos());
1506 } else if (right.IsConstant()) {
1507 compiler->EmitEqualityRegConstCompare(left.reg(),
1508 right.constant(),
1509 needs_number_check(),
1510 token_pos());
1511 } else {
1512 compiler->EmitEqualityRegRegCompare(left.reg(),
1513 right.reg(),
1514 needs_number_check(),
1515 token_pos());
1516 }
1517 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
1518 return true_condition;
1350 } 1519 }
1351 1520
1352 1521
1353 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1522 void StrictCompareInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1354 UNIMPLEMENTED(); 1523 __ Comment("StrictCompareInstr");
1524 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1525
1526 Label is_true, is_false;
1527 BranchLabels labels = { &is_true, &is_false, &is_false };
1528 Condition true_condition = EmitComparisonCode(compiler, labels);
1529 EmitBranchOnCondition(compiler, true_condition, labels);
1530
1531 Register result = locs()->out(0).reg();
1532 Label done;
1533 __ Bind(&is_false);
1534 __ LoadObject(result, Bool::False(), PP);
1535 __ b(&done);
1536 __ Bind(&is_true);
1537 __ LoadObject(result, Bool::True(), PP);
1538 __ Bind(&done);
1355 } 1539 }
1356 1540
1357 1541
1358 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 1542 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
1359 BranchInstr* branch) { 1543 BranchInstr* branch) {
1360 UNIMPLEMENTED(); 1544 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
1545
1546 BranchLabels labels = compiler->CreateBranchLabels(branch);
1547 Condition true_condition = EmitComparisonCode(compiler, labels);
1548 EmitBranchOnCondition(compiler, true_condition, labels);
1361 } 1549 }
1362 1550
1363 1551
1364 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const { 1552 LocationSummary* BooleanNegateInstr::MakeLocationSummary(bool opt) const {
1365 UNIMPLEMENTED(); 1553 UNIMPLEMENTED();
1366 return NULL; 1554 return NULL;
1367 } 1555 }
1368 1556
1369 1557
1370 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1558 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1371 UNIMPLEMENTED(); 1559 UNIMPLEMENTED();
1372 } 1560 }
1373 1561
1374 1562
1375 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const { 1563 LocationSummary* AllocateObjectInstr::MakeLocationSummary(bool opt) const {
1376 UNIMPLEMENTED(); 1564 UNIMPLEMENTED();
1377 return NULL; 1565 return NULL;
1378 } 1566 }
1379 1567
1380 1568
1381 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 1569 void AllocateObjectInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
1382 UNIMPLEMENTED(); 1570 UNIMPLEMENTED();
1383 } 1571 }
1384 1572
1385 } // namespace dart 1573 } // namespace dart
1386 1574
1387 #endif // defined TARGET_ARCH_ARM64 1575 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_compiler_arm64.cc ('k') | runtime/vm/intrinsifier_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698