12
12
#include " MCTargetDesc/AMDGPUMCTargetDesc.h"
13
13
#include " MCTargetDesc/AMDGPUTargetStreamer.h"
14
14
#include " SIDefines.h"
15
+ #include " SIInstrInfo.h"
15
16
#include " Utils/AMDGPUAsmUtils.h"
16
17
#include " Utils/AMDGPUBaseInfo.h"
17
18
#include " Utils/AMDKernelCodeTUtils.h"
@@ -128,6 +129,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
128
129
enum ImmTy {
129
130
ImmTyNone,
130
131
ImmTyGDS,
132
+ ImmTyLDS,
131
133
ImmTyOffen,
132
134
ImmTyIdxen,
133
135
ImmTyAddr64,
@@ -303,6 +305,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
303
305
bool isOffsetU12 () const { return (isImmTy (ImmTyOffset) || isImmTy (ImmTyInstOffset)) && isUInt<12 >(getImm ()); }
304
306
bool isOffsetS13 () const { return (isImmTy (ImmTyOffset) || isImmTy (ImmTyInstOffset)) && isInt<13 >(getImm ()); }
305
307
bool isGDS () const { return isImmTy (ImmTyGDS); }
308
+ bool isLDS () const { return isImmTy (ImmTyLDS); }
306
309
bool isGLC () const { return isImmTy (ImmTyGLC); }
307
310
bool isSLC () const { return isImmTy (ImmTySLC); }
308
311
bool isTFE () const { return isImmTy (ImmTyTFE); }
@@ -649,6 +652,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
649
652
switch (Type) {
650
653
case ImmTyNone: OS << " None" ; break ;
651
654
case ImmTyGDS: OS << " GDS" ; break ;
655
+ case ImmTyLDS: OS << " LDS" ; break ;
652
656
case ImmTyOffen: OS << " Offen" ; break ;
653
657
case ImmTyIdxen: OS << " Idxen" ; break ;
654
658
case ImmTyAddr64: OS << " Addr64" ; break ;
@@ -4078,6 +4082,7 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultTFE() const {
4078
4082
void AMDGPUAsmParser::cvtMubufImpl (MCInst &Inst,
4079
4083
const OperandVector &Operands,
4080
4084
bool IsAtomic, bool IsAtomicReturn) {
4085
+ bool HasLdsModifier = false ;
4081
4086
OptionalImmIndexMap OptionalIdx;
4082
4087
assert (IsAtomicReturn ? IsAtomic : true );
4083
4088
@@ -4096,6 +4101,8 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
4096
4101
continue ;
4097
4102
}
4098
4103
4104
+ HasLdsModifier = Op.isLDS ();
4105
+
4099
4106
// Handle tokens like 'offen' which are sometimes hard-coded into the
4100
4107
// asm string. There are no MCInst operands for these.
4101
4108
if (Op.isToken ()) {
@@ -4107,6 +4114,20 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
4107
4114
OptionalIdx[Op.getImmTy ()] = i;
4108
4115
}
4109
4116
4117
+ // This is a workaround for an llvm quirk which may result in an
4118
+ // incorrect instruction selection. Lds and non-lds versions of
4119
+ // MUBUF instructions are identical except that lds versions
4120
+ // have mandatory 'lds' modifier. However this modifier follows
4121
+ // optional modifiers and llvm asm matcher regards this 'lds'
4122
+ // modifier as an optional one. As a result, an lds version
4123
+ // of opcode may be selected even if it has no 'lds' modifier.
4124
+ if (!HasLdsModifier) {
4125
+ int NoLdsOpcode = AMDGPU::getMUBUFNoLdsInst (Inst.getOpcode ());
4126
+ if (NoLdsOpcode != -1 ) { // Got lds version - correct it.
4127
+ Inst.setOpcode (NoLdsOpcode);
4128
+ }
4129
+ }
4130
+
4110
4131
// Copy $vdata_in operand and insert as $vdata for MUBUF_Atomic RTN insns.
4111
4132
if (IsAtomicReturn) {
4112
4133
MCInst::iterator I = Inst.begin (); // $vdata_in is always at the beginning.
@@ -4118,7 +4139,10 @@ void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
4118
4139
addOptionalImmOperand (Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyGLC);
4119
4140
}
4120
4141
addOptionalImmOperand (Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTySLC);
4121
- addOptionalImmOperand (Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
4142
+
4143
+ if (!HasLdsModifier) { // tfe is not legal with lds opcodes
4144
+ addOptionalImmOperand (Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyTFE);
4145
+ }
4122
4146
}
4123
4147
4124
4148
void AMDGPUAsmParser::cvtMtbuf (MCInst &Inst, const OperandVector &Operands) {
@@ -4312,6 +4336,7 @@ static const OptionalOperand AMDGPUOptionalOperandTable[] = {
4312
4336
{" offset0" , AMDGPUOperand::ImmTyOffset0, false , nullptr },
4313
4337
{" offset1" , AMDGPUOperand::ImmTyOffset1, false , nullptr },
4314
4338
{" gds" , AMDGPUOperand::ImmTyGDS, true , nullptr },
4339
+ {" lds" , AMDGPUOperand::ImmTyLDS, true , nullptr },
4315
4340
{" offset" , AMDGPUOperand::ImmTyOffset, false , nullptr },
4316
4341
{" inst_offset" , AMDGPUOperand::ImmTyInstOffset, false , nullptr },
4317
4342
{" dfmt" , AMDGPUOperand::ImmTyDFMT, false , nullptr },
@@ -5022,6 +5047,8 @@ unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
5022
5047
return Operand.isAddr64 () ? Match_Success : Match_InvalidOperand;
5023
5048
case MCK_gds:
5024
5049
return Operand.isGDS () ? Match_Success : Match_InvalidOperand;
5050
+ case MCK_lds:
5051
+ return Operand.isLDS () ? Match_Success : Match_InvalidOperand;
5025
5052
case MCK_glc:
5026
5053
return Operand.isGLC () ? Match_Success : Match_InvalidOperand;
5027
5054
case MCK_d16:
0 commit comments