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

Side by Side Diff: src/compiler/mips/code-generator-mips.cc

Issue 745633002: [turbofan] Clean up and factor out branch generation logic. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix IA32 fall through. Created 6 years, 1 month 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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/code-generator.h" 5 #include "src/compiler/code-generator.h"
6 #include "src/compiler/code-generator-impl.h" 6 #include "src/compiler/code-generator-impl.h"
7 #include "src/compiler/gap-resolver.h" 7 #include "src/compiler/gap-resolver.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties-inl.h" 9 #include "src/compiler/node-properties-inl.h"
10 #include "src/mips/macro-assembler-mips.h" 10 #include "src/mips/macro-assembler-mips.h"
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset)); 147 __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
148 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg)); 148 __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
149 } 149 }
150 150
151 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset)); 151 __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
152 __ Call(at); 152 __ Call(at);
153 AddSafepointAndDeopt(instr); 153 AddSafepointAndDeopt(instr);
154 break; 154 break;
155 } 155 }
156 case kArchJmp: 156 case kArchJmp:
157 __ Branch(GetLabel(i.InputRpo(0))); 157 AssembleArchJump(i.InputRpo(0));
158 break; 158 break;
159 case kArchNop: 159 case kArchNop:
160 // don't emit code for nops. 160 // don't emit code for nops.
161 break; 161 break;
162 case kArchRet: 162 case kArchRet:
163 AssembleReturn(); 163 AssembleReturn();
164 break; 164 break;
165 case kArchStackPointer: 165 case kArchStackPointer:
166 __ mov(i.OutputRegister(), sp); 166 __ mov(i.OutputRegister(), sp);
167 break; 167 break;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 387
388 #define UNSUPPORTED_COND(opcode, condition) \ 388 #define UNSUPPORTED_COND(opcode, condition) \
389 OFStream out(stdout); \ 389 OFStream out(stdout); \
390 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \ 390 out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
391 UNIMPLEMENTED(); 391 UNIMPLEMENTED();
392 392
393 // Assembles branches after an instruction. 393 // Assembles branches after an instruction.
394 void CodeGenerator::AssembleArchBranch(Instruction* instr, 394 void CodeGenerator::AssembleArchBranch(Instruction* instr,
395 FlagsCondition condition) { 395 FlagsCondition condition) {
396 MipsOperandConverter i(this, instr); 396 MipsOperandConverter i(this, instr);
397 Label done; 397 Label* tlabel = branch->true_label;
398 398 Label* flabel = branch->false_label;
399 // Emit a branch. The true and false targets are always the last two inputs
400 // to the instruction.
401 BasicBlock::RpoNumber tblock =
402 i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
403 BasicBlock::RpoNumber fblock =
404 i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
405 bool fallthru = IsNextInAssemblyOrder(fblock);
406 Label* tlabel = GetLabel(tblock);
407 Label* flabel = fallthru ? &done : GetLabel(fblock);
408 Condition cc = kNoCondition; 399 Condition cc = kNoCondition;
409 400
410 // MIPS does not have condition code flags, so compare and branch are 401 // MIPS does not have condition code flags, so compare and branch are
411 // implemented differently than on the other arch's. The compare operations 402 // implemented differently than on the other arch's. The compare operations
412 // emit mips psuedo-instructions, which are handled here by branch 403 // emit mips pseudo-instructions, which are handled here by branch
413 // instructions that do the actual comparison. Essential that the input 404 // instructions that do the actual comparison. Essential that the input
414 // registers to compare psuedo-op are not modified before this branch op, as 405 // registers to compare pseudo-op are not modified before this branch op, as
415 // they are tested here. 406 // they are tested here.
416 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were 407 // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
417 // not separated by other instructions. 408 // not separated by other instructions.
418 409
419 if (instr->arch_opcode() == kMipsTst) { 410 if (instr->arch_opcode() == kMipsTst) {
420 switch (condition) { 411 switch (branch->condition) {
421 case kNotEqual: 412 case kNotEqual:
422 cc = ne; 413 cc = ne;
423 break; 414 break;
424 case kEqual: 415 case kEqual:
425 cc = eq; 416 cc = eq;
426 break; 417 break;
427 default: 418 default:
428 UNSUPPORTED_COND(kMipsTst, condition); 419 UNSUPPORTED_COND(kMipsTst, condition);
429 break; 420 break;
430 } 421 }
431 __ And(at, i.InputRegister(0), i.InputOperand(1)); 422 __ And(at, i.InputRegister(0), i.InputOperand(1));
432 __ Branch(tlabel, cc, at, Operand(zero_reg)); 423 __ Branch(tlabel, cc, at, Operand(zero_reg));
433 424
434 } else if (instr->arch_opcode() == kMipsAddOvf || 425 } else if (instr->arch_opcode() == kMipsAddOvf ||
435 instr->arch_opcode() == kMipsSubOvf) { 426 instr->arch_opcode() == kMipsSubOvf) {
436 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow. 427 // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
437 switch (condition) { 428 switch (branch->condition) {
438 case kOverflow: 429 case kOverflow:
439 cc = lt; 430 cc = lt;
440 break; 431 break;
441 case kNotOverflow: 432 case kNotOverflow:
442 cc = ge; 433 cc = ge;
443 break; 434 break;
444 default: 435 default:
445 UNSUPPORTED_COND(kMipsAddOvf, condition); 436 UNSUPPORTED_COND(kMipsAddOvf, branch->condition);
446 break; 437 break;
447 } 438 }
448 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg)); 439 __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
449 440
450 } else if (instr->arch_opcode() == kMipsCmp) { 441 } else if (instr->arch_opcode() == kMipsCmp) {
451 switch (condition) { 442 switch (branch->condition) {
452 case kEqual: 443 case kEqual:
453 cc = eq; 444 cc = eq;
454 break; 445 break;
455 case kNotEqual: 446 case kNotEqual:
456 cc = ne; 447 cc = ne;
457 break; 448 break;
458 case kSignedLessThan: 449 case kSignedLessThan:
459 cc = lt; 450 cc = lt;
460 break; 451 break;
461 case kSignedGreaterThanOrEqual: 452 case kSignedGreaterThanOrEqual:
(...skipping 11 matching lines...) Expand all
473 case kUnsignedGreaterThanOrEqual: 464 case kUnsignedGreaterThanOrEqual:
474 cc = hs; 465 cc = hs;
475 break; 466 break;
476 case kUnsignedLessThanOrEqual: 467 case kUnsignedLessThanOrEqual:
477 cc = ls; 468 cc = ls;
478 break; 469 break;
479 case kUnsignedGreaterThan: 470 case kUnsignedGreaterThan:
480 cc = hi; 471 cc = hi;
481 break; 472 break;
482 default: 473 default:
483 UNSUPPORTED_COND(kMipsCmp, condition); 474 UNSUPPORTED_COND(kMipsCmp, branch->condition);
484 break; 475 break;
485 } 476 }
486 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1)); 477 __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
487 478
488 if (!fallthru) __ Branch(flabel); // no fallthru to flabel. 479 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel.
489 __ bind(&done);
490 480
491 } else if (instr->arch_opcode() == kMipsCmpD) { 481 } else if (instr->arch_opcode() == kMipsCmpD) {
492 // TODO(dusmil) optimize unordered checks to use less instructions 482 // TODO(dusmil) optimize unordered checks to use fewer instructions
493 // even if we have to unfold BranchF macro. 483 // even if we have to unfold BranchF macro.
494 Label* nan = flabel; 484 Label* nan = flabel;
495 switch (condition) { 485 switch (branch->condition) {
496 case kUnorderedEqual: 486 case kUnorderedEqual:
497 cc = eq; 487 cc = eq;
498 break; 488 break;
499 case kUnorderedNotEqual: 489 case kUnorderedNotEqual:
500 cc = ne; 490 cc = ne;
501 nan = tlabel; 491 nan = tlabel;
502 break; 492 break;
503 case kUnorderedLessThan: 493 case kUnorderedLessThan:
504 cc = lt; 494 cc = lt;
505 break; 495 break;
506 case kUnorderedGreaterThanOrEqual: 496 case kUnorderedGreaterThanOrEqual:
507 cc = ge; 497 cc = ge;
508 nan = tlabel; 498 nan = tlabel;
509 break; 499 break;
510 case kUnorderedLessThanOrEqual: 500 case kUnorderedLessThanOrEqual:
511 cc = le; 501 cc = le;
512 break; 502 break;
513 case kUnorderedGreaterThan: 503 case kUnorderedGreaterThan:
514 cc = gt; 504 cc = gt;
515 nan = tlabel; 505 nan = tlabel;
516 break; 506 break;
517 default: 507 default:
518 UNSUPPORTED_COND(kMipsCmpD, condition); 508 UNSUPPORTED_COND(kMipsCmpD, branch->condition);
519 break; 509 break;
520 } 510 }
521 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0), 511 __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
522 i.InputDoubleRegister(1)); 512 i.InputDoubleRegister(1));
523 513
524 if (!fallthru) __ Branch(flabel); // no fallthru to flabel. 514 if (!branch->fallthru) __ Branch(flabel); // no fallthru to flabel.
525 __ bind(&done);
526 515
527 } else { 516 } else {
528 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n", 517 PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
529 instr->arch_opcode()); 518 instr->arch_opcode());
530 UNIMPLEMENTED(); 519 UNIMPLEMENTED();
531 } 520 }
532 } 521 }
533 522
534 523
524 void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
525 if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
526 }
527
528
535 // Assembles boolean materializations after an instruction. 529 // Assembles boolean materializations after an instruction.
536 void CodeGenerator::AssembleArchBoolean(Instruction* instr, 530 void CodeGenerator::AssembleArchBoolean(Instruction* instr,
537 FlagsCondition condition) { 531 FlagsCondition condition) {
538 MipsOperandConverter i(this, instr); 532 MipsOperandConverter i(this, instr);
539 Label done; 533 Label done;
540 534
541 // Materialize a full 32-bit 1 or 0 value. The result register is always the 535 // Materialize a full 32-bit 1 or 0 value. The result register is always the
542 // last output of the instruction. 536 // last output of the instruction.
543 Label false_value; 537 Label false_value;
544 DCHECK_NE(0, instr->OutputCount()); 538 DCHECK_NE(0, instr->OutputCount());
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
943 } 937 }
944 } 938 }
945 MarkLazyDeoptSite(); 939 MarkLazyDeoptSite();
946 } 940 }
947 941
948 #undef __ 942 #undef __
949 943
950 } // namespace compiler 944 } // namespace compiler
951 } // namespace internal 945 } // namespace internal
952 } // namespace v8 946 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector-impl.h ('k') | src/compiler/mips/instruction-selector-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698