summaryrefslogtreecommitdiff
path: root/include/llvm/MC/MCInstrDesc.h
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-12-19 23:38:53 +0000
committerJim Grosbach <grosbach@apple.com>2012-12-19 23:38:53 +0000
commitfbf3b4a07690751f72302757058ab0298dfb832e (patch)
tree3b0d8408bdb2e0ebe9e5aa6eec4edadda31e8182 /include/llvm/MC/MCInstrDesc.h
parent16f3204b95c952a70c9d2aa3b423162215beb6ae (diff)
downloadllvm-fbf3b4a07690751f72302757058ab0298dfb832e.tar.gz
llvm-fbf3b4a07690751f72302757058ab0298dfb832e.tar.bz2
llvm-fbf3b4a07690751f72302757058ab0298dfb832e.tar.xz
MC: Add MCInstrDesc::mayAffectControlFlow() method.
MC disassembler clients (LLDB) are interested in querying if an instruction may affect control flow other than by virtue of being an explicit branch instruction. For example, instructions which write directly to the PC on some architectures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@170610 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/MC/MCInstrDesc.h')
-rw-r--r--include/llvm/MC/MCInstrDesc.h30
1 files changed, 28 insertions, 2 deletions
diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index c6165d6ffa..e55a9d454c 100644
--- a/include/llvm/MC/MCInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -16,6 +16,8 @@
#define LLVM_MC_MCINSTRDESC_H
#include "llvm/Support/DataTypes.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCInst.h"
namespace llvm {
@@ -258,6 +260,17 @@ public:
return isBranch() & isBarrier() & !isIndirectBranch();
}
+ /// Return true if this is a branch or an instruction which directly
+ /// writes to the program counter. Considered 'may' affect rather than
+ /// 'does' affect as things like predication are not taken into account.
+ bool mayAffectControlFlow(const MCInst &MI, const MCRegisterInfo &RI) const {
+ if (isBranch() || isCall() || isReturn() || isIndirectBranch())
+ return true;
+ unsigned PC = RI.getProgramCounter();
+ if (PC == 0) return false;
+ return hasDefOfPhysReg(MI, PC, RI);
+ }
+
/// isPredicable - Return true if this instruction has a predicate operand
/// that controls execution. It may be set to 'always', or may be set to other
/// values. There are various methods in TargetInstrInfo that can be used to
@@ -502,13 +515,26 @@ public:
/// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
/// defines the specified physical register.
- bool hasImplicitDefOfPhysReg(unsigned Reg) const {
+ bool hasImplicitDefOfPhysReg(unsigned Reg,
+ const MCRegisterInfo *MRI = 0) const {
if (const uint16_t *ImpDefs = ImplicitDefs)
for (; *ImpDefs; ++ImpDefs)
- if (*ImpDefs == Reg) return true;
+ if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
+ return true;
return false;
}
+ /// Return true if this instruction defines the specified physical
+ /// register, either explicitly or implicitly.
+ bool hasDefOfPhysReg(const MCInst &MI, unsigned Reg,
+ const MCRegisterInfo &RI) const {
+ for (int i = 0, e = NumDefs; i != e; ++i)
+ if (MI.getOperand(i).isReg() &&
+ RI.isSubRegisterEq(Reg, MI.getOperand(i).getReg()))
+ return true;
+ return hasImplicitDefOfPhysReg(Reg, &RI);
+ }
+
/// getSchedClass - Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the