diff options
| author | Dmitry Preobrazhensky <dmitry.preobrazhensky@amd.com> | 2019-02-08 14:57:37 +0000 |
|---|---|---|
| committer | Dmitry Preobrazhensky <dmitry.preobrazhensky@amd.com> | 2019-02-08 14:57:37 +0000 |
| commit | 942c273d64c651b3fe8b802ecade1dd707ca5902 (patch) | |
| tree | b3d71ffd834f6ac13dd95af7eb9752b7797c73ff /llvm/lib/Target/AMDGPU/AsmParser | |
| parent | 01d6bfc94da5527e087e6443be39064fad66a490 (diff) | |
| download | bcm5719-llvm-942c273d64c651b3fe8b802ecade1dd707ca5902.tar.gz bcm5719-llvm-942c273d64c651b3fe8b802ecade1dd707ca5902.zip | |
[AMDGPU][MC] Added support of lds_direct operand
See bug 39293: https://bugs.llvm.org/show_bug.cgi?id=39293
Reviewers: artem.tamazov, rampitec
Differential Revision: https://reviews.llvm.org/D57889
llvm-svn: 353524
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index 89c0d48e117..0f0731bfc22 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1095,6 +1095,7 @@ private: bool validateMIMGGatherDMask(const MCInst &Inst); bool validateMIMGDataSize(const MCInst &Inst); bool validateMIMGD16(const MCInst &Inst); + bool validateLdsDirect(const MCInst &Inst); bool usesConstantBus(const MCInst &Inst, unsigned OpIdx); bool isInlineConstant(const MCInst &Inst, unsigned OpIdx) const; unsigned findImplicitSGPRReadInVOP(const MCInst &Inst) const; @@ -1599,6 +1600,8 @@ static unsigned getSpecialRegForName(StringRef RegName) { .Case("vcc", AMDGPU::VCC) .Case("flat_scratch", AMDGPU::FLAT_SCR) .Case("xnack_mask", AMDGPU::XNACK_MASK) + .Case("lds_direct", AMDGPU::LDS_DIRECT) + .Case("src_lds_direct", AMDGPU::LDS_DIRECT) .Case("m0", AMDGPU::M0) .Case("scc", AMDGPU::SCC) .Case("tba", AMDGPU::TBA) @@ -2465,6 +2468,86 @@ bool AMDGPUAsmParser::validateMIMGD16(const MCInst &Inst) { return true; } +bool AMDGPUAsmParser::validateLdsDirect(const MCInst &Inst) { + + using namespace SIInstrFlags; + const unsigned Opcode = Inst.getOpcode(); + const MCInstrDesc &Desc = MII.get(Opcode); + + // lds_direct register is defined so that it can be used + // with 9-bit operands only. Ignore encodings which do not accept these. + if ((Desc.TSFlags & (VOP1 | VOP2 | VOP3 | VOPC | VOP3P | SIInstrFlags::SDWA)) == 0) + return true; + + const int Src0Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0); + const int Src1Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1); + const int Src2Idx = AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src2); + + const int SrcIndices[] = { Src1Idx, Src2Idx }; + + // lds_direct cannot be specified as either src1 or src2. + for (int SrcIdx : SrcIndices) { + if (SrcIdx == -1) break; + const MCOperand &Src = Inst.getOperand(SrcIdx); + if (Src.isReg() && Src.getReg() == LDS_DIRECT) { + return false; + } + } + + if (Src0Idx == -1) + return true; + + const MCOperand &Src = Inst.getOperand(Src0Idx); + if (!Src.isReg() || Src.getReg() != LDS_DIRECT) + return true; + + // lds_direct is specified as src0. Check additional limitations. + + // FIXME: This is a workaround for bug 37943 + // which allows 64-bit VOP3 opcodes use 32-bit operands. + if (AMDGPU::getRegOperandSize(getMRI(), Desc, Src0Idx) != 4) + return false; + + // Documentation does not disable lds_direct for SDWA, but SP3 assembler does. + // FIXME: This inconsistence needs to be investigated further. + if (Desc.TSFlags & SIInstrFlags::SDWA) + return false; + + // The following opcodes do not accept lds_direct which is explicitly stated + // in AMD documentation. However SP3 disables lds_direct for most other 'rev' + // opcodes as well (e.g. for v_subrev_u32 but not for v_subrev_f32). + // FIXME: This inconsistence needs to be investigated further. + switch (Opcode) { + case AMDGPU::V_LSHLREV_B32_e32_si: + case AMDGPU::V_LSHLREV_B32_e64_si: + case AMDGPU::V_LSHLREV_B16_e32_vi: + case AMDGPU::V_LSHLREV_B16_e64_vi: + case AMDGPU::V_LSHLREV_B32_e32_vi: + case AMDGPU::V_LSHLREV_B32_e64_vi: + case AMDGPU::V_LSHLREV_B64_vi: + case AMDGPU::V_LSHRREV_B32_e32_si: + case AMDGPU::V_LSHRREV_B32_e64_si: + case AMDGPU::V_LSHRREV_B16_e32_vi: + case AMDGPU::V_LSHRREV_B16_e64_vi: + case AMDGPU::V_LSHRREV_B32_e32_vi: + case AMDGPU::V_LSHRREV_B32_e64_vi: + case AMDGPU::V_LSHRREV_B64_vi: + case AMDGPU::V_ASHRREV_I32_e64_si: + case AMDGPU::V_ASHRREV_I32_e32_si: + case AMDGPU::V_ASHRREV_I16_e32_vi: + case AMDGPU::V_ASHRREV_I16_e64_vi: + case AMDGPU::V_ASHRREV_I32_e32_vi: + case AMDGPU::V_ASHRREV_I32_e64_vi: + case AMDGPU::V_ASHRREV_I64_vi: + case AMDGPU::V_PK_LSHLREV_B16_vi: + case AMDGPU::V_PK_LSHRREV_B16_vi: + case AMDGPU::V_PK_ASHRREV_I16_vi: + return false; + default: + return true; + } +} + bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const { unsigned Opcode = Inst.getOpcode(); const MCInstrDesc &Desc = MII.get(Opcode); @@ -2500,6 +2583,11 @@ bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const { bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst, const SMLoc &IDLoc) { + if (!validateLdsDirect(Inst)) { + Error(IDLoc, + "invalid use of lds_direct"); + return false; + } if (!validateSOPLiteral(Inst)) { Error(IDLoc, "only one literal operand is allowed"); |

