[AVR] Insert JMP for long branches

Previously, on long branches (relative jumps of >4 kB), an assertion
failure was hit, as AVRInstrInfo::insertIndirectBranch was not
implemented. Despite its name, it is called by the branch relaxator
for *all* unconditional jumps.

Patch by Thomas Backman.

llvm-svn: 314891
This commit is contained in:
Dylan McKay 2017-10-04 09:51:28 +00:00
parent c4b002bf5a
commit 39069208d5
3 changed files with 4159 additions and 2 deletions

View File

@ -537,8 +537,7 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
llvm_unreachable("unexpected opcode!");
case AVR::JMPk:
case AVR::CALLk:
assert(BrOffset >= 0 && "offset must be absolute address");
return isUIntN(16, BrOffset);
return true;
case AVR::RCALLk:
case AVR::RJMPk:
return isIntN(13, BrOffset);
@ -556,5 +555,20 @@ bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
}
}
unsigned AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
MachineBasicBlock &NewDestBB,
const DebugLoc &DL,
int64_t BrOffset,
RegScavenger *RS) const {
// This method inserts a *direct* branch (JMP), despite its name.
// LLVM calls this method to fixup unconditional branches; it never calls
// insertBranch or some hypothetical "insertDirectBranch".
// See lib/CodeGen/RegisterRelaxation.cpp for details.
// We end up here when a jump is too long for a RJMP instruction.
auto &MI = *BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
return getInstSizeInBytes(MI);
}
} // end of namespace llvm

View File

@ -107,6 +107,12 @@ public:
bool isBranchOffsetInRange(unsigned BranchOpc,
int64_t BrOffset) const override;
unsigned insertIndirectBranch(MachineBasicBlock &MBB,
MachineBasicBlock &NewDestBB,
const DebugLoc &DL,
int64_t BrOffset,
RegScavenger *RS) const override;
private:
const AVRRegisterInfo RI;
};

File diff suppressed because it is too large Load Diff