diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -339,7 +339,7 @@ bool isSWZ() const { return isImmTy(ImmTySWZ); } bool isTFE() const { return isImmTy(ImmTyTFE); } bool isD16() const { return isImmTy(ImmTyD16); } - bool isFORMAT() const { return isImmTy(ImmTyFORMAT) && isUInt<8>(getImm()); } + bool isFORMAT() const { return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); } bool isBankMask() const { return isImmTy(ImmTyDppBankMask); } bool isRowMask() const { return isImmTy(ImmTyDppRowMask); } bool isBoundCtrl() const { return isImmTy(ImmTyDppBoundCtrl); } @@ -1295,7 +1295,10 @@ OperandMatchResultTy parseRegWithFPInputMods(OperandVector &Operands); OperandMatchResultTy parseRegWithIntInputMods(OperandVector &Operands); OperandMatchResultTy parseVReg32OrOff(OperandVector &Operands); - OperandMatchResultTy parseDfmtNfmt(OperandVector &Operands); + OperandMatchResultTy parseDfmtNfmt(int64_t &Format); + OperandMatchResultTy parseUfmt(int64_t &Format); + OperandMatchResultTy parseFORMAT(OperandVector &Operands); + bool tryParseFmt(const char *Pref, int64_t MaxVal, int64_t &Val); void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands); void cvtDS(MCInst &Inst, const OperandVector &Operands) { cvtDSImpl(Inst, Operands, false); } @@ -4870,50 +4873,96 @@ return MatchOperand_Success; } +//===----------------------------------------------------------------------===// +// MTBUF format +//===----------------------------------------------------------------------===// + +bool AMDGPUAsmParser::tryParseFmt(const char *Pref, + int64_t MaxVal, + int64_t &Fmt) { + int64_t Val; + SMLoc Loc = getLoc(); + + auto Res = parseIntWithPrefix(Pref, Val); + if (Res == MatchOperand_ParseFail) + return false; + if (Res == MatchOperand_NoMatch) + return true; + + if (Val < 0 || Val > MaxVal) { + Error(Loc, Twine("out of range ", StringRef(Pref))); + return false; + } + + Fmt = Val; + return true; +} + // dfmt and nfmt (in a tbuffer instruction) are parsed as one to allow their // values to live in a joint format operand in the MCInst encoding. OperandMatchResultTy -AMDGPUAsmParser::parseDfmtNfmt(OperandVector &Operands) { - SMLoc S = Parser.getTok().getLoc(); - int64_t Dfmt = 0, Nfmt = 0; +AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) { + using namespace llvm::AMDGPU::MTBUFFormat; + + int64_t Dfmt = DFMT_UNDEF; + int64_t Nfmt = NFMT_UNDEF; + // dfmt and nfmt can appear in either order, and each is optional. - bool GotDfmt = false, GotNfmt = false; - while (!GotDfmt || !GotNfmt) { - if (!GotDfmt) { - auto Res = parseIntWithPrefix("dfmt", Dfmt); - if (Res != MatchOperand_NoMatch) { - if (Res != MatchOperand_Success) - return Res; - if (Dfmt >= 16) { - Error(Parser.getTok().getLoc(), "out of range dfmt"); - return MatchOperand_ParseFail; - } - GotDfmt = true; - Parser.Lex(); - continue; - } + for (int I = 0; I < 2; ++I) { + if (Dfmt == DFMT_UNDEF && !tryParseFmt("dfmt", DFMT_MAX, Dfmt)) + return MatchOperand_ParseFail; + + if (Nfmt == NFMT_UNDEF && !tryParseFmt("nfmt", NFMT_MAX, Nfmt)) { + return MatchOperand_ParseFail; } - if (!GotNfmt) { - auto Res = parseIntWithPrefix("nfmt", Nfmt); - if (Res != MatchOperand_NoMatch) { - if (Res != MatchOperand_Success) - return Res; - if (Nfmt >= 8) { - Error(Parser.getTok().getLoc(), "out of range nfmt"); - return MatchOperand_ParseFail; - } - GotNfmt = true; - Parser.Lex(); - continue; - } + // Skip optional comma between dfmt/nfmt + // but guard against 2 commas following each other. + if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) && + !peekToken().is(AsmToken::Comma)) { + trySkipToken(AsmToken::Comma); } - break; } - if (!GotDfmt && !GotNfmt) + + if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF) return MatchOperand_NoMatch; - auto Format = Dfmt | Nfmt << 4; + + Dfmt = (Dfmt == DFMT_UNDEF)? DFMT_DEFAULT : Dfmt; + Nfmt = (Nfmt == NFMT_UNDEF)? NFMT_DEFAULT : Nfmt; + + Format = encodeDfmtNfmt(Dfmt, Nfmt); + return MatchOperand_Success; +} + +OperandMatchResultTy +AMDGPUAsmParser::parseUfmt(int64_t &Format) { + using namespace llvm::AMDGPU::MTBUFFormat; + + int64_t Fmt = UFMT_UNDEF; + + if (!tryParseFmt("format", UFMT_MAX, Fmt)) + return MatchOperand_ParseFail; + + if (Fmt == UFMT_UNDEF) + return MatchOperand_NoMatch; + + Format = Fmt; + return MatchOperand_Success; +} + +OperandMatchResultTy +AMDGPUAsmParser::parseFORMAT(OperandVector &Operands) { + using namespace llvm::AMDGPU::MTBUFFormat; + + int64_t Format = isGFX10() ? UFMT_DEFAULT : DFMT_NFMT_DEFAULT; + OperandMatchResultTy Res; + SMLoc Loc = getLoc(); + + Res = isGFX10() ? parseUfmt(Format) : parseDfmtNfmt(Format); + if (Res == MatchOperand_ParseFail) + return Res; + Operands.push_back( - AMDGPUOperand::CreateImm(this, Format, S, AMDGPUOperand::ImmTyFORMAT)); + AMDGPUOperand::CreateImm(this, Format, Loc, AMDGPUOperand::ImmTyFORMAT)); return MatchOperand_Success; } @@ -6242,7 +6291,6 @@ {"offset", AMDGPUOperand::ImmTyOffset, false, nullptr}, {"inst_offset", AMDGPUOperand::ImmTyInstOffset, false, nullptr}, {"dlc", AMDGPUOperand::ImmTyDLC, true, nullptr}, - {"format", AMDGPUOperand::ImmTyFORMAT, false, nullptr}, {"glc", AMDGPUOperand::ImmTyGLC, true, nullptr}, {"slc", AMDGPUOperand::ImmTySLC, true, nullptr}, {"swz", AMDGPUOperand::ImmTySWZ, true, nullptr}, @@ -6327,8 +6375,6 @@ Op.ConvertResult); } else if (Op.Type == AMDGPUOperand::ImmTyDim) { res = parseDim(Operands); - } else if (Op.Type == AMDGPUOperand::ImmTyFORMAT && !isGFX10()) { - res = parseDfmtNfmt(Operands); } else { res = parseIntWithPrefix(Op.Name, Operands, Op.Type, Op.ConvertResult); } diff --git a/llvm/lib/Target/AMDGPU/BUFInstructions.td b/llvm/lib/Target/AMDGPU/BUFInstructions.td --- a/llvm/lib/Target/AMDGPU/BUFInstructions.td +++ b/llvm/lib/Target/AMDGPU/BUFInstructions.td @@ -168,15 +168,15 @@ class getMTBUFAsmOps { string Pfx = - !if(!eq(addrKind, BUFAddrKind.Offset), "off, $srsrc, $format, $soffset", + !if(!eq(addrKind, BUFAddrKind.Offset), "off, $srsrc,$format $soffset", !if(!eq(addrKind, BUFAddrKind.OffEn), - "$vaddr, $srsrc, $format, $soffset offen", + "$vaddr, $srsrc,$format $soffset offen", !if(!eq(addrKind, BUFAddrKind.IdxEn), - "$vaddr, $srsrc, $format, $soffset idxen", + "$vaddr, $srsrc,$format $soffset idxen", !if(!eq(addrKind, BUFAddrKind.BothEn), - "$vaddr, $srsrc, $format, $soffset idxen offen", + "$vaddr, $srsrc,$format $soffset idxen offen", !if(!eq(addrKind, BUFAddrKind.Addr64), - "$vaddr, $srsrc, $format, $soffset addr64", + "$vaddr, $srsrc,$format $soffset addr64", ""))))); string ret = Pfx # "$offset"; } diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp @@ -299,14 +299,23 @@ void AMDGPUInstPrinter::printFORMAT(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O) { - if (unsigned Val = MI->getOperand(OpNo).getImm()) { - if (AMDGPU::isGFX10(STI)) - O << " format:" << Val; - else { - O << " dfmt:" << (Val & 15); - O << ", nfmt:" << (Val >> 4); - } + using namespace llvm::AMDGPU::MTBUFFormat; + + unsigned Val = MI->getOperand(OpNo).getImm(); + if (AMDGPU::isGFX10(STI)) { + if (Val == UFMT_DEFAULT) + return; + O << " format:" << Val; + } else { + if (Val == DFMT_NFMT_DEFAULT) + return; + unsigned Dfmt; + unsigned Nfmt; + decodeDfmtNfmt(Val, Dfmt, Nfmt); + O << " dfmt:" << Dfmt; + O << ", nfmt:" << Nfmt; } + O << ','; } void AMDGPUInstPrinter::printRegOperand(unsigned RegNo, raw_ostream &O, diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h --- a/llvm/lib/Target/AMDGPU/SIDefines.h +++ b/llvm/lib/Target/AMDGPU/SIDefines.h @@ -392,6 +392,48 @@ } // namespace Hwreg +namespace MTBUFFormat { + +enum DataFormat { + DFMT_MAX = 15, + + DFMT_UNDEF = -1, + DFMT_DEFAULT = 1, + + DFMT_SHIFT = 0, + DFMT_MASK = DFMT_MAX +}; + +enum NumFormat { + NFMT_MAX = 7, + + NFMT_UNDEF = -1, + NFMT_DEFAULT = 0, + + NFMT_SHIFT = 4, + NFMT_MASK = NFMT_MAX +}; + +enum MergedFormat { + DFMT_NFMT_UNDEF = -1, + DFMT_NFMT_DEFAULT = ((DFMT_DEFAULT & DFMT_MASK) << DFMT_SHIFT) | + ((NFMT_DEFAULT & NFMT_MASK) << NFMT_SHIFT), + + + DFMT_NFMT_MASK = (DFMT_MASK << DFMT_SHIFT) | (NFMT_MASK << NFMT_SHIFT), + + DFMT_NFMT_MAX = DFMT_NFMT_MASK +}; + +enum UnifiedFormat { + UFMT_MAX = 127, + + UFMT_UNDEF = -1, + UFMT_DEFAULT = 1 +}; + +} // namespace MTBUFFormat + namespace Swizzle { // Encoding of swizzle macro used in ds_swizzle_b32. enum Id : unsigned { // id of symbolic names diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -1115,7 +1115,7 @@ def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>; def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>; -def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT">>; +def FORMAT : NamedOperandU8<"FORMAT", NamedMatchClass<"FORMAT", 0>>; def DMask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>; def Dim : NamedOperandU8<"Dim", NamedMatchClass<"Dim", 0>>; diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -482,6 +482,15 @@ } // namespace Hwreg +namespace MTBUFFormat { + +LLVM_READNONE +int64_t encodeDfmtNfmt(unsigned Dfmt, unsigned Nfmt); + +void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt); + +} // namespace MTBUFFormat + namespace SendMsg { LLVM_READONLY diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -783,6 +783,23 @@ } // namespace Hwreg +//===----------------------------------------------------------------------===// +// MTBUF Format +//===----------------------------------------------------------------------===// + +namespace MTBUFFormat { + +int64_t encodeDfmtNfmt(unsigned Dfmt, unsigned Nfmt) { + return (Dfmt << DFMT_SHIFT) | (Nfmt << NFMT_SHIFT); +} + +void decodeDfmtNfmt(unsigned Format, unsigned &Dfmt, unsigned &Nfmt) { + Dfmt = (Format >> DFMT_SHIFT) & DFMT_MASK; + Nfmt = (Format >> NFMT_SHIFT) & NFMT_MASK; +} + +} // namespace MTBUFFormat + //===----------------------------------------------------------------------===// // SendMsg //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AMDGPU/mtbuf-gfx10.s b/llvm/test/MC/AMDGPU/mtbuf-gfx10.s --- a/llvm/test/MC/AMDGPU/mtbuf-gfx10.s +++ b/llvm/test/MC/AMDGPU/mtbuf-gfx10.s @@ -1,4 +1,5 @@ -// RUN: llvm-mc -arch=amdgcn -mcpu=gfx1010 -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=GFX10 %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1010 -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=GFX10 %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx1010 -show-encoding %s 2>&1 | FileCheck -check-prefix=GFX10-ERR %s // GFX10: tbuffer_load_format_d16_x v0, off, s[0:3], format:22, 0 ; encoding: [0x00,0x00,0xb0,0xe8,0x00,0x00,0x20,0x80] tbuffer_load_format_d16_x v0, off, s[0:3], format:22, 0 @@ -66,3 +67,49 @@ tbuffer_store_format_x v0, v1, s[0:3], format:125, 0 idxen // GFX10: tbuffer_store_format_xy v[0:1], v2, s[0:3], format:33, 0 idxen ; encoding: [0x00,0x20,0x0d,0xe9,0x02,0x00,0x00,0x80] tbuffer_store_format_xy v[0:1], v2, s[0:3], format:33, 0 idxen + +// GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:127, 0 idxen ; encoding: [0x00,0x20,0xfc,0xeb,0x01,0x00,0x00,0x80] +tbuffer_store_format_x v0, v1, s[0:3], format:127, 0 idxen + +// GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:127, 0 idxen ; encoding: [0x00,0x20,0xfc,0xeb,0x01,0x00,0x00,0x80] +tbuffer_store_format_x v0, v1, s[0:3] format:127 0 idxen + +// GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:0, s0 idxen ; encoding: [0x00,0x20,0x04,0xe8,0x01,0x00,0x00,0x00] +tbuffer_store_format_x v0, v1, s[0:3] format:0 s0 idxen + +// GFX10: tbuffer_store_format_x v0, v1, s[0:3], s0 idxen ; encoding: [0x00,0x20,0x0c,0xe8,0x01,0x00,0x00,0x00] +tbuffer_store_format_x v0, v1, s[0:3] format:1 s0 idxen + +// GFX10: tbuffer_store_format_x v0, v1, s[0:3], 0 idxen ; encoding: [0x00,0x20,0x0c,0xe8,0x01,0x00,0x00,0x80] +tbuffer_store_format_x v0, v1, s[0:3], 0 idxen + +// GFX10: tbuffer_load_format_d16_x v0, off, s[0:3], s0 ; encoding: [0x00,0x00,0x08,0xe8,0x00,0x00,0x20,0x00] +tbuffer_load_format_d16_x v0, off, s[0:3] s0 + +//===----------------------------------------------------------------------===// +// Errors handling. +//===----------------------------------------------------------------------===// + +// GFX10-ERR: error: out of range format +tbuffer_load_format_d16_x v0, off, s[0:3], format:-1, 0 + +// GFX10-ERR: error: out of range format +tbuffer_load_format_d16_x v0, off, s[0:3], format:128, s0 + +// GFX10-ERR: error: too few operands for instruction +tbuffer_load_format_d16_x v0, off, s[0:3], format:127 + +// GFX10-ERR: error: too few operands for instruction +tbuffer_load_format_d16_x v0, off, s[0:3] + +// GFX10-ERR: error: invalid operand for instruction +tbuffer_load_format_d16_x v0, off, s[0:3] idxen + +// GFX10-ERR: error: unknown token in expression +tbuffer_load_format_d16_x v0, off, s[0:3], format:1,, s0 + +// GFX10-ERR: error: unknown token in expression +tbuffer_load_format_d16_x v0, off, s[0:3], format:1:, s0 + +// GFX10-ERR: error: not a valid operand +tbuffer_load_format_d16_x v0, off, s[0:3],, format:1, s0 diff --git a/llvm/test/MC/AMDGPU/mtbuf.s b/llvm/test/MC/AMDGPU/mtbuf.s --- a/llvm/test/MC/AMDGPU/mtbuf.s +++ b/llvm/test/MC/AMDGPU/mtbuf.s @@ -1,6 +1,10 @@ -// RUN: llvm-mc -arch=amdgcn -mcpu=tahiti -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=SI -check-prefix=SICI %s -// RUN: llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=CI -check-prefix=SICI %s -// RUN: llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=VI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=SI -check-prefix=SICI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=CI -check-prefix=SICI %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=VI %s + +// RUN: not llvm-mc -arch=amdgcn -mcpu=tahiti -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN-ERR %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN-ERR %s +// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN-ERR %s //===----------------------------------------------------------------------===// // Test for dfmt and nfmt (tbuffer only) @@ -45,11 +49,81 @@ // dfmt is optional: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], nfmt:2, ttmp1 -// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:2, ttmp1 ; encoding: [0x00,0x00,0x07,0xe9,0x00,0x01,0x1d,0x71] -// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:2, ttmp1 ; encoding: [0x00,0x80,0x03,0xe9,0x00,0x01,0x1d,0x71] +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:1, nfmt:2, ttmp1 ; encoding: [0x00,0x00,0x0f,0xe9,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:1, nfmt:2, ttmp1 ; encoding: [0x00,0x80,0x0b,0xe9,0x00,0x01,0x1d,0x71] // nfmt and dfmt can be in either order: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], nfmt:2, dfmt:15, ttmp1 // SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:2, ttmp1 ; encoding: [0x00,0x00,0x7f,0xe9,0x00,0x01,0x1d,0x71] // VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:2, ttmp1 ; encoding: [0x00,0x80,0x7b,0xe9,0x00,0x01,0x1d,0x71] +// nfmt and dfmt may be omitted: +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 ; encoding: [0x00,0x00,0x0f,0xe8,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 ; encoding: [0x00,0x80,0x0b,0xe8,0x00,0x01,0x1d,0x71] + +// Check dfmt/nfmt min values +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:0, ttmp1 +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:0, ttmp1 ; encoding: [0x00,0x00,0x07,0xe8,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:0, ttmp1 ; encoding: [0x00,0x80,0x03,0xe8,0x00,0x01,0x1d,0x71] + +// Check dfmt/nfmt max values +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 ; encoding: [0x00,0x00,0xff,0xeb,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 ; encoding: [0x00,0x80,0xfb,0xeb,0x00,0x01,0x1d,0x71] + +// Check default dfmt/nfmt values +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:1, nfmt:0, ttmp1 +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 ; encoding: [0x00,0x00,0x0f,0xe8,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 ; encoding: [0x00,0x80,0x0b,0xe8,0x00,0x01,0x1d,0x71] + +// Check that comma separators are optional +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:15 nfmt:7 ttmp1 +// SICI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 ; encoding: [0x00,0x00,0xff,0xeb,0x00,0x01,0x1d,0x71] +// VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 ; encoding: [0x00,0x80,0xfb,0xeb,0x00,0x01,0x1d,0x71] + +//===----------------------------------------------------------------------===// +// Errors handling. +//===----------------------------------------------------------------------===// + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:-1 nfmt:1 s0 +// GCN-ERR: error: out of range dfmt + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:16 nfmt:1 s0 +// GCN-ERR: error: out of range dfmt + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 nfmt:-1 s0 +// GCN-ERR: error: out of range nfmt + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 nfmt:8 s0 +// GCN-ERR: error: out of range nfmt + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] +// GCN-ERR: error: too few operands for instruction + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7],, dfmt:1 nfmt:1 s0 +// GCN-ERR: error: not a valid operand + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1,, nfmt:1 s0 +// GCN-ERR: error: unknown token in expression + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 nfmt:1,, s0 +// GCN-ERR: error: unknown token in expression + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 dfmt:1 s0 +// GCN-ERR: error: not a valid operand + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] nfmt:1 nfmt:1 s0 +// GCN-ERR: error: not a valid operand + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 nfmt:1 dfmt:1 s0 +// GCN-ERR: error: not a valid operand + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] nfmt:1 dfmt:1 nfmt:1 s0 +// GCN-ERR: error: not a valid operand + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1: nfmt:1 s0 +// GCN-ERR: error: unknown token in expression + +tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7] dfmt:1 nfmt:1: s0 +// GCN-ERR: error: unknown token in expression diff --git a/llvm/test/MC/Disassembler/AMDGPU/mtbuf_gfx10.txt b/llvm/test/MC/Disassembler/AMDGPU/mtbuf_gfx10.txt --- a/llvm/test/MC/Disassembler/AMDGPU/mtbuf_gfx10.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/mtbuf_gfx10.txt @@ -67,3 +67,20 @@ # GFX10: tbuffer_store_format_xy v[0:1], v2, s[0:3], format:33, 0 idxen 0x00,0x20,0x0d,0xe9,0x02,0x00,0x00,0x80 +# GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:127, 0 idxen ; encoding: [0x00,0x20,0xfc,0xeb,0x01,0x00,0x00,0x80] +0x00,0x20,0xfc,0xeb,0x01,0x00,0x00,0x80 + +# GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:0, 0 idxen ; encoding: [0x00,0x20,0x04,0xe8,0x01,0x00,0x00,0x80] +0x00,0x20,0x04,0xe8,0x01,0x00,0x00,0x80 + +# GFX10: tbuffer_load_format_d16_x v0, off, s[0:3], format:0, s0 ; encoding: [0x00,0x00,0x00,0xe8,0x00,0x00,0x20,0x00] +0x00,0x00,0x00,0xe8,0x00,0x00,0x20,0x00 + +# GFX10: tbuffer_store_format_x v0, v1, s[0:3], 0 idxen ; encoding: [0x00,0x20,0x0c,0xe8,0x01,0x00,0x00,0x80] +0x00,0x20,0x0c,0xe8,0x01,0x00,0x00,0x80 + +# GFX10: tbuffer_load_format_d16_x v0, off, s[0:3], s0 ; encoding: [0x00,0x00,0x08,0xe8,0x00,0x00,0x20,0x00] +0x00,0x00,0x08,0xe8,0x00,0x00,0x20,0x00 + +# GFX10: tbuffer_store_format_x v0, v1, s[0:3], format:2, s0 idxen ; encoding: [0x00,0x20,0x14,0xe8,0x01,0x00,0x00,0x00] +0x00,0x20,0x14,0xe8,0x01,0x00,0x00,0x00 diff --git a/llvm/test/MC/Disassembler/AMDGPU/mtbuf_vi.txt b/llvm/test/MC/Disassembler/AMDGPU/mtbuf_vi.txt --- a/llvm/test/MC/Disassembler/AMDGPU/mtbuf_vi.txt +++ b/llvm/test/MC/Disassembler/AMDGPU/mtbuf_vi.txt @@ -20,3 +20,21 @@ # VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:2, ttmp1 ; encoding: [0x00,0x80,0x7b,0xe9,0x00,0x01,0x1d,0x71] 0x00 0x80 0x7b 0xe9 0x00 0x01 0x1d 0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:2, ttmp1 ; encoding: [0x00,0x80,0x03,0xe9,0x00,0x01,0x1d,0x71] +0x00,0x80,0x03,0xe9,0x00,0x01,0x1d,0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:0, ttmp1 ; encoding: [0x00,0x80,0x7b,0xe8,0x00,0x01,0x1d,0x71] +0x00,0x80,0x7b,0xe8,0x00,0x01,0x1d,0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], ttmp1 ; encoding: [0x00,0x80,0x0b,0xe8,0x00,0x01,0x1d,0x71] +0x00,0x80,0x0b,0xe8,0x00,0x01,0x1d,0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:0, nfmt:0, ttmp1 ; encoding: [0x00,0x80,0x03,0xe8,0x00,0x01,0x1d,0x71] +0x00,0x80,0x03,0xe8,0x00,0x01,0x1d,0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:1, nfmt:1, ttmp1 ; encoding: [0x00,0x80,0x8b,0xe8,0x00,0x01,0x1d,0x71] +0x00,0x80,0x8b,0xe8,0x00,0x01,0x1d,0x71 + +# VI: tbuffer_store_format_xyzw v[1:4], off, ttmp[4:7], dfmt:15, nfmt:7, ttmp1 ; encoding: [0x00,0x80,0xfb,0xeb,0x00,0x01,0x1d,0x71] +0x00,0x80,0xfb,0xeb,0x00,0x01,0x1d,0x71