|
33 | 33 | #include "llvm/MC/MCParser/MCAsmParser.h" |
34 | 34 | #include "llvm/MC/MCParser/MCParsedAsmOperand.h" |
35 | 35 | #include "llvm/MC/MCParser/MCTargetAsmParser.h" |
| 36 | +#include "llvm/MC/MCRegisterInfo.h" |
36 | 37 | #include "llvm/MC/MCSymbol.h" |
37 | 38 | #include "llvm/MC/TargetRegistry.h" |
38 | 39 | #include "llvm/Support/AMDGPUMetadata.h" |
@@ -1536,6 +1537,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser { |
1536 | 1537 | return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets]; |
1537 | 1538 | } |
1538 | 1539 |
|
| 1540 | + bool hasTrue16Insts() const { |
| 1541 | + return getFeatureBits()[AMDGPU::FeatureTrue16BitInsts]; |
| 1542 | + } |
| 1543 | + |
1539 | 1544 | bool hasArchitectedFlatScratch() const { |
1540 | 1545 | return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch]; |
1541 | 1546 | } |
@@ -1777,6 +1782,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser { |
1777 | 1782 | bool validateMIMGDim(const MCInst &Inst, const OperandVector &Operands); |
1778 | 1783 | bool validateMIMGMSAA(const MCInst &Inst); |
1779 | 1784 | bool validateOpSel(const MCInst &Inst); |
| 1785 | + bool validateTrue16OpSel(const MCInst &Inst); |
1780 | 1786 | bool validateNeg(const MCInst &Inst, int OpName); |
1781 | 1787 | bool validateDPP(const MCInst &Inst, const OperandVector &Operands); |
1782 | 1788 | bool validateVccOperand(MCRegister Reg) const; |
@@ -4651,6 +4657,39 @@ bool AMDGPUAsmParser::validateOpSel(const MCInst &Inst) { |
4651 | 4657 | return true; |
4652 | 4658 | } |
4653 | 4659 |
|
| 4660 | +bool AMDGPUAsmParser::validateTrue16OpSel(const MCInst &Inst) { |
| 4661 | + if (!hasTrue16Insts()) |
| 4662 | + return true; |
| 4663 | + const MCRegisterInfo *MRI = getMRI(); |
| 4664 | + const unsigned Opc = Inst.getOpcode(); |
| 4665 | + int OpSelIdx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel); |
| 4666 | + if (OpSelIdx == -1) |
| 4667 | + return true; |
| 4668 | + unsigned OpSelOpValue = Inst.getOperand(OpSelIdx).getImm(); |
| 4669 | + // If the value is 0 we could have a default OpSel Operand, so conservatively |
| 4670 | + // allow it. |
| 4671 | + if (OpSelOpValue == 0) |
| 4672 | + return true; |
| 4673 | + unsigned OpCount = 0; |
| 4674 | + for (int OpName : {AMDGPU::OpName::src0, AMDGPU::OpName::src1, |
| 4675 | + AMDGPU::OpName::src2, AMDGPU::OpName::vdst}) { |
| 4676 | + int OpIdx = AMDGPU::getNamedOperandIdx(Inst.getOpcode(), OpName); |
| 4677 | + if (OpIdx == -1) |
| 4678 | + continue; |
| 4679 | + const MCOperand &Op = Inst.getOperand(OpIdx); |
| 4680 | + if (Op.isReg() && |
| 4681 | + MRI->getRegClass(AMDGPU::VGPR_16RegClassID).contains(Op.getReg())) { |
| 4682 | + bool VGPRSuffixIsHi = AMDGPU::isHi16Reg(Op.getReg(), *MRI); |
| 4683 | + bool OpSelOpIsHi = ((OpSelOpValue & (1 << OpCount)) != 0); |
| 4684 | + if (OpSelOpIsHi != VGPRSuffixIsHi) |
| 4685 | + return false; |
| 4686 | + } |
| 4687 | + ++OpCount; |
| 4688 | + } |
| 4689 | + |
| 4690 | + return true; |
| 4691 | +} |
| 4692 | + |
4654 | 4693 | bool AMDGPUAsmParser::validateNeg(const MCInst &Inst, int OpName) { |
4655 | 4694 | assert(OpName == AMDGPU::OpName::neg_lo || OpName == AMDGPU::OpName::neg_hi); |
4656 | 4695 |
|
@@ -5135,6 +5174,11 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, |
5135 | 5174 | Error(getRegLoc(LDS_DIRECT, Operands), *ErrMsg); |
5136 | 5175 | return false; |
5137 | 5176 | } |
| 5177 | + if (!validateTrue16OpSel(Inst)) { |
| 5178 | + Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands), |
| 5179 | + "op_sel operand conflicts with 16-bit operand suffix"); |
| 5180 | + return false; |
| 5181 | + } |
5138 | 5182 | if (!validateSOPLiteral(Inst)) { |
5139 | 5183 | Error(getLitLoc(Operands), |
5140 | 5184 | "only one unique literal operand is allowed"); |
|
0 commit comments