Commit 722d0d27 authored by Joerg Sonnenberger's avatar Joerg Sonnenberger
Browse files

Merging r311921:

------------------------------------------------------------------------
r311921 | joerg | 2017-08-28 22:20:47 +0200 (Mon, 28 Aug 2017) | 16 lines

Fix ARMv4 support

ARMv4 doesn't support the "BX" instruction, which has been introduced
with ARMv4t. Adjust the call lowering and tail call implementation
accordingly.

Further changes are necessary to ensure that presence of the v4t feature
is correctly set. Most importantly, the "generic" CPU for thumb-*
triples should include ARMv4t, since thumb mode without thumb support
would naturally be pointless.

Add a couple of asserts to ensure thumb instructions are not emitted
without CPU support.

Differential Revision: https://reviews.llvm.org/D37030

------------------------------------------------------------------------

llvm-svn: 314417
parent c2f252c4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1276,6 +1276,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
      // Add 's' bit operand (always reg0 for this)
      .addReg(0));

    assert(Subtarget->hasV4TOps());
    EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
      .addReg(MI->getOperand(0).getReg()));
    return;
@@ -1896,6 +1897,7 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
      .addImm(ARMCC::AL)
      .addReg(0));

    assert(Subtarget->hasV4TOps());
    EmitToStreamer(*OutStreamer, MCInstBuilder(ARM::BX)
      .addReg(ScratchReg)
      // Predicate.
+3 −1
Original line number Diff line number Diff line
@@ -251,7 +251,9 @@ bool ARMCallLowering::lowerReturn(MachineIRBuilder &MIRBuilder,
                                  const Value *Val, unsigned VReg) const {
  assert(!Val == !VReg && "Return value without a vreg");

  auto Ret = MIRBuilder.buildInstrNoInsert(ARM::BX_RET).add(predOps(ARMCC::AL));
  auto const &ST = MIRBuilder.getMF().getSubtarget<ARMSubtarget>();
  unsigned Opcode = ST.getReturnOpcode();
  auto Ret = MIRBuilder.buildInstrNoInsert(Opcode).add(predOps(ARMCC::AL));

  if (!lowerReturnVal(MIRBuilder, Val, VReg, Ret))
    return false;
+4 −1
Original line number Diff line number Diff line
@@ -1030,8 +1030,11 @@ bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
        if (STI->isThumb())
          MIB.add(predOps(ARMCC::AL));
      } else if (RetOpcode == ARM::TCRETURNri) {
        unsigned Opcode =
          STI->isThumb() ? ARM::tTAILJMPr
                         : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
        BuildMI(MBB, MBBI, dl,
                TII.get(STI->isThumb() ? ARM::tTAILJMPr : ARM::TAILJMPr))
                TII.get(Opcode))
            .addReg(JumpTarget.getReg(), RegState::Kill);
      }

+3 −2
Original line number Diff line number Diff line
@@ -1332,6 +1332,8 @@ bool ARMFastISel::SelectIndirectBr(const Instruction *I) {
  if (AddrReg == 0) return false;

  unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX;
  assert(isThumb2 || Subtarget->hasV4TOps());

  AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
                          TII.get(Opc)).addReg(AddrReg));

@@ -2168,9 +2170,8 @@ bool ARMFastISel::SelectRet(const Instruction *I) {
    RetRegs.push_back(VA.getLocReg());
  }

  unsigned RetOpc = isThumb2 ? ARM::tBX_RET : ARM::BX_RET;
  MachineInstrBuilder MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
                                    TII.get(RetOpc));
                                    TII.get(Subtarget->getReturnOpcode()));
  AddOptionalDefs(MIB);
  for (unsigned R : RetRegs)
    MIB.addReg(R, RegState::Implicit);
+2 −3
Original line number Diff line number Diff line
@@ -2397,9 +2397,8 @@ void ARMFrameLowering::adjustForSegmentedStacks(
  BuildMI(AllocMBB, DL, TII.get(TargetOpcode::CFI_INSTRUCTION))
      .addCFIIndex(CFIIndex);

  // bx lr - Return from this function.
  Opcode = Thumb ? ARM::tBX_RET : ARM::BX_RET;
  BuildMI(AllocMBB, DL, TII.get(Opcode)).add(predOps(ARMCC::AL));
  // Return from this function.
  BuildMI(AllocMBB, DL, TII.get(ST->getReturnOpcode())).add(predOps(ARMCC::AL));

  // Restore SR0 and SR1 in case of __morestack() was not called.
  // pop {SR0, SR1}
Loading