diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb.td | 9 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 11 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 18 | ||||
| -rw-r--r-- | llvm/test/MC/ARM/basic-thumb2-instructions.s | 2 | 
10 files changed, 71 insertions, 24 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 0a1a09c9c9b..6c5dcbe6a71 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -963,6 +963,8 @@ void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {        MCInst BrInst;        BrInst.setOpcode(ARM::t2B);        BrInst.addOperand(MCOperand::CreateExpr(MBBSymbolExpr)); +      BrInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); +      BrInst.addOperand(MCOperand::CreateReg(0));        OutStreamer.EmitInstruction(BrInst);        continue;      } @@ -1677,6 +1679,8 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {        MCInst TmpInst;        TmpInst.setOpcode(ARM::tB);        TmpInst.addOperand(MCOperand::CreateExpr(SymbolExpr)); +      TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL)); +      TmpInst.addOperand(MCOperand::CreateReg(0));        OutStreamer.EmitInstruction(TmpInst);      }      { diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp index f8096b98c59..ac1f6f905bd 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -404,7 +404,8 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,      ? ARM::B : (AFI->isThumb2Function() ? ARM::t2B : ARM::tB);    int BccOpc = !AFI->isThumbFunction()      ? ARM::Bcc : (AFI->isThumb2Function() ? ARM::t2Bcc : ARM::tBcc); - +  bool isThumb = AFI->isThumbFunction() || AFI->isThumb2Function(); +     // Shouldn't be a fall through.    assert(TBB && "InsertBranch must not be told to insert a fallthrough");    assert((Cond.size() == 2 || Cond.size() == 0) && @@ -412,7 +413,10 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,    if (FBB == 0) {      if (Cond.empty()) // Unconditional branch? -      BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB); +      if (isThumb) +        BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB).addImm(ARMCC::AL).addReg(0); +      else +        BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);      else        BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)          .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); @@ -422,7 +426,10 @@ ARMBaseInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,    // Two-way conditional branch.    BuildMI(&MBB, DL, get(BccOpc)).addMBB(TBB)      .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()); -  BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB); +  if (isThumb) +    BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB).addImm(ARMCC::AL).addReg(0); +  else +    BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);    return 2;  } diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index 82d404c67d9..7565aa35d66 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -739,7 +739,11 @@ MachineBasicBlock *ARMConstantIslands::SplitBlockBeforeInstr(MachineInstr *MI) {    // There doesn't seem to be meaningful DebugInfo available; this doesn't    // correspond to anything in the source.    unsigned Opc = isThumb ? (isThumb2 ? ARM::t2B : ARM::tB) : ARM::B; -  BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB); +  if (!isThumb) +    BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB); +  else +    BuildMI(OrigBB, DebugLoc(), TII->get(Opc)).addMBB(NewBB) +            .addImm(ARMCC::AL).addReg(0);    ++NumSplit;    // Update the CFG.  All succs of OrigBB are now succs of NewBB. @@ -1151,7 +1155,11 @@ void ARMConstantIslands::CreateNewWater(unsigned CPUserIndex,      // targets will be exchanged, and the altered branch may be out of      // range, so the machinery has to know about it.      int UncondBr = isThumb ? ((isThumb2) ? ARM::t2B : ARM::tB) : ARM::B; -    BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB); +    if (!isThumb) +      BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB); +    else +      BuildMI(UserMBB, DebugLoc(), TII->get(UncondBr)).addMBB(NewMBB) +              .addImm(ARMCC::AL).addReg(0);      unsigned MaxDisp = getUnconditionalBrDisp(UncondBr);      ImmBranches.push_back(ImmBranch(&UserMBB->back(),                            MaxDisp, false, UncondBr)); @@ -1893,7 +1901,8 @@ AdjustJTTargetBlockForward(MachineBasicBlock *BB, MachineBasicBlock *JTBB)    // There doesn't seem to be meaningful DebugInfo available; this doesn't    // correspond directly to anything in the source.    assert (isThumb2 && "Adjusting for TB[BH] but not in Thumb2?"); -  BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)).addMBB(BB); +  BuildMI(NewBB, DebugLoc(), TII->get(ARM::t2B)).addMBB(BB) +          .addImm(ARMCC::AL).addReg(0);    // Update internal data structures to account for the newly inserted MBB.    MF.RenumberBlocks(NewBB); diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index ce3bd643a8a..2d1de6fe8e9 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -414,6 +414,9 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,          MIB.addExternalSymbol(JumpTarget.getSymbolName(),                                JumpTarget.getTargetFlags());        } + +      // Add the default predicate in Thumb mode. +      if (STI.isThumb()) MIB.addImm(ARMCC::AL).addReg(0);      } else if (RetOpcode == ARM::TCRETURNri) {        BuildMI(MBB, MBBI, dl,                TII.get(STI.isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr)). diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index f451b96dbbe..41bbf36ab08 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -5713,8 +5713,10 @@ ARMTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,      BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2Bcc : ARM::Bcc))        .addMBB(destMBB).addImm(ARMCC::EQ).addReg(ARM::CPSR); -    BuildMI(BB, dl, TII->get(isThumb2 ? ARM::t2B : ARM::B)) -      .addMBB(exitMBB); +    if (isThumb2) +      AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::t2B)).addMBB(exitMBB)); +    else +      BuildMI(BB, dl, TII->get(ARM::B)) .addMBB(exitMBB);      MI->eraseFromParent();   // The pseudo instruction is gone now.      return BB; diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td index 837d853f378..43fd4ed8c4f 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb.td @@ -487,8 +487,8 @@ let isCall = 1,  let isBranch = 1, isTerminator = 1, isBarrier = 1 in {    let isPredicable = 1 in -  def tB   : T1I<(outs), (ins t_brtarget:$target), IIC_Br, -                 "b\t$target", [(br bb:$target)]>, +  def tB   : T1pI<(outs), (ins t_brtarget:$target), IIC_Br, +                 "b", "\t$target", [(br bb:$target)]>,               T1Encoding<{1,1,1,0,0,?}> {      bits<11> target;      let Inst{10-0} = target; @@ -537,9 +537,10 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {    // Non-Darwin versions (the difference is R9).    let Defs = [R0, R1, R2, R3, R12, QQQQ0, QQQQ2, QQQQ3, PC],        Uses = [SP] in { -    def tTAILJMPdND : tPseudoExpand<(outs), (ins t_brtarget:$dst, variable_ops), +    def tTAILJMPdND : tPseudoExpand<(outs), +                   (ins t_brtarget:$dst, pred:$p, variable_ops),                     4, IIC_Br, [], -                   (tB t_brtarget:$dst)>, +                   (tB t_brtarget:$dst, pred:$p)>,                   Requires<[IsThumb, IsNotDarwin]>;      def tTAILJMPrND : tPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),                       4, IIC_Br, [], diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 2f25d861bf6..4aaa014784d 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -3004,8 +3004,8 @@ def t2LDMIA_RET: t2PseudoExpand<(outs GPR:$wb), (ins GPR:$Rn, pred:$p,  let isBranch = 1, isTerminator = 1, isBarrier = 1 in {  let isPredicable = 1 in -def t2B   : T2XI<(outs), (ins uncondbrtarget:$target), IIC_Br, -                 "b.w\t$target", +def t2B   : T2I<(outs), (ins uncondbrtarget:$target), IIC_Br, +                 "b", ".w\t$target",                   [(br bb:$target)]> {    let Inst{31-27} = 0b11110;    let Inst{15-14} = 0b10; @@ -3060,7 +3060,7 @@ def t2TBH : T2I<(outs), (ins GPR:$Rn, GPR:$Rm), IIC_Br,  } // isBranch, isTerminator, isBarrier  // FIXME: should be able to write a pattern for ARMBrcond, but can't use -// a two-value operand where a dag node expects two operands. :( +// a two-value operand where a dag node expects ", "two operands. :(  let isBranch = 1, isTerminator = 1 in  def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,                  "b", ".w\t$target", @@ -3088,9 +3088,10 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {    // Darwin version.    let Defs = [R0, R1, R2, R3, R9, R12, QQQQ0, QQQQ2, QQQQ3, PC],        Uses = [SP] in -  def tTAILJMPd: tPseudoExpand<(outs), (ins uncondbrtarget:$dst, variable_ops), +  def tTAILJMPd: tPseudoExpand<(outs), +                   (ins uncondbrtarget:$dst, pred:$p, variable_ops),                     4, IIC_Br, [], -                   (t2B uncondbrtarget:$dst)>, +                   (t2B uncondbrtarget:$dst, pred:$p)>,                   Requires<[IsThumb2, IsDarwin]>;  } diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 882c4fe3d20..44488cbb08e 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -3567,8 +3567,8 @@ validateInstruction(MCInst &Inst,    // Check for non-'al' condition codes outside of the IT block.    } else if (isThumbTwo() && MCID.isPredicable() &&               Inst.getOperand(MCID.findFirstPredOperandIdx()).getImm() != -             ARMCC::AL && Inst.getOpcode() != ARM::tBcc && -             Inst.getOpcode() != ARM::t2Bcc) +             ARMCC::AL && Inst.getOpcode() != ARM::tB && +             Inst.getOpcode() != ARM::t2B)      return Error(Loc, "predicated instructions must be in IT block");    switch (Inst.getOpcode()) { @@ -3721,6 +3721,16 @@ processInstruction(MCInst &Inst,      if (Inst.getOperand(3).getImm() < 8 && Operands.size() == 6)        Inst.setOpcode(ARM::tADDi3);      break; +  case ARM::tB: +    // A Thumb conditional branch outside of an IT block is a tBcc. +    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) +      Inst.setOpcode(ARM::tBcc); +    break; +  case ARM::t2B: +    // A Thumb2 conditional branch outside of an IT block is a t2Bcc. +    if (Inst.getOperand(1).getImm() != ARMCC::AL && !inITBlock()) +      Inst.setOpcode(ARM::t2Bcc); +    break;    case ARM::t2Bcc:      // If the conditional is AL or we're in an IT block, we really want t2B.      if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock()) diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 8a081f368e6..937c65edc72 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -426,6 +426,8 @@ static void AddThumb1SBit(MCInst &MI, bool InITBlock) {  // post-pass.  MCDisassembler::DecodeStatus  ThumbDisassembler::AddThumbPredicate(MCInst &MI) const { +  MCDisassembler::DecodeStatus S = Success; +    // A few instructions actually have predicates encoded in them.  Don't    // try to overwrite it if we're seeing one of those.    switch (MI.getOpcode()) { @@ -436,8 +438,16 @@ ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {        // Some instructions (mostly conditional branches) are not        // allowed in IT blocks.        if (!ITBlock.empty()) -        return SoftFail; -      return Success; +        S = SoftFail; +      else +        return Success; +      break; +    case ARM::tB: +    case ARM::t2B: +      // Some instructions (mostly unconditional branches) can +      // only appears at the end of, or outside of, an IT. +      if (ITBlock.size() > 1) +        S = SoftFail;        break;      default:        break; @@ -466,7 +476,7 @@ ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {          MI.insert(I, MCOperand::CreateReg(0));        else          MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); -      return Success; +      return S;      }    } @@ -477,7 +487,7 @@ ThumbDisassembler::AddThumbPredicate(MCInst &MI) const {    else      MI.insert(I, MCOperand::CreateReg(ARM::CPSR)); -  return Success; +  return S;  }  // Thumb VFP instructions are a special case.  Because we share their diff --git a/llvm/test/MC/ARM/basic-thumb2-instructions.s b/llvm/test/MC/ARM/basic-thumb2-instructions.s index 4e0f4f5c78d..bb57bb7ad88 100644 --- a/llvm/test/MC/ARM/basic-thumb2-instructions.s +++ b/llvm/test/MC/ARM/basic-thumb2-instructions.s @@ -188,7 +188,7 @@ _func:  @ CHECK: beq.w	_bar                    @ encoding: [A,0xf0'A',A,0x80'A']            @   fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch  @ CHECK: it	eq                      @ encoding: [0x08,0xbf] -@ CHECK: b.w	_bar                    @ encoding: [A,0xf0'A',A,0x90'A'] +@ CHECK: beq.w	_bar                    @ encoding: [A,0xf0'A',A,0x90'A']            @   fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch  @ CHECK: bmi.w   #-183396                @ encoding: [0x13,0xf5,0xce,0xa9]  | 

