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

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

Issue 2113523002: DBC: Implement TestSmi instruction. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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_DBC. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC.
6 #if defined(TARGET_ARCH_DBC) 6 #if defined(TARGET_ARCH_DBC)
7 7
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 9
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 M(BinaryUint32Op) \ 96 M(BinaryUint32Op) \
97 M(ShiftUint32Op) \ 97 M(ShiftUint32Op) \
98 M(UnaryUint32Op) \ 98 M(UnaryUint32Op) \
99 M(UnboxedIntConverter) \ 99 M(UnboxedIntConverter) \
100 M(GrowRegExpStack) \ 100 M(GrowRegExpStack) \
101 M(BoxInteger32) \ 101 M(BoxInteger32) \
102 M(UnboxInteger32) \ 102 M(UnboxInteger32) \
103 M(CheckedSmiOp) \ 103 M(CheckedSmiOp) \
104 M(CheckArrayBound) \ 104 M(CheckArrayBound) \
105 M(CheckClass) \ 105 M(CheckClass) \
106 M(TestSmi) \
107 M(RelationalOp) \ 106 M(RelationalOp) \
108 M(EqualityCompare) \ 107 M(EqualityCompare) \
109 M(LoadIndexed) 108 M(LoadIndexed)
110 109
111 // Location summaries actually are not used by the unoptimizing DBC compiler 110 // Location summaries actually are not used by the unoptimizing DBC compiler
112 // because we don't allocate any registers. 111 // because we don't allocate any registers.
113 static LocationSummary* CreateLocationSummary( 112 static LocationSummary* CreateLocationSummary(
114 Zone* zone, 113 Zone* zone,
115 intptr_t num_inputs, 114 intptr_t num_inputs,
116 Location output = Location::NoLocation(), 115 Location output = Location::NoLocation(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 UNIMPLEMENTED(); \ 151 UNIMPLEMENTED(); \
153 } 152 }
154 153
155 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \ 154 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \
156 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \ 155 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \
157 UNIMPLEMENTED(); \ 156 UNIMPLEMENTED(); \
158 } \ 157 } \
159 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \ 158 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \
160 BranchLabels) { \ 159 BranchLabels) { \
161 UNIMPLEMENTED(); \ 160 UNIMPLEMENTED(); \
162 return EQ; \ 161 return NEXT_IS_TRUE; \
163 } 162 }
164 163
165 #define DEFINE_UNIMPLEMENTED(Name) \ 164 #define DEFINE_UNIMPLEMENTED(Name) \
166 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \ 165 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \
167 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \ 166 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \
168 167
169 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED) 168 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED)
170 169
171 #undef DEFINE_UNIMPLEMENTED 170 #undef DEFINE_UNIMPLEMENTED
172 171
173 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids) 172 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids)
174 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestSmi)
175 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp) 173 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp)
176 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare) 174 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
177 175
178 176
179 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(), 177 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(),
180 LocationSummary::kCall) { 178 LocationSummary::kCall) {
181 SubtypeTestCache& test_cache = SubtypeTestCache::Handle(); 179 SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
182 if (!type().IsVoidType() && type().IsInstantiated()) { 180 if (!type().IsVoidType() && type().IsInstantiated()) {
183 test_cache = SubtypeTestCache::New(); 181 test_cache = SubtypeTestCache::New();
184 } 182 }
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 374
377 if (compiler->is_optimizing()) { 375 if (compiler->is_optimizing()) {
378 __ PopLocal(locs()->out(0).reg()); 376 __ PopLocal(locs()->out(0).reg());
379 } 377 }
380 } 378 }
381 379
382 380
383 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 381 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
384 Condition true_condition, 382 Condition true_condition,
385 BranchLabels labels) { 383 BranchLabels labels) {
386 if (labels.fall_through == labels.false_label) { 384 if (true_condition == NEXT_IS_TRUE) {
387 // If the next block is the false successor, fall through to it.
388 __ Jump(labels.true_label); 385 __ Jump(labels.true_label);
386 if (labels.fall_through != labels.false_label) {
387 __ Jump(labels.false_label);
388 }
389 } else { 389 } else {
390 // If the next block is not the false successor, branch to it. 390 ASSERT(true_condition == NEXT_IS_FALSE);
391 __ Jump(labels.false_label); 391 __ Jump(labels.false_label);
392
393 // Fall through or jump to the true successor.
394 if (labels.fall_through != labels.true_label) { 392 if (labels.fall_through != labels.true_label) {
395 __ Jump(labels.true_label); 393 __ Jump(labels.true_label);
396 } 394 }
397 } 395 }
398 } 396 }
399 397
400 398
401 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 399 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
402 BranchLabels labels) { 400 BranchLabels labels) {
403 ASSERT((kind() == Token::kNE_STRICT) || 401 ASSERT((kind() == Token::kNE_STRICT) ||
404 (kind() == Token::kEQ_STRICT)); 402 (kind() == Token::kEQ_STRICT));
405 403
404 Token::Kind comparison;
405 Condition condition;
406 if (labels.fall_through == labels.false_label) {
407 condition = NEXT_IS_TRUE;
408 comparison = kind();
409 } else {
410 // Flip comparision to save a jump.
411 condition = NEXT_IS_FALSE;
412 comparison = (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT
413 : Token::kEQ_STRICT;
414 }
415
406 if (!compiler->is_optimizing()) { 416 if (!compiler->is_optimizing()) {
407 const Bytecode::Opcode eq_op = needs_number_check() ? 417 const Bytecode::Opcode eq_op = needs_number_check() ?
408 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS; 418 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS;
409 const Bytecode::Opcode ne_op = needs_number_check() ? 419 const Bytecode::Opcode ne_op = needs_number_check() ?
410 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS; 420 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS;
411 421 __ Emit(comparison == Token::kEQ_STRICT ? eq_op : ne_op);
412 if (kind() == Token::kEQ_STRICT) {
413 __ Emit((labels.fall_through == labels.false_label) ? eq_op : ne_op);
414 } else {
415 __ Emit((labels.fall_through == labels.false_label) ? ne_op : eq_op);
416 }
417 } else { 422 } else {
418 const Bytecode::Opcode eq_op = needs_number_check() ? 423 const Bytecode::Opcode eq_op = needs_number_check() ?
419 Bytecode::kIfEqStrictNum : Bytecode::kIfEqStrict; 424 Bytecode::kIfEqStrictNum : Bytecode::kIfEqStrict;
420 const Bytecode::Opcode ne_op = needs_number_check() ? 425 const Bytecode::Opcode ne_op = needs_number_check() ?
421 Bytecode::kIfNeStrictNum : Bytecode::kIfNeStrict; 426 Bytecode::kIfNeStrictNum : Bytecode::kIfNeStrict;
422 427 __ Emit(Bytecode::Encode(
423 if (kind() == Token::kEQ_STRICT) { 428 (comparison == Token::kEQ_STRICT) ? eq_op : ne_op,
424 __ Emit(Bytecode::Encode( 429 locs()->in(0).reg(),
425 (labels.fall_through == labels.false_label) ? eq_op : ne_op, 430 locs()->in(1).reg()));
426 locs()->in(0).reg(),
427 locs()->in(1).reg()));
428 } else {
429 __ Emit(Bytecode::Encode(
430 (labels.fall_through == labels.false_label) ? ne_op : eq_op,
431 locs()->in(0).reg(),
432 locs()->in(1).reg()));
433 }
434 } 431 }
435 432
436 if (needs_number_check() && token_pos().IsReal()) { 433 if (needs_number_check() && token_pos().IsReal()) {
437 compiler->RecordSafepoint(locs()); 434 compiler->RecordSafepoint(locs());
438 compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 435 compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
439 Thread::kNoDeoptId, 436 Thread::kNoDeoptId,
440 token_pos()); 437 token_pos());
441 } 438 }
442 return EQ; 439
440 return condition;
443 } 441 }
444 442
445 443
446 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 444 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
447 BranchInstr* branch) { 445 BranchInstr* branch) {
448 ASSERT((kind() == Token::kEQ_STRICT) || 446 ASSERT((kind() == Token::kEQ_STRICT) ||
449 (kind() == Token::kNE_STRICT)); 447 (kind() == Token::kNE_STRICT));
450 448
451 BranchLabels labels = compiler->CreateBranchLabels(branch); 449 BranchLabels labels = compiler->CreateBranchLabels(branch);
452 Condition true_condition = EmitComparisonCode(compiler, labels); 450 Condition true_condition = EmitComparisonCode(compiler, labels);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 506 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
509 } 507 }
510 // We can fall through if the successor is the next block in the list. 508 // We can fall through if the successor is the next block in the list.
511 // Otherwise, we need a jump. 509 // Otherwise, we need a jump.
512 if (!compiler->CanFallThroughTo(successor())) { 510 if (!compiler->CanFallThroughTo(successor())) {
513 __ Jump(compiler->GetJumpLabel(successor())); 511 __ Jump(compiler->GetJumpLabel(successor()));
514 } 512 }
515 } 513 }
516 514
517 515
516 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
517 BranchLabels labels) {
518 ASSERT((kind() == Token::kEQ) ||
519 (kind() == Token::kNE));
520 Register left = locs()->in(0).reg();
521 Register right = locs()->in(1).reg();
522 __ TestSmi(left, right);
523 return (kind() == Token::kEQ) ? NEXT_IS_TRUE : NEXT_IS_FALSE;
524 }
525
526
527 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
528 BranchInstr* branch) {
529 BranchLabels labels = compiler->CreateBranchLabels(branch);
530 Condition true_condition = EmitComparisonCode(compiler, labels);
531 EmitBranchOnCondition(compiler, true_condition, labels);
532 }
533
534
535 EMIT_NATIVE_CODE(TestSmi,
536 2,
537 Location::RequiresRegister(),
538 LocationSummary::kNoCall) {
539 // Never emitted outside of the BranchInstr.
540 UNREACHABLE();
541 }
542
543
518 EMIT_NATIVE_CODE(CreateArray, 544 EMIT_NATIVE_CODE(CreateArray,
519 2, Location::RequiresRegister(), 545 2, Location::RequiresRegister(),
520 LocationSummary::kCall) { 546 LocationSummary::kCall) {
521 if (compiler->is_optimizing()) { 547 if (compiler->is_optimizing()) {
522 __ Push(locs()->in(0).reg()); 548 __ Push(locs()->in(0).reg());
523 __ Push(locs()->in(1).reg()); 549 __ Push(locs()->in(1).reg());
524 } 550 }
525 __ CreateArrayTOS(); 551 __ CreateArrayTOS();
526 compiler->RecordSafepoint(locs()); 552 compiler->RecordSafepoint(locs());
527 if (compiler->is_optimizing()) { 553 if (compiler->is_optimizing()) {
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
1058 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg()); 1084 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg());
1059 break; 1085 break;
1060 default: 1086 default:
1061 UNREACHABLE(); 1087 UNREACHABLE();
1062 } 1088 }
1063 } 1089 }
1064 1090
1065 } // namespace dart 1091 } // namespace dart
1066 1092
1067 #endif // defined TARGET_ARCH_DBC 1093 #endif // defined TARGET_ARCH_DBC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698