diff options
| author | Simon Dardis <simon.dardis@imgtec.com> | 2016-04-05 12:50:29 +0000 | 
|---|---|---|
| committer | Simon Dardis <simon.dardis@imgtec.com> | 2016-04-05 12:50:29 +0000 | 
| commit | d9d41f531ef63ecf14472df29c68d8113284f051 (patch) | |
| tree | 43394adb2c652f5c9a3c9e3b627c563dc43331a7 /llvm/lib/Target | |
| parent | c79979299aea78ae516bea2ecb25e4d4add37f08 (diff) | |
| download | bcm5719-llvm-d9d41f531ef63ecf14472df29c68d8113284f051.tar.gz bcm5719-llvm-d9d41f531ef63ecf14472df29c68d8113284f051.zip | |
[mips] MIPSR6 Compact jump support
This patch adds support for compact jumps similiar to the previous compact
branch support for MIPSR6. Unlike compact branches, compact jumps do not
have a forbidden slot.
As MipsInstrInfo::getEquivalentCompactForm can determine the correct
expansion for jumps and branches for both microMIPS and MIPSR6, remove the
unnecessary distinction in the delay slot filler.
Reviewers: vkalintiris
Subscribers: llvm-commits, dsanders
llvm-svn: 265390
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/Mips64r6InstrInfo.td | 17 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 49 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.cpp | 106 | 
4 files changed, 109 insertions, 67 deletions
| diff --git a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td index f3bd2bf275f..3e2c8293c26 100644 --- a/llvm/lib/Target/Mips/Mips32r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips32r6InstrInfo.td @@ -412,10 +412,11 @@ class JMP_IDX_COMPACT_DESC_BASE<string opstr, DAGOperand opnd,    dag InOperandList = (ins GPROpnd:$rt, opnd:$offset);    string AsmString = !strconcat(opstr, "\t$rt, $offset");    list<dag> Pattern = []; -  bit isTerminator = 1;    bit hasDelaySlot = 0;    InstrItinClass Itinerary = itin;    bit isCTI = 1; +  bit isBranch = 1; +  bit isIndirectBranch = 1;  }  class JIALC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jialc", calloffset16, @@ -427,6 +428,7 @@ class JIALC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jialc", calloffset16,  class JIC_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16,                                             GPR32Opnd, II_JIALC> {    bit isBarrier = 1; +  bit isTerminator = 1;    list<Register> Defs = [AT];  } diff --git a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td index b2fc9111170..d11f2a2890a 100644 --- a/llvm/lib/Target/Mips/Mips64r6InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64r6InstrInfo.td @@ -76,6 +76,18 @@ class SCD_R6_DESC   : SC_R6_DESC_BASE<"scd", GPR64Opnd, II_SCD>;  class SELEQZ64_DESC : SELEQNE_Z_DESC_BASE<"seleqz", GPR64Opnd>;  class SELNEZ64_DESC : SELEQNE_Z_DESC_BASE<"selnez", GPR64Opnd>; +class JIALC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jialc", calloffset16, +                                             GPR64Opnd> { +  bit isCall = 1; +  list<Register> Defs = [RA]; +} + +class JIC64_DESC : JMP_IDX_COMPACT_DESC_BASE<"jic", jmpoffset16, GPR64Opnd> { +  bit isBarrier = 1; +  bit isTerminator = 1; +  list<Register> Defs = [AT]; +} +  //===----------------------------------------------------------------------===//  //  // Instruction Definitions @@ -107,7 +119,10 @@ let DecoderNamespace = "Mips32r6_64r6_GP64" in {    def SELEQZ64 : SELEQZ_ENC, SELEQZ64_DESC, ISA_MIPS32R6, GPR_64;    def SELNEZ64 : SELNEZ_ENC, SELNEZ64_DESC, ISA_MIPS32R6, GPR_64;  } - +let isCodeGenOnly = 1 in { +def JIALC64 : JIALC_ENC, JIALC64_DESC, ISA_MIPS64R6; +def JIC64 : JIC_ENC, JIC64_DESC, ISA_MIPS64R6; +}  //===----------------------------------------------------------------------===//  //  // Instruction Aliases diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index a40b51cb19f..0a7ffb10153 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -205,9 +205,6 @@ namespace {      Iter replaceWithCompactBranch(MachineBasicBlock &MBB,                                    Iter Branch, DebugLoc DL); -    Iter replaceWithCompactJump(MachineBasicBlock &MBB, -                                Iter Jump, DebugLoc DL); -      /// This function checks if it is valid to move Candidate to the delay slot      /// and returns true if it isn't. It also updates memory and register      /// dependence information. @@ -522,24 +519,6 @@ Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB,    return Branch;  } -// Replace Jumps with the compact jump instruction. -Iter Filler::replaceWithCompactJump(MachineBasicBlock &MBB, -                                    Iter Jump, DebugLoc DL) { -  const MipsInstrInfo *TII = -      MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo(); - -  const MCInstrDesc &NewDesc = TII->get(Mips::JRC16_MM); -  MachineInstrBuilder MIB = BuildMI(MBB, Jump, DL, NewDesc); - -  MIB.addReg(Jump->getOperand(0).getReg()); - -  Iter tmpIter = Jump; -  Jump = std::prev(Jump); -  MBB.erase(tmpIter); - -  return Jump; -} -  // For given opcode returns opcode of corresponding instruction with short  // delay slot.  static int getEquivalentCallShort(int Opcode) { @@ -604,31 +583,21 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {            // corresponding instruction with short delay slot.            DSI->setDesc(TII->get(getEquivalentCallShort(DSI->getOpcode())));          } -          continue;        }      } -    // If instruction is BEQ or BNE with one ZERO register, then instead of -    // adding NOP replace this instruction with the corresponding compact -    // branch instruction, i.e. BEQZC or BNEZC. -    if (InMicroMipsMode) { -      if (TII->getEquivalentCompactForm(I)) { -        I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); -        continue; -      } - -      if (I->isIndirectBranch() || I->isReturn()) { -        // For microMIPS the PseudoReturn and PseudoIndirectBranch are always -        // expanded to JR_MM, so they can be replaced with JRC16_MM. -        I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); -        continue; -      } -    } +    // For microMIPS if instruction is BEQ or BNE with one ZERO register, then +    // instead of adding NOP replace this instruction with the corresponding +    // compact branch instruction, i.e. BEQZC or BNEZC. Additionally +    // PseudoReturn and PseudoIndirectBranch are expanded to JR_MM, so they can +    // be replaced with JRC16_MM.      // For MIPSR6 attempt to produce the corresponding compact (no delay slot) -    // form of the branch. This should save putting in a NOP. -    if ((STI.hasMips32r6()) && TII->getEquivalentCompactForm(I)) { +    // form of the CTI. For indirect jumps this will not require inserting a +    // NOP and for branches will hopefully avoid requiring a NOP. +    if ((InMicroMipsMode || STI.hasMips32r6()) && +         TII->getEquivalentCompactForm(I)) {        I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());        continue;      } diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.cpp b/llvm/lib/Target/Mips/MipsInstrInfo.cpp index 84368d7b80f..0f4e820fb00 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.cpp +++ b/llvm/lib/Target/Mips/MipsInstrInfo.cpp @@ -261,24 +261,40 @@ MipsInstrInfo::BranchType MipsInstrInfo::AnalyzeBranch(  unsigned MipsInstrInfo::getEquivalentCompactForm(      const MachineBasicBlock::iterator I) const {    unsigned Opcode = I->getOpcode(); -  bool canUseShortMMBranches = -      Subtarget.inMicroMipsMode() && -      (Opcode == Mips::BNE || Opcode == Mips::BEQ) && -      I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg(); +  bool canUseShortMicroMipsCTI = false; -  if (Subtarget.hasMips32r6() || canUseShortMMBranches) { +  if (Subtarget.inMicroMipsMode()) { +    switch (Opcode) { +    case Mips::BNE: +    case Mips::BEQ: +    // microMIPS has NE,EQ branches that do not have delay slots provided one +    // of the operands is zero. +      if (I->getOperand(1).getReg() == Subtarget.getABI().GetZeroReg()) +        canUseShortMicroMipsCTI = true; +      break; +    // For microMIPS the PseudoReturn and PseudoIndirectBranch are always +    // expanded to JR_MM, so they can be replaced with JRC16_MM. +    case Mips::JR: +    case Mips::PseudoReturn: +    case Mips::PseudoIndirectBranch: +      canUseShortMicroMipsCTI = true; +      break; +    } +  } + +  if (Subtarget.hasMips32r6() || canUseShortMicroMipsCTI) {      switch (Opcode) {      case Mips::B:        return Mips::BC;      case Mips::BAL:        return Mips::BALC;      case Mips::BEQ: -      if (canUseShortMMBranches) +      if (canUseShortMicroMipsCTI)          return Mips::BEQZC_MM;        else          return Mips::BEQC;      case Mips::BNE: -      if (canUseShortMMBranches) +      if (canUseShortMicroMipsCTI)          return Mips::BNEZC_MM;        else          return Mips::BNEC; @@ -298,7 +314,23 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(        return Mips::BLTUC;      case Mips::BLTZ:        return Mips::BLTZC; -    default: +    // For MIPSR6, the instruction 'jic' can be used for these cases. Some +    // tools will accept 'jrc reg' as an alias for 'jic 0, $reg'. +    case Mips::JR: +    case Mips::PseudoReturn: +    case Mips::PseudoIndirectBranch: +      if (canUseShortMicroMipsCTI) +        return Mips::JRC16_MM; +      return Mips::JIC; +    case Mips::JALRPseudo: +      return Mips::JIALC; +    case Mips::JR64: +    case Mips::PseudoReturn64: +    case Mips::PseudoIndirectBranch64: +      return Mips::JIC64; +    case Mips::JALR64Pseudo: +      return Mips::JIALC64; +     default:        return 0;      }    } @@ -343,19 +375,20 @@ MachineInstrBuilder  MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,                                    MachineBasicBlock::iterator I) const {    MachineInstrBuilder MIB; -  bool BranchWithZeroOperand = false;    // Certain branches have two forms: e.g beq $1, $zero, dst vs beqz $1, dest    // Pick the zero form of the branch for readable assembly and for greater    // branch distance in non-microMIPS mode. -  if (I->isBranch() && I->getOperand(1).isReg() && -      // FIXME: Certain atomic sequences on mips64 generate 32bit references to -      // Mips::ZERO, which is incorrect. This test should be updated to use -      // Subtarget.getABI().GetZeroReg() when those atomic sequences and others -      // are fixed. -      (I->getOperand(1).getReg() == Mips::ZERO || -       I->getOperand(1).getReg() == Mips::ZERO_64)) { -    BranchWithZeroOperand = true; +  // FIXME: Certain atomic sequences on mips64 generate 32bit references to +  // Mips::ZERO, which is incorrect. This test should be updated to use +  // Subtarget.getABI().GetZeroReg() when those atomic sequences and others +  // are fixed. +  bool BranchWithZeroOperand = +      (I->isBranch() && !I->isPseudo() && I->getOperand(1).isReg() && +       (I->getOperand(1).getReg() == Mips::ZERO || +        I->getOperand(1).getReg() == Mips::ZERO_64)); + +  if (BranchWithZeroOperand) {      switch (NewOpc) {      case Mips::BEQC:        NewOpc = Mips::BEQZC; @@ -369,20 +402,43 @@ MipsInstrInfo::genInstrWithNewOpc(unsigned NewOpc,      case Mips::BLTC:        NewOpc = Mips::BLTZC;        break; -    case Mips::BNEZC_MM: -    case Mips::BEQZC_MM: -      break; -    default: -      BranchWithZeroOperand = false; -      break;      }    }    MIB = BuildMI(*I->getParent(), I, I->getDebugLoc(), get(NewOpc)); -  for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) -    if (!(BranchWithZeroOperand && (J == 1))) +  // For MIPSR6 JI*C requires an immediate 0 as an operand, JIALC(64) an +  // immediate 0 as an operand and requires the removal of it's %RA<imp-def> +  // implicit operand as copying the implicit operations of the instructio we're +  // looking at will give us the correct flags. +  if (NewOpc == Mips::JIC || NewOpc == Mips::JIALC || NewOpc == Mips::JIC64 || +      NewOpc == Mips::JIALC64) { + +    if (NewOpc == Mips::JIALC || NewOpc == Mips::JIALC64) +      MIB->RemoveOperand(0); + +    for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { +      MIB.addOperand(I->getOperand(J)); +    } + +    MIB.addImm(0); + + } else if (BranchWithZeroOperand) { +    // For MIPSR6 and microMIPS branches with an explicit zero operand, copy +    // everything after the zero. +     MIB.addOperand(I->getOperand(0)); + +    for (unsigned J = 2, E = I->getDesc().getNumOperands(); J < E; ++J) {        MIB.addOperand(I->getOperand(J)); +    } +  } else { +    // All other cases copy all other operands. +    for (unsigned J = 0, E = I->getDesc().getNumOperands(); J < E; ++J) { +      MIB.addOperand(I->getOperand(J)); +    } +  } + +  MIB.copyImplicitOps(*I);    MIB.setMemRefs(I->memoperands_begin(), I->memoperands_end());    return MIB; | 

