| OLD | NEW |
| 1 // | 1 // |
| 2 // The Subzero Code Generator | 2 // The Subzero Code Generator |
| 3 // | 3 // |
| 4 // This file is distributed under the University of Illinois Open Source | 4 // This file is distributed under the University of Illinois Open Source |
| 5 // License. See LICENSE.TXT for details. | 5 // License. See LICENSE.TXT for details. |
| 6 // | 6 // |
| 7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
| 8 /// | 8 /// |
| 9 /// \file | 9 /// \file |
| 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost | 10 /// \brief Implements the TargetLoweringMIPS32 class, which consists almost |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 | 552 |
| 553 void TargetMIPS32::CallingConv::discardUnavailableVFPRegsAndTheirAliases( | 553 void TargetMIPS32::CallingConv::discardUnavailableVFPRegsAndTheirAliases( |
| 554 CfgVector<RegNumT> *Regs) { | 554 CfgVector<RegNumT> *Regs) { |
| 555 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { | 555 while (!Regs->empty() && VFPRegsUsed[Regs->back()]) { |
| 556 Regs->pop_back(); | 556 Regs->pop_back(); |
| 557 } | 557 } |
| 558 } | 558 } |
| 559 | 559 |
| 560 void TargetMIPS32::lowerArguments() { | 560 void TargetMIPS32::lowerArguments() { |
| 561 VarList &Args = Func->getArgs(); | 561 VarList &Args = Func->getArgs(); |
| 562 // We are only handling integer registers for now. The Mips o32 ABI is | 562 TargetMIPS32::CallingConv CC; |
| 563 // somewhat complex but will be implemented in its totality through follow | 563 |
| 564 // on patches. | 564 // For each register argument, replace Arg in the argument list with the home |
| 565 // | 565 // register. Then generate an instruction in the prolog to copy the home |
| 566 unsigned NumGPRRegsUsed = 0; | 566 // register to the assigned location of Arg. |
| 567 // For each register argument, replace Arg in the argument list with the | |
| 568 // home register. Then generate an instruction in the prolog to copy the | |
| 569 // home register to the assigned location of Arg. | |
| 570 Context.init(Func->getEntryNode()); | 567 Context.init(Func->getEntryNode()); |
| 571 Context.setInsertPoint(Context.getCur()); | 568 Context.setInsertPoint(Context.getCur()); |
| 569 |
| 572 for (SizeT I = 0, E = Args.size(); I < E; ++I) { | 570 for (SizeT I = 0, E = Args.size(); I < E; ++I) { |
| 573 Variable *Arg = Args[I]; | 571 Variable *Arg = Args[I]; |
| 574 Type Ty = Arg->getType(); | 572 Type Ty = Arg->getType(); |
| 575 // TODO(rkotler): handle float/vector types. | 573 RegNumT RegNum; |
| 576 if (isVectorType(Ty)) { | 574 if (!CC.argInReg(Ty, I,&RegNum)) { |
| 577 UnimplementedError(getFlags()); | |
| 578 continue; | 575 continue; |
| 579 } | 576 } |
| 580 if (isFloatingType(Ty)) { | 577 Variable *RegisterArg = Func->makeVariable(Ty); |
| 581 UnimplementedError(getFlags()); | 578 if (BuildDefs::dump()) { |
| 582 continue; | 579 RegisterArg->setName(Func, "home_reg:" + Arg->getName()); |
| 583 } | 580 } |
| 584 if (Ty == IceType_i64) { | 581 RegisterArg->setIsArg(); |
| 585 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | 582 Arg->setIsArg(false); |
| 586 continue; | 583 Args[I] = RegisterArg; |
| 587 auto RegLo = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); | 584 switch (Ty) { |
| 588 auto RegHi = RegNumT::fixme(RegLo + 1); | 585 default: { RegisterArg->setRegNum(RegNum); } break; |
| 589 ++NumGPRRegsUsed; | 586 case IceType_i64: { |
| 590 // Always start i64 registers at an even register, so this may end | 587 auto *RegisterArg64 = llvm::cast<Variable64On32>(RegisterArg); |
| 591 // up padding away a register. | 588 RegisterArg64->initHiLo(Func); |
| 592 if (RegLo % 2 != 0) { | 589 RegisterArg64->getLo()->setRegNum( |
| 593 RegLo = RegNumT::fixme(RegLo + 1); | 590 RegNumT::fixme(RegMIPS32::getI64PairFirstGPRNum(RegNum))); |
| 594 ++NumGPRRegsUsed; | 591 RegisterArg64->getHi()->setRegNum( |
| 595 } | 592 RegNumT::fixme(RegMIPS32::getI64PairSecondGPRNum(RegNum))); |
| 596 // If this leaves us without room to consume another register, | 593 } break; |
| 597 // leave any previously speculatively consumed registers as consumed. | |
| 598 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | |
| 599 continue; | |
| 600 // RegHi = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); | |
| 601 ++NumGPRRegsUsed; | |
| 602 Variable *RegisterArg = Func->makeVariable(Ty); | |
| 603 auto *RegisterArg64On32 = llvm::cast<Variable64On32>(RegisterArg); | |
| 604 if (BuildDefs::dump()) | |
| 605 RegisterArg64On32->setName(Func, "home_reg:" + Arg->getName()); | |
| 606 RegisterArg64On32->initHiLo(Func); | |
| 607 RegisterArg64On32->setIsArg(); | |
| 608 RegisterArg64On32->getLo()->setRegNum(RegLo); | |
| 609 RegisterArg64On32->getHi()->setRegNum(RegHi); | |
| 610 Arg->setIsArg(false); | |
| 611 Args[I] = RegisterArg64On32; | |
| 612 Context.insert<InstAssign>(Arg, RegisterArg); | |
| 613 continue; | |
| 614 } else { | |
| 615 assert(Ty == IceType_i32); | |
| 616 if (NumGPRRegsUsed >= MIPS32_MAX_GPR_ARG) | |
| 617 continue; | |
| 618 const auto RegNum = RegNumT::fixme(RegMIPS32::Reg_A0 + NumGPRRegsUsed); | |
| 619 ++NumGPRRegsUsed; | |
| 620 Variable *RegisterArg = Func->makeVariable(Ty); | |
| 621 if (BuildDefs::dump()) { | |
| 622 RegisterArg->setName(Func, "home_reg:" + Arg->getName()); | |
| 623 } | |
| 624 RegisterArg->setRegNum(RegNum); | |
| 625 RegisterArg->setIsArg(); | |
| 626 Arg->setIsArg(false); | |
| 627 Args[I] = RegisterArg; | |
| 628 Context.insert<InstAssign>(Arg, RegisterArg); | |
| 629 } | 594 } |
| 595 Context.insert<InstAssign>(Arg, RegisterArg); |
| 630 } | 596 } |
| 631 } | 597 } |
| 632 | 598 |
| 633 Type TargetMIPS32::stackSlotType() { return IceType_i32; } | 599 Type TargetMIPS32::stackSlotType() { return IceType_i32; } |
| 634 | 600 |
| 635 void TargetMIPS32::addProlog(CfgNode *Node) { | 601 void TargetMIPS32::addProlog(CfgNode *Node) { |
| 636 (void)Node; | 602 (void)Node; |
| 637 return; | 603 return; |
| 638 UnimplementedError(getFlags()); | 604 UnimplementedError(getFlags()); |
| 639 } | 605 } |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1868 Str << "\t.set\t" | 1834 Str << "\t.set\t" |
| 1869 << "nomips16\n"; | 1835 << "nomips16\n"; |
| 1870 } | 1836 } |
| 1871 | 1837 |
| 1872 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; | 1838 SmallBitVector TargetMIPS32::TypeToRegisterSet[RCMIPS32_NUM]; |
| 1873 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; | 1839 SmallBitVector TargetMIPS32::TypeToRegisterSetUnfiltered[RCMIPS32_NUM]; |
| 1874 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; | 1840 SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM]; |
| 1875 | 1841 |
| 1876 } // end of namespace MIPS32 | 1842 } // end of namespace MIPS32 |
| 1877 } // end of namespace Ice | 1843 } // end of namespace Ice |
| OLD | NEW |