/// to a Zero terminated array of registers that this register aliases. This is
/// needed for architectures like X86 which have AL alias AX alias EAX.
/// Registers that this does not apply to simply should set this to null.
+/// The SubRegs field is a zero terminated array of registers that are
+/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
+/// The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are sub-registers
+/// of AX.
///
struct TargetRegisterDesc {
const char *Name; // Assembly language name for the register
const unsigned *AliasSet; // Register Alias Set, described above
+ const unsigned *SubRegs; // Sub-register set, described above
+ const unsigned *SuperRegs; // Super-register set, described above
};
class TargetRegisterClass {
virtual ~MRegisterInfo();
public:
- /// getRegScavenger - Returns pointer to an instance of register scavenger it
- /// the specific target is making use of one.
- virtual RegScavenger *getRegScavenger() const {
- return NULL;
- }
-
enum { // Define some target independent constants
/// NoRegister - This physical register is not a real target register. It
/// is useful as a sentinal.
}
/// getAllocatableSet - Returns a bitset indexed by register number
- /// indicating if a register is allocatable or not.
- BitVector getAllocatableSet(MachineFunction &MF) const;
+ /// indicating if a register is allocatable or not. If a register class is
+ /// specified, returns the subset for the class.
+ BitVector getAllocatableSet(MachineFunction &MF,
+ const TargetRegisterClass *RC = NULL) const;
const TargetRegisterDesc &operator[](unsigned RegNo) const {
assert(RegNo < NumRegs &&
return get(RegNo).AliasSet;
}
+ /// getSubRegisters - Return the set of registers that are sub-registers of
+ /// the specified register, or a null list of there are none. The list
+ /// returned is zero terminated.
+ ///
+ const unsigned *getSubRegisters(unsigned RegNo) const {
+ return get(RegNo).SubRegs;
+ }
+
+ /// getSuperRegisters - Return the set of registers that are super-registers
+ /// of the specified register, or a null list of there are none. The list
+ /// returned is zero terminated.
+ ///
+ const unsigned *getSuperRegisters(unsigned RegNo) const {
+ return get(RegNo).SuperRegs;
+ }
+
/// getName - Return the symbolic target specific name for the specified
/// physical register.
const char *getName(unsigned RegNo) const {
return areAliases(regA, regB);
}
+ /// isSubRegister - Returns true if regB is a sub-register of regA.
+ ///
+ bool isSubRegister(unsigned regA, unsigned regB) const {
+ for (const unsigned *SR = getSubRegisters(regA); *SR; ++SR)
+ if (*SR == regB) return true;
+ return false;
+ }
+
+ /// isSuperRegister - Returns true if regB is a super-register of regA.
+ ///
+ bool isSuperRegister(unsigned regA, unsigned regB) const {
+ for (const unsigned *SR = getSuperRegisters(regA); *SR; ++SR)
+ if (*SR == regB) return true;
+ return false;
+ }
+
/// getCalleeSavedRegs - Return a null-terminated list of all of the
/// callee saved registers on this target. The register should be in the
/// order of desired callee-save stack frame offset. The first register is
unsigned DestReg, unsigned SrcReg,
const TargetRegisterClass *RC) const = 0;
+ /// reMaterialize - Re-issue the specified 'original' instruction at the
+ /// specific location targeting a new destination register.
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg,
+ const MachineInstr *Orig) const = 0;
+
/// foldMemoryOperand - Attempt to fold a load or store of the
/// specified stack slot into the specified machine instruction for
/// the specified operand. If this is possible, a new instruction
return false;
}
+ /// requiresRegisterScavenging - returns true if the target requires (and
+ /// can make use of) the register scavenger.
+ virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
+ return false;
+ }
+
/// hasFP - Return true if the specified function should have a dedicated frame
/// pointer register. For most targets this is true only if the function has
/// variable sized allocas or if frame pointer elimination is disabled.
/// processFunctionBeforeCalleeSavedScan - This method is called immediately
/// before PrologEpilogInserter scans the physical registers used to determine
/// what callee saved registers should be spilled. This method is optional.
- virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
+ virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+
}
/// processFunctionBeforeFrameFinalized - This method is called immediately
/// finished product. The return value is the number of instructions
/// added to (negative if removed from) the basic block.
///
- virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI) const = 0;
+ virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+ RegScavenger *RS = NULL) const = 0;
/// emitProlog/emitEpilog - These methods insert prolog and epilog code into
/// the function. The return value is the number of instructions