|
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 |
|
@@ -5132,6 +5171,11 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
|
5132 | 5171 | Error(getRegLoc(LDS_DIRECT, Operands), *ErrMsg);
|
5133 | 5172 | return false;
|
5134 | 5173 | }
|
| 5174 | + if (!validateTrue16OpSel(Inst)) { |
| 5175 | + Error(getImmLoc(AMDGPUOperand::ImmTyOpSel, Operands), |
| 5176 | + "op_sel operand conflicts with 16-bit operand suffix"); |
| 5177 | + return false; |
| 5178 | + } |
5135 | 5179 | if (!validateSOPLiteral(Inst)) {
|
5136 | 5180 | Error(getLitLoc(Operands),
|
5137 | 5181 | "only one unique literal operand is allowed");
|
|
0 commit comments