mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
[SystemZ] Update namespace formatting to match current guidelines
No functional change intended. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203103 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b0a3627443
commit
9a1cd05a3d
@ -428,7 +428,7 @@ public:
|
||||
return parsePCRel(Operands, -(1LL << 32), (1LL << 32) - 1);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
#define GET_REGISTER_MATCHER
|
||||
#define GET_SUBTARGET_FEATURE_NAME
|
||||
|
@ -25,6 +25,6 @@ public:
|
||||
getNonexecutableStackSection(MCContext &Ctx) const override;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -89,7 +89,7 @@ private:
|
||||
return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2);
|
||||
}
|
||||
};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
|
@ -14,18 +14,18 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace SystemZ {
|
||||
enum FixupKind {
|
||||
// These correspond directly to R_390_* relocations.
|
||||
FK_390_PC16DBL = FirstTargetFixupKind,
|
||||
FK_390_PC32DBL,
|
||||
FK_390_PLT16DBL,
|
||||
FK_390_PLT32DBL,
|
||||
enum FixupKind {
|
||||
// These correspond directly to R_390_* relocations.
|
||||
FK_390_PC16DBL = FirstTargetFixupKind,
|
||||
FK_390_PC32DBL,
|
||||
FK_390_PLT16DBL,
|
||||
FK_390_PLT32DBL,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
}
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
} // end namespace SystemZ
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -33,7 +33,7 @@ protected:
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const override;
|
||||
};
|
||||
} // end anonymouse namespace
|
||||
} // end anonymous namespace
|
||||
|
||||
SystemZObjectWriter::SystemZObjectWriter(uint8_t OSABI)
|
||||
: MCELFObjectTargetWriter(/*Is64Bit=*/true, OSABI, ELF::EM_S390,
|
||||
|
@ -28,47 +28,47 @@ class raw_ostream;
|
||||
extern Target TheSystemZTarget;
|
||||
|
||||
namespace SystemZMC {
|
||||
// How many bytes are in the ABI-defined, caller-allocated part of
|
||||
// a stack frame.
|
||||
const int64_t CallFrameSize = 160;
|
||||
// How many bytes are in the ABI-defined, caller-allocated part of
|
||||
// a stack frame.
|
||||
const int64_t CallFrameSize = 160;
|
||||
|
||||
// The offset of the DWARF CFA from the incoming stack pointer.
|
||||
const int64_t CFAOffsetFromInitialSP = CallFrameSize;
|
||||
// The offset of the DWARF CFA from the incoming stack pointer.
|
||||
const int64_t CFAOffsetFromInitialSP = CallFrameSize;
|
||||
|
||||
// Maps of asm register numbers to LLVM register numbers, with 0 indicating
|
||||
// an invalid register. In principle we could use 32-bit and 64-bit register
|
||||
// classes directly, provided that we relegated the GPR allocation order
|
||||
// in SystemZRegisterInfo.td to an AltOrder and left the default order
|
||||
// as %r0-%r15. It seems better to provide the same interface for
|
||||
// all classes though.
|
||||
extern const unsigned GR32Regs[16];
|
||||
extern const unsigned GRH32Regs[16];
|
||||
extern const unsigned GR64Regs[16];
|
||||
extern const unsigned GR128Regs[16];
|
||||
extern const unsigned FP32Regs[16];
|
||||
extern const unsigned FP64Regs[16];
|
||||
extern const unsigned FP128Regs[16];
|
||||
// Maps of asm register numbers to LLVM register numbers, with 0 indicating
|
||||
// an invalid register. In principle we could use 32-bit and 64-bit register
|
||||
// classes directly, provided that we relegated the GPR allocation order
|
||||
// in SystemZRegisterInfo.td to an AltOrder and left the default order
|
||||
// as %r0-%r15. It seems better to provide the same interface for
|
||||
// all classes though.
|
||||
extern const unsigned GR32Regs[16];
|
||||
extern const unsigned GRH32Regs[16];
|
||||
extern const unsigned GR64Regs[16];
|
||||
extern const unsigned GR128Regs[16];
|
||||
extern const unsigned FP32Regs[16];
|
||||
extern const unsigned FP64Regs[16];
|
||||
extern const unsigned FP128Regs[16];
|
||||
|
||||
// Return the 0-based number of the first architectural register that
|
||||
// contains the given LLVM register. E.g. R1D -> 1.
|
||||
unsigned getFirstReg(unsigned Reg);
|
||||
// Return the 0-based number of the first architectural register that
|
||||
// contains the given LLVM register. E.g. R1D -> 1.
|
||||
unsigned getFirstReg(unsigned Reg);
|
||||
|
||||
// Return the given register as a GR64.
|
||||
inline unsigned getRegAsGR64(unsigned Reg) {
|
||||
return GR64Regs[getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a low GR32.
|
||||
inline unsigned getRegAsGR32(unsigned Reg) {
|
||||
return GR32Regs[getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a high GR32.
|
||||
inline unsigned getRegAsGRH32(unsigned Reg) {
|
||||
return GRH32Regs[getFirstReg(Reg)];
|
||||
}
|
||||
// Return the given register as a GR64.
|
||||
inline unsigned getRegAsGR64(unsigned Reg) {
|
||||
return GR64Regs[getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a low GR32.
|
||||
inline unsigned getRegAsGR32(unsigned Reg) {
|
||||
return GR32Regs[getFirstReg(Reg)];
|
||||
}
|
||||
|
||||
// Return the given register as a high GR32.
|
||||
inline unsigned getRegAsGRH32(unsigned Reg) {
|
||||
return GRH32Regs[getFirstReg(Reg)];
|
||||
}
|
||||
} // end namespace SystemZMC
|
||||
|
||||
MCCodeEmitter *createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCSubtargetInfo &STI,
|
||||
|
@ -19,97 +19,98 @@
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
|
||||
namespace llvm {
|
||||
class SystemZTargetMachine;
|
||||
class FunctionPass;
|
||||
class SystemZTargetMachine;
|
||||
class FunctionPass;
|
||||
|
||||
namespace SystemZ {
|
||||
// Condition-code mask values.
|
||||
const unsigned CCMASK_0 = 1 << 3;
|
||||
const unsigned CCMASK_1 = 1 << 2;
|
||||
const unsigned CCMASK_2 = 1 << 1;
|
||||
const unsigned CCMASK_3 = 1 << 0;
|
||||
const unsigned CCMASK_ANY = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3;
|
||||
namespace SystemZ {
|
||||
// Condition-code mask values.
|
||||
const unsigned CCMASK_0 = 1 << 3;
|
||||
const unsigned CCMASK_1 = 1 << 2;
|
||||
const unsigned CCMASK_2 = 1 << 1;
|
||||
const unsigned CCMASK_3 = 1 << 0;
|
||||
const unsigned CCMASK_ANY = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3;
|
||||
|
||||
// Condition-code mask assignments for integer and floating-point
|
||||
// comparisons.
|
||||
const unsigned CCMASK_CMP_EQ = CCMASK_0;
|
||||
const unsigned CCMASK_CMP_LT = CCMASK_1;
|
||||
const unsigned CCMASK_CMP_GT = CCMASK_2;
|
||||
const unsigned CCMASK_CMP_NE = CCMASK_CMP_LT | CCMASK_CMP_GT;
|
||||
const unsigned CCMASK_CMP_LE = CCMASK_CMP_EQ | CCMASK_CMP_LT;
|
||||
const unsigned CCMASK_CMP_GE = CCMASK_CMP_EQ | CCMASK_CMP_GT;
|
||||
// Condition-code mask assignments for integer and floating-point
|
||||
// comparisons.
|
||||
const unsigned CCMASK_CMP_EQ = CCMASK_0;
|
||||
const unsigned CCMASK_CMP_LT = CCMASK_1;
|
||||
const unsigned CCMASK_CMP_GT = CCMASK_2;
|
||||
const unsigned CCMASK_CMP_NE = CCMASK_CMP_LT | CCMASK_CMP_GT;
|
||||
const unsigned CCMASK_CMP_LE = CCMASK_CMP_EQ | CCMASK_CMP_LT;
|
||||
const unsigned CCMASK_CMP_GE = CCMASK_CMP_EQ | CCMASK_CMP_GT;
|
||||
|
||||
// Condition-code mask assignments for floating-point comparisons only.
|
||||
const unsigned CCMASK_CMP_UO = CCMASK_3;
|
||||
const unsigned CCMASK_CMP_O = CCMASK_ANY ^ CCMASK_CMP_UO;
|
||||
// Condition-code mask assignments for floating-point comparisons only.
|
||||
const unsigned CCMASK_CMP_UO = CCMASK_3;
|
||||
const unsigned CCMASK_CMP_O = CCMASK_ANY ^ CCMASK_CMP_UO;
|
||||
|
||||
// All condition-code values produced by comparisons.
|
||||
const unsigned CCMASK_ICMP = CCMASK_0 | CCMASK_1 | CCMASK_2;
|
||||
const unsigned CCMASK_FCMP = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3;
|
||||
// All condition-code values produced by comparisons.
|
||||
const unsigned CCMASK_ICMP = CCMASK_0 | CCMASK_1 | CCMASK_2;
|
||||
const unsigned CCMASK_FCMP = CCMASK_0 | CCMASK_1 | CCMASK_2 | CCMASK_3;
|
||||
|
||||
// Condition-code mask assignments for CS.
|
||||
const unsigned CCMASK_CS_EQ = CCMASK_0;
|
||||
const unsigned CCMASK_CS_NE = CCMASK_1;
|
||||
const unsigned CCMASK_CS = CCMASK_0 | CCMASK_1;
|
||||
// Condition-code mask assignments for CS.
|
||||
const unsigned CCMASK_CS_EQ = CCMASK_0;
|
||||
const unsigned CCMASK_CS_NE = CCMASK_1;
|
||||
const unsigned CCMASK_CS = CCMASK_0 | CCMASK_1;
|
||||
|
||||
// Condition-code mask assignments for a completed SRST loop.
|
||||
const unsigned CCMASK_SRST_FOUND = CCMASK_1;
|
||||
const unsigned CCMASK_SRST_NOTFOUND = CCMASK_2;
|
||||
const unsigned CCMASK_SRST = CCMASK_1 | CCMASK_2;
|
||||
// Condition-code mask assignments for a completed SRST loop.
|
||||
const unsigned CCMASK_SRST_FOUND = CCMASK_1;
|
||||
const unsigned CCMASK_SRST_NOTFOUND = CCMASK_2;
|
||||
const unsigned CCMASK_SRST = CCMASK_1 | CCMASK_2;
|
||||
|
||||
// Condition-code mask assignments for TEST UNDER MASK.
|
||||
const unsigned CCMASK_TM_ALL_0 = CCMASK_0;
|
||||
const unsigned CCMASK_TM_MIXED_MSB_0 = CCMASK_1;
|
||||
const unsigned CCMASK_TM_MIXED_MSB_1 = CCMASK_2;
|
||||
const unsigned CCMASK_TM_ALL_1 = CCMASK_3;
|
||||
const unsigned CCMASK_TM_SOME_0 = CCMASK_TM_ALL_1 ^ CCMASK_ANY;
|
||||
const unsigned CCMASK_TM_SOME_1 = CCMASK_TM_ALL_0 ^ CCMASK_ANY;
|
||||
const unsigned CCMASK_TM_MSB_0 = CCMASK_0 | CCMASK_1;
|
||||
const unsigned CCMASK_TM_MSB_1 = CCMASK_2 | CCMASK_3;
|
||||
const unsigned CCMASK_TM = CCMASK_ANY;
|
||||
// Condition-code mask assignments for TEST UNDER MASK.
|
||||
const unsigned CCMASK_TM_ALL_0 = CCMASK_0;
|
||||
const unsigned CCMASK_TM_MIXED_MSB_0 = CCMASK_1;
|
||||
const unsigned CCMASK_TM_MIXED_MSB_1 = CCMASK_2;
|
||||
const unsigned CCMASK_TM_ALL_1 = CCMASK_3;
|
||||
const unsigned CCMASK_TM_SOME_0 = CCMASK_TM_ALL_1 ^ CCMASK_ANY;
|
||||
const unsigned CCMASK_TM_SOME_1 = CCMASK_TM_ALL_0 ^ CCMASK_ANY;
|
||||
const unsigned CCMASK_TM_MSB_0 = CCMASK_0 | CCMASK_1;
|
||||
const unsigned CCMASK_TM_MSB_1 = CCMASK_2 | CCMASK_3;
|
||||
const unsigned CCMASK_TM = CCMASK_ANY;
|
||||
|
||||
// The position of the low CC bit in an IPM result.
|
||||
const unsigned IPM_CC = 28;
|
||||
// The position of the low CC bit in an IPM result.
|
||||
const unsigned IPM_CC = 28;
|
||||
|
||||
// Mask assignments for PFD.
|
||||
const unsigned PFD_READ = 1;
|
||||
const unsigned PFD_WRITE = 2;
|
||||
// Mask assignments for PFD.
|
||||
const unsigned PFD_READ = 1;
|
||||
const unsigned PFD_WRITE = 2;
|
||||
|
||||
// Return true if Val fits an LLILL operand.
|
||||
static inline bool isImmLL(uint64_t Val) {
|
||||
return (Val & ~0x000000000000ffffULL) == 0;
|
||||
}
|
||||
// Return true if Val fits an LLILL operand.
|
||||
static inline bool isImmLL(uint64_t Val) {
|
||||
return (Val & ~0x000000000000ffffULL) == 0;
|
||||
}
|
||||
|
||||
// Return true if Val fits an LLILH operand.
|
||||
static inline bool isImmLH(uint64_t Val) {
|
||||
return (Val & ~0x00000000ffff0000ULL) == 0;
|
||||
}
|
||||
// Return true if Val fits an LLILH operand.
|
||||
static inline bool isImmLH(uint64_t Val) {
|
||||
return (Val & ~0x00000000ffff0000ULL) == 0;
|
||||
}
|
||||
|
||||
// Return true if Val fits an LLIHL operand.
|
||||
static inline bool isImmHL(uint64_t Val) {
|
||||
return (Val & ~0x00000ffff00000000ULL) == 0;
|
||||
}
|
||||
// Return true if Val fits an LLIHL operand.
|
||||
static inline bool isImmHL(uint64_t Val) {
|
||||
return (Val & ~0x00000ffff00000000ULL) == 0;
|
||||
}
|
||||
|
||||
// Return true if Val fits an LLIHH operand.
|
||||
static inline bool isImmHH(uint64_t Val) {
|
||||
return (Val & ~0xffff000000000000ULL) == 0;
|
||||
}
|
||||
// Return true if Val fits an LLIHH operand.
|
||||
static inline bool isImmHH(uint64_t Val) {
|
||||
return (Val & ~0xffff000000000000ULL) == 0;
|
||||
}
|
||||
|
||||
// Return true if Val fits an LLILF operand.
|
||||
static inline bool isImmLF(uint64_t Val) {
|
||||
return (Val & ~0x00000000ffffffffULL) == 0;
|
||||
}
|
||||
// Return true if Val fits an LLILF operand.
|
||||
static inline bool isImmLF(uint64_t Val) {
|
||||
return (Val & ~0x00000000ffffffffULL) == 0;
|
||||
}
|
||||
|
||||
// Return true if Val fits an LLIHF operand.
|
||||
static inline bool isImmHF(uint64_t Val) {
|
||||
return (Val & ~0xffffffff00000000ULL) == 0;
|
||||
}
|
||||
}
|
||||
// Return true if Val fits an LLIHF operand.
|
||||
static inline bool isImmHF(uint64_t Val) {
|
||||
return (Val & ~0xffffffff00000000ULL) == 0;
|
||||
}
|
||||
} // end namespace SystemZ
|
||||
|
||||
FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
FunctionPass *createSystemZElimComparePass(SystemZTargetMachine &TM);
|
||||
FunctionPass *createSystemZShortenInstPass(SystemZTargetMachine &TM);
|
||||
FunctionPass *createSystemZLongBranchPass(SystemZTargetMachine &TM);
|
||||
} // end namespace llvm
|
||||
|
||||
FunctionPass *createSystemZISelDag(SystemZTargetMachine &TM,
|
||||
CodeGenOpt::Level OptLevel);
|
||||
FunctionPass *createSystemZElimComparePass(SystemZTargetMachine &TM);
|
||||
FunctionPass *createSystemZShortenInstPass(SystemZTargetMachine &TM);
|
||||
FunctionPass *createSystemZLongBranchPass(SystemZTargetMachine &TM);
|
||||
} // end namespace llvm;
|
||||
#endif
|
||||
|
@ -11,13 +11,13 @@
|
||||
#define SYSTEMZCALLINGCONV_H
|
||||
|
||||
namespace llvm {
|
||||
namespace SystemZ {
|
||||
const unsigned NumArgGPRs = 5;
|
||||
extern const unsigned ArgGPRs[NumArgGPRs];
|
||||
namespace SystemZ {
|
||||
const unsigned NumArgGPRs = 5;
|
||||
extern const unsigned ArgGPRs[NumArgGPRs];
|
||||
|
||||
const unsigned NumArgFPRs = 4;
|
||||
extern const unsigned ArgFPRs[NumArgFPRs];
|
||||
}
|
||||
}
|
||||
const unsigned NumArgFPRs = 4;
|
||||
extern const unsigned ArgFPRs[NumArgFPRs];
|
||||
} // end namespace SystemZ
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -18,10 +18,10 @@ namespace llvm {
|
||||
class GlobalValue;
|
||||
|
||||
namespace SystemZCP {
|
||||
enum SystemZCPModifier {
|
||||
NTPOFF
|
||||
};
|
||||
}
|
||||
enum SystemZCPModifier {
|
||||
NTPOFF
|
||||
};
|
||||
} // end namespace SystemZCP
|
||||
|
||||
/// A SystemZ-specific constant pool value. At present, the only
|
||||
/// defined constant pool values are offsets of thread-local variables
|
||||
@ -50,6 +50,6 @@ public:
|
||||
SystemZCP::SystemZCPModifier getModifier() const { return Modifier; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -33,64 +33,64 @@ STATISTIC(EliminatedComparisons, "Number of eliminated comparisons");
|
||||
STATISTIC(FusedComparisons, "Number of fused compare-and-branch instructions");
|
||||
|
||||
namespace {
|
||||
// Represents the references to a particular register in one or more
|
||||
// instructions.
|
||||
struct Reference {
|
||||
Reference()
|
||||
: Def(false), Use(false), IndirectDef(false), IndirectUse(false) {}
|
||||
// Represents the references to a particular register in one or more
|
||||
// instructions.
|
||||
struct Reference {
|
||||
Reference()
|
||||
: Def(false), Use(false), IndirectDef(false), IndirectUse(false) {}
|
||||
|
||||
Reference &operator|=(const Reference &Other) {
|
||||
Def |= Other.Def;
|
||||
IndirectDef |= Other.IndirectDef;
|
||||
Use |= Other.Use;
|
||||
IndirectUse |= Other.IndirectUse;
|
||||
return *this;
|
||||
}
|
||||
Reference &operator|=(const Reference &Other) {
|
||||
Def |= Other.Def;
|
||||
IndirectDef |= Other.IndirectDef;
|
||||
Use |= Other.Use;
|
||||
IndirectUse |= Other.IndirectUse;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const { return Def || Use; }
|
||||
operator bool() const { return Def || Use; }
|
||||
|
||||
// True if the register is defined or used in some form, either directly or
|
||||
// via a sub- or super-register.
|
||||
bool Def;
|
||||
bool Use;
|
||||
// True if the register is defined or used in some form, either directly or
|
||||
// via a sub- or super-register.
|
||||
bool Def;
|
||||
bool Use;
|
||||
|
||||
// True if the register is defined or used indirectly, by a sub- or
|
||||
// super-register.
|
||||
bool IndirectDef;
|
||||
bool IndirectUse;
|
||||
};
|
||||
// True if the register is defined or used indirectly, by a sub- or
|
||||
// super-register.
|
||||
bool IndirectDef;
|
||||
bool IndirectUse;
|
||||
};
|
||||
|
||||
class SystemZElimCompare : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZElimCompare(const SystemZTargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TII(0), TRI(0) {}
|
||||
class SystemZElimCompare : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZElimCompare(const SystemZTargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TII(0), TRI(0) {}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Comparison Elimination";
|
||||
}
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Comparison Elimination";
|
||||
}
|
||||
|
||||
bool processBlock(MachineBasicBlock *MBB);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
bool processBlock(MachineBasicBlock *MBB);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
private:
|
||||
Reference getRegReferences(MachineInstr *MI, unsigned Reg);
|
||||
bool convertToBRCT(MachineInstr *MI, MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool convertToLoadAndTest(MachineInstr *MI);
|
||||
bool adjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool optimizeCompareZero(MachineInstr *Compare,
|
||||
private:
|
||||
Reference getRegReferences(MachineInstr *MI, unsigned Reg);
|
||||
bool convertToBRCT(MachineInstr *MI, MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool convertToLoadAndTest(MachineInstr *MI);
|
||||
bool adjustCCMasksForInstr(MachineInstr *MI, MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool fuseCompareAndBranch(MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool optimizeCompareZero(MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
bool fuseCompareAndBranch(MachineInstr *Compare,
|
||||
SmallVectorImpl<MachineInstr *> &CCUsers);
|
||||
|
||||
const SystemZInstrInfo *TII;
|
||||
const TargetRegisterInfo *TRI;
|
||||
};
|
||||
const SystemZInstrInfo *TII;
|
||||
const TargetRegisterInfo *TRI;
|
||||
};
|
||||
|
||||
char SystemZElimCompare::ID = 0;
|
||||
} // end of anonymous namespace
|
||||
char SystemZElimCompare::ID = 0;
|
||||
} // end anonymous namespace
|
||||
|
||||
FunctionPass *llvm::createSystemZElimComparePass(SystemZTargetMachine &TM) {
|
||||
return new SystemZElimCompare(TM);
|
||||
|
@ -20,29 +20,29 @@
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
// The ABI-defined register save slots, relative to the incoming stack
|
||||
// pointer.
|
||||
static const TargetFrameLowering::SpillSlot SpillOffsetTable[] = {
|
||||
{ SystemZ::R2D, 0x10 },
|
||||
{ SystemZ::R3D, 0x18 },
|
||||
{ SystemZ::R4D, 0x20 },
|
||||
{ SystemZ::R5D, 0x28 },
|
||||
{ SystemZ::R6D, 0x30 },
|
||||
{ SystemZ::R7D, 0x38 },
|
||||
{ SystemZ::R8D, 0x40 },
|
||||
{ SystemZ::R9D, 0x48 },
|
||||
{ SystemZ::R10D, 0x50 },
|
||||
{ SystemZ::R11D, 0x58 },
|
||||
{ SystemZ::R12D, 0x60 },
|
||||
{ SystemZ::R13D, 0x68 },
|
||||
{ SystemZ::R14D, 0x70 },
|
||||
{ SystemZ::R15D, 0x78 },
|
||||
{ SystemZ::F0D, 0x80 },
|
||||
{ SystemZ::F2D, 0x88 },
|
||||
{ SystemZ::F4D, 0x90 },
|
||||
{ SystemZ::F6D, 0x98 }
|
||||
};
|
||||
}
|
||||
// The ABI-defined register save slots, relative to the incoming stack
|
||||
// pointer.
|
||||
static const TargetFrameLowering::SpillSlot SpillOffsetTable[] = {
|
||||
{ SystemZ::R2D, 0x10 },
|
||||
{ SystemZ::R3D, 0x18 },
|
||||
{ SystemZ::R4D, 0x20 },
|
||||
{ SystemZ::R5D, 0x28 },
|
||||
{ SystemZ::R6D, 0x30 },
|
||||
{ SystemZ::R7D, 0x38 },
|
||||
{ SystemZ::R8D, 0x40 },
|
||||
{ SystemZ::R9D, 0x48 },
|
||||
{ SystemZ::R10D, 0x50 },
|
||||
{ SystemZ::R11D, 0x58 },
|
||||
{ SystemZ::R12D, 0x60 },
|
||||
{ SystemZ::R13D, 0x68 },
|
||||
{ SystemZ::R14D, 0x70 },
|
||||
{ SystemZ::R15D, 0x78 },
|
||||
{ SystemZ::F0D, 0x80 },
|
||||
{ SystemZ::F2D, 0x88 },
|
||||
{ SystemZ::F4D, 0x90 },
|
||||
{ SystemZ::F6D, 0x98 }
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
SystemZFrameLowering::SystemZFrameLowering(const SystemZTargetMachine &tm,
|
||||
const SystemZSubtarget &sti)
|
||||
|
@ -58,7 +58,7 @@ struct Comparison {
|
||||
// The mask of CC values for which the original condition is true.
|
||||
unsigned CCMask;
|
||||
};
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
// Classify VT as either 32 or 64 bit.
|
||||
static bool is32Bit(EVT VT) {
|
||||
|
@ -22,176 +22,176 @@
|
||||
|
||||
namespace llvm {
|
||||
namespace SystemZISD {
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
enum {
|
||||
FIRST_NUMBER = ISD::BUILTIN_OP_END,
|
||||
|
||||
// Return with a flag operand. Operand 0 is the chain operand.
|
||||
RET_FLAG,
|
||||
// Return with a flag operand. Operand 0 is the chain operand.
|
||||
RET_FLAG,
|
||||
|
||||
// Calls a function. Operand 0 is the chain operand and operand 1
|
||||
// is the target address. The arguments start at operand 2.
|
||||
// There is an optional glue operand at the end.
|
||||
CALL,
|
||||
SIBCALL,
|
||||
// Calls a function. Operand 0 is the chain operand and operand 1
|
||||
// is the target address. The arguments start at operand 2.
|
||||
// There is an optional glue operand at the end.
|
||||
CALL,
|
||||
SIBCALL,
|
||||
|
||||
// Wraps a TargetGlobalAddress that should be loaded using PC-relative
|
||||
// accesses (LARL). Operand 0 is the address.
|
||||
PCREL_WRAPPER,
|
||||
// Wraps a TargetGlobalAddress that should be loaded using PC-relative
|
||||
// accesses (LARL). Operand 0 is the address.
|
||||
PCREL_WRAPPER,
|
||||
|
||||
// Used in cases where an offset is applied to a TargetGlobalAddress.
|
||||
// Operand 0 is the full TargetGlobalAddress and operand 1 is a
|
||||
// PCREL_WRAPPER for an anchor point. This is used so that we can
|
||||
// cheaply refer to either the full address or the anchor point
|
||||
// as a register base.
|
||||
PCREL_OFFSET,
|
||||
// Used in cases where an offset is applied to a TargetGlobalAddress.
|
||||
// Operand 0 is the full TargetGlobalAddress and operand 1 is a
|
||||
// PCREL_WRAPPER for an anchor point. This is used so that we can
|
||||
// cheaply refer to either the full address or the anchor point
|
||||
// as a register base.
|
||||
PCREL_OFFSET,
|
||||
|
||||
// Integer absolute.
|
||||
IABS,
|
||||
// Integer absolute.
|
||||
IABS,
|
||||
|
||||
// Integer comparisons. There are three operands: the two values
|
||||
// to compare, and an integer of type SystemZICMP.
|
||||
ICMP,
|
||||
// Integer comparisons. There are three operands: the two values
|
||||
// to compare, and an integer of type SystemZICMP.
|
||||
ICMP,
|
||||
|
||||
// Floating-point comparisons. The two operands are the values to compare.
|
||||
FCMP,
|
||||
// Floating-point comparisons. The two operands are the values to compare.
|
||||
FCMP,
|
||||
|
||||
// Test under mask. The first operand is ANDed with the second operand
|
||||
// and the condition codes are set on the result. The third operand is
|
||||
// a boolean that is true if the condition codes need to distinguish
|
||||
// between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
|
||||
// register forms do but the memory forms don't).
|
||||
TM,
|
||||
// Test under mask. The first operand is ANDed with the second operand
|
||||
// and the condition codes are set on the result. The third operand is
|
||||
// a boolean that is true if the condition codes need to distinguish
|
||||
// between CCMASK_TM_MIXED_MSB_0 and CCMASK_TM_MIXED_MSB_1 (which the
|
||||
// register forms do but the memory forms don't).
|
||||
TM,
|
||||
|
||||
// Branches if a condition is true. Operand 0 is the chain operand;
|
||||
// operand 1 is the 4-bit condition-code mask, with bit N in
|
||||
// big-endian order meaning "branch if CC=N"; operand 2 is the
|
||||
// target block and operand 3 is the flag operand.
|
||||
BR_CCMASK,
|
||||
// Branches if a condition is true. Operand 0 is the chain operand;
|
||||
// operand 1 is the 4-bit condition-code mask, with bit N in
|
||||
// big-endian order meaning "branch if CC=N"; operand 2 is the
|
||||
// target block and operand 3 is the flag operand.
|
||||
BR_CCMASK,
|
||||
|
||||
// Selects between operand 0 and operand 1. Operand 2 is the
|
||||
// mask of condition-code values for which operand 0 should be
|
||||
// chosen over operand 1; it has the same form as BR_CCMASK.
|
||||
// Operand 3 is the flag operand.
|
||||
SELECT_CCMASK,
|
||||
// Selects between operand 0 and operand 1. Operand 2 is the
|
||||
// mask of condition-code values for which operand 0 should be
|
||||
// chosen over operand 1; it has the same form as BR_CCMASK.
|
||||
// Operand 3 is the flag operand.
|
||||
SELECT_CCMASK,
|
||||
|
||||
// Evaluates to the gap between the stack pointer and the
|
||||
// base of the dynamically-allocatable area.
|
||||
ADJDYNALLOC,
|
||||
// Evaluates to the gap between the stack pointer and the
|
||||
// base of the dynamically-allocatable area.
|
||||
ADJDYNALLOC,
|
||||
|
||||
// Extracts the value of a 32-bit access register. Operand 0 is
|
||||
// the number of the register.
|
||||
EXTRACT_ACCESS,
|
||||
// Extracts the value of a 32-bit access register. Operand 0 is
|
||||
// the number of the register.
|
||||
EXTRACT_ACCESS,
|
||||
|
||||
// Wrappers around the ISD opcodes of the same name. The output and
|
||||
// first input operands are GR128s. The trailing numbers are the
|
||||
// widths of the second operand in bits.
|
||||
UMUL_LOHI64,
|
||||
SDIVREM32,
|
||||
SDIVREM64,
|
||||
UDIVREM32,
|
||||
UDIVREM64,
|
||||
// Wrappers around the ISD opcodes of the same name. The output and
|
||||
// first input operands are GR128s. The trailing numbers are the
|
||||
// widths of the second operand in bits.
|
||||
UMUL_LOHI64,
|
||||
SDIVREM32,
|
||||
SDIVREM64,
|
||||
UDIVREM32,
|
||||
UDIVREM64,
|
||||
|
||||
// Use a series of MVCs to copy bytes from one memory location to another.
|
||||
// The operands are:
|
||||
// - the target address
|
||||
// - the source address
|
||||
// - the constant length
|
||||
//
|
||||
// This isn't a memory opcode because we'd need to attach two
|
||||
// MachineMemOperands rather than one.
|
||||
MVC,
|
||||
// Use a series of MVCs to copy bytes from one memory location to another.
|
||||
// The operands are:
|
||||
// - the target address
|
||||
// - the source address
|
||||
// - the constant length
|
||||
//
|
||||
// This isn't a memory opcode because we'd need to attach two
|
||||
// MachineMemOperands rather than one.
|
||||
MVC,
|
||||
|
||||
// Like MVC, but implemented as a loop that handles X*256 bytes
|
||||
// followed by straight-line code to handle the rest (if any).
|
||||
// The value of X is passed as an additional operand.
|
||||
MVC_LOOP,
|
||||
// Like MVC, but implemented as a loop that handles X*256 bytes
|
||||
// followed by straight-line code to handle the rest (if any).
|
||||
// The value of X is passed as an additional operand.
|
||||
MVC_LOOP,
|
||||
|
||||
// Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR).
|
||||
NC,
|
||||
NC_LOOP,
|
||||
OC,
|
||||
OC_LOOP,
|
||||
XC,
|
||||
XC_LOOP,
|
||||
// Similar to MVC and MVC_LOOP, but for logic operations (AND, OR, XOR).
|
||||
NC,
|
||||
NC_LOOP,
|
||||
OC,
|
||||
OC_LOOP,
|
||||
XC,
|
||||
XC_LOOP,
|
||||
|
||||
// Use CLC to compare two blocks of memory, with the same comments
|
||||
// as for MVC and MVC_LOOP.
|
||||
CLC,
|
||||
CLC_LOOP,
|
||||
// Use CLC to compare two blocks of memory, with the same comments
|
||||
// as for MVC and MVC_LOOP.
|
||||
CLC,
|
||||
CLC_LOOP,
|
||||
|
||||
// Use an MVST-based sequence to implement stpcpy().
|
||||
STPCPY,
|
||||
// Use an MVST-based sequence to implement stpcpy().
|
||||
STPCPY,
|
||||
|
||||
// Use a CLST-based sequence to implement strcmp(). The two input operands
|
||||
// are the addresses of the strings to compare.
|
||||
STRCMP,
|
||||
// Use a CLST-based sequence to implement strcmp(). The two input operands
|
||||
// are the addresses of the strings to compare.
|
||||
STRCMP,
|
||||
|
||||
// Use an SRST-based sequence to search a block of memory. The first
|
||||
// operand is the end address, the second is the start, and the third
|
||||
// is the character to search for. CC is set to 1 on success and 2
|
||||
// on failure.
|
||||
SEARCH_STRING,
|
||||
// Use an SRST-based sequence to search a block of memory. The first
|
||||
// operand is the end address, the second is the start, and the third
|
||||
// is the character to search for. CC is set to 1 on success and 2
|
||||
// on failure.
|
||||
SEARCH_STRING,
|
||||
|
||||
// Store the CC value in bits 29 and 28 of an integer.
|
||||
IPM,
|
||||
// Store the CC value in bits 29 and 28 of an integer.
|
||||
IPM,
|
||||
|
||||
// Perform a serialization operation. (BCR 15,0 or BCR 14,0.)
|
||||
SERIALIZE,
|
||||
// Perform a serialization operation. (BCR 15,0 or BCR 14,0.)
|
||||
SERIALIZE,
|
||||
|
||||
// Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
|
||||
// ATOMIC_LOAD_<op>.
|
||||
//
|
||||
// Operand 0: the address of the containing 32-bit-aligned field
|
||||
// Operand 1: the second operand of <op>, in the high bits of an i32
|
||||
// for everything except ATOMIC_SWAPW
|
||||
// Operand 2: how many bits to rotate the i32 left to bring the first
|
||||
// operand into the high bits
|
||||
// Operand 3: the negative of operand 2, for rotating the other way
|
||||
// Operand 4: the width of the field in bits (8 or 16)
|
||||
ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
|
||||
ATOMIC_LOADW_ADD,
|
||||
ATOMIC_LOADW_SUB,
|
||||
ATOMIC_LOADW_AND,
|
||||
ATOMIC_LOADW_OR,
|
||||
ATOMIC_LOADW_XOR,
|
||||
ATOMIC_LOADW_NAND,
|
||||
ATOMIC_LOADW_MIN,
|
||||
ATOMIC_LOADW_MAX,
|
||||
ATOMIC_LOADW_UMIN,
|
||||
ATOMIC_LOADW_UMAX,
|
||||
// Wrappers around the inner loop of an 8- or 16-bit ATOMIC_SWAP or
|
||||
// ATOMIC_LOAD_<op>.
|
||||
//
|
||||
// Operand 0: the address of the containing 32-bit-aligned field
|
||||
// Operand 1: the second operand of <op>, in the high bits of an i32
|
||||
// for everything except ATOMIC_SWAPW
|
||||
// Operand 2: how many bits to rotate the i32 left to bring the first
|
||||
// operand into the high bits
|
||||
// Operand 3: the negative of operand 2, for rotating the other way
|
||||
// Operand 4: the width of the field in bits (8 or 16)
|
||||
ATOMIC_SWAPW = ISD::FIRST_TARGET_MEMORY_OPCODE,
|
||||
ATOMIC_LOADW_ADD,
|
||||
ATOMIC_LOADW_SUB,
|
||||
ATOMIC_LOADW_AND,
|
||||
ATOMIC_LOADW_OR,
|
||||
ATOMIC_LOADW_XOR,
|
||||
ATOMIC_LOADW_NAND,
|
||||
ATOMIC_LOADW_MIN,
|
||||
ATOMIC_LOADW_MAX,
|
||||
ATOMIC_LOADW_UMIN,
|
||||
ATOMIC_LOADW_UMAX,
|
||||
|
||||
// A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
|
||||
//
|
||||
// Operand 0: the address of the containing 32-bit-aligned field
|
||||
// Operand 1: the compare value, in the low bits of an i32
|
||||
// Operand 2: the swap value, in the low bits of an i32
|
||||
// Operand 3: how many bits to rotate the i32 left to bring the first
|
||||
// operand into the high bits
|
||||
// Operand 4: the negative of operand 2, for rotating the other way
|
||||
// Operand 5: the width of the field in bits (8 or 16)
|
||||
ATOMIC_CMP_SWAPW,
|
||||
// A wrapper around the inner loop of an ATOMIC_CMP_SWAP.
|
||||
//
|
||||
// Operand 0: the address of the containing 32-bit-aligned field
|
||||
// Operand 1: the compare value, in the low bits of an i32
|
||||
// Operand 2: the swap value, in the low bits of an i32
|
||||
// Operand 3: how many bits to rotate the i32 left to bring the first
|
||||
// operand into the high bits
|
||||
// Operand 4: the negative of operand 2, for rotating the other way
|
||||
// Operand 5: the width of the field in bits (8 or 16)
|
||||
ATOMIC_CMP_SWAPW,
|
||||
|
||||
// Prefetch from the second operand using the 4-bit control code in
|
||||
// the first operand. The code is 1 for a load prefetch and 2 for
|
||||
// a store prefetch.
|
||||
PREFETCH
|
||||
};
|
||||
// Prefetch from the second operand using the 4-bit control code in
|
||||
// the first operand. The code is 1 for a load prefetch and 2 for
|
||||
// a store prefetch.
|
||||
PREFETCH
|
||||
};
|
||||
|
||||
// Return true if OPCODE is some kind of PC-relative address.
|
||||
inline bool isPCREL(unsigned Opcode) {
|
||||
return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
|
||||
}
|
||||
// Return true if OPCODE is some kind of PC-relative address.
|
||||
inline bool isPCREL(unsigned Opcode) {
|
||||
return Opcode == PCREL_WRAPPER || Opcode == PCREL_OFFSET;
|
||||
}
|
||||
} // end namespace SystemZISD
|
||||
|
||||
namespace SystemZICMP {
|
||||
// Describes whether an integer comparison needs to be signed or unsigned,
|
||||
// or whether either type is OK.
|
||||
enum {
|
||||
Any,
|
||||
UnsignedOnly,
|
||||
SignedOnly
|
||||
};
|
||||
}
|
||||
// Describes whether an integer comparison needs to be signed or unsigned,
|
||||
// or whether either type is OK.
|
||||
enum {
|
||||
Any,
|
||||
UnsignedOnly,
|
||||
SignedOnly
|
||||
};
|
||||
} // end namespace SystemZICMP
|
||||
|
||||
class SystemZSubtarget;
|
||||
class SystemZTargetMachine;
|
||||
|
@ -43,6 +43,6 @@ addFrameReference(const MachineInstrBuilder &MIB, int FI) {
|
||||
return MIB.addFrameIndex(FI).addImm(Offset).addReg(0).addMemOperand(MMO);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -628,16 +628,16 @@ static bool isSimpleBD12Move(const MachineInstr *MI, unsigned Flag) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct LogicOp {
|
||||
LogicOp() : RegSize(0), ImmLSB(0), ImmSize(0) {}
|
||||
LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize)
|
||||
: RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
|
||||
struct LogicOp {
|
||||
LogicOp() : RegSize(0), ImmLSB(0), ImmSize(0) {}
|
||||
LogicOp(unsigned regSize, unsigned immLSB, unsigned immSize)
|
||||
: RegSize(regSize), ImmLSB(immLSB), ImmSize(immSize) {}
|
||||
|
||||
operator bool() const { return RegSize; }
|
||||
operator bool() const { return RegSize; }
|
||||
|
||||
unsigned RegSize, ImmLSB, ImmSize;
|
||||
};
|
||||
}
|
||||
unsigned RegSize, ImmLSB, ImmSize;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static LogicOp interpretAndImmediate(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
|
@ -26,89 +26,89 @@ namespace llvm {
|
||||
class SystemZTargetMachine;
|
||||
|
||||
namespace SystemZII {
|
||||
enum {
|
||||
// See comments in SystemZInstrFormats.td.
|
||||
SimpleBDXLoad = (1 << 0),
|
||||
SimpleBDXStore = (1 << 1),
|
||||
Has20BitOffset = (1 << 2),
|
||||
HasIndex = (1 << 3),
|
||||
Is128Bit = (1 << 4),
|
||||
AccessSizeMask = (31 << 5),
|
||||
AccessSizeShift = 5,
|
||||
CCValuesMask = (15 << 10),
|
||||
CCValuesShift = 10,
|
||||
CompareZeroCCMaskMask = (15 << 14),
|
||||
CompareZeroCCMaskShift = 14,
|
||||
CCMaskFirst = (1 << 18),
|
||||
CCMaskLast = (1 << 19),
|
||||
IsLogical = (1 << 20)
|
||||
};
|
||||
static inline unsigned getAccessSize(unsigned int Flags) {
|
||||
return (Flags & AccessSizeMask) >> AccessSizeShift;
|
||||
}
|
||||
static inline unsigned getCCValues(unsigned int Flags) {
|
||||
return (Flags & CCValuesMask) >> CCValuesShift;
|
||||
}
|
||||
static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
|
||||
return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
|
||||
}
|
||||
|
||||
// SystemZ MachineOperand target flags.
|
||||
enum {
|
||||
// Masks out the bits for the access model.
|
||||
MO_SYMBOL_MODIFIER = (1 << 0),
|
||||
|
||||
// @GOT (aka @GOTENT)
|
||||
MO_GOT = (1 << 0)
|
||||
};
|
||||
// Classifies a branch.
|
||||
enum BranchType {
|
||||
// An instruction that branches on the current value of CC.
|
||||
BranchNormal,
|
||||
|
||||
// An instruction that peforms a 32-bit signed comparison and branches
|
||||
// on the result.
|
||||
BranchC,
|
||||
|
||||
// An instruction that peforms a 32-bit unsigned comparison and branches
|
||||
// on the result.
|
||||
BranchCL,
|
||||
|
||||
// An instruction that peforms a 64-bit signed comparison and branches
|
||||
// on the result.
|
||||
BranchCG,
|
||||
|
||||
// An instruction that peforms a 64-bit unsigned comparison and branches
|
||||
// on the result.
|
||||
BranchCLG,
|
||||
|
||||
// An instruction that decrements a 32-bit register and branches if
|
||||
// the result is nonzero.
|
||||
BranchCT,
|
||||
|
||||
// An instruction that decrements a 64-bit register and branches if
|
||||
// the result is nonzero.
|
||||
BranchCTG
|
||||
};
|
||||
// Information about a branch instruction.
|
||||
struct Branch {
|
||||
// The type of the branch.
|
||||
BranchType Type;
|
||||
|
||||
// CCMASK_<N> is set if CC might be equal to N.
|
||||
unsigned CCValid;
|
||||
|
||||
// CCMASK_<N> is set if the branch should be taken when CC == N.
|
||||
unsigned CCMask;
|
||||
|
||||
// The target of the branch.
|
||||
const MachineOperand *Target;
|
||||
|
||||
Branch(BranchType type, unsigned ccValid, unsigned ccMask,
|
||||
const MachineOperand *target)
|
||||
: Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
|
||||
};
|
||||
enum {
|
||||
// See comments in SystemZInstrFormats.td.
|
||||
SimpleBDXLoad = (1 << 0),
|
||||
SimpleBDXStore = (1 << 1),
|
||||
Has20BitOffset = (1 << 2),
|
||||
HasIndex = (1 << 3),
|
||||
Is128Bit = (1 << 4),
|
||||
AccessSizeMask = (31 << 5),
|
||||
AccessSizeShift = 5,
|
||||
CCValuesMask = (15 << 10),
|
||||
CCValuesShift = 10,
|
||||
CompareZeroCCMaskMask = (15 << 14),
|
||||
CompareZeroCCMaskShift = 14,
|
||||
CCMaskFirst = (1 << 18),
|
||||
CCMaskLast = (1 << 19),
|
||||
IsLogical = (1 << 20)
|
||||
};
|
||||
static inline unsigned getAccessSize(unsigned int Flags) {
|
||||
return (Flags & AccessSizeMask) >> AccessSizeShift;
|
||||
}
|
||||
static inline unsigned getCCValues(unsigned int Flags) {
|
||||
return (Flags & CCValuesMask) >> CCValuesShift;
|
||||
}
|
||||
static inline unsigned getCompareZeroCCMask(unsigned int Flags) {
|
||||
return (Flags & CompareZeroCCMaskMask) >> CompareZeroCCMaskShift;
|
||||
}
|
||||
|
||||
// SystemZ MachineOperand target flags.
|
||||
enum {
|
||||
// Masks out the bits for the access model.
|
||||
MO_SYMBOL_MODIFIER = (1 << 0),
|
||||
|
||||
// @GOT (aka @GOTENT)
|
||||
MO_GOT = (1 << 0)
|
||||
};
|
||||
// Classifies a branch.
|
||||
enum BranchType {
|
||||
// An instruction that branches on the current value of CC.
|
||||
BranchNormal,
|
||||
|
||||
// An instruction that peforms a 32-bit signed comparison and branches
|
||||
// on the result.
|
||||
BranchC,
|
||||
|
||||
// An instruction that peforms a 32-bit unsigned comparison and branches
|
||||
// on the result.
|
||||
BranchCL,
|
||||
|
||||
// An instruction that peforms a 64-bit signed comparison and branches
|
||||
// on the result.
|
||||
BranchCG,
|
||||
|
||||
// An instruction that peforms a 64-bit unsigned comparison and branches
|
||||
// on the result.
|
||||
BranchCLG,
|
||||
|
||||
// An instruction that decrements a 32-bit register and branches if
|
||||
// the result is nonzero.
|
||||
BranchCT,
|
||||
|
||||
// An instruction that decrements a 64-bit register and branches if
|
||||
// the result is nonzero.
|
||||
BranchCTG
|
||||
};
|
||||
// Information about a branch instruction.
|
||||
struct Branch {
|
||||
// The type of the branch.
|
||||
BranchType Type;
|
||||
|
||||
// CCMASK_<N> is set if CC might be equal to N.
|
||||
unsigned CCValid;
|
||||
|
||||
// CCMASK_<N> is set if the branch should be taken when CC == N.
|
||||
unsigned CCMask;
|
||||
|
||||
// The target of the branch.
|
||||
const MachineOperand *Target;
|
||||
|
||||
Branch(BranchType type, unsigned ccValid, unsigned ccMask,
|
||||
const MachineOperand *target)
|
||||
: Type(type), CCValid(ccValid), CCMask(ccMask), Target(target) {}
|
||||
};
|
||||
} // end namespace SystemZII
|
||||
|
||||
class SystemZInstrInfo : public SystemZGenInstrInfo {
|
||||
const SystemZRegisterInfo RI;
|
||||
|
@ -71,99 +71,99 @@ using namespace llvm;
|
||||
STATISTIC(LongBranches, "Number of long branches.");
|
||||
|
||||
namespace {
|
||||
// Represents positional information about a basic block.
|
||||
struct MBBInfo {
|
||||
// The address that we currently assume the block has.
|
||||
uint64_t Address;
|
||||
// Represents positional information about a basic block.
|
||||
struct MBBInfo {
|
||||
// The address that we currently assume the block has.
|
||||
uint64_t Address;
|
||||
|
||||
// The size of the block in bytes, excluding terminators.
|
||||
// This value never changes.
|
||||
uint64_t Size;
|
||||
// The size of the block in bytes, excluding terminators.
|
||||
// This value never changes.
|
||||
uint64_t Size;
|
||||
|
||||
// The minimum alignment of the block, as a log2 value.
|
||||
// This value never changes.
|
||||
unsigned Alignment;
|
||||
// The minimum alignment of the block, as a log2 value.
|
||||
// This value never changes.
|
||||
unsigned Alignment;
|
||||
|
||||
// The number of terminators in this block. This value never changes.
|
||||
unsigned NumTerminators;
|
||||
// The number of terminators in this block. This value never changes.
|
||||
unsigned NumTerminators;
|
||||
|
||||
MBBInfo()
|
||||
: Address(0), Size(0), Alignment(0), NumTerminators(0) {}
|
||||
};
|
||||
MBBInfo()
|
||||
: Address(0), Size(0), Alignment(0), NumTerminators(0) {}
|
||||
};
|
||||
|
||||
// Represents the state of a block terminator.
|
||||
struct TerminatorInfo {
|
||||
// If this terminator is a relaxable branch, this points to the branch
|
||||
// instruction, otherwise it is null.
|
||||
MachineInstr *Branch;
|
||||
// Represents the state of a block terminator.
|
||||
struct TerminatorInfo {
|
||||
// If this terminator is a relaxable branch, this points to the branch
|
||||
// instruction, otherwise it is null.
|
||||
MachineInstr *Branch;
|
||||
|
||||
// The address that we currently assume the terminator has.
|
||||
uint64_t Address;
|
||||
// The address that we currently assume the terminator has.
|
||||
uint64_t Address;
|
||||
|
||||
// The current size of the terminator in bytes.
|
||||
uint64_t Size;
|
||||
// The current size of the terminator in bytes.
|
||||
uint64_t Size;
|
||||
|
||||
// If Branch is nonnull, this is the number of the target block,
|
||||
// otherwise it is unused.
|
||||
unsigned TargetBlock;
|
||||
// If Branch is nonnull, this is the number of the target block,
|
||||
// otherwise it is unused.
|
||||
unsigned TargetBlock;
|
||||
|
||||
// If Branch is nonnull, this is the length of the longest relaxed form,
|
||||
// otherwise it is zero.
|
||||
unsigned ExtraRelaxSize;
|
||||
// If Branch is nonnull, this is the length of the longest relaxed form,
|
||||
// otherwise it is zero.
|
||||
unsigned ExtraRelaxSize;
|
||||
|
||||
TerminatorInfo() : Branch(0), Size(0), TargetBlock(0), ExtraRelaxSize(0) {}
|
||||
};
|
||||
TerminatorInfo() : Branch(0), Size(0), TargetBlock(0), ExtraRelaxSize(0) {}
|
||||
};
|
||||
|
||||
// Used to keep track of the current position while iterating over the blocks.
|
||||
struct BlockPosition {
|
||||
// The address that we assume this position has.
|
||||
uint64_t Address;
|
||||
// Used to keep track of the current position while iterating over the blocks.
|
||||
struct BlockPosition {
|
||||
// The address that we assume this position has.
|
||||
uint64_t Address;
|
||||
|
||||
// The number of low bits in Address that are known to be the same
|
||||
// as the runtime address.
|
||||
unsigned KnownBits;
|
||||
// The number of low bits in Address that are known to be the same
|
||||
// as the runtime address.
|
||||
unsigned KnownBits;
|
||||
|
||||
BlockPosition(unsigned InitialAlignment)
|
||||
: Address(0), KnownBits(InitialAlignment) {}
|
||||
};
|
||||
BlockPosition(unsigned InitialAlignment)
|
||||
: Address(0), KnownBits(InitialAlignment) {}
|
||||
};
|
||||
|
||||
class SystemZLongBranch : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZLongBranch(const SystemZTargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TII(0) {}
|
||||
class SystemZLongBranch : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZLongBranch(const SystemZTargetMachine &tm)
|
||||
: MachineFunctionPass(ID), TII(0) {}
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Long Branch";
|
||||
}
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Long Branch";
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
private:
|
||||
void skipNonTerminators(BlockPosition &Position, MBBInfo &Block);
|
||||
void skipTerminator(BlockPosition &Position, TerminatorInfo &Terminator,
|
||||
bool AssumeRelaxed);
|
||||
TerminatorInfo describeTerminator(MachineInstr *MI);
|
||||
uint64_t initMBBInfo();
|
||||
bool mustRelaxBranch(const TerminatorInfo &Terminator, uint64_t Address);
|
||||
bool mustRelaxABranch();
|
||||
void setWorstCaseAddresses();
|
||||
void splitBranchOnCount(MachineInstr *MI, unsigned AddOpcode);
|
||||
void splitCompareBranch(MachineInstr *MI, unsigned CompareOpcode);
|
||||
void relaxBranch(TerminatorInfo &Terminator);
|
||||
void relaxBranches();
|
||||
private:
|
||||
void skipNonTerminators(BlockPosition &Position, MBBInfo &Block);
|
||||
void skipTerminator(BlockPosition &Position, TerminatorInfo &Terminator,
|
||||
bool AssumeRelaxed);
|
||||
TerminatorInfo describeTerminator(MachineInstr *MI);
|
||||
uint64_t initMBBInfo();
|
||||
bool mustRelaxBranch(const TerminatorInfo &Terminator, uint64_t Address);
|
||||
bool mustRelaxABranch();
|
||||
void setWorstCaseAddresses();
|
||||
void splitBranchOnCount(MachineInstr *MI, unsigned AddOpcode);
|
||||
void splitCompareBranch(MachineInstr *MI, unsigned CompareOpcode);
|
||||
void relaxBranch(TerminatorInfo &Terminator);
|
||||
void relaxBranches();
|
||||
|
||||
const SystemZInstrInfo *TII;
|
||||
MachineFunction *MF;
|
||||
SmallVector<MBBInfo, 16> MBBs;
|
||||
SmallVector<TerminatorInfo, 16> Terminators;
|
||||
};
|
||||
const SystemZInstrInfo *TII;
|
||||
MachineFunction *MF;
|
||||
SmallVector<MBBInfo, 16> MBBs;
|
||||
SmallVector<TerminatorInfo, 16> Terminators;
|
||||
};
|
||||
|
||||
char SystemZLongBranch::ID = 0;
|
||||
char SystemZLongBranch::ID = 0;
|
||||
|
||||
const uint64_t MaxBackwardRange = 0x10000;
|
||||
const uint64_t MaxForwardRange = 0xfffe;
|
||||
} // end of anonymous namespace
|
||||
const uint64_t MaxBackwardRange = 0x10000;
|
||||
const uint64_t MaxForwardRange = 0xfffe;
|
||||
} // end anonymous namespace
|
||||
|
||||
FunctionPass *llvm::createSystemZLongBranchPass(SystemZTargetMachine &TM) {
|
||||
return new SystemZLongBranch(TM);
|
||||
|
@ -63,6 +63,6 @@ public:
|
||||
void setManipulatesSP(bool MSP) { ManipulatesSP = MSP; }
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -19,15 +19,15 @@
|
||||
namespace llvm {
|
||||
|
||||
namespace SystemZ {
|
||||
// Return the subreg to use for referring to the even and odd registers
|
||||
// in a GR128 pair. Is32Bit says whether we want a GR32 or GR64.
|
||||
inline unsigned even128(bool Is32bit) {
|
||||
return Is32bit ? subreg_hl32 : subreg_h64;
|
||||
}
|
||||
inline unsigned odd128(bool Is32bit) {
|
||||
return Is32bit ? subreg_l32 : subreg_l64;
|
||||
}
|
||||
// Return the subreg to use for referring to the even and odd registers
|
||||
// in a GR128 pair. Is32Bit says whether we want a GR32 or GR64.
|
||||
inline unsigned even128(bool Is32bit) {
|
||||
return Is32bit ? subreg_hl32 : subreg_h64;
|
||||
}
|
||||
inline unsigned odd128(bool Is32bit) {
|
||||
return Is32bit ? subreg_l32 : subreg_l64;
|
||||
}
|
||||
} // end namespace SystemZ
|
||||
|
||||
class SystemZSubtarget;
|
||||
class SystemZInstrInfo;
|
||||
|
@ -74,6 +74,6 @@ public:
|
||||
MachinePointerInfo SrcPtrInfo) const override;
|
||||
};
|
||||
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
|
@ -21,32 +21,32 @@
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class SystemZShortenInst : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZShortenInst(const SystemZTargetMachine &tm);
|
||||
class SystemZShortenInst : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
SystemZShortenInst(const SystemZTargetMachine &tm);
|
||||
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Instruction Shortening";
|
||||
}
|
||||
virtual const char *getPassName() const {
|
||||
return "SystemZ Instruction Shortening";
|
||||
}
|
||||
|
||||
bool processBlock(MachineBasicBlock *MBB);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
bool processBlock(MachineBasicBlock *MBB);
|
||||
bool runOnMachineFunction(MachineFunction &F);
|
||||
|
||||
private:
|
||||
bool shortenIIF(MachineInstr &MI, unsigned *GPRMap, unsigned LiveOther,
|
||||
unsigned LLIxL, unsigned LLIxH);
|
||||
private:
|
||||
bool shortenIIF(MachineInstr &MI, unsigned *GPRMap, unsigned LiveOther,
|
||||
unsigned LLIxL, unsigned LLIxH);
|
||||
|
||||
const SystemZInstrInfo *TII;
|
||||
const SystemZInstrInfo *TII;
|
||||
|
||||
// LowGPRs[I] has bit N set if LLVM register I includes the low
|
||||
// word of GPR N. HighGPRs is the same for the high word.
|
||||
unsigned LowGPRs[SystemZ::NUM_TARGET_REGS];
|
||||
unsigned HighGPRs[SystemZ::NUM_TARGET_REGS];
|
||||
};
|
||||
// LowGPRs[I] has bit N set if LLVM register I includes the low
|
||||
// word of GPR N. HighGPRs is the same for the high word.
|
||||
unsigned LowGPRs[SystemZ::NUM_TARGET_REGS];
|
||||
unsigned HighGPRs[SystemZ::NUM_TARGET_REGS];
|
||||
};
|
||||
|
||||
char SystemZShortenInst::ID = 0;
|
||||
} // end of anonymous namespace
|
||||
char SystemZShortenInst::ID = 0;
|
||||
} // end anonymous namespace
|
||||
|
||||
FunctionPass *llvm::createSystemZShortenInstPass(SystemZTargetMachine &TM) {
|
||||
return new SystemZShortenInst(TM);
|
||||
|
Loading…
Reference in New Issue
Block a user