diff options
| author | Dylan McKay <me@dylanmckay.io> | 2017-10-04 09:51:28 +0000 |
|---|---|---|
| committer | Dylan McKay <me@dylanmckay.io> | 2017-10-04 09:51:28 +0000 |
| commit | 39069208d5e24f62116fa8a6ed7c47596fb21a98 (patch) | |
| tree | 1cd2a4fcdecf5b548457222068e5a20b8a9c31c3 /llvm/lib/Target/AVR | |
| parent | c4b002bf5a5770f7ecfdc528b49a8768a486ec17 (diff) | |
| download | bcm5719-llvm-39069208d5e24f62116fa8a6ed7c47596fb21a98.tar.gz bcm5719-llvm-39069208d5e24f62116fa8a6ed7c47596fb21a98.zip | |
[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
Diffstat (limited to 'llvm/lib/Target/AVR')
| -rw-r--r-- | llvm/lib/Target/AVR/AVRInstrInfo.cpp | 18 | ||||
| -rw-r--r-- | llvm/lib/Target/AVR/AVRInstrInfo.h | 6 |
2 files changed, 22 insertions, 2 deletions
diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.cpp b/llvm/lib/Target/AVR/AVRInstrInfo.cpp index 744aa723c41..1a89a13693e 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.cpp +++ b/llvm/lib/Target/AVR/AVRInstrInfo.cpp @@ -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 diff --git a/llvm/lib/Target/AVR/AVRInstrInfo.h b/llvm/lib/Target/AVR/AVRInstrInfo.h index f42d34fb284..eee8a92c619 100644 --- a/llvm/lib/Target/AVR/AVRInstrInfo.h +++ b/llvm/lib/Target/AVR/AVRInstrInfo.h @@ -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; }; |

