summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp29
-rw-r--r--llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp24
-rw-r--r--llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp4
-rw-r--r--llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h2
4 files changed, 44 insertions, 15 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
index 5d5fe6ecee7..8052ea8253e 100644
--- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
+++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
@@ -911,6 +911,10 @@ public:
return AMDGPU::hasMIMG_R128(getSTI());
}
+ bool hasPackedD16() const {
+ return AMDGPU::hasPackedD16(getSTI());
+ }
+
bool isSI() const {
return AMDGPU::isSI(getSTI());
}
@@ -2309,7 +2313,12 @@ bool AMDGPUAsmParser::validateMIMGDataSize(const MCInst &Inst) {
if (DMask == 0)
DMask = 1;
- return (VDataSize / 4) == countPopulation(DMask) + TFESize;
+ unsigned DataSize = countPopulation(DMask);
+ if ((Desc.TSFlags & SIInstrFlags::D16) != 0 && hasPackedD16()) {
+ DataSize = (DataSize + 1) / 2;
+ }
+
+ return (VDataSize / 4) == DataSize + TFESize;
}
bool AMDGPUAsmParser::validateMIMGAtomicDMask(const MCInst &Inst) {
@@ -2378,25 +2387,25 @@ bool AMDGPUAsmParser::validateInstruction(const MCInst &Inst,
"integer clamping is not supported on this GPU");
return false;
}
- if (!validateMIMGDataSize(Inst)) {
+ if (!validateMIMGR128(Inst)) {
Error(IDLoc,
- "image data size does not match dmask and tfe");
+ "r128 modifier is not supported on this GPU");
return false;
}
- if (!validateMIMGAtomicDMask(Inst)) {
+ // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate.
+ if (!validateMIMGD16(Inst)) {
Error(IDLoc,
- "invalid atomic image dmask");
+ "d16 modifier is not supported on this GPU");
return false;
}
- if (!validateMIMGR128(Inst)) {
+ if (!validateMIMGDataSize(Inst)) {
Error(IDLoc,
- "r128 modifier is not supported on this GPU");
+ "image data size does not match dmask and tfe");
return false;
}
- // For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate.
- if (!validateMIMGD16(Inst)) {
+ if (!validateMIMGAtomicDMask(Inst)) {
Error(IDLoc,
- "d16 modifier is not supported on this GPU");
+ "invalid atomic image dmask");
return false;
}
diff --git a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
index 32f1248dae5..578fe50146e 100644
--- a/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
+++ b/llvm/lib/Target/AMDGPU/Disassembler/AMDGPUDisassembler.cpp
@@ -269,6 +269,9 @@ DecodeStatus AMDGPUDisassembler::convertSDWAInst(MCInst &MI) const {
return MCDisassembler::Success;
}
+// Note that MIMG format provides no information about VADDR size.
+// Consequently, decoded instructions always show address
+// as if it has 1 dword, which could be not really so.
DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const {
int VDstIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
AMDGPU::OpName::vdst);
@@ -279,8 +282,12 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const {
int DMaskIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
AMDGPU::OpName::dmask);
+ int TFEIdx = AMDGPU::getNamedOperandIdx(MI.getOpcode(),
+ AMDGPU::OpName::tfe);
+
assert(VDataIdx != -1);
assert(DMaskIdx != -1);
+ assert(TFEIdx != -1);
bool isAtomic = (VDstIdx != -1);
@@ -288,19 +295,28 @@ DecodeStatus AMDGPUDisassembler::convertMIMGInst(MCInst &MI) const {
if (DMask == 0)
return MCDisassembler::Success;
- unsigned ChannelCount = countPopulation(DMask);
- if (ChannelCount == 1)
+ unsigned DstSize = countPopulation(DMask);
+ if (DstSize == 1)
+ return MCDisassembler::Success;
+
+ bool D16 = MCII->get(MI.getOpcode()).TSFlags & SIInstrFlags::D16;
+ if (D16 && AMDGPU::hasPackedD16(STI)) {
+ DstSize = (DstSize + 1) / 2;
+ }
+
+ // FIXME: Add tfe support
+ if (MI.getOperand(TFEIdx).getImm())
return MCDisassembler::Success;
int NewOpcode = -1;
if (isAtomic) {
if (DMask == 0x1 || DMask == 0x3 || DMask == 0xF) {
- NewOpcode = AMDGPU::getMaskedMIMGAtomicOp(*MCII, MI.getOpcode(), ChannelCount);
+ NewOpcode = AMDGPU::getMaskedMIMGAtomicOp(*MCII, MI.getOpcode(), DstSize);
}
if (NewOpcode == -1) return MCDisassembler::Success;
} else {
- NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), ChannelCount);
+ NewOpcode = AMDGPU::getMaskedMIMGOp(*MCII, MI.getOpcode(), DstSize);
assert(NewOpcode != -1 && "could not find matching mimg channel instruction");
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
index 594fa935223..50311c241f2 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp
@@ -628,6 +628,10 @@ bool hasMIMG_R128(const MCSubtargetInfo &STI) {
return STI.getFeatureBits()[AMDGPU::FeatureMIMG_R128];
}
+bool hasPackedD16(const MCSubtargetInfo &STI) {
+ return !STI.getFeatureBits()[AMDGPU::FeatureUnpackedD16VMem];
+}
+
bool isSI(const MCSubtargetInfo &STI) {
return STI.getFeatureBits()[AMDGPU::FeatureSouthernIslands];
}
diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
index 9e143aa7cf9..5e15e2e233a 100644
--- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
+++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h
@@ -284,8 +284,8 @@ inline bool isKernel(CallingConv::ID CC) {
}
bool hasXNACK(const MCSubtargetInfo &STI);
-
bool hasMIMG_R128(const MCSubtargetInfo &STI);
+bool hasPackedD16(const MCSubtargetInfo &STI);
bool isSI(const MCSubtargetInfo &STI);
bool isCI(const MCSubtargetInfo &STI);
OpenPOWER on IntegriCloud