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

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
« no previous file with comments | « runtime/vm/constants_dbc.h ('k') | runtime/vm/simulator_dbc.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) 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 M(ExtractNthOutput) \ 95 M(ExtractNthOutput) \
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(TestSmi) \
106 M(RelationalOp) \ 105 M(RelationalOp) \
107 M(EqualityCompare) \ 106 M(EqualityCompare) \
108 M(LoadIndexed) 107 M(LoadIndexed)
109 108
110 // Location summaries actually are not used by the unoptimizing DBC compiler 109 // Location summaries actually are not used by the unoptimizing DBC compiler
111 // because we don't allocate any registers. 110 // because we don't allocate any registers.
112 static LocationSummary* CreateLocationSummary( 111 static LocationSummary* CreateLocationSummary(
113 Zone* zone, 112 Zone* zone,
114 intptr_t num_inputs, 113 intptr_t num_inputs,
115 Location output = Location::NoLocation(), 114 Location output = Location::NoLocation(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 UNIMPLEMENTED(); \ 150 UNIMPLEMENTED(); \
152 } 151 }
153 152
154 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \ 153 #define DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(Name) \
155 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \ 154 void Name##Instr::EmitBranchCode(FlowGraphCompiler*, BranchInstr*) { \
156 UNIMPLEMENTED(); \ 155 UNIMPLEMENTED(); \
157 } \ 156 } \
158 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \ 157 Condition Name##Instr::EmitComparisonCode(FlowGraphCompiler*, \
159 BranchLabels) { \ 158 BranchLabels) { \
160 UNIMPLEMENTED(); \ 159 UNIMPLEMENTED(); \
161 return EQ; \ 160 return NEXT_IS_TRUE; \
162 } 161 }
163 162
164 #define DEFINE_UNIMPLEMENTED(Name) \ 163 #define DEFINE_UNIMPLEMENTED(Name) \
165 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \ 164 DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name) \
166 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \ 165 DEFINE_UNIMPLEMENTED_EMIT_NATIVE_CODE(Name) \
167 166
168 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED) 167 FOR_EACH_UNIMPLEMENTED_INSTRUCTION(DEFINE_UNIMPLEMENTED)
169 168
170 #undef DEFINE_UNIMPLEMENTED 169 #undef DEFINE_UNIMPLEMENTED
171 170
172 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids) 171 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestCids)
173 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(TestSmi)
174 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp) 172 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(RelationalOp)
175 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare) 173 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
176 174
177 175
178 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(), 176 EMIT_NATIVE_CODE(InstanceOf, 2, Location::SameAsFirstInput(),
179 LocationSummary::kCall) { 177 LocationSummary::kCall) {
180 SubtypeTestCache& test_cache = SubtypeTestCache::Handle(); 178 SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
181 if (!type().IsVoidType() && type().IsInstantiated()) { 179 if (!type().IsVoidType() && type().IsInstantiated()) {
182 test_cache = SubtypeTestCache::New(); 180 test_cache = SubtypeTestCache::New();
183 } 181 }
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 373
376 if (compiler->is_optimizing()) { 374 if (compiler->is_optimizing()) {
377 __ PopLocal(locs()->out(0).reg()); 375 __ PopLocal(locs()->out(0).reg());
378 } 376 }
379 } 377 }
380 378
381 379
382 static void EmitBranchOnCondition(FlowGraphCompiler* compiler, 380 static void EmitBranchOnCondition(FlowGraphCompiler* compiler,
383 Condition true_condition, 381 Condition true_condition,
384 BranchLabels labels) { 382 BranchLabels labels) {
385 if (labels.fall_through == labels.false_label) { 383 if (true_condition == NEXT_IS_TRUE) {
386 // If the next block is the false successor, fall through to it.
387 __ Jump(labels.true_label); 384 __ Jump(labels.true_label);
385 if (labels.fall_through != labels.false_label) {
386 __ Jump(labels.false_label);
387 }
388 } else { 388 } else {
389 // If the next block is not the false successor, branch to it. 389 ASSERT(true_condition == NEXT_IS_FALSE);
390 __ Jump(labels.false_label); 390 __ Jump(labels.false_label);
391
392 // Fall through or jump to the true successor.
393 if (labels.fall_through != labels.true_label) { 391 if (labels.fall_through != labels.true_label) {
394 __ Jump(labels.true_label); 392 __ Jump(labels.true_label);
395 } 393 }
396 } 394 }
397 } 395 }
398 396
399 397
400 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler, 398 Condition StrictCompareInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
401 BranchLabels labels) { 399 BranchLabels labels) {
402 ASSERT((kind() == Token::kNE_STRICT) || 400 ASSERT((kind() == Token::kNE_STRICT) ||
403 (kind() == Token::kEQ_STRICT)); 401 (kind() == Token::kEQ_STRICT));
404 402
403 Token::Kind comparison;
404 Condition condition;
405 if (labels.fall_through == labels.false_label) {
406 condition = NEXT_IS_TRUE;
407 comparison = kind();
408 } else {
409 // Flip comparision to save a jump.
410 condition = NEXT_IS_FALSE;
411 comparison = (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT
412 : Token::kEQ_STRICT;
413 }
414
405 if (!compiler->is_optimizing()) { 415 if (!compiler->is_optimizing()) {
406 const Bytecode::Opcode eq_op = needs_number_check() ? 416 const Bytecode::Opcode eq_op = needs_number_check() ?
407 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS; 417 Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS;
408 const Bytecode::Opcode ne_op = needs_number_check() ? 418 const Bytecode::Opcode ne_op = needs_number_check() ?
409 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS; 419 Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS;
410 420 __ Emit(comparison == Token::kEQ_STRICT ? eq_op : ne_op);
411 if (kind() == Token::kEQ_STRICT) {
412 __ Emit((labels.fall_through == labels.false_label) ? eq_op : ne_op);
413 } else {
414 __ Emit((labels.fall_through == labels.false_label) ? ne_op : eq_op);
415 }
416 } else { 421 } else {
417 const Bytecode::Opcode eq_op = needs_number_check() ? 422 const Bytecode::Opcode eq_op = needs_number_check() ?
418 Bytecode::kIfEqStrictNum : Bytecode::kIfEqStrict; 423 Bytecode::kIfEqStrictNum : Bytecode::kIfEqStrict;
419 const Bytecode::Opcode ne_op = needs_number_check() ? 424 const Bytecode::Opcode ne_op = needs_number_check() ?
420 Bytecode::kIfNeStrictNum : Bytecode::kIfNeStrict; 425 Bytecode::kIfNeStrictNum : Bytecode::kIfNeStrict;
421 426 __ Emit(Bytecode::Encode(
422 if (kind() == Token::kEQ_STRICT) { 427 (comparison == Token::kEQ_STRICT) ? eq_op : ne_op,
423 __ Emit(Bytecode::Encode( 428 locs()->in(0).reg(),
424 (labels.fall_through == labels.false_label) ? eq_op : ne_op, 429 locs()->in(1).reg()));
425 locs()->in(0).reg(),
426 locs()->in(1).reg()));
427 } else {
428 __ Emit(Bytecode::Encode(
429 (labels.fall_through == labels.false_label) ? ne_op : eq_op,
430 locs()->in(0).reg(),
431 locs()->in(1).reg()));
432 }
433 } 430 }
434 431
435 if (needs_number_check() && token_pos().IsReal()) { 432 if (needs_number_check() && token_pos().IsReal()) {
436 compiler->RecordSafepoint(locs()); 433 compiler->RecordSafepoint(locs());
437 compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall, 434 compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
438 Thread::kNoDeoptId, 435 Thread::kNoDeoptId,
439 token_pos()); 436 token_pos());
440 } 437 }
441 return EQ; 438
439 return condition;
442 } 440 }
443 441
444 442
445 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler, 443 void StrictCompareInstr::EmitBranchCode(FlowGraphCompiler* compiler,
446 BranchInstr* branch) { 444 BranchInstr* branch) {
447 ASSERT((kind() == Token::kEQ_STRICT) || 445 ASSERT((kind() == Token::kEQ_STRICT) ||
448 (kind() == Token::kNE_STRICT)); 446 (kind() == Token::kNE_STRICT));
449 447
450 BranchLabels labels = compiler->CreateBranchLabels(branch); 448 BranchLabels labels = compiler->CreateBranchLabels(branch);
451 Condition true_condition = EmitComparisonCode(compiler, labels); 449 Condition true_condition = EmitComparisonCode(compiler, labels);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move()); 512 compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
515 } 513 }
516 // We can fall through if the successor is the next block in the list. 514 // We can fall through if the successor is the next block in the list.
517 // Otherwise, we need a jump. 515 // Otherwise, we need a jump.
518 if (!compiler->CanFallThroughTo(successor())) { 516 if (!compiler->CanFallThroughTo(successor())) {
519 __ Jump(compiler->GetJumpLabel(successor())); 517 __ Jump(compiler->GetJumpLabel(successor()));
520 } 518 }
521 } 519 }
522 520
523 521
522 Condition TestSmiInstr::EmitComparisonCode(FlowGraphCompiler* compiler,
523 BranchLabels labels) {
524 ASSERT((kind() == Token::kEQ) ||
525 (kind() == Token::kNE));
526 Register left = locs()->in(0).reg();
527 Register right = locs()->in(1).reg();
528 __ TestSmi(left, right);
529 return (kind() == Token::kEQ) ? NEXT_IS_TRUE : NEXT_IS_FALSE;
530 }
531
532
533 void TestSmiInstr::EmitBranchCode(FlowGraphCompiler* compiler,
534 BranchInstr* branch) {
535 BranchLabels labels = compiler->CreateBranchLabels(branch);
536 Condition true_condition = EmitComparisonCode(compiler, labels);
537 EmitBranchOnCondition(compiler, true_condition, labels);
538 }
539
540
541 EMIT_NATIVE_CODE(TestSmi,
542 2,
543 Location::RequiresRegister(),
544 LocationSummary::kNoCall) {
545 // Never emitted outside of the BranchInstr.
546 UNREACHABLE();
547 }
548
549
524 EMIT_NATIVE_CODE(CreateArray, 550 EMIT_NATIVE_CODE(CreateArray,
525 2, Location::RequiresRegister(), 551 2, Location::RequiresRegister(),
526 LocationSummary::kCall) { 552 LocationSummary::kCall) {
527 if (compiler->is_optimizing()) { 553 if (compiler->is_optimizing()) {
528 __ Push(locs()->in(0).reg()); 554 __ Push(locs()->in(0).reg());
529 __ Push(locs()->in(1).reg()); 555 __ Push(locs()->in(1).reg());
530 } 556 }
531 __ CreateArrayTOS(); 557 __ CreateArrayTOS();
532 compiler->RecordSafepoint(locs()); 558 compiler->RecordSafepoint(locs());
533 if (compiler->is_optimizing()) { 559 if (compiler->is_optimizing()) {
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg()); 1159 __ BitNot(locs()->out(0).reg(), locs()->in(0).reg());
1134 break; 1160 break;
1135 default: 1161 default:
1136 UNREACHABLE(); 1162 UNREACHABLE();
1137 } 1163 }
1138 } 1164 }
1139 1165
1140 } // namespace dart 1166 } // namespace dart
1141 1167
1142 #endif // defined TARGET_ARCH_DBC 1168 #endif // defined TARGET_ARCH_DBC
OLDNEW
« no previous file with comments | « runtime/vm/constants_dbc.h ('k') | runtime/vm/simulator_dbc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698