summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AVR
diff options
context:
space:
mode:
authorDylan McKay <me@dylanmckay.io>2017-10-04 09:51:28 +0000
committerDylan McKay <me@dylanmckay.io>2017-10-04 09:51:28 +0000
commit39069208d5e24f62116fa8a6ed7c47596fb21a98 (patch)
tree1cd2a4fcdecf5b548457222068e5a20b8a9c31c3 /llvm/lib/Target/AVR
parentc4b002bf5a5770f7ecfdc528b49a8768a486ec17 (diff)
downloadbcm5719-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.cpp18
-rw-r--r--llvm/lib/Target/AVR/AVRInstrInfo.h6
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;
};
OpenPOWER on IntegriCloud