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

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

Issue 14192032: Implement missing features to run Hello world! in checked mode on simulated ARM. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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
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_ARM. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM.
6 #if defined(TARGET_ARCH_ARM) 6 #if defined(TARGET_ARCH_ARM)
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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 } 201 }
202 } 202 }
203 203
204 204
205 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const { 205 LocationSummary* AssertAssignableInstr::MakeLocationSummary() const {
206 const intptr_t kNumInputs = 3; 206 const intptr_t kNumInputs = 3;
207 const intptr_t kNumTemps = 0; 207 const intptr_t kNumTemps = 0;
208 LocationSummary* summary = 208 LocationSummary* summary =
209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 209 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
210 summary->set_in(0, Location::RegisterLocation(R0)); // Value. 210 summary->set_in(0, Location::RegisterLocation(R0)); // Value.
211 summary->set_in(1, Location::RegisterLocation(R1)); // Instantiator. 211 summary->set_in(1, Location::RegisterLocation(R2)); // Instantiator.
212 summary->set_in(2, Location::RegisterLocation(R2)); // Type arguments. 212 summary->set_in(2, Location::RegisterLocation(R1)); // Type arguments.
213 summary->set_out(Location::RegisterLocation(R0)); 213 summary->set_out(Location::RegisterLocation(R0));
214 return summary; 214 return summary;
215 } 215 }
216 216
217 217
218 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const { 218 LocationSummary* AssertBooleanInstr::MakeLocationSummary() const {
219 const intptr_t kNumInputs = 1; 219 const intptr_t kNumInputs = 1;
220 const intptr_t kNumTemps = 0; 220 const intptr_t kNumTemps = 0;
221 LocationSummary* locs = 221 LocationSummary* locs =
222 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 222 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 LocationSummary* locs = 337 LocationSummary* locs =
338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 338 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
339 UNIMPLEMENTED(); // TODO(regis): Verify register allocation. 339 UNIMPLEMENTED(); // TODO(regis): Verify register allocation.
340 return locs; 340 return locs;
341 } 341 }
342 const intptr_t kNumTemps = 1; 342 const intptr_t kNumTemps = 1;
343 LocationSummary* locs = 343 LocationSummary* locs =
344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); 344 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
345 locs->set_in(0, Location::RegisterLocation(R1)); 345 locs->set_in(0, Location::RegisterLocation(R1));
346 locs->set_in(1, Location::RegisterLocation(R0)); 346 locs->set_in(1, Location::RegisterLocation(R0));
347 locs->set_temp(0, Location::RegisterLocation(R6)); 347 locs->set_temp(0, Location::RegisterLocation(R5));
348 locs->set_out(Location::RegisterLocation(R0)); 348 locs->set_out(Location::RegisterLocation(R0));
349 return locs; 349 return locs;
350 } 350 }
351 351
352 352
353 // R1: left. 353 // R1: left.
354 // R0: right. 354 // R0: right.
355 // Uses R6 to load ic_call_data. 355 // Uses R5 to load ic_call_data.
356 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, 356 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler,
357 intptr_t deopt_id, 357 intptr_t deopt_id,
358 intptr_t token_pos, 358 intptr_t token_pos,
359 Token::Kind kind, 359 Token::Kind kind,
360 LocationSummary* locs, 360 LocationSummary* locs,
361 const ICData& original_ic_data) { 361 const ICData& original_ic_data) {
362 if (!compiler->is_optimizing()) { 362 if (!compiler->is_optimizing()) {
363 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, 363 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt,
364 deopt_id, 364 deopt_id,
365 token_pos); 365 token_pos);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 kNoArgumentNames, 398 kNoArgumentNames,
399 locs, 399 locs,
400 equality_ic_data); 400 equality_ic_data);
401 Label check_ne; 401 Label check_ne;
402 __ b(&check_ne); 402 __ b(&check_ne);
403 403
404 __ Bind(&check_identity); 404 __ Bind(&check_identity);
405 Label equality_done; 405 Label equality_done;
406 if (compiler->is_optimizing()) { 406 if (compiler->is_optimizing()) {
407 // No need to update IC data. 407 // No need to update IC data.
408 Label is_true;
409 __ cmp(R0, ShifterOperand(R1)); 408 __ cmp(R0, ShifterOperand(R1));
410 __ b(&is_true, EQ); 409 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True(), NE);
411 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::False() : Bool::True()); 410 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False(), EQ);
412 __ b(&equality_done);
413 __ Bind(&is_true);
414 __ LoadObject(R0, (kind == Token::kEQ) ? Bool::True() : Bool::False());
415 if (kind == Token::kNE) { 411 if (kind == Token::kNE) {
416 // Skip not-equal result conversion. 412 // Skip not-equal result conversion.
417 __ b(&equality_done); 413 __ b(&equality_done);
418 } 414 }
419 } else { 415 } else {
420 // Call stub, load IC data in register. The stub will update ICData if 416 // Call stub, load IC data in register. The stub will update ICData if
421 // necessary. 417 // necessary.
422 Register ic_data_reg = locs->temp(0).reg(); 418 Register ic_data_reg = locs->temp(0).reg();
423 ASSERT(ic_data_reg == R6); // Stub depends on it. 419 ASSERT(ic_data_reg == R5); // Stub depends on it.
424 __ LoadObject(ic_data_reg, equality_ic_data); 420 __ LoadObject(ic_data_reg, equality_ic_data);
425 // Pass left in R1 and right in R0. 421 // Pass left in R1 and right in R0.
426 compiler->GenerateCall(token_pos, 422 compiler->GenerateCall(token_pos,
427 &StubCode::EqualityWithNullArgLabel(), 423 &StubCode::EqualityWithNullArgLabel(),
428 PcDescriptors::kOther, 424 PcDescriptors::kOther,
429 locs); 425 locs);
430 } 426 }
431 __ Bind(&check_ne); 427 __ Bind(&check_ne);
432 if (kind == Token::kNE) { 428 if (kind == Token::kNE) {
433 Label true_label, done;
434 // Negate the condition: true label returns false and vice versa. 429 // Negate the condition: true label returns false and vice versa.
435 __ CompareObject(R0, Bool::True()); 430 __ CompareObject(R0, Bool::True());
436 __ b(&true_label, EQ); 431 __ LoadObject(R0, Bool::True(), NE);
437 __ LoadObject(R0, Bool::True()); 432 __ LoadObject(R0, Bool::False(), EQ);
438 __ b(&done);
439 __ Bind(&true_label);
440 __ LoadObject(R0, Bool::False());
441 __ Bind(&done);
442 } 433 }
443 __ Bind(&equality_done); 434 __ Bind(&equality_done);
444 } 435 }
445 436
446 437
447 static void LoadValueCid(FlowGraphCompiler* compiler, 438 static void LoadValueCid(FlowGraphCompiler* compiler,
448 Register value_cid_reg, 439 Register value_cid_reg,
449 Register value_reg, 440 Register value_reg,
450 Label* value_is_smi = NULL) { 441 Label* value_is_smi = NULL) {
451 Label done; 442 Label done;
(...skipping 29 matching lines...) Expand all
481 LocationSummary* locs, 472 LocationSummary* locs,
482 Token::Kind kind, 473 Token::Kind kind,
483 BranchInstr* branch, 474 BranchInstr* branch,
484 const ICData& ic_data, 475 const ICData& ic_data,
485 intptr_t deopt_id, 476 intptr_t deopt_id,
486 intptr_t token_pos) { 477 intptr_t token_pos) {
487 UNIMPLEMENTED(); 478 UNIMPLEMENTED();
488 } 479 }
489 480
490 481
482 static Condition NegateCondition(Condition condition) {
483 switch (condition) {
484 case EQ: return NE;
485 case NE: return EQ;
486 case LT: return GE;
487 case LE: return GT;
488 case GT: return LE;
489 case GE: return LT;
490 case CC: return CS;
491 case LS: return HI;
492 case HI: return LS;
493 case CS: return CC;
494 default:
495 OS::Print("Error %d\n", condition);
srdjan 2013/04/19 22:56:40 You could use PrintErr
regis 2013/04/19 23:19:19 I deleted this line here and in the Intel sources.
496 UNIMPLEMENTED();
497 return EQ;
498 }
499 }
500
501
491 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, 502 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler,
492 const LocationSummary& locs, 503 const LocationSummary& locs,
493 Token::Kind kind, 504 Token::Kind kind,
494 BranchInstr* branch) { 505 BranchInstr* branch) {
495 Location left = locs.in(0); 506 Location left = locs.in(0);
496 Location right = locs.in(1); 507 Location right = locs.in(1);
497 ASSERT(!left.IsConstant() || !right.IsConstant()); 508 ASSERT(!left.IsConstant() || !right.IsConstant());
498 509
499 Condition true_condition = TokenKindToSmiCondition(kind); 510 Condition true_condition = TokenKindToSmiCondition(kind);
500 511
501 if (left.IsConstant()) { 512 if (left.IsConstant()) {
502 __ CompareObject(right.reg(), left.constant()); 513 __ CompareObject(right.reg(), left.constant());
503 true_condition = FlowGraphCompiler::FlipCondition(true_condition); 514 true_condition = FlowGraphCompiler::FlipCondition(true_condition);
504 } else if (right.IsConstant()) { 515 } else if (right.IsConstant()) {
505 __ CompareObject(left.reg(), right.constant()); 516 __ CompareObject(left.reg(), right.constant());
506 } else { 517 } else {
507 __ cmp(left.reg(), ShifterOperand(right.reg())); 518 __ cmp(left.reg(), ShifterOperand(right.reg()));
508 } 519 }
509 520
510 if (branch != NULL) { 521 if (branch != NULL) {
511 branch->EmitBranchOnCondition(compiler, true_condition); 522 branch->EmitBranchOnCondition(compiler, true_condition);
512 } else { 523 } else {
513 Register result = locs.out().reg(); 524 Register result = locs.out().reg();
514 Label done, is_true; 525 __ LoadObject(result, Bool::True(), true_condition);
515 __ b(&is_true, true_condition); 526 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
516 __ LoadObject(result, Bool::False());
517 __ b(&done);
518 __ Bind(&is_true);
519 __ LoadObject(result, Bool::True());
520 __ Bind(&done);
521 } 527 }
522 } 528 }
523 529
524 530
525 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler, 531 static void EmitUnboxedMintEqualityOp(FlowGraphCompiler* compiler,
526 const LocationSummary& locs, 532 const LocationSummary& locs,
527 Token::Kind kind, 533 Token::Kind kind,
528 BranchInstr* branch) { 534 BranchInstr* branch) {
529 UNIMPLEMENTED(); 535 UNIMPLEMENTED();
530 } 536 }
(...skipping 1582 matching lines...) Expand 10 before | Expand all | Expand 10 after
2113 } 2119 }
2114 2120
2115 // We can fall through if the successor is the next block in the list. 2121 // We can fall through if the successor is the next block in the list.
2116 // Otherwise, we need a jump. 2122 // Otherwise, we need a jump.
2117 if (!compiler->CanFallThroughTo(successor())) { 2123 if (!compiler->CanFallThroughTo(successor())) {
2118 __ b(compiler->GetJumpLabel(successor())); 2124 __ b(compiler->GetJumpLabel(successor()));
2119 } 2125 }
2120 } 2126 }
2121 2127
2122 2128
2123 static Condition NegateCondition(Condition condition) {
2124 switch (condition) {
2125 case EQ: return NE;
2126 case NE: return EQ;
2127 case LT: return GE;
2128 case LE: return GT;
2129 case GT: return LE;
2130 case GE: return LT;
2131 case CC: return CS;
2132 case LS: return HI;
2133 case HI: return LS;
2134 case CS: return CC;
2135 default:
2136 OS::Print("Error %d\n", condition);
2137 UNIMPLEMENTED();
2138 return EQ;
2139 }
2140 }
2141
2142
2143 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler, 2129 void ControlInstruction::EmitBranchOnValue(FlowGraphCompiler* compiler,
2144 bool value) { 2130 bool value) {
2145 if (value && !compiler->CanFallThroughTo(true_successor())) { 2131 if (value && !compiler->CanFallThroughTo(true_successor())) {
2146 __ b(compiler->GetJumpLabel(true_successor())); 2132 __ b(compiler->GetJumpLabel(true_successor()));
2147 } else if (!value && !compiler->CanFallThroughTo(false_successor())) { 2133 } else if (!value && !compiler->CanFallThroughTo(false_successor())) {
2148 __ b(compiler->GetJumpLabel(false_successor())); 2134 __ b(compiler->GetJumpLabel(false_successor()));
2149 } 2135 }
2150 } 2136 }
2151 2137
2152 2138
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 compiler->EmitEqualityRegConstCompare(left.reg(), 2200 compiler->EmitEqualityRegConstCompare(left.reg(),
2215 right.constant(), 2201 right.constant(),
2216 needs_number_check()); 2202 needs_number_check());
2217 } else { 2203 } else {
2218 compiler->EmitEqualityRegRegCompare(left.reg(), 2204 compiler->EmitEqualityRegRegCompare(left.reg(),
2219 right.reg(), 2205 right.reg(),
2220 needs_number_check()); 2206 needs_number_check());
2221 } 2207 }
2222 2208
2223 Register result = locs()->out().reg(); 2209 Register result = locs()->out().reg();
2224 Label load_true, done;
2225 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE; 2210 Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
2226 __ b(&load_true, true_condition); 2211 __ LoadObject(result, Bool::True(), true_condition);
2227 __ LoadObject(result, Bool::False()); 2212 __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
2228 __ b(&done);
2229 __ Bind(&load_true);
2230 __ LoadObject(result, Bool::True());
2231 __ Bind(&done);
2232 } 2213 }
2233 2214
2234 2215
2235 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 2216 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
2236 BranchInstr* branch) { 2217 BranchInstr* branch) {
2237 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT); 2218 ASSERT(kind() == Token::kEQ_STRICT || kind() == Token::kNE_STRICT);
2238 Location left = locs()->in(0); 2219 Location left = locs()->in(0);
2239 Location right = locs()->in(1); 2220 Location right = locs()->in(1);
2240 if (left.IsConstant() && right.IsConstant()) { 2221 if (left.IsConstant() && right.IsConstant()) {
2241 // TODO(vegorov): should be eliminated earlier by constant propagation. 2222 // TODO(vegorov): should be eliminated earlier by constant propagation.
(...skipping 26 matching lines...) Expand all
2268 return LocationSummary::Make(1, 2249 return LocationSummary::Make(1,
2269 Location::RequiresRegister(), 2250 Location::RequiresRegister(),
2270 LocationSummary::kNoCall); 2251 LocationSummary::kNoCall);
2271 } 2252 }
2272 2253
2273 2254
2274 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2255 void BooleanNegateInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
2275 Register value = locs()->in(0).reg(); 2256 Register value = locs()->in(0).reg();
2276 Register result = locs()->out().reg(); 2257 Register result = locs()->out().reg();
2277 2258
2278 Label done;
2279 __ LoadObject(result, Bool::True()); 2259 __ LoadObject(result, Bool::True());
2280 __ cmp(result, ShifterOperand(value)); 2260 __ cmp(result, ShifterOperand(value));
2281 __ b(&done, NE); 2261 __ LoadObject(result, Bool::False(), EQ);
2282 __ LoadObject(result, Bool::False());
2283 __ Bind(&done);
2284 } 2262 }
2285 2263
2286 2264
2287 LocationSummary* ChainContextInstr::MakeLocationSummary() const { 2265 LocationSummary* ChainContextInstr::MakeLocationSummary() const {
2288 UNIMPLEMENTED(); 2266 UNIMPLEMENTED();
2289 return NULL; 2267 return NULL;
2290 } 2268 }
2291 2269
2292 2270
2293 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) { 2271 void ChainContextInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2338 &label, 2316 &label,
2339 PcDescriptors::kOther, 2317 PcDescriptors::kOther,
2340 locs()); 2318 locs());
2341 __ Drop(2); // Discard type arguments and receiver. 2319 __ Drop(2); // Discard type arguments and receiver.
2342 } 2320 }
2343 2321
2344 } // namespace dart 2322 } // namespace dart
2345 2323
2346 #endif // defined TARGET_ARCH_ARM 2324 #endif // defined TARGET_ARCH_ARM
2347 2325
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698