aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/AArch64/AArch64InstrInfo.cpp
diff options
context:
space:
mode:
authorTim Northover <Tim.Northover@arm.com>2013-02-15 14:32:20 +0000
committerTim Northover <Tim.Northover@arm.com>2013-02-15 14:32:20 +0000
commit85d2760c8e1d36657ae4d86a6aeee03b3a723d9c (patch)
tree1eece9d72cea7eb50b1833133c096cbccb20ddcf /lib/Target/AArch64/AArch64InstrInfo.cpp
parent8a8a2dcae054a7b4dfea360b9b88e6be53fda40f (diff)
downloadexternal_llvm-85d2760c8e1d36657ae4d86a6aeee03b3a723d9c.zip
external_llvm-85d2760c8e1d36657ae4d86a6aeee03b3a723d9c.tar.gz
external_llvm-85d2760c8e1d36657ae4d86a6aeee03b3a723d9c.tar.bz2
AArch64: add branch fixup pass.
This is essentially a stripped-down version of the ConstandIslands pass (which always had these two functions), providing just the features necessary for correctness. In particular there needs to be a way to resolve the situation where a conditional branch's destination block ends up out of range. This issue crops up when self-hosting for AArch64. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175269 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/AArch64/AArch64InstrInfo.cpp')
-rw-r--r--lib/Target/AArch64/AArch64InstrInfo.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/Target/AArch64/AArch64InstrInfo.cpp b/lib/Target/AArch64/AArch64InstrInfo.cpp
index b4e9e8d..7b93463 100644
--- a/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -558,6 +558,48 @@ void AArch64InstrInfo::getAddressConstraints(const MachineInstr &MI,
}
}
+unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
+ const MCInstrDesc &MCID = MI.getDesc();
+ const MachineBasicBlock &MBB = *MI.getParent();
+ const MachineFunction &MF = *MBB.getParent();
+ const MCAsmInfo &MAI = *MF.getTarget().getMCAsmInfo();
+
+ if (MCID.getSize())
+ return MCID.getSize();
+
+ if (MI.getOpcode() == AArch64::INLINEASM)
+ return getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI);
+
+ if (MI.isLabel())
+ return 0;
+
+ switch (MI.getOpcode()) {
+ case TargetOpcode::BUNDLE:
+ return getInstBundleLength(MI);
+ case TargetOpcode::IMPLICIT_DEF:
+ case TargetOpcode::KILL:
+ case TargetOpcode::PROLOG_LABEL:
+ case TargetOpcode::EH_LABEL:
+ case TargetOpcode::DBG_VALUE:
+ return 0;
+ case AArch64::TLSDESCCALL:
+ return 0;
+ default:
+ llvm_unreachable("Unknown instruction class");
+ }
+}
+
+unsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const {
+ unsigned Size = 0;
+ MachineBasicBlock::const_instr_iterator I = MI;
+ MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end();
+ while (++I != E && I->isInsideBundle()) {
+ assert(!I->isBundle() && "No nested bundle!");
+ Size += getInstSizeInBytes(*I);
+ }
+ return Size;
+}
+
bool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx,
unsigned FrameReg, int &Offset,
const AArch64InstrInfo &TII) {