mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 13:10:42 +00:00
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
This commit is contained in:
parent
16f3204b95
commit
fbf3b4a076
@ -16,6 +16,8 @@
|
|||||||
#define LLVM_MC_MCINSTRDESC_H
|
#define LLVM_MC_MCINSTRDESC_H
|
||||||
|
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include "llvm/MC/MCRegisterInfo.h"
|
||||||
|
#include "llvm/MC/MCInst.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -258,6 +260,17 @@ public:
|
|||||||
return isBranch() & isBarrier() & !isIndirectBranch();
|
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
|
/// 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
|
/// 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
|
/// values. There are various methods in TargetInstrInfo that can be used to
|
||||||
@ -502,13 +515,26 @@ public:
|
|||||||
|
|
||||||
/// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
|
/// hasImplicitDefOfPhysReg - Return true if this instruction implicitly
|
||||||
/// defines the specified physical register.
|
/// 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)
|
if (const uint16_t *ImpDefs = ImplicitDefs)
|
||||||
for (; *ImpDefs; ++ImpDefs)
|
for (; *ImpDefs; ++ImpDefs)
|
||||||
if (*ImpDefs == Reg) return true;
|
if (*ImpDefs == Reg || (MRI && MRI->isSubRegister(Reg, *ImpDefs)))
|
||||||
|
return true;
|
||||||
return false;
|
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
|
/// getSchedClass - Return the scheduling class for this instruction. The
|
||||||
/// scheduling class is an index into the InstrItineraryData table. This
|
/// scheduling class is an index into the InstrItineraryData table. This
|
||||||
/// returns zero if there is no known scheduling information for the
|
/// returns zero if there is no known scheduling information for the
|
||||||
|
@ -152,6 +152,7 @@ private:
|
|||||||
const MCRegisterDesc *Desc; // Pointer to the descriptor array
|
const MCRegisterDesc *Desc; // Pointer to the descriptor array
|
||||||
unsigned NumRegs; // Number of entries in the array
|
unsigned NumRegs; // Number of entries in the array
|
||||||
unsigned RAReg; // Return address register
|
unsigned RAReg; // Return address register
|
||||||
|
unsigned PCReg; // Program counter register
|
||||||
const MCRegisterClass *Classes; // Pointer to the regclass array
|
const MCRegisterClass *Classes; // Pointer to the regclass array
|
||||||
unsigned NumClasses; // Number of entries in the array
|
unsigned NumClasses; // Number of entries in the array
|
||||||
unsigned NumRegUnits; // Number of regunits.
|
unsigned NumRegUnits; // Number of regunits.
|
||||||
@ -232,6 +233,7 @@ public:
|
|||||||
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
|
/// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
|
||||||
/// auto-generated routines. *DO NOT USE*.
|
/// auto-generated routines. *DO NOT USE*.
|
||||||
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
|
void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA,
|
||||||
|
unsigned PC,
|
||||||
const MCRegisterClass *C, unsigned NC,
|
const MCRegisterClass *C, unsigned NC,
|
||||||
const uint16_t (*RURoots)[2],
|
const uint16_t (*RURoots)[2],
|
||||||
unsigned NRU,
|
unsigned NRU,
|
||||||
@ -243,6 +245,7 @@ public:
|
|||||||
Desc = D;
|
Desc = D;
|
||||||
NumRegs = NR;
|
NumRegs = NR;
|
||||||
RAReg = RA;
|
RAReg = RA;
|
||||||
|
PCReg = PC;
|
||||||
Classes = C;
|
Classes = C;
|
||||||
DiffLists = DL;
|
DiffLists = DL;
|
||||||
RegStrings = Strings;
|
RegStrings = Strings;
|
||||||
@ -297,6 +300,11 @@ public:
|
|||||||
return RAReg;
|
return RAReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the register which is the program counter.
|
||||||
|
unsigned getProgramCounter() const {
|
||||||
|
return PCReg;
|
||||||
|
}
|
||||||
|
|
||||||
const MCRegisterDesc &operator[](unsigned RegNo) const {
|
const MCRegisterDesc &operator[](unsigned RegNo) const {
|
||||||
assert(RegNo < NumRegs &&
|
assert(RegNo < NumRegs &&
|
||||||
"Attempting to access record for invalid register number!");
|
"Attempting to access record for invalid register number!");
|
||||||
|
@ -45,7 +45,7 @@ using namespace llvm;
|
|||||||
|
|
||||||
ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
|
ARMBaseRegisterInfo::ARMBaseRegisterInfo(const ARMBaseInstrInfo &tii,
|
||||||
const ARMSubtarget &sti)
|
const ARMSubtarget &sti)
|
||||||
: ARMGenRegisterInfo(ARM::LR), TII(tii), STI(sti),
|
: ARMGenRegisterInfo(ARM::LR, 0, 0, ARM::PC), TII(tii), STI(sti),
|
||||||
FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
|
FramePtr((STI.isTargetDarwin() || STI.isThumb()) ? ARM::R7 : ARM::R11),
|
||||||
BasePtr(ARM::R6) {
|
BasePtr(ARM::R6) {
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ static MCInstrInfo *createARMMCInstrInfo() {
|
|||||||
|
|
||||||
static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
|
static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) {
|
||||||
MCRegisterInfo *X = new MCRegisterInfo();
|
MCRegisterInfo *X = new MCRegisterInfo();
|
||||||
InitARMMCRegisterInfo(X, ARM::LR);
|
InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC);
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,7 +257,8 @@ static MCRegisterInfo *createX86MCRegisterInfo(StringRef TT) {
|
|||||||
MCRegisterInfo *X = new MCRegisterInfo();
|
MCRegisterInfo *X = new MCRegisterInfo();
|
||||||
InitX86MCRegisterInfo(X, RA,
|
InitX86MCRegisterInfo(X, RA,
|
||||||
X86_MC::getDwarfRegFlavour(TT, false),
|
X86_MC::getDwarfRegFlavour(TT, false),
|
||||||
X86_MC::getDwarfRegFlavour(TT, true));
|
X86_MC::getDwarfRegFlavour(TT, true),
|
||||||
|
RA);
|
||||||
X86_MC::InitLLVM2SEHRegisterMapping(X);
|
X86_MC::InitLLVM2SEHRegisterMapping(X);
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
|
@ -56,10 +56,12 @@ EnableBasePointer("x86-use-base-pointer", cl::Hidden, cl::init(true),
|
|||||||
|
|
||||||
X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
|
X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
|
||||||
const TargetInstrInfo &tii)
|
const TargetInstrInfo &tii)
|
||||||
: X86GenRegisterInfo(tm.getSubtarget<X86Subtarget>().is64Bit()
|
: X86GenRegisterInfo((tm.getSubtarget<X86Subtarget>().is64Bit()
|
||||||
? X86::RIP : X86::EIP,
|
? X86::RIP : X86::EIP),
|
||||||
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), false),
|
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), false),
|
||||||
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), true)),
|
X86_MC::getDwarfRegFlavour(tm.getTargetTriple(), true),
|
||||||
|
(tm.getSubtarget<X86Subtarget>().is64Bit()
|
||||||
|
? X86::RIP : X86::EIP)),
|
||||||
TM(tm), TII(tii) {
|
TM(tm), TII(tii) {
|
||||||
X86_MC::InitLLVM2SEHRegisterMapping(this);
|
X86_MC::InitLLVM2SEHRegisterMapping(this);
|
||||||
|
|
||||||
|
@ -921,9 +921,9 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
// MCRegisterInfo initialization routine.
|
// MCRegisterInfo initialization routine.
|
||||||
OS << "static inline void Init" << TargetName
|
OS << "static inline void Init" << TargetName
|
||||||
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
|
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
|
||||||
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"
|
<< "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0, unsigned PC = 0) {\n"
|
||||||
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
<< " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
||||||
<< Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, "
|
<< Regs.size()+1 << ", RA, PC, " << TargetName << "MCRegisterClasses, "
|
||||||
<< RegisterClasses.size() << ", "
|
<< RegisterClasses.size() << ", "
|
||||||
<< TargetName << "RegUnitRoots, "
|
<< TargetName << "RegUnitRoots, "
|
||||||
<< RegBank.getNumNativeRegUnits() << ", "
|
<< RegBank.getNumNativeRegUnits() << ", "
|
||||||
@ -958,7 +958,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
|
|
||||||
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
|
OS << "struct " << ClassName << " : public TargetRegisterInfo {\n"
|
||||||
<< " explicit " << ClassName
|
<< " explicit " << ClassName
|
||||||
<< "(unsigned RA, unsigned D = 0, unsigned E = 0);\n"
|
<< "(unsigned RA, unsigned D = 0, unsigned E = 0, unsigned PC = 0);\n"
|
||||||
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
|
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
|
||||||
<< " { return false; }\n";
|
<< " { return false; }\n";
|
||||||
if (!RegBank.getSubRegIndices().empty()) {
|
if (!RegBank.getSubRegIndices().empty()) {
|
||||||
@ -1267,12 +1267,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
EmitRegMappingTables(OS, Regs, true);
|
EmitRegMappingTables(OS, Regs, true);
|
||||||
|
|
||||||
OS << ClassName << "::\n" << ClassName
|
OS << ClassName << "::\n" << ClassName
|
||||||
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
|
<< "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour, unsigned PC)\n"
|
||||||
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
|
<< " : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
|
||||||
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
<< ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
|
||||||
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
|
<< " SubRegIndexNameTable, SubRegIndexLaneMaskTable) {\n"
|
||||||
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
<< " InitMCRegisterInfo(" << TargetName << "RegDesc, "
|
||||||
<< Regs.size()+1 << ", RA,\n " << TargetName
|
<< Regs.size()+1 << ", RA, PC,\n " << TargetName
|
||||||
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
|
<< "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
|
||||||
<< " " << TargetName << "RegUnitRoots,\n"
|
<< " " << TargetName << "RegUnitRoots,\n"
|
||||||
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
|
<< " " << RegBank.getNumNativeRegUnits() << ",\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user