mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-20 20:38:48 +00:00
R600/SI: Clean up checks for legality of immediate operands
There are new register classes VCSrc_* which represent operands that can take an SGPR, VGPR or inline constant. The VSrc_* class is now used to represent operands that can take an SGPR, VGPR, or a 32-bit immediate. This allows us to have more accurate checks for legality of immediates, since before we had no way to distinguish between operands that supported any 32-bit immediate and operands which could only support inline constants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218334 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
30e7514d01
commit
33aca6d4a0
@ -85,21 +85,13 @@ MCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII,
|
|||||||
|
|
||||||
bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
|
bool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc,
|
||||||
unsigned OpNo) const {
|
unsigned OpNo) const {
|
||||||
// FIXME: We need a better way to figure out which operands can be immediate
|
|
||||||
// values
|
|
||||||
//
|
|
||||||
// Some VOP* instructions like ADDC use VReg32 as the register class
|
|
||||||
// for source 0, because they read VCC and can't take an SGPR as an
|
|
||||||
// argument due to constant bus restrictions.
|
|
||||||
if (OpNo == 1 && (Desc.TSFlags & (SIInstrFlags::VOP1 | SIInstrFlags::VOP2 |
|
|
||||||
SIInstrFlags::VOPC)))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
unsigned RegClass = Desc.OpInfo[OpNo].RegClass;
|
unsigned RegClass = Desc.OpInfo[OpNo].RegClass;
|
||||||
return (AMDGPU::SSrc_32RegClassID == RegClass) ||
|
return (AMDGPU::SSrc_32RegClassID == RegClass) ||
|
||||||
(AMDGPU::SSrc_64RegClassID == RegClass) ||
|
(AMDGPU::SSrc_64RegClassID == RegClass) ||
|
||||||
(AMDGPU::VSrc_32RegClassID == RegClass) ||
|
(AMDGPU::VSrc_32RegClassID == RegClass) ||
|
||||||
(AMDGPU::VSrc_64RegClassID == RegClass);
|
(AMDGPU::VSrc_64RegClassID == RegClass) ||
|
||||||
|
(AMDGPU::VCSrc_32RegClassID == RegClass) ||
|
||||||
|
(AMDGPU::VCSrc_64RegClassID == RegClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const {
|
uint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const {
|
||||||
|
@ -1498,8 +1498,14 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
|
|||||||
|
|
||||||
/// \brief Test if RegClass is one of the VSrc classes
|
/// \brief Test if RegClass is one of the VSrc classes
|
||||||
static bool isVSrc(unsigned RegClass) {
|
static bool isVSrc(unsigned RegClass) {
|
||||||
return AMDGPU::VSrc_32RegClassID == RegClass ||
|
switch(RegClass) {
|
||||||
AMDGPU::VSrc_64RegClassID == RegClass;
|
default: return false;
|
||||||
|
case AMDGPU::VSrc_32RegClassID:
|
||||||
|
case AMDGPU::VCSrc_32RegClassID:
|
||||||
|
case AMDGPU::VSrc_64RegClassID:
|
||||||
|
case AMDGPU::VCSrc_64RegClassID:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Test if RegClass is one of the SSrc classes
|
/// \brief Test if RegClass is one of the SSrc classes
|
||||||
@ -1611,10 +1617,9 @@ const TargetRegisterClass *SITargetLowering::getRegClassForNode(
|
|||||||
// If the COPY_TO_REGCLASS instruction is copying to a VSrc register
|
// If the COPY_TO_REGCLASS instruction is copying to a VSrc register
|
||||||
// class, then the register class for the value could be either a
|
// class, then the register class for the value could be either a
|
||||||
// VReg or and SReg. In order to get a more accurate
|
// VReg or and SReg. In order to get a more accurate
|
||||||
if (OpClassID == AMDGPU::VSrc_32RegClassID ||
|
if (isVSrc(OpClassID))
|
||||||
OpClassID == AMDGPU::VSrc_64RegClassID) {
|
|
||||||
return getRegClassForNode(DAG, Op.getOperand(0));
|
return getRegClassForNode(DAG, Op.getOperand(0));
|
||||||
}
|
|
||||||
return TRI.getRegClass(OpClassID);
|
return TRI.getRegClass(OpClassID);
|
||||||
case AMDGPU::EXTRACT_SUBREG: {
|
case AMDGPU::EXTRACT_SUBREG: {
|
||||||
int SubIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
|
int SubIdx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
|
||||||
@ -1648,14 +1653,23 @@ void SITargetLowering::ensureSRegLimit(SelectionDAG &DAG, SDValue &Operand,
|
|||||||
unsigned RegClass,
|
unsigned RegClass,
|
||||||
bool &ScalarSlotUsed) const {
|
bool &ScalarSlotUsed) const {
|
||||||
|
|
||||||
// First map the operands register class to a destination class
|
if (!isVSrc(RegClass))
|
||||||
if (RegClass == AMDGPU::VSrc_32RegClassID)
|
|
||||||
RegClass = AMDGPU::VReg_32RegClassID;
|
|
||||||
else if (RegClass == AMDGPU::VSrc_64RegClassID)
|
|
||||||
RegClass = AMDGPU::VReg_64RegClassID;
|
|
||||||
else
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// First map the operands register class to a destination class
|
||||||
|
switch (RegClass) {
|
||||||
|
case AMDGPU::VSrc_32RegClassID:
|
||||||
|
case AMDGPU::VCSrc_32RegClassID:
|
||||||
|
RegClass = AMDGPU::VReg_32RegClassID;
|
||||||
|
break;
|
||||||
|
case AMDGPU::VSrc_64RegClassID:
|
||||||
|
case AMDGPU::VCSrc_64RegClassID:
|
||||||
|
RegClass = AMDGPU::VReg_64RegClassID;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
llvm_unreachable("Unknown vsrc reg class");
|
||||||
|
}
|
||||||
|
|
||||||
// Nothing to do if they fit naturally
|
// Nothing to do if they fit naturally
|
||||||
if (fitsRegClass(DAG, Operand, RegClass))
|
if (fitsRegClass(DAG, Operand, RegClass))
|
||||||
return;
|
return;
|
||||||
@ -1745,6 +1759,15 @@ SDNode *SITargetLowering::legalizeOperands(MachineSDNode *Node,
|
|||||||
// No scalar allowed when we have both VSrc and SSrc
|
// No scalar allowed when we have both VSrc and SSrc
|
||||||
bool ScalarSlotUsed = HaveVSrc && HaveSSrc;
|
bool ScalarSlotUsed = HaveVSrc && HaveSSrc;
|
||||||
|
|
||||||
|
// If this instruction has an implicit use of VCC, then it can't use the
|
||||||
|
// constant bus.
|
||||||
|
for (unsigned i = 0, e = Desc->getNumImplicitUses(); i != e; ++i) {
|
||||||
|
if (Desc->ImplicitUses[i] == AMDGPU::VCC) {
|
||||||
|
ScalarSlotUsed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Second go over the operands and try to fold them
|
// Second go over the operands and try to fold them
|
||||||
std::vector<SDValue> Ops;
|
std::vector<SDValue> Ops;
|
||||||
for (unsigned i = 0, e = Node->getNumOperands(), Op = NumDefs;
|
for (unsigned i = 0, e = Node->getNumOperands(), Op = NumDefs;
|
||||||
|
@ -747,7 +747,7 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
|
|||||||
const MachineOperand &MO) const {
|
const MachineOperand &MO) const {
|
||||||
const MCOperandInfo &OpInfo = get(MI->getOpcode()).OpInfo[OpNo];
|
const MCOperandInfo &OpInfo = get(MI->getOpcode()).OpInfo[OpNo];
|
||||||
|
|
||||||
assert(MO.isImm() || MO.isFPImm());
|
assert(MO.isImm() || MO.isFPImm() || MO.isTargetIndex() || MO.isFI());
|
||||||
|
|
||||||
if (OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE)
|
if (OpInfo.OperandType == MCOI::OPERAND_IMMEDIATE)
|
||||||
return true;
|
return true;
|
||||||
@ -755,7 +755,10 @@ bool SIInstrInfo::isImmOperandLegal(const MachineInstr *MI, unsigned OpNo,
|
|||||||
if (OpInfo.RegClass < 0)
|
if (OpInfo.RegClass < 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return RI.regClassCanUseImmediate(OpInfo.RegClass);
|
if (isLiteralConstant(MO))
|
||||||
|
return RI.regClassCanUseLiteralConstant(OpInfo.RegClass);
|
||||||
|
|
||||||
|
return RI.regClassCanUseInlineConstant(OpInfo.RegClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) {
|
bool SIInstrInfo::canFoldOffset(unsigned OffsetSize, unsigned AS) {
|
||||||
@ -792,9 +795,41 @@ bool SIInstrInfo::hasModifiers(unsigned Opcode) const {
|
|||||||
AMDGPU::OpName::src0_modifiers) != -1;
|
AMDGPU::OpName::src0_modifiers) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SIInstrInfo::usesConstantBus(const MachineRegisterInfo &MRI,
|
||||||
|
const MachineOperand &MO) const {
|
||||||
|
// Literal constants use the constant bus.
|
||||||
|
if (isLiteralConstant(MO))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!MO.isReg() || !MO.isUse())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (TargetRegisterInfo::isVirtualRegister(MO.getReg()))
|
||||||
|
return RI.isSGPRClass(MRI.getRegClass(MO.getReg()));
|
||||||
|
|
||||||
|
// FLAT_SCR is just an SGPR pair.
|
||||||
|
if (!MO.isImplicit() && (MO.getReg() == AMDGPU::FLAT_SCR))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// EXEC register uses the constant bus.
|
||||||
|
if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// SGPRs use the constant bus
|
||||||
|
if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
|
||||||
|
(!MO.isImplicit() &&
|
||||||
|
(AMDGPU::SGPR_32RegClass.contains(MO.getReg()) ||
|
||||||
|
AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
|
bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
|
||||||
StringRef &ErrInfo) const {
|
StringRef &ErrInfo) const {
|
||||||
uint16_t Opcode = MI->getOpcode();
|
uint16_t Opcode = MI->getOpcode();
|
||||||
|
const MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
|
||||||
int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
|
int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
|
||||||
int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
|
int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
|
||||||
int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
|
int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2);
|
||||||
@ -811,19 +846,12 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
|
|||||||
for (int i = 0, e = Desc.getNumOperands(); i != e; ++i) {
|
for (int i = 0, e = Desc.getNumOperands(); i != e; ++i) {
|
||||||
switch (Desc.OpInfo[i].OperandType) {
|
switch (Desc.OpInfo[i].OperandType) {
|
||||||
case MCOI::OPERAND_REGISTER: {
|
case MCOI::OPERAND_REGISTER: {
|
||||||
int RegClass = Desc.OpInfo[i].RegClass;
|
if ((MI->getOperand(i).isImm() || MI->getOperand(i).isFPImm()) &&
|
||||||
if (!RI.regClassCanUseImmediate(RegClass) &&
|
!isImmOperandLegal(MI, i, MI->getOperand(i))) {
|
||||||
(MI->getOperand(i).isImm() || MI->getOperand(i).isFPImm())) {
|
ErrInfo = "Illegal immediate value for operand.";
|
||||||
// Handle some special cases:
|
|
||||||
// Src0 can of VOP1, VOP2, VOPC can be an immediate no matter what
|
|
||||||
// the register class.
|
|
||||||
if (i != Src0Idx || (!isVOP1(Opcode) && !isVOP2(Opcode) &&
|
|
||||||
!isVOPC(Opcode))) {
|
|
||||||
ErrInfo = "Expected register, but got immediate";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case MCOI::OPERAND_IMMEDIATE:
|
case MCOI::OPERAND_IMMEDIATE:
|
||||||
// Check if this operand is an immediate.
|
// Check if this operand is an immediate.
|
||||||
@ -863,31 +891,15 @@ bool SIInstrInfo::verifyInstruction(const MachineInstr *MI,
|
|||||||
unsigned SGPRUsed = AMDGPU::NoRegister;
|
unsigned SGPRUsed = AMDGPU::NoRegister;
|
||||||
for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
for (int i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
const MachineOperand &MO = MI->getOperand(i);
|
||||||
if (MO.isReg() && MO.isUse() &&
|
if (usesConstantBus(MRI, MO)) {
|
||||||
!TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
|
if (MO.isReg()) {
|
||||||
|
if (MO.getReg() != SGPRUsed)
|
||||||
// EXEC register uses the constant bus.
|
|
||||||
if (!MO.isImplicit() && MO.getReg() == AMDGPU::EXEC)
|
|
||||||
++ConstantBusCount;
|
|
||||||
|
|
||||||
// FLAT_SCR is just an SGPR pair.
|
|
||||||
if (!MO.isImplicit() && (MO.getReg() == AMDGPU::FLAT_SCR))
|
|
||||||
++ConstantBusCount;
|
|
||||||
|
|
||||||
// SGPRs use the constant bus
|
|
||||||
if (MO.getReg() == AMDGPU::M0 || MO.getReg() == AMDGPU::VCC ||
|
|
||||||
(!MO.isImplicit() &&
|
|
||||||
(AMDGPU::SGPR_32RegClass.contains(MO.getReg()) ||
|
|
||||||
AMDGPU::SGPR_64RegClass.contains(MO.getReg())))) {
|
|
||||||
if (SGPRUsed != MO.getReg()) {
|
|
||||||
++ConstantBusCount;
|
++ConstantBusCount;
|
||||||
SGPRUsed = MO.getReg();
|
SGPRUsed = MO.getReg();
|
||||||
}
|
} else {
|
||||||
|
++ConstantBusCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Literal constants use the constant bus.
|
|
||||||
if (isLiteralConstant(MO))
|
|
||||||
++ConstantBusCount;
|
|
||||||
}
|
}
|
||||||
if (ConstantBusCount > 1) {
|
if (ConstantBusCount > 1) {
|
||||||
ErrInfo = "VOP* instruction uses the constant bus more than once";
|
ErrInfo = "VOP* instruction uses the constant bus more than once";
|
||||||
@ -1136,6 +1148,18 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
|
|||||||
if (!MO)
|
if (!MO)
|
||||||
MO = &MI->getOperand(OpIdx);
|
MO = &MI->getOperand(OpIdx);
|
||||||
|
|
||||||
|
if (usesConstantBus(MRI, *MO)) {
|
||||||
|
unsigned SGPRUsed = MO->isReg() ? MO->getReg() : AMDGPU::NoRegister;
|
||||||
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
|
if (i == OpIdx)
|
||||||
|
continue;
|
||||||
|
if (usesConstantBus(MRI, MI->getOperand(i)) &&
|
||||||
|
MI->getOperand(i).isReg() && MI->getOperand(i).getReg() != SGPRUsed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (MO->isReg()) {
|
if (MO->isReg()) {
|
||||||
assert(DefinedRC);
|
assert(DefinedRC);
|
||||||
const TargetRegisterClass *RC = MRI.getRegClass(MO->getReg());
|
const TargetRegisterClass *RC = MRI.getRegClass(MO->getReg());
|
||||||
@ -1151,7 +1175,7 @@ bool SIInstrInfo::isOperandLegal(const MachineInstr *MI, unsigned OpIdx,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RI.regClassCanUseImmediate(DefinedRC);
|
return isImmOperandLegal(MI, OpIdx, *MO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
|
void SIInstrInfo::legalizeOperands(MachineInstr *MI) const {
|
||||||
|
@ -132,6 +132,10 @@ public:
|
|||||||
/// This function will return false if you pass it a 32-bit instruction.
|
/// This function will return false if you pass it a 32-bit instruction.
|
||||||
bool hasVALU32BitEncoding(unsigned Opcode) const;
|
bool hasVALU32BitEncoding(unsigned Opcode) const;
|
||||||
|
|
||||||
|
/// \brief Returns true if this operand uses the constant bus.
|
||||||
|
bool usesConstantBus(const MachineRegisterInfo &MRI,
|
||||||
|
const MachineOperand &MO) const;
|
||||||
|
|
||||||
/// \brief Return true if this instruction has any modifiers.
|
/// \brief Return true if this instruction has any modifiers.
|
||||||
/// e.g. src[012]_mod, omod, clamp.
|
/// e.g. src[012]_mod, omod, clamp.
|
||||||
bool hasModifiers(unsigned Opcode) const;
|
bool hasModifiers(unsigned Opcode) const;
|
||||||
|
@ -361,7 +361,7 @@ class getInRC32 <list<ValueType> SrcVT> {
|
|||||||
// Returns the register class to use for sources of VOP3 instructions for the
|
// Returns the register class to use for sources of VOP3 instructions for the
|
||||||
// given VT.
|
// given VT.
|
||||||
class getVOP3SrcForVT<ValueType VT> {
|
class getVOP3SrcForVT<ValueType VT> {
|
||||||
RegisterClass ret = !if(!eq(VT.Size, 32), VSrc_32, VSrc_64);
|
RegisterClass ret = !if(!eq(VT.Size, 32), VCSrc_32, VCSrc_64);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the register classes for the source arguments of a VOP3
|
// Returns the register classes for the source arguments of a VOP3
|
||||||
@ -494,7 +494,7 @@ def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
|
|||||||
def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
|
def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
|
||||||
def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
|
def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
|
||||||
def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
|
def VOP_I32_I32_I32_VCC : VOPProfile <[i32, i32, i32, untyped]> {
|
||||||
let Src0RC32 = VReg_32;
|
let Src0RC32 = VCSrc_32;
|
||||||
}
|
}
|
||||||
def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
|
def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
|
||||||
def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
|
def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
|
||||||
|
@ -275,7 +275,7 @@ unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg,
|
|||||||
return SubRC->getRegister(Index + Channel);
|
return SubRC->getRegister(Index + Channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIRegisterInfo::regClassCanUseImmediate(int RCID) const {
|
bool SIRegisterInfo::regClassCanUseLiteralConstant(int RCID) const {
|
||||||
switch (RCID) {
|
switch (RCID) {
|
||||||
default: return false;
|
default: return false;
|
||||||
case AMDGPU::SSrc_32RegClassID:
|
case AMDGPU::SSrc_32RegClassID:
|
||||||
@ -286,11 +286,29 @@ bool SIRegisterInfo::regClassCanUseImmediate(int RCID) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SIRegisterInfo::regClassCanUseImmediate(
|
bool SIRegisterInfo::regClassCanUseLiteralConstant(
|
||||||
const TargetRegisterClass *RC) const {
|
const TargetRegisterClass *RC) const {
|
||||||
return regClassCanUseImmediate(RC->getID());
|
return regClassCanUseLiteralConstant(RC->getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SIRegisterInfo::regClassCanUseInlineConstant(int RCID) const {
|
||||||
|
if (regClassCanUseLiteralConstant(RCID))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (RCID) {
|
||||||
|
default: return false;
|
||||||
|
case AMDGPU::VCSrc_32RegClassID:
|
||||||
|
case AMDGPU::VCSrc_64RegClassID:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SIRegisterInfo::regClassCanUseInlineConstant(
|
||||||
|
const TargetRegisterClass *RC) const {
|
||||||
|
return regClassCanUseInlineConstant(RC->getID());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
|
unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF,
|
||||||
enum PreloadedValue Value) const {
|
enum PreloadedValue Value) const {
|
||||||
|
|
||||||
|
@ -68,12 +68,21 @@ struct SIRegisterInfo : public AMDGPURegisterInfo {
|
|||||||
unsigned Channel) const;
|
unsigned Channel) const;
|
||||||
|
|
||||||
/// \returns True if operands defined with this register class can accept
|
/// \returns True if operands defined with this register class can accept
|
||||||
/// inline immediates.
|
/// a literal constant (i.e. any 32-bit immediate).
|
||||||
bool regClassCanUseImmediate(int RCID) const;
|
bool regClassCanUseLiteralConstant(int RCID) const;
|
||||||
|
|
||||||
/// \returns True if operands defined with this register class can accept
|
/// \returns True if operands defined with this register class can accept
|
||||||
/// inline immediates.
|
/// a literal constant (i.e. any 32-bit immediate).
|
||||||
bool regClassCanUseImmediate(const TargetRegisterClass *RC) const;
|
bool regClassCanUseLiteralConstant(const TargetRegisterClass *RC) const;
|
||||||
|
|
||||||
|
/// \returns True if operands defined with this register class can accept
|
||||||
|
/// an inline constant. i.e. An integer value in the range (-16, 64) or
|
||||||
|
/// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
|
||||||
|
bool regClassCanUseInlineConstant(int RCID) const;
|
||||||
|
|
||||||
|
/// \returns True if operands defined with this register class can accept
|
||||||
|
/// a literal constant. i.e. A value in the range (-16, 64).
|
||||||
|
bool regClassCanUseInlineConstant(const TargetRegisterClass *RC) const;
|
||||||
|
|
||||||
enum PreloadedValue {
|
enum PreloadedValue {
|
||||||
TGID_X,
|
TGID_X,
|
||||||
|
@ -210,17 +210,29 @@ def VReg_512 : RegisterClass<"AMDGPU", [v16i32, v16f32], 512, (add VGPR_512)>;
|
|||||||
def VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add VGPR_32)>;
|
def VReg_1 : RegisterClass<"AMDGPU", [i1], 32, (add VGPR_32)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// [SV]Src_(32|64) register classes, can have either an immediate or an register
|
// SSrc_* Operands with an SGPR or a 32-bit immediate
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def SSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add SReg_32)>;
|
def SSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add SReg_32)>;
|
||||||
|
|
||||||
def SSrc_64 : RegisterClass<"AMDGPU", [i64, f64, i1], 64, (add SReg_64)>;
|
def SSrc_64 : RegisterClass<"AMDGPU", [i64, f64, i1], 64, (add SReg_64)>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// VSrc_* Operands with an SGPR, VGPR or a 32-bit immediate
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
def VSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
|
def VSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
|
||||||
|
|
||||||
def VSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
|
def VSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// VCSrc_* Operands with an SGPR, VGPR or an inline constant
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
def VCSrc_32 : RegisterClass<"AMDGPU", [i32, f32], 32, (add VReg_32, SReg_32)>;
|
||||||
|
|
||||||
|
def VCSrc_64 : RegisterClass<"AMDGPU", [i64, f64], 64, (add VReg_64, SReg_64)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// SGPR and VGPR register classes
|
// SGPR and VGPR register classes
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
Loading…
x
Reference in New Issue
Block a user