Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
AMDGPUAsmParser.cpp
Go to the documentation of this file.
1//===- AMDGPUAsmParser.cpp - Parse SI asm to MCInst instructions ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "AMDKernelCodeT.h"
10#include "MCTargetDesc/AMDGPUInstPrinter.h"
11#include "MCTargetDesc/AMDGPUMCExpr.h"
12#include "MCTargetDesc/AMDGPUMCKernelDescriptor.h"
13#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
14#include "MCTargetDesc/AMDGPUTargetStreamer.h"
15#include "SIDefines.h"
16#include "SIInstrInfo.h"
17#include "TargetInfo/AMDGPUTargetInfo.h"
18#include "Utils/AMDGPUAsmUtils.h"
19#include "Utils/AMDGPUBaseInfo.h"
20#include "Utils/AMDKernelCodeTUtils.h"
21#include "llvm/ADT/APFloat.h"
22#include "llvm/ADT/SmallBitVector.h"
23#include "llvm/ADT/StringSet.h"
24#include "llvm/ADT/Twine.h"
25#include "llvm/BinaryFormat/ELF.h"
26#include "llvm/CodeGenTypes/MachineValueType.h"
27#include "llvm/MC/MCAsmInfo.h"
28#include "llvm/MC/MCContext.h"
29#include "llvm/MC/MCExpr.h"
30#include "llvm/MC/MCInst.h"
31#include "llvm/MC/MCInstrDesc.h"
32#include "llvm/MC/MCParser/MCAsmLexer.h"
33#include "llvm/MC/MCParser/MCAsmParser.h"
34#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
35#include "llvm/MC/MCParser/MCTargetAsmParser.h"
36#include "llvm/MC/MCSymbol.h"
37#include "llvm/MC/TargetRegistry.h"
38#include "llvm/Support/AMDGPUMetadata.h"
39#include "llvm/Support/AMDHSAKernelDescriptor.h"
40#include "llvm/Support/Casting.h"
41#include "llvm/Support/MathExtras.h"
42#include "llvm/TargetParser/TargetParser.h"
43#include <optional>
44
45using namespacellvm;
46using namespacellvm::AMDGPU;
47using namespacellvm::amdhsa;
48
49namespace{
50
51classAMDGPUAsmParser;
52
53enum RegisterKind { IS_UNKNOWN,IS_VGPR, IS_SGPR,IS_AGPR, IS_TTMP, IS_SPECIAL };
54
55//===----------------------------------------------------------------------===//
56// Operand
57//===----------------------------------------------------------------------===//
58
59classAMDGPUOperand :publicMCParsedAsmOperand {
60enum KindTy {
61 Token,
62 Immediate,
63Register,
64Expression
65 }Kind;
66
67SMLoc StartLoc, EndLoc;
68const AMDGPUAsmParser *AsmParser;
69
70public:
71 AMDGPUOperand(KindTy Kind_,const AMDGPUAsmParser *AsmParser_)
72 :Kind(Kind_), AsmParser(AsmParser_) {}
73
74usingPtr = std::unique_ptr<AMDGPUOperand>;
75
76structModifiers {
77bool Abs =false;
78bool Neg =false;
79bool Sext =false;
80bool Lit =false;
81
82bool hasFPModifiers() const{return Abs || Neg; }
83bool hasIntModifiers() const{return Sext; }
84bool hasModifiers() const{return hasFPModifiers() || hasIntModifiers(); }
85
86 int64_t getFPModifiersOperand() const{
87 int64_t Operand = 0;
88 Operand |= Abs ?SISrcMods::ABS : 0u;
89 Operand |= Neg ?SISrcMods::NEG : 0u;
90return Operand;
91 }
92
93 int64_t getIntModifiersOperand() const{
94 int64_t Operand = 0;
95 Operand |= Sext ?SISrcMods::SEXT : 0u;
96return Operand;
97 }
98
99 int64_t getModifiersOperand() const{
100assert(!(hasFPModifiers() && hasIntModifiers())
101 &&"fp and int modifiers should not be used simultaneously");
102if (hasFPModifiers())
103return getFPModifiersOperand();
104if (hasIntModifiers())
105return getIntModifiersOperand();
106return 0;
107 }
108
109friendraw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
110 };
111
112enum ImmTy {
113 ImmTyNone,
114 ImmTyGDS,
115 ImmTyLDS,
116 ImmTyOffen,
117 ImmTyIdxen,
118 ImmTyAddr64,
119 ImmTyOffset,
120 ImmTyInstOffset,
121 ImmTyOffset0,
122 ImmTyOffset1,
123 ImmTySMEMOffsetMod,
124 ImmTyCPol,
125 ImmTyTFE,
126 ImmTyD16,
127 ImmTyClamp,
128 ImmTyOModSI,
129 ImmTySDWADstSel,
130 ImmTySDWASrc0Sel,
131 ImmTySDWASrc1Sel,
132 ImmTySDWADstUnused,
133 ImmTyDMask,
134 ImmTyDim,
135 ImmTyUNorm,
136 ImmTyDA,
137 ImmTyR128A16,
138 ImmTyA16,
139 ImmTyLWE,
140 ImmTyExpTgt,
141 ImmTyExpCompr,
142 ImmTyExpVM,
143 ImmTyFORMAT,
144 ImmTyHwreg,
145 ImmTyOff,
146 ImmTySendMsg,
147 ImmTyInterpSlot,
148 ImmTyInterpAttr,
149 ImmTyInterpAttrChan,
150 ImmTyOpSel,
151 ImmTyOpSelHi,
152 ImmTyNegLo,
153 ImmTyNegHi,
154 ImmTyIndexKey8bit,
155 ImmTyIndexKey16bit,
156 ImmTyDPP8,
157 ImmTyDppCtrl,
158 ImmTyDppRowMask,
159 ImmTyDppBankMask,
160 ImmTyDppBoundCtrl,
161 ImmTyDppFI,
162 ImmTySwizzle,
163 ImmTyGprIdxMode,
164 ImmTyHigh,
165 ImmTyBLGP,
166 ImmTyCBSZ,
167 ImmTyABID,
168 ImmTyEndpgm,
169 ImmTyWaitVDST,
170 ImmTyWaitEXP,
171 ImmTyWaitVAVDst,
172 ImmTyWaitVMVSrc,
173 ImmTyByteSel,
174 ImmTyBitOp3,
175 };
176
177// Immediate operand kind.
178// It helps to identify the location of an offending operand after an error.
179// Note that regular literals and mandatory literals (KImm) must be handled
180// differently. When looking for an offending operand, we should usually
181// ignore mandatory literals because they are part of the instruction and
182// cannot be changed. Report location of mandatory operands only for VOPD,
183// when both OpX and OpY have a KImm and there are no other literals.
184enum ImmKindTy {
185 ImmKindTyNone,
186 ImmKindTyLiteral,
187 ImmKindTyMandatoryLiteral,
188 ImmKindTyConst,
189 };
190
191private:
192structTokOp {
193constchar *Data;
194unsignedLength;
195 };
196
197structImmOp {
198 int64_t Val;
199 ImmTyType;
200bool IsFPImm;
201mutable ImmKindTyKind;
202 Modifiers Mods;
203 };
204
205structRegOp {
206MCRegister RegNo;
207 Modifiers Mods;
208 };
209
210union{
211 TokOp Tok;
212 ImmOpImm;
213 RegOpReg;
214constMCExpr *Expr;
215 };
216
217public:
218boolisToken() const override{returnKind == Token; }
219
220bool isSymbolRefExpr() const{
221return isExpr() && Expr && isa<MCSymbolRefExpr>(Expr);
222 }
223
224boolisImm() const override{
225returnKind == Immediate;
226 }
227
228void setImmKindNone() const{
229assert(isImm());
230Imm.Kind = ImmKindTyNone;
231 }
232
233void setImmKindLiteral() const{
234assert(isImm());
235Imm.Kind = ImmKindTyLiteral;
236 }
237
238void setImmKindMandatoryLiteral() const{
239assert(isImm());
240Imm.Kind = ImmKindTyMandatoryLiteral;
241 }
242
243void setImmKindConst() const{
244assert(isImm());
245Imm.Kind = ImmKindTyConst;
246 }
247
248bool IsImmKindLiteral() const{
249returnisImm() &&Imm.Kind == ImmKindTyLiteral;
250 }
251
252bool IsImmKindMandatoryLiteral() const{
253returnisImm() &&Imm.Kind == ImmKindTyMandatoryLiteral;
254 }
255
256bool isImmKindConst() const{
257returnisImm() &&Imm.Kind == ImmKindTyConst;
258 }
259
260bool isInlinableImm(MVT type)const;
261bool isLiteralImm(MVT type)const;
262
263bool isRegKind() const{
264returnKind ==Register;
265 }
266
267boolisReg() const override{
268return isRegKind() && !hasModifiers();
269 }
270
271bool isRegOrInline(unsigned RCID,MVT type) const{
272return isRegClass(RCID) || isInlinableImm(type);
273 }
274
275boolisRegOrImmWithInputMods(unsigned RCID,MVT type) const{
276return isRegOrInline(RCID, type) || isLiteralImm(type);
277 }
278
279bool isRegOrImmWithInt16InputMods() const{
280returnisRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::i16);
281 }
282
283template <bool IsFake16>bool isRegOrImmWithIntT16InputMods() const{
284returnisRegOrImmWithInputMods(
285 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
286 }
287
288bool isRegOrImmWithInt32InputMods() const{
289returnisRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::i32);
290 }
291
292bool isRegOrInlineImmWithInt16InputMods() const{
293return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i16);
294 }
295
296template <bool IsFake16>bool isRegOrInlineImmWithIntT16InputMods() const{
297return isRegOrInline(
298 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::i16);
299 }
300
301bool isRegOrInlineImmWithInt32InputMods() const{
302return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::i32);
303 }
304
305bool isRegOrImmWithInt64InputMods() const{
306returnisRegOrImmWithInputMods(AMDGPU::VS_64RegClassID, MVT::i64);
307 }
308
309bool isRegOrImmWithFP16InputMods() const{
310returnisRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::f16);
311 }
312
313template <bool IsFake16>bool isRegOrImmWithFPT16InputMods() const{
314returnisRegOrImmWithInputMods(
315 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
316 }
317
318bool isRegOrImmWithFP32InputMods() const{
319returnisRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::f32);
320 }
321
322bool isRegOrImmWithFP64InputMods() const{
323returnisRegOrImmWithInputMods(AMDGPU::VS_64RegClassID, MVT::f64);
324 }
325
326template <bool IsFake16>bool isRegOrInlineImmWithFP16InputMods() const{
327return isRegOrInline(
328 IsFake16 ? AMDGPU::VS_32RegClassID : AMDGPU::VS_16RegClassID, MVT::f16);
329 }
330
331bool isRegOrInlineImmWithFP32InputMods() const{
332return isRegOrInline(AMDGPU::VS_32RegClassID, MVT::f32);
333 }
334
335bool isPackedFP16InputMods() const{
336returnisRegOrImmWithInputMods(AMDGPU::VS_32RegClassID, MVT::v2f16);
337 }
338
339bool isPackedFP32InputMods() const{
340returnisRegOrImmWithInputMods(AMDGPU::VS_64RegClassID, MVT::v2f32);
341 }
342
343bool isVReg() const{
344return isRegClass(AMDGPU::VGPR_32RegClassID) ||
345 isRegClass(AMDGPU::VReg_64RegClassID) ||
346 isRegClass(AMDGPU::VReg_96RegClassID) ||
347 isRegClass(AMDGPU::VReg_128RegClassID) ||
348 isRegClass(AMDGPU::VReg_160RegClassID) ||
349 isRegClass(AMDGPU::VReg_192RegClassID) ||
350 isRegClass(AMDGPU::VReg_256RegClassID) ||
351 isRegClass(AMDGPU::VReg_512RegClassID) ||
352 isRegClass(AMDGPU::VReg_1024RegClassID);
353 }
354
355bool isVReg32() const{
356return isRegClass(AMDGPU::VGPR_32RegClassID);
357 }
358
359bool isVReg32OrOff() const{
360return isOff() || isVReg32();
361 }
362
363bool isNull() const{
364return isRegKind() &&getReg() == AMDGPU::SGPR_NULL;
365 }
366
367bool isVRegWithInputMods()const;
368template <bool IsFake16>bool isT16_Lo128VRegWithInputMods()const;
369template <bool IsFake16>bool isT16VRegWithInputMods()const;
370
371bool isSDWAOperand(MVT type)const;
372bool isSDWAFP16Operand()const;
373bool isSDWAFP32Operand()const;
374bool isSDWAInt16Operand()const;
375bool isSDWAInt32Operand()const;
376
377bool isImmTy(ImmTy ImmT) const{
378returnisImm() &&Imm.Type == ImmT;
379 }
380
381template <ImmTy Ty>bool isImmTy() const{return isImmTy(Ty); }
382
383bool isImmLiteral() const{return isImmTy(ImmTyNone); }
384
385bool isImmModifier() const{
386returnisImm() &&Imm.Type != ImmTyNone;
387 }
388
389bool isOModSI() const{return isImmTy(ImmTyOModSI); }
390bool isDim() const{return isImmTy(ImmTyDim); }
391bool isR128A16() const{return isImmTy(ImmTyR128A16); }
392bool isOff() const{return isImmTy(ImmTyOff); }
393bool isExpTgt() const{return isImmTy(ImmTyExpTgt); }
394bool isOffen() const{return isImmTy(ImmTyOffen); }
395bool isIdxen() const{return isImmTy(ImmTyIdxen); }
396bool isAddr64() const{return isImmTy(ImmTyAddr64); }
397bool isSMEMOffsetMod() const{return isImmTy(ImmTySMEMOffsetMod); }
398bool isFlatOffset() const{return isImmTy(ImmTyOffset) || isImmTy(ImmTyInstOffset); }
399bool isGDS() const{return isImmTy(ImmTyGDS); }
400bool isLDS() const{return isImmTy(ImmTyLDS); }
401bool isCPol() const{return isImmTy(ImmTyCPol); }
402bool isIndexKey8bit() const{return isImmTy(ImmTyIndexKey8bit); }
403bool isIndexKey16bit() const{return isImmTy(ImmTyIndexKey16bit); }
404bool isTFE() const{return isImmTy(ImmTyTFE); }
405bool isFORMAT() const{return isImmTy(ImmTyFORMAT) && isUInt<7>(getImm()); }
406bool isDppFI() const{return isImmTy(ImmTyDppFI); }
407bool isSDWADstSel() const{return isImmTy(ImmTySDWADstSel); }
408bool isSDWASrc0Sel() const{return isImmTy(ImmTySDWASrc0Sel); }
409bool isSDWASrc1Sel() const{return isImmTy(ImmTySDWASrc1Sel); }
410bool isSDWADstUnused() const{return isImmTy(ImmTySDWADstUnused); }
411bool isInterpSlot() const{return isImmTy(ImmTyInterpSlot); }
412bool isInterpAttr() const{return isImmTy(ImmTyInterpAttr); }
413bool isInterpAttrChan() const{return isImmTy(ImmTyInterpAttrChan); }
414bool isOpSel() const{return isImmTy(ImmTyOpSel); }
415bool isOpSelHi() const{return isImmTy(ImmTyOpSelHi); }
416bool isNegLo() const{return isImmTy(ImmTyNegLo); }
417bool isNegHi() const{return isImmTy(ImmTyNegHi); }
418bool isBitOp3() const{return isImmTy(ImmTyBitOp3) && isUInt<8>(getImm()); }
419
420bool isRegOrImm() const{
421returnisReg() ||isImm();
422 }
423
424bool isRegClass(unsigned RCID)const;
425
426boolisInlineValue()const;
427
428bool isRegOrInlineNoMods(unsigned RCID,MVT type) const{
429return isRegOrInline(RCID, type) && !hasModifiers();
430 }
431
432bool isSCSrcB16() const{
433return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i16);
434 }
435
436bool isSCSrcV2B16() const{
437return isSCSrcB16();
438 }
439
440bool isSCSrc_b32() const{
441return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::i32);
442 }
443
444bool isSCSrc_b64() const{
445return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::i64);
446 }
447
448bool isBoolReg()const;
449
450bool isSCSrcF16() const{
451return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f16);
452 }
453
454bool isSCSrcV2F16() const{
455return isSCSrcF16();
456 }
457
458bool isSCSrcF32() const{
459return isRegOrInlineNoMods(AMDGPU::SReg_32RegClassID, MVT::f32);
460 }
461
462bool isSCSrcF64() const{
463return isRegOrInlineNoMods(AMDGPU::SReg_64RegClassID, MVT::f64);
464 }
465
466bool isSSrc_b32() const{
467return isSCSrc_b32() || isLiteralImm(MVT::i32) || isExpr();
468 }
469
470bool isSSrc_b16() const{return isSCSrcB16() || isLiteralImm(MVT::i16); }
471
472bool isSSrcV2B16() const{
473llvm_unreachable("cannot happen");
474return isSSrc_b16();
475 }
476
477bool isSSrc_b64() const{
478// TODO: Find out how SALU supports extension of 32-bit literals to 64 bits.
479// See isVSrc64().
480return isSCSrc_b64() || isLiteralImm(MVT::i64);
481 }
482
483bool isSSrc_f32() const{
484return isSCSrc_b32() || isLiteralImm(MVT::f32) || isExpr();
485 }
486
487bool isSSrcF64() const{return isSCSrc_b64() || isLiteralImm(MVT::f64); }
488
489bool isSSrc_bf16() const{return isSCSrcB16() || isLiteralImm(MVT::bf16); }
490
491bool isSSrc_f16() const{return isSCSrcB16() || isLiteralImm(MVT::f16); }
492
493bool isSSrcV2F16() const{
494llvm_unreachable("cannot happen");
495return isSSrc_f16();
496 }
497
498bool isSSrcV2FP32() const{
499llvm_unreachable("cannot happen");
500return isSSrc_f32();
501 }
502
503bool isSCSrcV2FP32() const{
504llvm_unreachable("cannot happen");
505return isSCSrcF32();
506 }
507
508bool isSSrcV2INT32() const{
509llvm_unreachable("cannot happen");
510return isSSrc_b32();
511 }
512
513bool isSCSrcV2INT32() const{
514llvm_unreachable("cannot happen");
515return isSCSrc_b32();
516 }
517
518bool isSSrcOrLds_b32() const{
519return isRegOrInlineNoMods(AMDGPU::SRegOrLds_32RegClassID, MVT::i32) ||
520 isLiteralImm(MVT::i32) || isExpr();
521 }
522
523bool isVCSrc_b32() const{
524return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i32);
525 }
526
527bool isVCSrcB64() const{
528return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::i64);
529 }
530
531bool isVCSrcT_b16() const{
532return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::i16);
533 }
534
535bool isVCSrcTB16_Lo128() const{
536return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::i16);
537 }
538
539bool isVCSrcFake16B16_Lo128() const{
540return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::i16);
541 }
542
543bool isVCSrc_b16() const{
544return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::i16);
545 }
546
547bool isVCSrc_v2b16() const{return isVCSrc_b16(); }
548
549bool isVCSrc_f32() const{
550return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f32);
551 }
552
553bool isVCSrcF64() const{
554return isRegOrInlineNoMods(AMDGPU::VS_64RegClassID, MVT::f64);
555 }
556
557bool isVCSrcTBF16() const{
558return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::bf16);
559 }
560
561bool isVCSrcT_f16() const{
562return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
563 }
564
565bool isVCSrcT_bf16() const{
566return isRegOrInlineNoMods(AMDGPU::VS_16RegClassID, MVT::f16);
567 }
568
569bool isVCSrcTBF16_Lo128() const{
570return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::bf16);
571 }
572
573bool isVCSrcTF16_Lo128() const{
574return isRegOrInlineNoMods(AMDGPU::VS_16_Lo128RegClassID, MVT::f16);
575 }
576
577bool isVCSrcFake16BF16_Lo128() const{
578return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::bf16);
579 }
580
581bool isVCSrcFake16F16_Lo128() const{
582return isRegOrInlineNoMods(AMDGPU::VS_32_Lo128RegClassID, MVT::f16);
583 }
584
585bool isVCSrc_bf16() const{
586return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::bf16);
587 }
588
589bool isVCSrc_f16() const{
590return isRegOrInlineNoMods(AMDGPU::VS_32RegClassID, MVT::f16);
591 }
592
593bool isVCSrc_v2bf16() const{return isVCSrc_bf16(); }
594
595bool isVCSrc_v2f16() const{return isVCSrc_f16(); }
596
597bool isVSrc_b32() const{
598return isVCSrc_f32() || isLiteralImm(MVT::i32) || isExpr();
599 }
600
601bool isVSrc_b64() const{return isVCSrcF64() || isLiteralImm(MVT::i64); }
602
603bool isVSrcT_b16() const{return isVCSrcT_b16() || isLiteralImm(MVT::i16); }
604
605bool isVSrcT_b16_Lo128() const{
606return isVCSrcTB16_Lo128() || isLiteralImm(MVT::i16);
607 }
608
609bool isVSrcFake16_b16_Lo128() const{
610return isVCSrcFake16B16_Lo128() || isLiteralImm(MVT::i16);
611 }
612
613bool isVSrc_b16() const{return isVCSrc_b16() || isLiteralImm(MVT::i16); }
614
615bool isVSrc_v2b16() const{return isVSrc_b16() || isLiteralImm(MVT::v2i16); }
616
617bool isVCSrcV2FP32() const{
618return isVCSrcF64();
619 }
620
621bool isVSrc_v2f32() const{return isVSrc_f64() || isLiteralImm(MVT::v2f32); }
622
623bool isVCSrcV2INT32() const{
624return isVCSrcB64();
625 }
626
627bool isVSrc_v2b32() const{return isVSrc_b64() || isLiteralImm(MVT::v2i32); }
628
629bool isVSrc_f32() const{
630return isVCSrc_f32() || isLiteralImm(MVT::f32) || isExpr();
631 }
632
633bool isVSrc_f64() const{return isVCSrcF64() || isLiteralImm(MVT::f64); }
634
635bool isVSrcT_bf16() const{return isVCSrcTBF16() || isLiteralImm(MVT::bf16); }
636
637bool isVSrcT_f16() const{return isVCSrcT_f16() || isLiteralImm(MVT::f16); }
638
639bool isVSrcT_bf16_Lo128() const{
640return isVCSrcTBF16_Lo128() || isLiteralImm(MVT::bf16);
641 }
642
643bool isVSrcT_f16_Lo128() const{
644return isVCSrcTF16_Lo128() || isLiteralImm(MVT::f16);
645 }
646
647bool isVSrcFake16_bf16_Lo128() const{
648return isVCSrcFake16BF16_Lo128() || isLiteralImm(MVT::bf16);
649 }
650
651bool isVSrcFake16_f16_Lo128() const{
652return isVCSrcFake16F16_Lo128() || isLiteralImm(MVT::f16);
653 }
654
655bool isVSrc_bf16() const{return isVCSrc_bf16() || isLiteralImm(MVT::bf16); }
656
657bool isVSrc_f16() const{return isVCSrc_f16() || isLiteralImm(MVT::f16); }
658
659bool isVSrc_v2bf16() const{
660return isVSrc_bf16() || isLiteralImm(MVT::v2bf16);
661 }
662
663bool isVSrc_v2f16() const{return isVSrc_f16() || isLiteralImm(MVT::v2f16); }
664
665bool isVISrcB32() const{
666return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i32);
667 }
668
669bool isVISrcB16() const{
670return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::i16);
671 }
672
673bool isVISrcV2B16() const{
674return isVISrcB16();
675 }
676
677bool isVISrcF32() const{
678return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f32);
679 }
680
681bool isVISrcF16() const{
682return isRegOrInlineNoMods(AMDGPU::VGPR_32RegClassID, MVT::f16);
683 }
684
685bool isVISrcV2F16() const{
686return isVISrcF16() || isVISrcB32();
687 }
688
689bool isVISrc_64_bf16() const{
690return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::bf16);
691 }
692
693bool isVISrc_64_f16() const{
694return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f16);
695 }
696
697bool isVISrc_64_b32() const{
698return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
699 }
700
701bool isVISrc_64B64() const{
702return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i64);
703 }
704
705bool isVISrc_64_f64() const{
706return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f64);
707 }
708
709bool isVISrc_64V2FP32() const{
710return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::f32);
711 }
712
713bool isVISrc_64V2INT32() const{
714return isRegOrInlineNoMods(AMDGPU::VReg_64RegClassID, MVT::i32);
715 }
716
717bool isVISrc_256_b32() const{
718return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
719 }
720
721bool isVISrc_256_f32() const{
722return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
723 }
724
725bool isVISrc_256B64() const{
726return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i64);
727 }
728
729bool isVISrc_256_f64() const{
730return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f64);
731 }
732
733bool isVISrc_128B16() const{
734return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i16);
735 }
736
737bool isVISrc_128V2B16() const{
738return isVISrc_128B16();
739 }
740
741bool isVISrc_128_b32() const{
742return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::i32);
743 }
744
745bool isVISrc_128_f32() const{
746return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f32);
747 }
748
749bool isVISrc_256V2FP32() const{
750return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::f32);
751 }
752
753bool isVISrc_256V2INT32() const{
754return isRegOrInlineNoMods(AMDGPU::VReg_256RegClassID, MVT::i32);
755 }
756
757bool isVISrc_512_b32() const{
758return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i32);
759 }
760
761bool isVISrc_512B16() const{
762return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::i16);
763 }
764
765bool isVISrc_512V2B16() const{
766return isVISrc_512B16();
767 }
768
769bool isVISrc_512_f32() const{
770return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f32);
771 }
772
773bool isVISrc_512F16() const{
774return isRegOrInlineNoMods(AMDGPU::VReg_512RegClassID, MVT::f16);
775 }
776
777bool isVISrc_512V2F16() const{
778return isVISrc_512F16() || isVISrc_512_b32();
779 }
780
781bool isVISrc_1024_b32() const{
782return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i32);
783 }
784
785bool isVISrc_1024B16() const{
786return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::i16);
787 }
788
789bool isVISrc_1024V2B16() const{
790return isVISrc_1024B16();
791 }
792
793bool isVISrc_1024_f32() const{
794return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f32);
795 }
796
797bool isVISrc_1024F16() const{
798return isRegOrInlineNoMods(AMDGPU::VReg_1024RegClassID, MVT::f16);
799 }
800
801bool isVISrc_1024V2F16() const{
802return isVISrc_1024F16() || isVISrc_1024_b32();
803 }
804
805bool isAISrcB32() const{
806return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i32);
807 }
808
809bool isAISrcB16() const{
810return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::i16);
811 }
812
813bool isAISrcV2B16() const{
814return isAISrcB16();
815 }
816
817bool isAISrcF32() const{
818return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f32);
819 }
820
821bool isAISrcF16() const{
822return isRegOrInlineNoMods(AMDGPU::AGPR_32RegClassID, MVT::f16);
823 }
824
825bool isAISrcV2F16() const{
826return isAISrcF16() || isAISrcB32();
827 }
828
829bool isAISrc_64B64() const{
830return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::i64);
831 }
832
833bool isAISrc_64_f64() const{
834return isRegOrInlineNoMods(AMDGPU::AReg_64RegClassID, MVT::f64);
835 }
836
837bool isAISrc_128_b32() const{
838return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i32);
839 }
840
841bool isAISrc_128B16() const{
842return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::i16);
843 }
844
845bool isAISrc_128V2B16() const{
846return isAISrc_128B16();
847 }
848
849bool isAISrc_128_f32() const{
850return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f32);
851 }
852
853bool isAISrc_128F16() const{
854return isRegOrInlineNoMods(AMDGPU::AReg_128RegClassID, MVT::f16);
855 }
856
857bool isAISrc_128V2F16() const{
858return isAISrc_128F16() || isAISrc_128_b32();
859 }
860
861bool isVISrc_128_bf16() const{
862return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::bf16);
863 }
864
865bool isVISrc_128_f16() const{
866return isRegOrInlineNoMods(AMDGPU::VReg_128RegClassID, MVT::f16);
867 }
868
869bool isVISrc_128V2F16() const{
870return isVISrc_128_f16() || isVISrc_128_b32();
871 }
872
873bool isAISrc_256B64() const{
874return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::i64);
875 }
876
877bool isAISrc_256_f64() const{
878return isRegOrInlineNoMods(AMDGPU::AReg_256RegClassID, MVT::f64);
879 }
880
881bool isAISrc_512_b32() const{
882return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i32);
883 }
884
885bool isAISrc_512B16() const{
886return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::i16);
887 }
888
889bool isAISrc_512V2B16() const{
890return isAISrc_512B16();
891 }
892
893bool isAISrc_512_f32() const{
894return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f32);
895 }
896
897bool isAISrc_512F16() const{
898return isRegOrInlineNoMods(AMDGPU::AReg_512RegClassID, MVT::f16);
899 }
900
901bool isAISrc_512V2F16() const{
902return isAISrc_512F16() || isAISrc_512_b32();
903 }
904
905bool isAISrc_1024_b32() const{
906return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i32);
907 }
908
909bool isAISrc_1024B16() const{
910return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::i16);
911 }
912
913bool isAISrc_1024V2B16() const{
914return isAISrc_1024B16();
915 }
916
917bool isAISrc_1024_f32() const{
918return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f32);
919 }
920
921bool isAISrc_1024F16() const{
922return isRegOrInlineNoMods(AMDGPU::AReg_1024RegClassID, MVT::f16);
923 }
924
925bool isAISrc_1024V2F16() const{
926return isAISrc_1024F16() || isAISrc_1024_b32();
927 }
928
929bool isKImmFP32() const{
930return isLiteralImm(MVT::f32);
931 }
932
933bool isKImmFP16() const{
934return isLiteralImm(MVT::f16);
935 }
936
937boolisMem() const override{
938returnfalse;
939 }
940
941bool isExpr() const{
942returnKind ==Expression;
943 }
944
945bool isSOPPBrTarget() const{return isExpr() ||isImm(); }
946
947bool isSWaitCnt()const;
948bool isDepCtr()const;
949bool isSDelayALU()const;
950bool isHwreg()const;
951bool isSendMsg()const;
952bool isSplitBarrier()const;
953bool isSwizzle()const;
954bool isSMRDOffset8()const;
955bool isSMEMOffset()const;
956bool isSMRDLiteralOffset()const;
957bool isDPP8()const;
958bool isDPPCtrl()const;
959bool isBLGP()const;
960bool isGPRIdxMode()const;
961bool isS16Imm()const;
962bool isU16Imm()const;
963bool isEndpgm()const;
964
965autogetPredicate(std::function<bool(const AMDGPUOperand &Op)>P) const{
966return [=](){returnP(*this); };
967 }
968
969StringRef getToken() const{
970assert(isToken());
971returnStringRef(Tok.Data, Tok.Length);
972 }
973
974 int64_t getImm() const{
975assert(isImm());
976returnImm.Val;
977 }
978
979void setImm(int64_t Val) {
980assert(isImm());
981Imm.Val = Val;
982 }
983
984 ImmTy getImmTy() const{
985assert(isImm());
986returnImm.Type;
987 }
988
989MCRegistergetReg() const override{
990assert(isRegKind());
991returnReg.RegNo;
992 }
993
994SMLoc getStartLoc() const override{
995return StartLoc;
996 }
997
998SMLoc getEndLoc() const override{
999return EndLoc;
1000 }
1001
1002SMRange getLocRange() const{
1003returnSMRange(StartLoc, EndLoc);
1004 }
1005
1006 Modifiers getModifiers() const{
1007assert(isRegKind() || isImmTy(ImmTyNone));
1008return isRegKind() ?Reg.Mods :Imm.Mods;
1009 }
1010
1011void setModifiers(Modifiers Mods) {
1012assert(isRegKind() || isImmTy(ImmTyNone));
1013if (isRegKind())
1014Reg.Mods = Mods;
1015else
1016Imm.Mods = Mods;
1017 }
1018
1019bool hasModifiers() const{
1020return getModifiers().hasModifiers();
1021 }
1022
1023bool hasFPModifiers() const{
1024return getModifiers().hasFPModifiers();
1025 }
1026
1027bool hasIntModifiers() const{
1028return getModifiers().hasIntModifiers();
1029 }
1030
1031uint64_t applyInputFPModifiers(uint64_t Val,unsignedSize)const;
1032
1033void addImmOperands(MCInst &Inst,unsignedN,bool ApplyModifiers =true)const;
1034
1035void addLiteralImmOperand(MCInst &Inst, int64_t Val,bool ApplyModifiers)const;
1036
1037void addRegOperands(MCInst &Inst,unsignedN)const;
1038
1039void addRegOrImmOperands(MCInst &Inst,unsignedN) const{
1040if (isRegKind())
1041 addRegOperands(Inst,N);
1042else
1043 addImmOperands(Inst,N);
1044 }
1045
1046void addRegOrImmWithInputModsOperands(MCInst &Inst,unsignedN) const{
1047 Modifiers Mods = getModifiers();
1048 Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
1049if (isRegKind()) {
1050 addRegOperands(Inst,N);
1051 }else {
1052 addImmOperands(Inst,N,false);
1053 }
1054 }
1055
1056void addRegOrImmWithFPInputModsOperands(MCInst &Inst,unsignedN) const{
1057assert(!hasIntModifiers());
1058 addRegOrImmWithInputModsOperands(Inst,N);
1059 }
1060
1061void addRegOrImmWithIntInputModsOperands(MCInst &Inst,unsignedN) const{
1062assert(!hasFPModifiers());
1063 addRegOrImmWithInputModsOperands(Inst,N);
1064 }
1065
1066void addRegWithInputModsOperands(MCInst &Inst,unsignedN) const{
1067 Modifiers Mods = getModifiers();
1068 Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
1069assert(isRegKind());
1070 addRegOperands(Inst,N);
1071 }
1072
1073void addRegWithFPInputModsOperands(MCInst &Inst,unsignedN) const{
1074assert(!hasIntModifiers());
1075 addRegWithInputModsOperands(Inst,N);
1076 }
1077
1078void addRegWithIntInputModsOperands(MCInst &Inst,unsignedN) const{
1079assert(!hasFPModifiers());
1080 addRegWithInputModsOperands(Inst,N);
1081 }
1082
1083staticvoid printImmTy(raw_ostream&OS, ImmTyType) {
1084// clang-format off
1085switch (Type) {
1086case ImmTyNone:OS <<"None";break;
1087case ImmTyGDS:OS <<"GDS";break;
1088case ImmTyLDS:OS <<"LDS";break;
1089case ImmTyOffen:OS <<"Offen";break;
1090case ImmTyIdxen:OS <<"Idxen";break;
1091case ImmTyAddr64:OS <<"Addr64";break;
1092case ImmTyOffset:OS <<"Offset";break;
1093case ImmTyInstOffset:OS <<"InstOffset";break;
1094case ImmTyOffset0:OS <<"Offset0";break;
1095case ImmTyOffset1:OS <<"Offset1";break;
1096case ImmTySMEMOffsetMod:OS <<"SMEMOffsetMod";break;
1097case ImmTyCPol:OS <<"CPol";break;
1098case ImmTyIndexKey8bit:OS <<"index_key";break;
1099case ImmTyIndexKey16bit:OS <<"index_key";break;
1100case ImmTyTFE:OS <<"TFE";break;
1101case ImmTyD16:OS <<"D16";break;
1102case ImmTyFORMAT:OS <<"FORMAT";break;
1103case ImmTyClamp:OS <<"Clamp";break;
1104case ImmTyOModSI:OS <<"OModSI";break;
1105case ImmTyDPP8:OS <<"DPP8";break;
1106case ImmTyDppCtrl:OS <<"DppCtrl";break;
1107case ImmTyDppRowMask:OS <<"DppRowMask";break;
1108case ImmTyDppBankMask:OS <<"DppBankMask";break;
1109case ImmTyDppBoundCtrl:OS <<"DppBoundCtrl";break;
1110case ImmTyDppFI:OS <<"DppFI";break;
1111case ImmTySDWADstSel:OS <<"SDWADstSel";break;
1112case ImmTySDWASrc0Sel:OS <<"SDWASrc0Sel";break;
1113case ImmTySDWASrc1Sel:OS <<"SDWASrc1Sel";break;
1114case ImmTySDWADstUnused:OS <<"SDWADstUnused";break;
1115case ImmTyDMask:OS <<"DMask";break;
1116case ImmTyDim:OS <<"Dim";break;
1117case ImmTyUNorm:OS <<"UNorm";break;
1118case ImmTyDA:OS <<"DA";break;
1119case ImmTyR128A16:OS <<"R128A16";break;
1120case ImmTyA16:OS <<"A16";break;
1121case ImmTyLWE:OS <<"LWE";break;
1122case ImmTyOff:OS <<"Off";break;
1123case ImmTyExpTgt:OS <<"ExpTgt";break;
1124case ImmTyExpCompr:OS <<"ExpCompr";break;
1125case ImmTyExpVM:OS <<"ExpVM";break;
1126case ImmTyHwreg:OS <<"Hwreg";break;
1127case ImmTySendMsg:OS <<"SendMsg";break;
1128case ImmTyInterpSlot:OS <<"InterpSlot";break;
1129case ImmTyInterpAttr:OS <<"InterpAttr";break;
1130case ImmTyInterpAttrChan:OS <<"InterpAttrChan";break;
1131case ImmTyOpSel:OS <<"OpSel";break;
1132case ImmTyOpSelHi:OS <<"OpSelHi";break;
1133case ImmTyNegLo:OS <<"NegLo";break;
1134case ImmTyNegHi:OS <<"NegHi";break;
1135case ImmTySwizzle:OS <<"Swizzle";break;
1136case ImmTyGprIdxMode:OS <<"GprIdxMode";break;
1137case ImmTyHigh:OS <<"High";break;
1138case ImmTyBLGP:OS <<"BLGP";break;
1139case ImmTyCBSZ:OS <<"CBSZ";break;
1140case ImmTyABID:OS <<"ABID";break;
1141case ImmTyEndpgm:OS <<"Endpgm";break;
1142case ImmTyWaitVDST:OS <<"WaitVDST";break;
1143case ImmTyWaitEXP:OS <<"WaitEXP";break;
1144case ImmTyWaitVAVDst:OS <<"WaitVAVDst";break;
1145case ImmTyWaitVMVSrc:OS <<"WaitVMVSrc";break;
1146case ImmTyByteSel:OS <<"ByteSel" ;break;
1147case ImmTyBitOp3:OS <<"BitOp3";break;
1148 }
1149// clang-format on
1150 }
1151
1152voidprint(raw_ostream &OS) const override{
1153switch (Kind) {
1154caseRegister:
1155OS <<"<register " <<AMDGPUInstPrinter::getRegisterName(getReg())
1156 <<" mods: " <<Reg.Mods <<'>';
1157break;
1158case Immediate:
1159OS <<'<' << getImm();
1160if (getImmTy() != ImmTyNone) {
1161OS <<" type: "; printImmTy(OS, getImmTy());
1162 }
1163OS <<" mods: " <<Imm.Mods <<'>';
1164break;
1165case Token:
1166OS <<'\'' << getToken() <<'\'';
1167break;
1168caseExpression:
1169OS <<"<expr " << *Expr <<'>';
1170break;
1171 }
1172 }
1173
1174static AMDGPUOperand::Ptr CreateImm(const AMDGPUAsmParser *AsmParser,
1175 int64_t Val,SMLoc Loc,
1176 ImmTyType = ImmTyNone,
1177bool IsFPImm =false) {
1178autoOp = std::make_unique<AMDGPUOperand>(Immediate, AsmParser);
1179Op->Imm.Val = Val;
1180Op->Imm.IsFPImm = IsFPImm;
1181Op->Imm.Kind = ImmKindTyNone;
1182Op->Imm.Type =Type;
1183Op->Imm.Mods = Modifiers();
1184Op->StartLoc = Loc;
1185Op->EndLoc = Loc;
1186returnOp;
1187 }
1188
1189static AMDGPUOperand::Ptr CreateToken(const AMDGPUAsmParser *AsmParser,
1190StringRef Str,SMLoc Loc,
1191bool HasExplicitEncodingSize =true) {
1192auto Res = std::make_unique<AMDGPUOperand>(Token, AsmParser);
1193 Res->Tok.Data = Str.data();
1194 Res->Tok.Length = Str.size();
1195 Res->StartLoc = Loc;
1196 Res->EndLoc = Loc;
1197return Res;
1198 }
1199
1200static AMDGPUOperand::Ptr CreateReg(const AMDGPUAsmParser *AsmParser,
1201MCRegister Reg,SMLoc S,SMLoc E) {
1202autoOp = std::make_unique<AMDGPUOperand>(Register, AsmParser);
1203Op->Reg.RegNo =Reg;
1204Op->Reg.Mods = Modifiers();
1205Op->StartLoc = S;
1206Op->EndLoc = E;
1207returnOp;
1208 }
1209
1210static AMDGPUOperand::Ptr CreateExpr(const AMDGPUAsmParser *AsmParser,
1211constclassMCExpr *Expr,SMLoc S) {
1212autoOp = std::make_unique<AMDGPUOperand>(Expression, AsmParser);
1213Op->Expr = Expr;
1214Op->StartLoc = S;
1215Op->EndLoc = S;
1216returnOp;
1217 }
1218};
1219
1220raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
1221OS <<"abs:" << Mods.Abs <<" neg: " << Mods.Neg <<" sext:" << Mods.Sext;
1222returnOS;
1223}
1224
1225//===----------------------------------------------------------------------===//
1226// AsmParser
1227//===----------------------------------------------------------------------===//
1228
1229// Holds info related to the current kernel, e.g. count of SGPRs used.
1230// Kernel scope begins at .amdgpu_hsa_kernel directive, ends at next
1231// .amdgpu_hsa_kernel or at EOF.
1232classKernelScopeInfo {
1233int SgprIndexUnusedMin = -1;
1234int VgprIndexUnusedMin = -1;
1235int AgprIndexUnusedMin = -1;
1236MCContext *Ctx =nullptr;
1237MCSubtargetInfoconst *MSTI =nullptr;
1238
1239void usesSgprAt(int i) {
1240if (i >= SgprIndexUnusedMin) {
1241 SgprIndexUnusedMin = ++i;
1242if (Ctx) {
1243MCSymbol*constSym =
1244 Ctx->getOrCreateSymbol(Twine(".kernel.sgpr_count"));
1245Sym->setVariableValue(MCConstantExpr::create(SgprIndexUnusedMin, *Ctx));
1246 }
1247 }
1248 }
1249
1250void usesVgprAt(int i) {
1251if (i >= VgprIndexUnusedMin) {
1252 VgprIndexUnusedMin = ++i;
1253if (Ctx) {
1254MCSymbol*constSym =
1255 Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1256int totalVGPR =getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1257 VgprIndexUnusedMin);
1258Sym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1259 }
1260 }
1261 }
1262
1263void usesAgprAt(int i) {
1264// Instruction will error in AMDGPUAsmParser::matchAndEmitInstruction
1265if (!hasMAIInsts(*MSTI))
1266return;
1267
1268if (i >= AgprIndexUnusedMin) {
1269 AgprIndexUnusedMin = ++i;
1270if (Ctx) {
1271MCSymbol*constSym =
1272 Ctx->getOrCreateSymbol(Twine(".kernel.agpr_count"));
1273Sym->setVariableValue(MCConstantExpr::create(AgprIndexUnusedMin, *Ctx));
1274
1275// Also update vgpr_count (dependent on agpr_count for gfx908/gfx90a)
1276MCSymbol*const vSym =
1277 Ctx->getOrCreateSymbol(Twine(".kernel.vgpr_count"));
1278int totalVGPR =getTotalNumVGPRs(isGFX90A(*MSTI), AgprIndexUnusedMin,
1279 VgprIndexUnusedMin);
1280 vSym->setVariableValue(MCConstantExpr::create(totalVGPR, *Ctx));
1281 }
1282 }
1283 }
1284
1285public:
1286 KernelScopeInfo() =default;
1287
1288voidinitialize(MCContext &Context) {
1289 Ctx = &Context;
1290 MSTI = Ctx->getSubtargetInfo();
1291
1292 usesSgprAt(SgprIndexUnusedMin = -1);
1293 usesVgprAt(VgprIndexUnusedMin = -1);
1294if (hasMAIInsts(*MSTI)) {
1295 usesAgprAt(AgprIndexUnusedMin = -1);
1296 }
1297 }
1298
1299void usesRegister(RegisterKind RegKind,unsigned DwordRegIndex,
1300unsigned RegWidth) {
1301switch (RegKind) {
1302case IS_SGPR:
1303 usesSgprAt(DwordRegIndex +divideCeil(RegWidth, 32) - 1);
1304break;
1305caseIS_AGPR:
1306 usesAgprAt(DwordRegIndex +divideCeil(RegWidth, 32) - 1);
1307break;
1308caseIS_VGPR:
1309 usesVgprAt(DwordRegIndex +divideCeil(RegWidth, 32) - 1);
1310break;
1311default:
1312break;
1313 }
1314 }
1315};
1316
1317classAMDGPUAsmParser :publicMCTargetAsmParser {
1318MCAsmParser &Parser;
1319
1320unsigned ForcedEncodingSize = 0;
1321bool ForcedDPP =false;
1322bool ForcedSDWA =false;
1323 KernelScopeInfo KernelScope;
1324
1325 /// @name Auto-generated Match Functions
1326 /// {
1327
1328#define GET_ASSEMBLER_HEADER
1329#include "AMDGPUGenAsmMatcher.inc"
1330
1331 /// }
1332
1333private:
1334void createConstantSymbol(StringRef Id, int64_t Val);
1335
1336bool ParseAsAbsoluteExpression(uint32_t &Ret);
1337bool OutOfRangeError(SMRangeRange);
1338 /// Calculate VGPR/SGPR blocks required for given target, reserved
1339 /// registers, and user-specified NextFreeXGPR values.
1340 ///
1341 /// \param Features [in] Target features, used for bug corrections.
1342 /// \param VCCUsed [in] Whether VCC special SGPR is reserved.
1343 /// \param FlatScrUsed [in] Whether FLAT_SCRATCH special SGPR is reserved.
1344 /// \param XNACKUsed [in] Whether XNACK_MASK special SGPR is reserved.
1345 /// \param EnableWavefrontSize32 [in] Value of ENABLE_WAVEFRONT_SIZE32 kernel
1346 /// descriptor field, if valid.
1347 /// \param NextFreeVGPR [in] Max VGPR number referenced, plus one.
1348 /// \param VGPRRange [in] Token range, used for VGPR diagnostics.
1349 /// \param NextFreeSGPR [in] Max SGPR number referenced, plus one.
1350 /// \param SGPRRange [in] Token range, used for SGPR diagnostics.
1351 /// \param VGPRBlocks [out] Result VGPR block count.
1352 /// \param SGPRBlocks [out] Result SGPR block count.
1353bool calculateGPRBlocks(constFeatureBitset &Features,constMCExpr *VCCUsed,
1354constMCExpr *FlatScrUsed,bool XNACKUsed,
1355 std::optional<bool> EnableWavefrontSize32,
1356constMCExpr *NextFreeVGPR,SMRange VGPRRange,
1357constMCExpr *NextFreeSGPR,SMRange SGPRRange,
1358constMCExpr *&VGPRBlocks,constMCExpr *&SGPRBlocks);
1359bool ParseDirectiveAMDGCNTarget();
1360bool ParseDirectiveAMDHSACodeObjectVersion();
1361bool ParseDirectiveAMDHSAKernel();
1362bool ParseAMDKernelCodeTValue(StringRefID,AMDGPUMCKernelCodeT &Header);
1363bool ParseDirectiveAMDKernelCodeT();
1364// TODO: Possibly make subtargetHasRegister const.
1365bool subtargetHasRegister(constMCRegisterInfo &MRI,MCRegister Reg);
1366bool ParseDirectiveAMDGPUHsaKernel();
1367
1368bool ParseDirectiveISAVersion();
1369bool ParseDirectiveHSAMetadata();
1370bool ParseDirectivePALMetadataBegin();
1371bool ParseDirectivePALMetadata();
1372bool ParseDirectiveAMDGPULDS();
1373
1374 /// Common code to parse out a block of text (typically YAML) between start and
1375 /// end directives.
1376bool ParseToEndDirective(constchar *AssemblerDirectiveBegin,
1377constchar *AssemblerDirectiveEnd,
1378 std::string &CollectString);
1379
1380bool AddNextRegisterToList(MCRegister &Reg,unsigned &RegWidth,
1381 RegisterKind RegKind,MCRegister Reg1,SMLoc Loc);
1382bool ParseAMDGPURegister(RegisterKind &RegKind,MCRegister &Reg,
1383unsigned &RegNum,unsigned &RegWidth,
1384bool RestoreOnFailure =false);
1385bool ParseAMDGPURegister(RegisterKind &RegKind,MCRegister &Reg,
1386unsigned &RegNum,unsigned &RegWidth,
1387SmallVectorImpl<AsmToken> &Tokens);
1388MCRegister ParseRegularReg(RegisterKind &RegKind,unsigned &RegNum,
1389unsigned &RegWidth,
1390SmallVectorImpl<AsmToken> &Tokens);
1391MCRegister ParseSpecialReg(RegisterKind &RegKind,unsigned &RegNum,
1392unsigned &RegWidth,
1393SmallVectorImpl<AsmToken> &Tokens);
1394MCRegister ParseRegList(RegisterKind &RegKind,unsigned &RegNum,
1395unsigned &RegWidth,
1396SmallVectorImpl<AsmToken> &Tokens);
1397bool ParseRegRange(unsigned& Num,unsigned& Width);
1398MCRegister getRegularReg(RegisterKind RegKind,unsigned RegNum,
1399unsignedSubReg,unsigned RegWidth,SMLoc Loc);
1400
1401bool isRegister();
1402bool isRegister(constAsmToken &Token,constAsmToken &NextToken)const;
1403 std::optional<StringRef> getGprCountSymbolName(RegisterKind RegKind);
1404void initializeGprCountSymbol(RegisterKind RegKind);
1405bool updateGprCountSymbols(RegisterKind RegKind,unsigned DwordRegIndex,
1406unsigned RegWidth);
1407void cvtMubufImpl(MCInst &Inst,constOperandVector &Operands,
1408bool IsAtomic);
1409
1410public:
1411enum OperandMode {
1412 OperandMode_Default,
1413 OperandMode_NSA,
1414 };
1415
1416usingOptionalImmIndexMap = std::map<AMDGPUOperand::ImmTy, unsigned>;
1417
1418 AMDGPUAsmParser(constMCSubtargetInfo &STI,MCAsmParser &_Parser,
1419constMCInstrInfo &MII,
1420constMCTargetOptions &Options)
1421 :MCTargetAsmParser(Options, STI, MII), Parser(_Parser) {
1422MCAsmParserExtension::Initialize(Parser);
1423
1424if (getFeatureBits().none()) {
1425// Set default features.
1426copySTI().ToggleFeature("southern-islands");
1427 }
1428
1429FeatureBitset FB = getFeatureBits();
1430if (!FB[AMDGPU::FeatureWavefrontSize64] &&
1431 !FB[AMDGPU::FeatureWavefrontSize32]) {
1432// If there is no default wave size it must be a generation before gfx10,
1433// these have FeatureWavefrontSize64 in their definition already. For
1434// gfx10+ set wave32 as a default.
1435copySTI().ToggleFeature(AMDGPU::FeatureWavefrontSize32);
1436 }
1437
1438setAvailableFeatures(ComputeAvailableFeatures(getFeatureBits()));
1439
1440AMDGPU::IsaVersionISA =AMDGPU::getIsaVersion(getSTI().getCPU());
1441if (ISA.Major >= 6 &&isHsaAbi(getSTI())) {
1442 createConstantSymbol(".amdgcn.gfx_generation_number",ISA.Major);
1443 createConstantSymbol(".amdgcn.gfx_generation_minor",ISA.Minor);
1444 createConstantSymbol(".amdgcn.gfx_generation_stepping",ISA.Stepping);
1445 }else {
1446 createConstantSymbol(".option.machine_version_major",ISA.Major);
1447 createConstantSymbol(".option.machine_version_minor",ISA.Minor);
1448 createConstantSymbol(".option.machine_version_stepping",ISA.Stepping);
1449 }
1450if (ISA.Major >= 6 &&isHsaAbi(getSTI())) {
1451 initializeGprCountSymbol(IS_VGPR);
1452 initializeGprCountSymbol(IS_SGPR);
1453 }else
1454 KernelScope.initialize(getContext());
1455
1456for (auto [Symbol, Code] :AMDGPU::UCVersion::getGFXVersions())
1457 createConstantSymbol(Symbol, Code);
1458
1459 createConstantSymbol("UC_VERSION_W64_BIT", 0x2000);
1460 createConstantSymbol("UC_VERSION_W32_BIT", 0x4000);
1461 createConstantSymbol("UC_VERSION_MDP_BIT", 0x8000);
1462 }
1463
1464boolhasMIMG_R128() const{
1465returnAMDGPU::hasMIMG_R128(getSTI());
1466 }
1467
1468boolhasPackedD16() const{
1469returnAMDGPU::hasPackedD16(getSTI());
1470 }
1471
1472boolhasA16() const{returnAMDGPU::hasA16(getSTI()); }
1473
1474boolhasG16() const{returnAMDGPU::hasG16(getSTI()); }
1475
1476boolhasGDS() const{returnAMDGPU::hasGDS(getSTI()); }
1477
1478boolisSI() const{
1479returnAMDGPU::isSI(getSTI());
1480 }
1481
1482boolisCI() const{
1483returnAMDGPU::isCI(getSTI());
1484 }
1485
1486boolisVI() const{
1487returnAMDGPU::isVI(getSTI());
1488 }
1489
1490boolisGFX9() const{
1491returnAMDGPU::isGFX9(getSTI());
1492 }
1493
1494// TODO: isGFX90A is also true for GFX940. We need to clean it.
1495boolisGFX90A() const{
1496returnAMDGPU::isGFX90A(getSTI());
1497 }
1498
1499boolisGFX940() const{
1500returnAMDGPU::isGFX940(getSTI());
1501 }
1502
1503boolisGFX9Plus() const{
1504returnAMDGPU::isGFX9Plus(getSTI());
1505 }
1506
1507boolisGFX10() const{
1508returnAMDGPU::isGFX10(getSTI());
1509 }
1510
1511boolisGFX10Plus() const{returnAMDGPU::isGFX10Plus(getSTI()); }
1512
1513boolisGFX11() const{
1514returnAMDGPU::isGFX11(getSTI());
1515 }
1516
1517boolisGFX11Plus() const{
1518returnAMDGPU::isGFX11Plus(getSTI());
1519 }
1520
1521boolisGFX12() const{returnAMDGPU::isGFX12(getSTI()); }
1522
1523boolisGFX12Plus() const{returnAMDGPU::isGFX12Plus(getSTI()); }
1524
1525boolisGFX10_AEncoding() const{returnAMDGPU::isGFX10_AEncoding(getSTI()); }
1526
1527boolisGFX10_BEncoding() const{
1528returnAMDGPU::isGFX10_BEncoding(getSTI());
1529 }
1530
1531bool hasInv2PiInlineImm() const{
1532return getFeatureBits()[AMDGPU::FeatureInv2PiInlineImm];
1533 }
1534
1535bool hasFlatOffsets() const{
1536return getFeatureBits()[AMDGPU::FeatureFlatInstOffsets];
1537 }
1538
1539boolhasArchitectedFlatScratch() const{
1540return getFeatureBits()[AMDGPU::FeatureArchitectedFlatScratch];
1541 }
1542
1543bool hasSGPR102_SGPR103() const{
1544return !isVI() && !isGFX9();
1545 }
1546
1547bool hasSGPR104_SGPR105() const{returnisGFX10Plus(); }
1548
1549bool hasIntClamp() const{
1550return getFeatureBits()[AMDGPU::FeatureIntClamp];
1551 }
1552
1553bool hasPartialNSAEncoding() const{
1554return getFeatureBits()[AMDGPU::FeaturePartialNSAEncoding];
1555 }
1556
1557unsignedgetNSAMaxSize(bool HasSampler =false) const{
1558returnAMDGPU::getNSAMaxSize(getSTI(), HasSampler);
1559 }
1560
1561unsignedgetMaxNumUserSGPRs() const{
1562returnAMDGPU::getMaxNumUserSGPRs(getSTI());
1563 }
1564
1565boolhasKernargPreload() const{returnAMDGPU::hasKernargPreload(getSTI()); }
1566
1567AMDGPUTargetStreamer &getTargetStreamer() {
1568MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
1569returnstatic_cast<AMDGPUTargetStreamer &>(TS);
1570 }
1571
1572constMCRegisterInfo *getMRI() const{
1573// We need this const_cast because for some reason getContext() is not const
1574// in MCAsmParser.
1575returnconst_cast<AMDGPUAsmParser*>(this)->getContext().getRegisterInfo();
1576 }
1577
1578constMCInstrInfo *getMII() const{
1579return &MII;
1580 }
1581
1582constFeatureBitset &getFeatureBits() const{
1583returngetSTI().getFeatureBits();
1584 }
1585
1586void setForcedEncodingSize(unsignedSize) { ForcedEncodingSize =Size; }
1587void setForcedDPP(bool ForceDPP_) { ForcedDPP = ForceDPP_; }
1588void setForcedSDWA(bool ForceSDWA_) { ForcedSDWA = ForceSDWA_; }
1589
1590unsigned getForcedEncodingSize() const{return ForcedEncodingSize; }
1591bool isForcedVOP3() const{return ForcedEncodingSize == 64; }
1592bool isForcedDPP() const{return ForcedDPP; }
1593bool isForcedSDWA() const{return ForcedSDWA; }
1594ArrayRef<unsigned> getMatchedVariants()const;
1595StringRef getMatchedVariantName()const;
1596
1597 std::unique_ptr<AMDGPUOperand>parseRegister(bool RestoreOnFailure =false);
1598bool ParseRegister(MCRegister &RegNo,SMLoc &StartLoc,SMLoc &EndLoc,
1599bool RestoreOnFailure);
1600boolparseRegister(MCRegister &Reg,SMLoc &StartLoc,SMLoc &EndLoc)override;
1601ParseStatustryParseRegister(MCRegister &Reg,SMLoc &StartLoc,
1602SMLoc &EndLoc)override;
1603unsignedcheckTargetMatchPredicate(MCInst &Inst)override;
1604unsignedvalidateTargetOperandClass(MCParsedAsmOperand &Op,
1605unsigned Kind)override;
1606boolmatchAndEmitInstruction(SMLoc IDLoc,unsigned &Opcode,
1607OperandVector &Operands,MCStreamer &Out,
1608uint64_t &ErrorInfo,
1609bool MatchingInlineAsm)override;
1610boolParseDirective(AsmToken DirectiveID)override;
1611ParseStatus parseOperand(OperandVector &Operands,StringRef Mnemonic,
1612 OperandMode Mode = OperandMode_Default);
1613StringRef parseMnemonicSuffix(StringRefName);
1614boolparseInstruction(ParseInstructionInfo &Info,StringRefName,
1615SMLoc NameLoc,OperandVector &Operands)override;
1616//bool ProcessInstruction(MCInst &Inst);
1617
1618ParseStatus parseTokenOp(StringRefName,OperandVector &Operands);
1619
1620ParseStatus parseIntWithPrefix(constchar *Prefix, int64_t &Int);
1621
1622ParseStatus
1623 parseIntWithPrefix(constchar *Prefix,OperandVector &Operands,
1624 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1625 std::function<bool(int64_t &)> ConvertResult =nullptr);
1626
1627ParseStatus parseOperandArrayWithPrefix(
1628constchar *Prefix,OperandVector &Operands,
1629 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone,
1630bool (*ConvertResult)(int64_t &) =nullptr);
1631
1632ParseStatus
1633 parseNamedBit(StringRefName,OperandVector &Operands,
1634 AMDGPUOperand::ImmTy ImmTy = AMDGPUOperand::ImmTyNone);
1635unsigned getCPolKind(StringRef Id,StringRef Mnemo,bool &Disabling)const;
1636ParseStatus parseCPol(OperandVector &Operands);
1637ParseStatus parseScope(OperandVector &Operands, int64_t &Scope);
1638ParseStatus parseTH(OperandVector &Operands, int64_t &TH);
1639ParseStatus parseStringWithPrefix(StringRef Prefix,StringRef &Value,
1640SMLoc &StringLoc);
1641ParseStatus parseStringOrIntWithPrefix(OperandVector &Operands,
1642StringRefName,
1643ArrayRef<const char *> Ids,
1644 int64_t &IntVal);
1645ParseStatus parseStringOrIntWithPrefix(OperandVector &Operands,
1646StringRefName,
1647ArrayRef<const char *> Ids,
1648 AMDGPUOperand::ImmTyType);
1649
1650bool isModifier();
1651bool isOperandModifier(constAsmToken &Token,constAsmToken &NextToken)const;
1652bool isRegOrOperandModifier(constAsmToken &Token,constAsmToken &NextToken)const;
1653bool isNamedOperandModifier(constAsmToken &Token,constAsmToken &NextToken)const;
1654bool isOpcodeModifierWithVal(constAsmToken &Token,constAsmToken &NextToken)const;
1655bool parseSP3NegModifier();
1656ParseStatus parseImm(OperandVector &Operands,bool HasSP3AbsModifier =false,
1657bool HasLit =false);
1658ParseStatus parseReg(OperandVector &Operands);
1659ParseStatus parseRegOrImm(OperandVector &Operands,bool HasSP3AbsMod =false,
1660bool HasLit =false);
1661ParseStatus parseRegOrImmWithFPInputMods(OperandVector &Operands,
1662bool AllowImm =true);
1663ParseStatus parseRegOrImmWithIntInputMods(OperandVector &Operands,
1664bool AllowImm =true);
1665ParseStatus parseRegWithFPInputMods(OperandVector &Operands);
1666ParseStatus parseRegWithIntInputMods(OperandVector &Operands);
1667ParseStatus parseVReg32OrOff(OperandVector &Operands);
1668ParseStatus tryParseIndexKey(OperandVector &Operands,
1669 AMDGPUOperand::ImmTy ImmTy);
1670ParseStatus parseIndexKey8bit(OperandVector &Operands);
1671ParseStatus parseIndexKey16bit(OperandVector &Operands);
1672
1673ParseStatus parseDfmtNfmt(int64_t &Format);
1674ParseStatus parseUfmt(int64_t &Format);
1675ParseStatus parseSymbolicSplitFormat(StringRef FormatStr,SMLoc Loc,
1676 int64_t &Format);
1677ParseStatus parseSymbolicUnifiedFormat(StringRef FormatStr,SMLoc Loc,
1678 int64_t &Format);
1679ParseStatus parseFORMAT(OperandVector &Operands);
1680ParseStatus parseSymbolicOrNumericFormat(int64_t &Format);
1681ParseStatus parseNumericFormat(int64_t &Format);
1682ParseStatus parseFlatOffset(OperandVector &Operands);
1683ParseStatus parseR128A16(OperandVector &Operands);
1684ParseStatus parseBLGP(OperandVector &Operands);
1685bool tryParseFmt(constchar *Pref, int64_t MaxVal, int64_t &Val);
1686bool matchDfmtNfmt(int64_t &Dfmt, int64_t &Nfmt,StringRef FormatStr,SMLoc Loc);
1687
1688void cvtExp(MCInst &Inst,constOperandVector &Operands);
1689
1690bool parseCnt(int64_t &IntVal);
1691ParseStatus parseSWaitCnt(OperandVector &Operands);
1692
1693bool parseDepCtr(int64_t &IntVal,unsigned &Mask);
1694void depCtrError(SMLoc Loc,int ErrorId,StringRef DepCtrName);
1695ParseStatus parseDepCtr(OperandVector &Operands);
1696
1697bool parseDelay(int64_t &Delay);
1698ParseStatus parseSDelayALU(OperandVector &Operands);
1699
1700ParseStatus parseHwreg(OperandVector &Operands);
1701
1702private:
1703structOperandInfoTy {
1704SMLoc Loc;
1705 int64_t Val;
1706bool IsSymbolic =false;
1707bool IsDefined =false;
1708
1709 OperandInfoTy(int64_t Val) : Val(Val) {}
1710 };
1711
1712structStructuredOpField : OperandInfoTy {
1713StringLiteralId;
1714StringLiteralDesc;
1715unsigned Width;
1716bool IsDefined =false;
1717
1718 StructuredOpField(StringLiteral Id,StringLiteralDesc,unsigned Width,
1719 int64_tDefault)
1720 : OperandInfoTy(Default),Id(Id),Desc(Desc), Width(Width) {}
1721virtual ~StructuredOpField() =default;
1722
1723boolError(AMDGPUAsmParser &Parser,constTwine &Err) const{
1724 Parser.Error(Loc,"invalid " +Desc +": " + Err);
1725returnfalse;
1726 }
1727
1728virtualboolvalidate(AMDGPUAsmParser &Parser) const{
1729if (IsSymbolic && Val ==OPR_ID_UNSUPPORTED)
1730returnError(Parser,"not supported on this GPU");
1731if (!isUIntN(Width, Val))
1732returnError(Parser,"only " +Twine(Width) +"-bit values are legal");
1733returntrue;
1734 }
1735 };
1736
1737ParseStatus parseStructuredOpFields(ArrayRef<StructuredOpField *> Fields);
1738bool validateStructuredOpFields(ArrayRef<const StructuredOpField *> Fields);
1739
1740bool parseSendMsgBody(OperandInfoTy &Msg, OperandInfoTy &Op, OperandInfoTy &Stream);
1741bool validateSendMsg(const OperandInfoTy &Msg,
1742const OperandInfoTy &Op,
1743const OperandInfoTy &Stream);
1744
1745ParseStatus parseHwregFunc(OperandInfoTy &HwReg, OperandInfoTy &Offset,
1746 OperandInfoTy &Width);
1747
1748SMLoc getFlatOffsetLoc(constOperandVector &Operands)const;
1749SMLoc getSMEMOffsetLoc(constOperandVector &Operands)const;
1750SMLoc getBLGPLoc(constOperandVector &Operands)const;
1751
1752SMLoc getOperandLoc(std::function<bool(const AMDGPUOperand&)>Test,
1753constOperandVector &Operands)const;
1754SMLoc getImmLoc(AMDGPUOperand::ImmTyType,constOperandVector &Operands)const;
1755SMLoc getRegLoc(MCRegister Reg,constOperandVector &Operands)const;
1756SMLoc getLitLoc(constOperandVector &Operands,
1757bool SearchMandatoryLiterals =false)const;
1758SMLoc getMandatoryLitLoc(constOperandVector &Operands)const;
1759SMLoc getConstLoc(constOperandVector &Operands)const;
1760SMLoc getInstLoc(constOperandVector &Operands)const;
1761
1762bool validateInstruction(constMCInst &Inst,constSMLoc &IDLoc,constOperandVector &Operands);
1763bool validateOffset(constMCInst &Inst,constOperandVector &Operands);
1764bool validateFlatOffset(constMCInst &Inst,constOperandVector &Operands);
1765bool validateSMEMOffset(constMCInst &Inst,constOperandVector &Operands);
1766bool validateSOPLiteral(constMCInst &Inst)const;
1767bool validateConstantBusLimitations(constMCInst &Inst,constOperandVector &Operands);
1768bool validateVOPDRegBankConstraints(constMCInst &Inst,
1769constOperandVector &Operands);
1770bool validateIntClampSupported(constMCInst &Inst);
1771bool validateMIMGAtomicDMask(constMCInst &Inst);
1772bool validateMIMGGatherDMask(constMCInst &Inst);
1773bool validateMovrels(constMCInst &Inst,constOperandVector &Operands);
1774bool validateMIMGDataSize(constMCInst &Inst,constSMLoc &IDLoc);
1775bool validateMIMGAddrSize(constMCInst &Inst,constSMLoc &IDLoc);
1776bool validateMIMGD16(constMCInst &Inst);
1777bool validateMIMGDim(constMCInst &Inst,constOperandVector &Operands);
1778bool validateMIMGMSAA(constMCInst &Inst);
1779bool validateOpSel(constMCInst &Inst);
1780bool validateNeg(constMCInst &Inst,intOpName);
1781bool validateDPP(constMCInst &Inst,constOperandVector &Operands);
1782bool validateVccOperand(MCRegister Reg)const;
1783bool validateVOPLiteral(constMCInst &Inst,constOperandVector &Operands);
1784bool validateMAIAccWrite(constMCInst &Inst,constOperandVector &Operands);
1785bool validateMAISrc2(constMCInst &Inst,constOperandVector &Operands);
1786bool validateMFMA(constMCInst &Inst,constOperandVector &Operands);
1787bool validateAGPRLdSt(constMCInst &Inst)const;
1788bool validateVGPRAlign(constMCInst &Inst)const;
1789bool validateBLGP(constMCInst &Inst,constOperandVector &Operands);
1790bool validateDS(constMCInst &Inst,constOperandVector &Operands);
1791bool validateGWS(constMCInst &Inst,constOperandVector &Operands);
1792bool validateDivScale(constMCInst &Inst);
1793bool validateWaitCnt(constMCInst &Inst,constOperandVector &Operands);
1794bool validateCoherencyBits(constMCInst &Inst,constOperandVector &Operands,
1795constSMLoc &IDLoc);
1796bool validateTHAndScopeBits(constMCInst &Inst,constOperandVector &Operands,
1797constunsigned CPol);
1798bool validateTFE(constMCInst &Inst,constOperandVector &Operands);
1799 std::optional<StringRef> validateLdsDirect(constMCInst &Inst);
1800unsigned getConstantBusLimit(unsigned Opcode)const;
1801bool usesConstantBus(constMCInst &Inst,unsigned OpIdx);
1802bool isInlineConstant(constMCInst &Inst,unsigned OpIdx)const;
1803unsigned findImplicitSGPRReadInVOP(constMCInst &Inst)const;
1804
1805bool isSupportedMnemo(StringRef Mnemo,
1806constFeatureBitset &FBS);
1807bool isSupportedMnemo(StringRef Mnemo,
1808constFeatureBitset &FBS,
1809ArrayRef<unsigned> Variants);
1810bool checkUnsupportedInstruction(StringRefName,constSMLoc &IDLoc);
1811
1812bool isId(constStringRef Id)const;
1813bool isId(constAsmToken &Token,constStringRef Id)const;
1814bool isToken(constAsmToken::TokenKind Kind)const;
1815StringRef getId()const;
1816bool trySkipId(constStringRef Id);
1817bool trySkipId(constStringRef Pref,constStringRef Id);
1818bool trySkipId(constStringRef Id,constAsmToken::TokenKind Kind);
1819bool trySkipToken(constAsmToken::TokenKind Kind);
1820bool skipToken(constAsmToken::TokenKind Kind,constStringRef ErrMsg);
1821bool parseString(StringRef &Val,constStringRef ErrMsg ="expected a string");
1822bool parseId(StringRef &Val,constStringRef ErrMsg ="");
1823
1824void peekTokens(MutableArrayRef<AsmToken> Tokens);
1825AsmToken::TokenKind getTokenKind()const;
1826boolparseExpr(int64_t &Imm,StringRefExpected ="");
1827boolparseExpr(OperandVector &Operands);
1828StringRef getTokenStr()const;
1829AsmToken peekToken(bool ShouldSkipSpace =true);
1830AsmToken getToken()const;
1831SMLoc getLoc()const;
1832void lex();
1833
1834public:
1835void onBeginOfFile()override;
1836bool parsePrimaryExpr(constMCExpr *&Res,SMLoc &EndLoc)override;
1837
1838ParseStatus parseCustomOperand(OperandVector &Operands,unsigned MCK);
1839
1840ParseStatus parseExpTgt(OperandVector &Operands);
1841ParseStatus parseSendMsg(OperandVector &Operands);
1842ParseStatus parseInterpSlot(OperandVector &Operands);
1843ParseStatus parseInterpAttr(OperandVector &Operands);
1844ParseStatus parseSOPPBrTarget(OperandVector &Operands);
1845ParseStatus parseBoolReg(OperandVector &Operands);
1846
1847bool parseSwizzleOperand(int64_t &Op,constunsigned MinVal,
1848constunsigned MaxVal,constTwine &ErrMsg,
1849SMLoc &Loc);
1850bool parseSwizzleOperands(constunsigned OpNum, int64_t*Op,
1851constunsigned MinVal,
1852constunsigned MaxVal,
1853constStringRef ErrMsg);
1854ParseStatus parseSwizzle(OperandVector &Operands);
1855bool parseSwizzleOffset(int64_t &Imm);
1856bool parseSwizzleMacro(int64_t &Imm);
1857bool parseSwizzleQuadPerm(int64_t &Imm);
1858bool parseSwizzleBitmaskPerm(int64_t &Imm);
1859bool parseSwizzleBroadcast(int64_t &Imm);
1860bool parseSwizzleSwap(int64_t &Imm);
1861bool parseSwizzleReverse(int64_t &Imm);
1862bool parseSwizzleFFT(int64_t &Imm);
1863bool parseSwizzleRotate(int64_t &Imm);
1864
1865ParseStatus parseGPRIdxMode(OperandVector &Operands);
1866 int64_t parseGPRIdxMacro();
1867
1868void cvtMubuf(MCInst &Inst,constOperandVector &Operands) { cvtMubufImpl(Inst,Operands,false); }
1869void cvtMubufAtomic(MCInst &Inst,constOperandVector &Operands) { cvtMubufImpl(Inst,Operands,true); }
1870
1871ParseStatus parseOModSI(OperandVector &Operands);
1872
1873void cvtVOP3(MCInst &Inst,constOperandVector &Operands,
1874 OptionalImmIndexMap &OptionalIdx);
1875void cvtVOP3OpSel(MCInst &Inst,constOperandVector &Operands);
1876void cvtVOP3(MCInst &Inst,constOperandVector &Operands);
1877void cvtVOP3P(MCInst &Inst,constOperandVector &Operands);
1878void cvtSWMMAC(MCInst &Inst,constOperandVector &Operands);
1879
1880void cvtVOPD(MCInst &Inst,constOperandVector &Operands);
1881void cvtVOP3OpSel(MCInst &Inst,constOperandVector &Operands,
1882 OptionalImmIndexMap &OptionalIdx);
1883void cvtVOP3P(MCInst &Inst,constOperandVector &Operands,
1884 OptionalImmIndexMap &OptionalIdx);
1885
1886void cvtVOP3Interp(MCInst &Inst,constOperandVector &Operands);
1887void cvtVINTERP(MCInst &Inst,constOperandVector &Operands);
1888
1889bool parseDimId(unsigned &Encoding);
1890ParseStatus parseDim(OperandVector &Operands);
1891bool convertDppBoundCtrl(int64_t &BoundCtrl);
1892ParseStatus parseDPP8(OperandVector &Operands);
1893ParseStatus parseDPPCtrl(OperandVector &Operands);
1894bool isSupportedDPPCtrl(StringRef Ctrl,constOperandVector &Operands);
1895 int64_t parseDPPCtrlSel(StringRef Ctrl);
1896 int64_t parseDPPCtrlPerm();
1897void cvtDPP(MCInst &Inst,constOperandVector &Operands,bool IsDPP8 =false);
1898void cvtDPP8(MCInst &Inst,constOperandVector &Operands) {
1899 cvtDPP(Inst,Operands,true);
1900 }
1901void cvtVOP3DPP(MCInst &Inst,constOperandVector &Operands,
1902bool IsDPP8 =false);
1903void cvtVOP3DPP8(MCInst &Inst,constOperandVector &Operands) {
1904 cvtVOP3DPP(Inst,Operands,true);
1905 }
1906
1907ParseStatus parseSDWASel(OperandVector &Operands,StringRef Prefix,
1908 AMDGPUOperand::ImmTyType);
1909ParseStatus parseSDWADstUnused(OperandVector &Operands);
1910void cvtSdwaVOP1(MCInst &Inst,constOperandVector &Operands);
1911void cvtSdwaVOP2(MCInst &Inst,constOperandVector &Operands);
1912void cvtSdwaVOP2b(MCInst &Inst,constOperandVector &Operands);
1913void cvtSdwaVOP2e(MCInst &Inst,constOperandVector &Operands);
1914void cvtSdwaVOPC(MCInst &Inst,constOperandVector &Operands);
1915void cvtSDWA(MCInst &Inst,constOperandVector &Operands,
1916uint64_t BasicInstType,
1917bool SkipDstVcc =false,
1918bool SkipSrcVcc =false);
1919
1920ParseStatus parseEndpgm(OperandVector &Operands);
1921
1922ParseStatus parseVOPD(OperandVector &Operands);
1923};
1924
1925}// end anonymous namespace
1926
1927// May be called with integer type with equivalent bitwidth.
1928staticconstfltSemantics *getFltSemantics(unsignedSize) {
1929switch (Size) {
1930case 4:
1931return &APFloat::IEEEsingle();
1932case 8:
1933return &APFloat::IEEEdouble();
1934case 2:
1935return &APFloat::IEEEhalf();
1936default:
1937llvm_unreachable("unsupported fp type");
1938 }
1939}
1940
1941staticconstfltSemantics *getFltSemantics(MVT VT) {
1942returngetFltSemantics(VT.getSizeInBits() / 8);
1943}
1944
1945staticconstfltSemantics *getOpFltSemantics(uint8_tOperandType) {
1946switch (OperandType) {
1947// When floating-point immediate is used as operand of type i16, the 32-bit
1948// representation of the constant truncated to the 16 LSBs should be used.
1949caseAMDGPU::OPERAND_REG_IMM_INT16:
1950caseAMDGPU::OPERAND_REG_INLINE_C_INT16:
1951caseAMDGPU::OPERAND_REG_INLINE_AC_INT16:
1952caseAMDGPU::OPERAND_REG_IMM_INT32:
1953caseAMDGPU::OPERAND_REG_IMM_FP32:
1954caseAMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
1955caseAMDGPU::OPERAND_REG_INLINE_C_INT32:
1956caseAMDGPU::OPERAND_REG_INLINE_C_FP32:
1957caseAMDGPU::OPERAND_REG_INLINE_AC_INT32:
1958caseAMDGPU::OPERAND_REG_INLINE_AC_FP32:
1959caseAMDGPU::OPERAND_REG_INLINE_C_V2FP32:
1960caseAMDGPU::OPERAND_REG_IMM_V2FP32:
1961caseAMDGPU::OPERAND_REG_INLINE_C_V2INT32:
1962caseAMDGPU::OPERAND_REG_IMM_V2INT32:
1963caseAMDGPU::OPERAND_REG_IMM_V2INT16:
1964caseAMDGPU::OPERAND_REG_INLINE_C_V2INT16:
1965caseAMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
1966caseAMDGPU::OPERAND_KIMM32:
1967caseAMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
1968return &APFloat::IEEEsingle();
1969caseAMDGPU::OPERAND_REG_IMM_INT64:
1970caseAMDGPU::OPERAND_REG_IMM_FP64:
1971caseAMDGPU::OPERAND_REG_INLINE_C_INT64:
1972caseAMDGPU::OPERAND_REG_INLINE_C_FP64:
1973caseAMDGPU::OPERAND_REG_INLINE_AC_FP64:
1974return &APFloat::IEEEdouble();
1975caseAMDGPU::OPERAND_REG_IMM_FP16:
1976caseAMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
1977caseAMDGPU::OPERAND_REG_INLINE_C_FP16:
1978caseAMDGPU::OPERAND_REG_INLINE_C_V2FP16:
1979caseAMDGPU::OPERAND_REG_INLINE_AC_FP16:
1980caseAMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
1981caseAMDGPU::OPERAND_REG_IMM_V2FP16:
1982caseAMDGPU::OPERAND_KIMM16:
1983return &APFloat::IEEEhalf();
1984caseAMDGPU::OPERAND_REG_IMM_BF16:
1985caseAMDGPU::OPERAND_REG_IMM_BF16_DEFERRED:
1986caseAMDGPU::OPERAND_REG_INLINE_C_BF16:
1987caseAMDGPU::OPERAND_REG_INLINE_C_V2BF16:
1988caseAMDGPU::OPERAND_REG_INLINE_AC_BF16:
1989caseAMDGPU::OPERAND_REG_INLINE_AC_V2BF16:
1990caseAMDGPU::OPERAND_REG_IMM_V2BF16:
1991return &APFloat::BFloat();
1992default:
1993llvm_unreachable("unsupported fp type");
1994 }
1995}
1996
1997//===----------------------------------------------------------------------===//
1998// Operand
1999//===----------------------------------------------------------------------===//
2000
2001staticboolcanLosslesslyConvertToFPType(APFloat &FPLiteral,MVT VT) {
2002bool Lost;
2003
2004// Convert literal to single precision
2005APFloat::opStatusStatus = FPLiteral.convert(*getFltSemantics(VT),
2006 APFloat::rmNearestTiesToEven,
2007 &Lost);
2008// We allow precision lost but not overflow or underflow
2009if (Status != APFloat::opOK &&
2010 Lost &&
2011 ((Status & APFloat::opOverflow) != 0 ||
2012 (Status & APFloat::opUnderflow) != 0)) {
2013returnfalse;
2014 }
2015
2016returntrue;
2017}
2018
2019staticboolisSafeTruncation(int64_t Val,unsignedSize) {
2020returnisUIntN(Size, Val) ||isIntN(Size, Val);
2021}
2022
2023staticboolisInlineableLiteralOp16(int64_t Val,MVT VT,bool HasInv2Pi) {
2024if (VT.getScalarType() == MVT::i16)
2025returnisInlinableLiteral32(Val, HasInv2Pi);
2026
2027if (VT.getScalarType() == MVT::f16)
2028returnAMDGPU::isInlinableLiteralFP16(Val, HasInv2Pi);
2029
2030assert(VT.getScalarType() == MVT::bf16);
2031
2032returnAMDGPU::isInlinableLiteralBF16(Val, HasInv2Pi);
2033}
2034
2035bool AMDGPUOperand::isInlinableImm(MVT type) const{
2036
2037// This is a hack to enable named inline values like
2038// shared_base with both 32-bit and 64-bit operands.
2039// Note that these values are defined as
2040// 32-bit operands only.
2041if (isInlineValue()) {
2042returntrue;
2043 }
2044
2045if (!isImmTy(ImmTyNone)) {
2046// Only plain immediates are inlinable (e.g. "clamp" attribute is not)
2047returnfalse;
2048 }
2049// TODO: We should avoid using host float here. It would be better to
2050// check the float bit values which is what a few other places do.
2051// We've had bot failures before due to weird NaN support on mips hosts.
2052
2053APIntLiteral(64,Imm.Val);
2054
2055if (Imm.IsFPImm) {// We got fp literal token
2056if (type == MVT::f64 || type == MVT::i64) {// Expected 64-bit operand
2057returnAMDGPU::isInlinableLiteral64(Imm.Val,
2058 AsmParser->hasInv2PiInlineImm());
2059 }
2060
2061APFloat FPLiteral(APFloat::IEEEdouble(),APInt(64,Imm.Val));
2062if (!canLosslesslyConvertToFPType(FPLiteral, type))
2063returnfalse;
2064
2065if (type.getScalarSizeInBits() == 16) {
2066bool Lost =false;
2067switch (type.getScalarType().SimpleTy) {
2068default:
2069llvm_unreachable("unknown 16-bit type");
2070case MVT::bf16:
2071 FPLiteral.convert(APFloatBase::BFloat(), APFloat::rmNearestTiesToEven,
2072 &Lost);
2073break;
2074case MVT::f16:
2075 FPLiteral.convert(APFloatBase::IEEEhalf(), APFloat::rmNearestTiesToEven,
2076 &Lost);
2077break;
2078case MVT::i16:
2079 FPLiteral.convert(APFloatBase::IEEEsingle(),
2080 APFloat::rmNearestTiesToEven, &Lost);
2081break;
2082 }
2083// We need to use 32-bit representation here because when a floating-point
2084// inline constant is used as an i16 operand, its 32-bit representation
2085// representation will be used. We will need the 32-bit value to check if
2086// it is FP inline constant.
2087uint32_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2088returnisInlineableLiteralOp16(ImmVal, type,
2089 AsmParser->hasInv2PiInlineImm());
2090 }
2091
2092// Check if single precision literal is inlinable
2093returnAMDGPU::isInlinableLiteral32(
2094static_cast<int32_t>(FPLiteral.bitcastToAPInt().getZExtValue()),
2095 AsmParser->hasInv2PiInlineImm());
2096 }
2097
2098// We got int literal token.
2099if (type == MVT::f64 || type == MVT::i64) {// Expected 64-bit operand
2100returnAMDGPU::isInlinableLiteral64(Imm.Val,
2101 AsmParser->hasInv2PiInlineImm());
2102 }
2103
2104if (!isSafeTruncation(Imm.Val, type.getScalarSizeInBits())) {
2105returnfalse;
2106 }
2107
2108if (type.getScalarSizeInBits() == 16) {
2109returnisInlineableLiteralOp16(
2110static_cast<int16_t>(Literal.getLoBits(16).getSExtValue()),
2111 type, AsmParser->hasInv2PiInlineImm());
2112 }
2113
2114returnAMDGPU::isInlinableLiteral32(
2115static_cast<int32_t>(Literal.getLoBits(32).getZExtValue()),
2116 AsmParser->hasInv2PiInlineImm());
2117}
2118
2119bool AMDGPUOperand::isLiteralImm(MVT type) const{
2120// Check that this immediate can be added as literal
2121if (!isImmTy(ImmTyNone)) {
2122returnfalse;
2123 }
2124
2125if (!Imm.IsFPImm) {
2126// We got int literal token.
2127
2128if (type == MVT::f64 && hasFPModifiers()) {
2129// Cannot apply fp modifiers to int literals preserving the same semantics
2130// for VOP1/2/C and VOP3 because of integer truncation. To avoid ambiguity,
2131// disable these cases.
2132returnfalse;
2133 }
2134
2135unsignedSize = type.getSizeInBits();
2136if (Size == 64)
2137Size = 32;
2138
2139// FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP
2140// types.
2141returnisSafeTruncation(Imm.Val,Size);
2142 }
2143
2144// We got fp literal token
2145if (type == MVT::f64) {// Expected 64-bit fp operand
2146// We would set low 64-bits of literal to zeroes but we accept this literals
2147returntrue;
2148 }
2149
2150if (type == MVT::i64) {// Expected 64-bit int operand
2151// We don't allow fp literals in 64-bit integer instructions. It is
2152// unclear how we should encode them.
2153returnfalse;
2154 }
2155
2156// We allow fp literals with f16x2 operands assuming that the specified
2157// literal goes into the lower half and the upper half is zero. We also
2158// require that the literal may be losslessly converted to f16.
2159//
2160// For i16x2 operands, we assume that the specified literal is encoded as a
2161// single-precision float. This is pretty odd, but it matches SP3 and what
2162// happens in hardware.
2163MVT ExpectedType = (type == MVT::v2f16) ? MVT::f16
2164 : (type == MVT::v2i16) ? MVT::f32
2165 : (type == MVT::v2f32) ? MVT::f32
2166 : type;
2167
2168APFloat FPLiteral(APFloat::IEEEdouble(),APInt(64,Imm.Val));
2169returncanLosslesslyConvertToFPType(FPLiteral, ExpectedType);
2170}
2171
2172bool AMDGPUOperand::isRegClass(unsigned RCID) const{
2173return isRegKind() && AsmParser->getMRI()->getRegClass(RCID).contains(getReg());
2174}
2175
2176bool AMDGPUOperand::isVRegWithInputMods() const{
2177return isRegClass(AMDGPU::VGPR_32RegClassID) ||
2178// GFX90A allows DPP on 64-bit operands.
2179 (isRegClass(AMDGPU::VReg_64RegClassID) &&
2180 AsmParser->getFeatureBits()[AMDGPU::FeatureDPALU_DPP]);
2181}
2182
2183template <bool IsFake16>
2184bool AMDGPUOperand::isT16_Lo128VRegWithInputMods() const{
2185return isRegClass(IsFake16 ? AMDGPU::VGPR_32_Lo128RegClassID
2186 : AMDGPU::VGPR_16_Lo128RegClassID);
2187}
2188
2189template <bool IsFake16>bool AMDGPUOperand::isT16VRegWithInputMods() const{
2190return isRegClass(IsFake16 ? AMDGPU::VGPR_32RegClassID
2191 : AMDGPU::VGPR_16RegClassID);
2192}
2193
2194bool AMDGPUOperand::isSDWAOperand(MVT type) const{
2195if (AsmParser->isVI())
2196return isVReg32();
2197if (AsmParser->isGFX9Plus())
2198return isRegClass(AMDGPU::VS_32RegClassID) || isInlinableImm(type);
2199returnfalse;
2200}
2201
2202bool AMDGPUOperand::isSDWAFP16Operand() const{
2203return isSDWAOperand(MVT::f16);
2204}
2205
2206bool AMDGPUOperand::isSDWAFP32Operand() const{
2207return isSDWAOperand(MVT::f32);
2208}
2209
2210bool AMDGPUOperand::isSDWAInt16Operand() const{
2211return isSDWAOperand(MVT::i16);
2212}
2213
2214bool AMDGPUOperand::isSDWAInt32Operand() const{
2215return isSDWAOperand(MVT::i32);
2216}
2217
2218bool AMDGPUOperand::isBoolReg() const{
2219auto FB = AsmParser->getFeatureBits();
2220returnisReg() && ((FB[AMDGPU::FeatureWavefrontSize64] && isSCSrc_b64()) ||
2221 (FB[AMDGPU::FeatureWavefrontSize32] && isSCSrc_b32()));
2222}
2223
2224uint64_t AMDGPUOperand::applyInputFPModifiers(uint64_t Val,unsignedSize) const
2225{
2226assert(isImmTy(ImmTyNone) &&Imm.Mods.hasFPModifiers());
2227assert(Size == 2 ||Size == 4 ||Size == 8);
2228
2229constuint64_t FpSignMask = (1ULL << (Size * 8 - 1));
2230
2231if (Imm.Mods.Abs) {
2232 Val &= ~FpSignMask;
2233 }
2234if (Imm.Mods.Neg) {
2235 Val ^= FpSignMask;
2236 }
2237
2238return Val;
2239}
2240
2241void AMDGPUOperand::addImmOperands(MCInst &Inst,unsignedN,bool ApplyModifiers) const{
2242if (isExpr()) {
2243 Inst.addOperand(MCOperand::createExpr(Expr));
2244return;
2245 }
2246
2247if (AMDGPU::isSISrcOperand(AsmParser->getMII()->get(Inst.getOpcode()),
2248 Inst.getNumOperands())) {
2249 addLiteralImmOperand(Inst,Imm.Val,
2250 ApplyModifiers &
2251 isImmTy(ImmTyNone) &&Imm.Mods.hasFPModifiers());
2252 }else {
2253assert(!isImmTy(ImmTyNone) || !hasModifiers());
2254 Inst.addOperand(MCOperand::createImm(Imm.Val));
2255 setImmKindNone();
2256 }
2257}
2258
2259void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val,bool ApplyModifiers) const{
2260constauto& InstDesc = AsmParser->getMII()->get(Inst.getOpcode());
2261auto OpNum = Inst.getNumOperands();
2262// Check that this operand accepts literals
2263assert(AMDGPU::isSISrcOperand(InstDesc, OpNum));
2264
2265if (ApplyModifiers) {
2266assert(AMDGPU::isSISrcFPOperand(InstDesc, OpNum));
2267constunsignedSize =Imm.IsFPImm ?sizeof(double) :getOperandSize(InstDesc, OpNum);
2268 Val = applyInputFPModifiers(Val,Size);
2269 }
2270
2271APIntLiteral(64, Val);
2272uint8_t OpTy = InstDesc.operands()[OpNum].OperandType;
2273
2274if (Imm.IsFPImm) {// We got fp literal token
2275switch (OpTy) {
2276caseAMDGPU::OPERAND_REG_IMM_INT64:
2277caseAMDGPU::OPERAND_REG_IMM_FP64:
2278caseAMDGPU::OPERAND_REG_INLINE_C_INT64:
2279caseAMDGPU::OPERAND_REG_INLINE_C_FP64:
2280caseAMDGPU::OPERAND_REG_INLINE_AC_FP64:
2281if (AMDGPU::isInlinableLiteral64(Literal.getZExtValue(),
2282 AsmParser->hasInv2PiInlineImm())) {
2283 Inst.addOperand(MCOperand::createImm(Literal.getZExtValue()));
2284 setImmKindConst();
2285return;
2286 }
2287
2288// Non-inlineable
2289if (AMDGPU::isSISrcFPOperand(InstDesc, OpNum)) {// Expected 64-bit fp operand
2290// For fp operands we check if low 32 bits are zeros
2291if (Literal.getLoBits(32) != 0) {
2292const_cast<AMDGPUAsmParser *>(AsmParser)->Warning(Inst.getLoc(),
2293"Can't encode literal as exact 64-bit floating-point operand. "
2294"Low 32-bits will be set to zero");
2295 Val &= 0xffffffff00000000u;
2296 }
2297
2298 Inst.addOperand(MCOperand::createImm(Val));
2299 setImmKindLiteral();
2300return;
2301 }
2302
2303// We don't allow fp literals in 64-bit integer instructions. It is
2304// unclear how we should encode them. This case should be checked earlier
2305// in predicate methods (isLiteralImm())
2306llvm_unreachable("fp literal in 64-bit integer instruction.");
2307
2308caseAMDGPU::OPERAND_REG_IMM_BF16:
2309caseAMDGPU::OPERAND_REG_IMM_BF16_DEFERRED:
2310caseAMDGPU::OPERAND_REG_INLINE_C_BF16:
2311caseAMDGPU::OPERAND_REG_INLINE_C_V2BF16:
2312caseAMDGPU::OPERAND_REG_INLINE_AC_BF16:
2313caseAMDGPU::OPERAND_REG_INLINE_AC_V2BF16:
2314caseAMDGPU::OPERAND_REG_IMM_V2BF16:
2315if (AsmParser->hasInv2PiInlineImm() &&Literal == 0x3fc45f306725feed) {
2316// This is the 1/(2*pi) which is going to be truncated to bf16 with the
2317// loss of precision. The constant represents ideomatic fp32 value of
2318// 1/(2*pi) = 0.15915494 since bf16 is in fact fp32 with cleared low 16
2319// bits. Prevent rounding below.
2320 Inst.addOperand(MCOperand::createImm(0x3e22));
2321 setImmKindLiteral();
2322return;
2323 }
2324 [[fallthrough]];
2325
2326caseAMDGPU::OPERAND_REG_IMM_INT32:
2327caseAMDGPU::OPERAND_REG_IMM_FP32:
2328caseAMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
2329caseAMDGPU::OPERAND_REG_INLINE_C_INT32:
2330caseAMDGPU::OPERAND_REG_INLINE_C_FP32:
2331caseAMDGPU::OPERAND_REG_INLINE_AC_INT32:
2332caseAMDGPU::OPERAND_REG_INLINE_AC_FP32:
2333caseAMDGPU::OPERAND_REG_IMM_INT16:
2334caseAMDGPU::OPERAND_REG_IMM_FP16:
2335caseAMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
2336caseAMDGPU::OPERAND_REG_INLINE_C_INT16:
2337caseAMDGPU::OPERAND_REG_INLINE_C_FP16:
2338caseAMDGPU::OPERAND_REG_INLINE_C_V2INT16:
2339caseAMDGPU::OPERAND_REG_INLINE_C_V2FP16:
2340caseAMDGPU::OPERAND_REG_INLINE_AC_INT16:
2341caseAMDGPU::OPERAND_REG_INLINE_AC_FP16:
2342caseAMDGPU::OPERAND_REG_INLINE_AC_V2INT16:
2343caseAMDGPU::OPERAND_REG_INLINE_AC_V2FP16:
2344caseAMDGPU::OPERAND_REG_IMM_V2INT16:
2345caseAMDGPU::OPERAND_REG_IMM_V2FP16:
2346caseAMDGPU::OPERAND_REG_INLINE_C_V2FP32:
2347caseAMDGPU::OPERAND_REG_IMM_V2FP32:
2348caseAMDGPU::OPERAND_REG_INLINE_C_V2INT32:
2349caseAMDGPU::OPERAND_REG_IMM_V2INT32:
2350caseAMDGPU::OPERAND_KIMM32:
2351caseAMDGPU::OPERAND_KIMM16:
2352caseAMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32: {
2353bool lost;
2354APFloat FPLiteral(APFloat::IEEEdouble(),Literal);
2355// Convert literal to single precision
2356 FPLiteral.convert(*getOpFltSemantics(OpTy),
2357 APFloat::rmNearestTiesToEven, &lost);
2358// We allow precision lost but not overflow or underflow. This should be
2359// checked earlier in isLiteralImm()
2360
2361uint64_t ImmVal = FPLiteral.bitcastToAPInt().getZExtValue();
2362 Inst.addOperand(MCOperand::createImm(ImmVal));
2363if (OpTy ==AMDGPU::OPERAND_KIMM32 || OpTy ==AMDGPU::OPERAND_KIMM16) {
2364 setImmKindMandatoryLiteral();
2365 }else {
2366 setImmKindLiteral();
2367 }
2368return;
2369 }
2370default:
2371llvm_unreachable("invalid operand size");
2372 }
2373
2374return;
2375 }
2376
2377// We got int literal token.
2378// Only sign extend inline immediates.
2379switch (OpTy) {
2380caseAMDGPU::OPERAND_REG_IMM_INT32:
2381caseAMDGPU::OPERAND_REG_IMM_FP32:
2382caseAMDGPU::OPERAND_REG_IMM_FP32_DEFERRED:
2383caseAMDGPU::OPERAND_REG_INLINE_C_INT32:
2384caseAMDGPU::OPERAND_REG_INLINE_C_FP32:
2385caseAMDGPU::OPERAND_REG_INLINE_AC_INT32:
2386caseAMDGPU::OPERAND_REG_INLINE_AC_FP32:
2387caseAMDGPU::OPERAND_REG_IMM_V2INT16:
2388caseAMDGPU::OPERAND_REG_IMM_V2BF16:
2389caseAMDGPU::OPERAND_REG_IMM_V2FP16:
2390caseAMDGPU::OPERAND_REG_IMM_V2FP32:
2391caseAMDGPU::OPERAND_REG_INLINE_C_V2FP32:
2392caseAMDGPU::OPERAND_REG_IMM_V2INT32:
2393caseAMDGPU::OPERAND_REG_INLINE_C_V2INT32:
2394caseAMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32:
2395if (isSafeTruncation(Val, 32) &&
2396AMDGPU::isInlinableLiteral32(static_cast<int32_t>(Val),
2397 AsmParser->hasInv2PiInlineImm())) {
2398 Inst.addOperand(MCOperand::createImm(Val));
2399 setImmKindConst();
2400return;
2401 }
2402
2403 Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
2404 setImmKindLiteral();
2405return;
2406
2407caseAMDGPU::OPERAND_REG_IMM_INT64:
2408caseAMDGPU::OPERAND_REG_IMM_FP64:
2409caseAMDGPU::OPERAND_REG_INLINE_C_INT64:
2410caseAMDGPU::OPERAND_REG_INLINE_C_FP64:
2411caseAMDGPU::OPERAND_REG_INLINE_AC_FP64:
2412if (AMDGPU::isInlinableLiteral64(Val, AsmParser->hasInv2PiInlineImm())) {
2413 Inst.addOperand(MCOperand::createImm(Val));
2414 setImmKindConst();
2415return;
2416 }
2417
2418 Val =AMDGPU::isSISrcFPOperand(InstDesc, OpNum) ? (uint64_t)Val << 32
2419 :Lo_32(Val);
2420
2421 Inst.addOperand(MCOperand::createImm(Val));
2422 setImmKindLiteral();
2423return;
2424
2425caseAMDGPU::OPERAND_REG_IMM_INT16:
2426caseAMDGPU::OPERAND_REG_INLINE_C_INT16:
2427caseAMDGPU::OPERAND_REG_INLINE_AC_INT16:
2428if (isSafeTruncation(Val, 16) &&
2429AMDGPU::isInlinableIntLiteral(static_cast<int16_t>(Val))) {
2430 Inst.addOperand(MCOperand::createImm(Lo_32(Val)));
2431 setImmKindConst();
2432return;
2433 }
2434
2435 Inst.addOperand(MCOperand::createImm(Val & 0xffff));
2436 setImmKindLiteral();
2437return;
2438
2439caseAMDGPU::OPERAND_REG_INLINE_C_FP16:
2440caseAMDGPU::OPERAND_REG_IMM_FP16:
2441caseAMDGPU::OPERAND_REG_IMM_FP16_DEFERRED:
2442caseAMDGPU::OPERAND_REG_INLINE_AC_FP16:
2443if (isSafeTruncation(Val, 16) &&
2444AMDGPU::isInlinableLiteralFP16(static_cast<int16_t>(Val),
2445 AsmParser->hasInv2PiInlineImm())) {
2446 Inst.addOperand(MCOperand::createImm(Val));
2447 setImmKindConst();
2448return;
2449 }
2450
2451 Inst.addOperand(MCOperand::createImm(Val & 0xffff));
2452 setImmKindLiteral();
2453return;
2454
2455caseAMDGPU::OPERAND_REG_IMM_BF16:
2456caseAMDGPU::OPERAND_REG_IMM_BF16_DEFERRED:
2457caseAMDGPU::OPERAND_REG_INLINE_C_BF16:
2458caseAMDGPU::OPERAND_REG_INLINE_AC_BF16:
2459if (isSafeTruncation(Val, 16) &&
2460AMDGPU::isInlinableLiteralBF16(static_cast<int16_t>(Val),
2461 AsmParser->hasInv2PiInlineImm())) {
2462 Inst.addOperand(MCOperand::createImm(Val));
2463 setImmKindConst();
2464return;
2465 }
2466
2467 Inst.addOperand(MCOperand::createImm(Val & 0xffff));
2468 setImmKindLiteral();
2469return;
2470
2471caseAMDGPU::OPERAND_REG_INLINE_C_V2INT16:
2472caseAMDGPU::OPERAND_REG_INLINE_AC_V2INT16: {
2473assert(isSafeTruncation(Val, 16));
2474assert(AMDGPU::isInlinableIntLiteral(static_cast<int16_t>(Val)));
2475 Inst.addOperand(MCOperand::createImm(Val));
2476return;
2477 }
2478caseAMDGPU::OPERAND_REG_INLINE_C_V2FP16:
2479caseAMDGPU::OPERAND_REG_INLINE_AC_V2FP16: {
2480assert(isSafeTruncation(Val, 16));
2481assert(AMDGPU::isInlinableLiteralFP16(static_cast<int16_t>(Val),
2482 AsmParser->hasInv2PiInlineImm()));
2483
2484 Inst.addOperand(MCOperand::createImm(Val));
2485return;
2486 }
2487
2488caseAMDGPU::OPERAND_REG_INLINE_C_V2BF16:
2489caseAMDGPU::OPERAND_REG_INLINE_AC_V2BF16: {
2490assert(isSafeTruncation(Val, 16));
2491assert(AMDGPU::isInlinableLiteralBF16(static_cast<int16_t>(Val),
2492 AsmParser->hasInv2PiInlineImm()));
2493
2494 Inst.addOperand(MCOperand::createImm(Val));
2495return;
2496 }
2497
2498caseAMDGPU::OPERAND_KIMM32:
2499 Inst.addOperand(MCOperand::createImm(Literal.getLoBits(32).getZExtValue()));
2500 setImmKindMandatoryLiteral();
2501return;
2502caseAMDGPU::OPERAND_KIMM16:
2503 Inst.addOperand(MCOperand::createImm(Literal.getLoBits(16).getZExtValue()));
2504 setImmKindMandatoryLiteral();
2505return;
2506default:
2507llvm_unreachable("invalid operand size");
2508 }
2509}
2510
2511void AMDGPUOperand::addRegOperands(MCInst &Inst,unsignedN) const{
2512 Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), AsmParser->getSTI())));
2513}
2514
2515bool AMDGPUOperand::isInlineValue() const{
2516return isRegKind() &&::isInlineValue(getReg());
2517}
2518
2519//===----------------------------------------------------------------------===//
2520// AsmParser
2521//===----------------------------------------------------------------------===//
2522
2523void AMDGPUAsmParser::createConstantSymbol(StringRef Id, int64_t Val) {
2524// TODO: make those pre-defined variables read-only.
2525// Currently there is none suitable machinery in the core llvm-mc for this.
2526// MCSymbol::isRedefinable is intended for another purpose, and
2527// AsmParser::parseDirectiveSet() cannot be specialized for specific target.
2528MCContext &Ctx = getContext();
2529MCSymbol *Sym = Ctx.getOrCreateSymbol(Id);
2530Sym->setVariableValue(MCConstantExpr::create(Val, Ctx));
2531}
2532
2533staticintgetRegClass(RegisterKind Is,unsigned RegWidth) {
2534if (Is == IS_VGPR) {
2535switch (RegWidth) {
2536default:return -1;
2537case 32:
2538return AMDGPU::VGPR_32RegClassID;
2539case 64:
2540return AMDGPU::VReg_64RegClassID;
2541case 96:
2542return AMDGPU::VReg_96RegClassID;
2543case 128:
2544return AMDGPU::VReg_128RegClassID;
2545case 160:
2546return AMDGPU::VReg_160RegClassID;
2547case 192:
2548return AMDGPU::VReg_192RegClassID;
2549case 224:
2550return AMDGPU::VReg_224RegClassID;
2551case 256:
2552return AMDGPU::VReg_256RegClassID;
2553case 288:
2554return AMDGPU::VReg_288RegClassID;
2555case 320:
2556return AMDGPU::VReg_320RegClassID;
2557case 352:
2558return AMDGPU::VReg_352RegClassID;
2559case 384:
2560return AMDGPU::VReg_384RegClassID;
2561case 512:
2562return AMDGPU::VReg_512RegClassID;
2563case 1024:
2564return AMDGPU::VReg_1024RegClassID;
2565 }
2566 }elseif (Is == IS_TTMP) {
2567switch (RegWidth) {
2568default:return -1;
2569case 32:
2570return AMDGPU::TTMP_32RegClassID;
2571case 64:
2572return AMDGPU::TTMP_64RegClassID;
2573case 128:
2574return AMDGPU::TTMP_128RegClassID;
2575case 256:
2576return AMDGPU::TTMP_256RegClassID;
2577case 512:
2578return AMDGPU::TTMP_512RegClassID;
2579 }
2580 }elseif (Is == IS_SGPR) {
2581switch (RegWidth) {
2582default:return -1;
2583case 32:
2584return AMDGPU::SGPR_32RegClassID;
2585case 64:
2586return AMDGPU::SGPR_64RegClassID;
2587case 96:
2588return AMDGPU::SGPR_96RegClassID;
2589case 128:
2590return AMDGPU::SGPR_128RegClassID;
2591case 160:
2592return AMDGPU::SGPR_160RegClassID;
2593case 192:
2594return AMDGPU::SGPR_192RegClassID;
2595case 224:
2596return AMDGPU::SGPR_224RegClassID;
2597case 256:
2598return AMDGPU::SGPR_256RegClassID;
2599case 288:
2600return AMDGPU::SGPR_288RegClassID;
2601case 320:
2602return AMDGPU::SGPR_320RegClassID;
2603case 352:
2604return AMDGPU::SGPR_352RegClassID;
2605case 384:
2606return AMDGPU::SGPR_384RegClassID;
2607case 512:
2608return AMDGPU::SGPR_512RegClassID;
2609 }
2610 }elseif (Is == IS_AGPR) {
2611switch (RegWidth) {
2612default:return -1;
2613case 32:
2614return AMDGPU::AGPR_32RegClassID;
2615case 64:
2616return AMDGPU::AReg_64RegClassID;
2617case 96:
2618return AMDGPU::AReg_96RegClassID;
2619case 128:
2620return AMDGPU::AReg_128RegClassID;
2621case 160:
2622return AMDGPU::AReg_160RegClassID;
2623case 192:
2624return AMDGPU::AReg_192RegClassID;
2625case 224:
2626return AMDGPU::AReg_224RegClassID;
2627case 256:
2628return AMDGPU::AReg_256RegClassID;
2629case 288:
2630return AMDGPU::AReg_288RegClassID;
2631case 320:
2632return AMDGPU::AReg_320RegClassID;
2633case 352:
2634return AMDGPU::AReg_352RegClassID;
2635case 384:
2636return AMDGPU::AReg_384RegClassID;
2637case 512:
2638return AMDGPU::AReg_512RegClassID;
2639case 1024:
2640return AMDGPU::AReg_1024RegClassID;
2641 }
2642 }
2643return -1;
2644}
2645
2646staticMCRegistergetSpecialRegForName(StringRefRegName) {
2647returnStringSwitch<unsigned>(RegName)
2648 .Case("exec", AMDGPU::EXEC)
2649 .Case("vcc", AMDGPU::VCC)
2650 .Case("flat_scratch", AMDGPU::FLAT_SCR)
2651 .Case("xnack_mask", AMDGPU::XNACK_MASK)
2652 .Case("shared_base", AMDGPU::SRC_SHARED_BASE)
2653 .Case("src_shared_base", AMDGPU::SRC_SHARED_BASE)
2654 .Case("shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2655 .Case("src_shared_limit", AMDGPU::SRC_SHARED_LIMIT)
2656 .Case("private_base", AMDGPU::SRC_PRIVATE_BASE)
2657 .Case("src_private_base", AMDGPU::SRC_PRIVATE_BASE)
2658 .Case("private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2659 .Case("src_private_limit", AMDGPU::SRC_PRIVATE_LIMIT)
2660 .Case("pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2661 .Case("src_pops_exiting_wave_id", AMDGPU::SRC_POPS_EXITING_WAVE_ID)
2662 .Case("lds_direct", AMDGPU::LDS_DIRECT)
2663 .Case("src_lds_direct", AMDGPU::LDS_DIRECT)
2664 .Case("m0", AMDGPU::M0)
2665 .Case("vccz", AMDGPU::SRC_VCCZ)
2666 .Case("src_vccz", AMDGPU::SRC_VCCZ)
2667 .Case("execz", AMDGPU::SRC_EXECZ)
2668 .Case("src_execz", AMDGPU::SRC_EXECZ)
2669 .Case("scc", AMDGPU::SRC_SCC)
2670 .Case("src_scc", AMDGPU::SRC_SCC)
2671 .Case("tba", AMDGPU::TBA)
2672 .Case("tma", AMDGPU::TMA)
2673 .Case("flat_scratch_lo", AMDGPU::FLAT_SCR_LO)
2674 .Case("flat_scratch_hi", AMDGPU::FLAT_SCR_HI)
2675 .Case("xnack_mask_lo", AMDGPU::XNACK_MASK_LO)
2676 .Case("xnack_mask_hi", AMDGPU::XNACK_MASK_HI)
2677 .Case("vcc_lo", AMDGPU::VCC_LO)
2678 .Case("vcc_hi", AMDGPU::VCC_HI)
2679 .Case("exec_lo", AMDGPU::EXEC_LO)
2680 .Case("exec_hi", AMDGPU::EXEC_HI)
2681 .Case("tma_lo", AMDGPU::TMA_LO)
2682 .Case("tma_hi", AMDGPU::TMA_HI)
2683 .Case("tba_lo", AMDGPU::TBA_LO)
2684 .Case("tba_hi", AMDGPU::TBA_HI)
2685 .Case("pc", AMDGPU::PC_REG)
2686 .Case("null", AMDGPU::SGPR_NULL)
2687 .Default(AMDGPU::NoRegister);
2688}
2689
2690bool AMDGPUAsmParser::ParseRegister(MCRegister &RegNo,SMLoc &StartLoc,
2691SMLoc &EndLoc,bool RestoreOnFailure) {
2692autoR = parseRegister();
2693if (!R)returntrue;
2694assert(R->isReg());
2695 RegNo =R->getReg();
2696 StartLoc =R->getStartLoc();
2697 EndLoc =R->getEndLoc();
2698returnfalse;
2699}
2700
2701bool AMDGPUAsmParser::parseRegister(MCRegister &Reg,SMLoc &StartLoc,
2702SMLoc &EndLoc) {
2703return ParseRegister(Reg, StartLoc, EndLoc,/*RestoreOnFailure=*/false);
2704}
2705
2706ParseStatus AMDGPUAsmParser::tryParseRegister(MCRegister &Reg,SMLoc &StartLoc,
2707SMLoc &EndLoc) {
2708boolResult = ParseRegister(Reg, StartLoc, EndLoc,/*RestoreOnFailure=*/true);
2709bool PendingErrors = getParser().hasPendingError();
2710 getParser().clearPendingErrors();
2711if (PendingErrors)
2712returnParseStatus::Failure;
2713if (Result)
2714returnParseStatus::NoMatch;
2715returnParseStatus::Success;
2716}
2717
2718bool AMDGPUAsmParser::AddNextRegisterToList(MCRegister &Reg,unsigned &RegWidth,
2719 RegisterKind RegKind,
2720MCRegister Reg1,SMLoc Loc) {
2721switch (RegKind) {
2722case IS_SPECIAL:
2723if (Reg == AMDGPU::EXEC_LO && Reg1 == AMDGPU::EXEC_HI) {
2724Reg = AMDGPU::EXEC;
2725 RegWidth = 64;
2726returntrue;
2727 }
2728if (Reg == AMDGPU::FLAT_SCR_LO && Reg1 == AMDGPU::FLAT_SCR_HI) {
2729Reg = AMDGPU::FLAT_SCR;
2730 RegWidth = 64;
2731returntrue;
2732 }
2733if (Reg == AMDGPU::XNACK_MASK_LO && Reg1 == AMDGPU::XNACK_MASK_HI) {
2734Reg = AMDGPU::XNACK_MASK;
2735 RegWidth = 64;
2736returntrue;
2737 }
2738if (Reg == AMDGPU::VCC_LO && Reg1 == AMDGPU::VCC_HI) {
2739Reg = AMDGPU::VCC;
2740 RegWidth = 64;
2741returntrue;
2742 }
2743if (Reg == AMDGPU::TBA_LO && Reg1 == AMDGPU::TBA_HI) {
2744Reg = AMDGPU::TBA;
2745 RegWidth = 64;
2746returntrue;
2747 }
2748if (Reg == AMDGPU::TMA_LO && Reg1 == AMDGPU::TMA_HI) {
2749Reg = AMDGPU::TMA;
2750 RegWidth = 64;
2751returntrue;
2752 }
2753Error(Loc,"register does not fit in the list");
2754returnfalse;
2755caseIS_VGPR:
2756case IS_SGPR:
2757caseIS_AGPR:
2758case IS_TTMP:
2759if (Reg1 != Reg + RegWidth / 32) {
2760Error(Loc,"registers in a list must have consecutive indices");
2761returnfalse;
2762 }
2763 RegWidth += 32;
2764returntrue;
2765default:
2766llvm_unreachable("unexpected register kind");
2767 }
2768}
2769
2770structRegInfo {
2771StringLiteralName;
2772 RegisterKindKind;
2773};
2774
2775staticconstexprRegInfoRegularRegisters[] = {
2776 {{"v"}, IS_VGPR},
2777 {{"s"}, IS_SGPR},
2778 {{"ttmp"}, IS_TTMP},
2779 {{"acc"}, IS_AGPR},
2780 {{"a"}, IS_AGPR},
2781};
2782
2783staticboolisRegularReg(RegisterKind Kind) {
2784return Kind == IS_VGPR ||
2785 Kind == IS_SGPR ||
2786 Kind == IS_TTMP ||
2787 Kind == IS_AGPR;
2788}
2789
2790staticconstRegInfo*getRegularRegInfo(StringRef Str) {
2791for (constRegInfo &Reg :RegularRegisters)
2792if (Str.starts_with(Reg.Name))
2793return &Reg;
2794returnnullptr;
2795}
2796
2797staticboolgetRegNum(StringRef Str,unsigned& Num) {
2798return !Str.getAsInteger(10, Num);
2799}
2800
2801bool
2802AMDGPUAsmParser::isRegister(constAsmToken &Token,
2803constAsmToken &NextToken) const{
2804
2805// A list of consecutive registers: [s0,s1,s2,s3]
2806if (Token.is(AsmToken::LBrac))
2807returntrue;
2808
2809if (!Token.is(AsmToken::Identifier))
2810returnfalse;
2811
2812// A single register like s0 or a range of registers like s[0:1]
2813
2814StringRef Str = Token.getString();
2815constRegInfo *Reg =getRegularRegInfo(Str);
2816if (Reg) {
2817StringRefRegName =Reg->Name;
2818StringRef RegSuffix = Str.substr(RegName.size());
2819if (!RegSuffix.empty()) {
2820 RegSuffix.consume_back(".l");
2821 RegSuffix.consume_back(".h");
2822unsigned Num;
2823// A single register with an index: rXX
2824if (getRegNum(RegSuffix, Num))
2825returntrue;
2826 }else {
2827// A range of registers: r[XX:YY].
2828if (NextToken.is(AsmToken::LBrac))
2829returntrue;
2830 }
2831 }
2832
2833returngetSpecialRegForName(Str).isValid();
2834}
2835
2836bool
2837AMDGPUAsmParser::isRegister()
2838{
2839return isRegister(getToken(), peekToken());
2840}
2841
2842MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind,unsigned RegNum,
2843unsignedSubReg,unsigned RegWidth,
2844SMLoc Loc) {
2845assert(isRegularReg(RegKind));
2846
2847unsigned AlignSize = 1;
2848if (RegKind == IS_SGPR || RegKind == IS_TTMP) {
2849// SGPR and TTMP registers must be aligned.
2850// Max required alignment is 4 dwords.
2851 AlignSize = std::min(llvm::bit_ceil(RegWidth / 32), 4u);
2852 }
2853
2854if (RegNum % AlignSize != 0) {
2855Error(Loc,"invalid register alignment");
2856returnMCRegister();
2857 }
2858
2859unsigned RegIdx = RegNum / AlignSize;
2860int RCID =getRegClass(RegKind, RegWidth);
2861if (RCID == -1) {
2862Error(Loc,"invalid or unsupported register size");
2863returnMCRegister();
2864 }
2865
2866constMCRegisterInfo *TRI = getContext().getRegisterInfo();
2867constMCRegisterClass RC =TRI->getRegClass(RCID);
2868if (RegIdx >= RC.getNumRegs()) {
2869Error(Loc,"register index is out of range");
2870returnMCRegister();
2871 }
2872
2873MCRegisterReg = RC.getRegister(RegIdx);
2874
2875if (SubReg) {
2876Reg =TRI->getSubReg(Reg,SubReg);
2877
2878// Currently all regular registers have their .l and .h subregisters, so
2879// we should never need to generate an error here.
2880assert(Reg &&"Invalid subregister!");
2881 }
2882
2883returnReg;
2884}
2885
2886bool AMDGPUAsmParser::ParseRegRange(unsigned &Num,unsigned &RegWidth) {
2887 int64_t RegLo, RegHi;
2888if (!skipToken(AsmToken::LBrac,"missing register index"))
2889returnfalse;
2890
2891SMLoc FirstIdxLoc = getLoc();
2892SMLoc SecondIdxLoc;
2893
2894if (!parseExpr(RegLo))
2895returnfalse;
2896
2897if (trySkipToken(AsmToken::Colon)) {
2898 SecondIdxLoc = getLoc();
2899if (!parseExpr(RegHi))
2900returnfalse;
2901 }else {
2902 RegHi = RegLo;
2903 }
2904
2905if (!skipToken(AsmToken::RBrac,"expected a closing square bracket"))
2906returnfalse;
2907
2908if (!isUInt<32>(RegLo)) {
2909Error(FirstIdxLoc,"invalid register index");
2910returnfalse;
2911 }
2912
2913if (!isUInt<32>(RegHi)) {
2914Error(SecondIdxLoc,"invalid register index");
2915returnfalse;
2916 }
2917
2918if (RegLo > RegHi) {
2919Error(FirstIdxLoc,"first register index should not exceed second index");
2920returnfalse;
2921 }
2922
2923 Num =static_cast<unsigned>(RegLo);
2924 RegWidth = 32 * ((RegHi - RegLo) + 1);
2925returntrue;
2926}
2927
2928MCRegister AMDGPUAsmParser::ParseSpecialReg(RegisterKind &RegKind,
2929unsigned &RegNum,
2930unsigned &RegWidth,
2931SmallVectorImpl<AsmToken> &Tokens) {
2932assert(isToken(AsmToken::Identifier));
2933MCRegisterReg =getSpecialRegForName(getTokenStr());
2934if (Reg) {
2935 RegNum = 0;
2936 RegWidth = 32;
2937 RegKind = IS_SPECIAL;
2938 Tokens.push_back(getToken());
2939 lex();// skip register name
2940 }
2941returnReg;
2942}
2943
2944MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind,
2945unsigned &RegNum,
2946unsigned &RegWidth,
2947SmallVectorImpl<AsmToken> &Tokens) {
2948assert(isToken(AsmToken::Identifier));
2949StringRefRegName = getTokenStr();
2950auto Loc = getLoc();
2951
2952constRegInfo *RI =getRegularRegInfo(RegName);
2953if (!RI) {
2954Error(Loc,"invalid register name");
2955returnMCRegister();
2956 }
2957
2958 Tokens.push_back(getToken());
2959 lex();// skip register name
2960
2961 RegKind = RI->Kind;
2962StringRef RegSuffix =RegName.substr(RI->Name.size());
2963unsignedSubReg = NoSubRegister;
2964if (!RegSuffix.empty()) {
2965if (RegSuffix.consume_back(".l"))
2966SubReg = AMDGPU::lo16;
2967elseif (RegSuffix.consume_back(".h"))
2968SubReg = AMDGPU::hi16;
2969
2970// Single 32-bit register: vXX.
2971if (!getRegNum(RegSuffix, RegNum)) {
2972Error(Loc,"invalid register index");
2973returnMCRegister();
2974 }
2975 RegWidth = 32;
2976 }else {
2977// Range of registers: v[XX:YY]. ":YY" is optional.
2978if (!ParseRegRange(RegNum, RegWidth))
2979returnMCRegister();
2980 }
2981
2982return getRegularReg(RegKind, RegNum,SubReg, RegWidth, Loc);
2983}
2984
2985MCRegister AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind,
2986unsigned &RegNum,unsigned &RegWidth,
2987SmallVectorImpl<AsmToken> &Tokens) {
2988MCRegisterReg;
2989auto ListLoc = getLoc();
2990
2991if (!skipToken(AsmToken::LBrac,
2992"expected a register or a list of registers")) {
2993returnMCRegister();
2994 }
2995
2996// List of consecutive registers, e.g.: [s0,s1,s2,s3]
2997
2998auto Loc = getLoc();
2999if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth))
3000returnMCRegister();
3001if (RegWidth != 32) {
3002Error(Loc,"expected a single 32-bit register");
3003returnMCRegister();
3004 }
3005
3006for (; trySkipToken(AsmToken::Comma); ) {
3007 RegisterKind NextRegKind;
3008MCRegister NextReg;
3009unsigned NextRegNum, NextRegWidth;
3010 Loc = getLoc();
3011
3012if (!ParseAMDGPURegister(NextRegKind, NextReg,
3013 NextRegNum, NextRegWidth,
3014 Tokens)) {
3015returnMCRegister();
3016 }
3017if (NextRegWidth != 32) {
3018Error(Loc,"expected a single 32-bit register");
3019returnMCRegister();
3020 }
3021if (NextRegKind != RegKind) {
3022Error(Loc,"registers in a list must be of the same kind");
3023returnMCRegister();
3024 }
3025if (!AddNextRegisterToList(Reg, RegWidth, RegKind, NextReg, Loc))
3026returnMCRegister();
3027 }
3028
3029if (!skipToken(AsmToken::RBrac,
3030"expected a comma or a closing square bracket")) {
3031returnMCRegister();
3032 }
3033
3034if (isRegularReg(RegKind))
3035Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc);
3036
3037returnReg;
3038}
3039
3040bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3041MCRegister &Reg,unsigned &RegNum,
3042unsigned &RegWidth,
3043SmallVectorImpl<AsmToken> &Tokens) {
3044auto Loc = getLoc();
3045Reg =MCRegister();
3046
3047if (isToken(AsmToken::Identifier)) {
3048Reg = ParseSpecialReg(RegKind, RegNum, RegWidth, Tokens);
3049if (!Reg)
3050Reg = ParseRegularReg(RegKind, RegNum, RegWidth, Tokens);
3051 }else {
3052Reg = ParseRegList(RegKind, RegNum, RegWidth, Tokens);
3053 }
3054
3055constMCRegisterInfo *TRI = getContext().getRegisterInfo();
3056if (!Reg) {
3057assert(Parser.hasPendingError());
3058returnfalse;
3059 }
3060
3061if (!subtargetHasRegister(*TRI, Reg)) {
3062if (Reg == AMDGPU::SGPR_NULL) {
3063Error(Loc,"'null' operand is not supported on this GPU");
3064 }else {
3065Error(Loc,Twine(AMDGPUInstPrinter::getRegisterName(Reg)) +
3066" register not available on this GPU");
3067 }
3068returnfalse;
3069 }
3070
3071returntrue;
3072}
3073
3074bool AMDGPUAsmParser::ParseAMDGPURegister(RegisterKind &RegKind,
3075MCRegister &Reg,unsigned &RegNum,
3076unsigned &RegWidth,
3077bool RestoreOnFailure/*=false*/) {
3078Reg =MCRegister();
3079
3080SmallVector<AsmToken, 1> Tokens;
3081if (ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth, Tokens)) {
3082if (RestoreOnFailure) {
3083while (!Tokens.empty()) {
3084 getLexer().UnLex(Tokens.pop_back_val());
3085 }
3086 }
3087returntrue;
3088 }
3089returnfalse;
3090}
3091
3092std::optional<StringRef>
3093AMDGPUAsmParser::getGprCountSymbolName(RegisterKind RegKind) {
3094switch (RegKind) {
3095caseIS_VGPR:
3096returnStringRef(".amdgcn.next_free_vgpr");
3097case IS_SGPR:
3098returnStringRef(".amdgcn.next_free_sgpr");
3099default:
3100return std::nullopt;
3101 }
3102}
3103
3104void AMDGPUAsmParser::initializeGprCountSymbol(RegisterKind RegKind) {
3105autoSymbolName = getGprCountSymbolName(RegKind);
3106assert(SymbolName &&"initializing invalid register kind");
3107MCSymbol *Sym = getContext().getOrCreateSymbol(*SymbolName);
3108Sym->setVariableValue(MCConstantExpr::create(0, getContext()));
3109}
3110
3111bool AMDGPUAsmParser::updateGprCountSymbols(RegisterKind RegKind,
3112unsigned DwordRegIndex,
3113unsigned RegWidth) {
3114// Symbols are only defined for GCN targets
3115if (AMDGPU::getIsaVersion(getSTI().getCPU()).Major < 6)
3116returntrue;
3117
3118autoSymbolName = getGprCountSymbolName(RegKind);
3119if (!SymbolName)
3120returntrue;
3121MCSymbol *Sym = getContext().getOrCreateSymbol(*SymbolName);
3122
3123 int64_t NewMax = DwordRegIndex +divideCeil(RegWidth, 32) - 1;
3124 int64_t OldCount;
3125
3126if (!Sym->isVariable())
3127return !Error(getLoc(),
3128".amdgcn.next_free_{v,s}gpr symbols must be variable");
3129if (!Sym->getVariableValue(false)->evaluateAsAbsolute(OldCount))
3130return !Error(
3131 getLoc(),
3132".amdgcn.next_free_{v,s}gpr symbols must be absolute expressions");
3133
3134if (OldCount <= NewMax)
3135Sym->setVariableValue(MCConstantExpr::create(NewMax + 1, getContext()));
3136
3137returntrue;
3138}
3139
3140std::unique_ptr<AMDGPUOperand>
3141AMDGPUAsmParser::parseRegister(bool RestoreOnFailure) {
3142constauto &Tok = getToken();
3143SMLoc StartLoc = Tok.getLoc();
3144SMLoc EndLoc = Tok.getEndLoc();
3145 RegisterKind RegKind;
3146MCRegisterReg;
3147unsigned RegNum, RegWidth;
3148
3149if (!ParseAMDGPURegister(RegKind, Reg, RegNum, RegWidth)) {
3150returnnullptr;
3151 }
3152if (isHsaAbi(getSTI())) {
3153if (!updateGprCountSymbols(RegKind, RegNum, RegWidth))
3154returnnullptr;
3155 }else
3156 KernelScope.usesRegister(RegKind, RegNum, RegWidth);
3157return AMDGPUOperand::CreateReg(this, Reg, StartLoc, EndLoc);
3158}
3159
3160ParseStatus AMDGPUAsmParser::parseImm(OperandVector &Operands,
3161bool HasSP3AbsModifier,bool HasLit) {
3162// TODO: add syntactic sugar for 1/(2*PI)
3163
3164if (isRegister())
3165returnParseStatus::NoMatch;
3166assert(!isModifier());
3167
3168if (!HasLit) {
3169 HasLit = trySkipId("lit");
3170if (HasLit) {
3171if (!skipToken(AsmToken::LParen,"expected left paren after lit"))
3172returnParseStatus::Failure;
3173ParseStatus S = parseImm(Operands, HasSP3AbsModifier, HasLit);
3174if (S.isSuccess() &&
3175 !skipToken(AsmToken::RParen,"expected closing parentheses"))
3176returnParseStatus::Failure;
3177return S;
3178 }
3179 }
3180
3181constauto& Tok = getToken();
3182constauto& NextTok = peekToken();
3183bool IsReal = Tok.is(AsmToken::Real);
3184SMLoc S = getLoc();
3185bool Negate =false;
3186
3187if (!IsReal && Tok.is(AsmToken::Minus) && NextTok.is(AsmToken::Real)) {
3188 lex();
3189 IsReal =true;
3190 Negate =true;
3191 }
3192
3193 AMDGPUOperand::Modifiers Mods;
3194 Mods.Lit = HasLit;
3195
3196if (IsReal) {
3197// Floating-point expressions are not supported.
3198// Can only allow floating-point literals with an
3199// optional sign.
3200
3201StringRef Num = getTokenStr();
3202 lex();
3203
3204APFloat RealVal(APFloat::IEEEdouble());
3205auto roundMode = APFloat::rmNearestTiesToEven;
3206if (errorToBool(RealVal.convertFromString(Num, roundMode).takeError()))
3207returnParseStatus::Failure;
3208if (Negate)
3209 RealVal.changeSign();
3210
3211Operands.push_back(
3212 AMDGPUOperand::CreateImm(this, RealVal.bitcastToAPInt().getZExtValue(), S,
3213 AMDGPUOperand::ImmTyNone,true));
3214 AMDGPUOperand &Op =static_cast<AMDGPUOperand &>(*Operands.back());
3215Op.setModifiers(Mods);
3216
3217returnParseStatus::Success;
3218
3219 }else {
3220 int64_tIntVal;
3221constMCExpr *Expr;
3222SMLoc S = getLoc();
3223
3224if (HasSP3AbsModifier) {
3225// This is a workaround for handling expressions
3226// as arguments of SP3 'abs' modifier, for example:
3227// |1.0|
3228// |-1|
3229// |1+x|
3230// This syntax is not compatible with syntax of standard
3231// MC expressions (due to the trailing '|').
3232SMLoc EndLoc;
3233if (getParser().parsePrimaryExpr(Expr, EndLoc,nullptr))
3234returnParseStatus::Failure;
3235 }else {
3236if (Parser.parseExpression(Expr))
3237returnParseStatus::Failure;
3238 }
3239
3240if (Expr->evaluateAsAbsolute(IntVal)) {
3241Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
3242 AMDGPUOperand &Op =static_cast<AMDGPUOperand &>(*Operands.back());
3243Op.setModifiers(Mods);
3244 }else {
3245if (HasLit)
3246returnParseStatus::NoMatch;
3247Operands.push_back(AMDGPUOperand::CreateExpr(this, Expr, S));
3248 }
3249
3250returnParseStatus::Success;
3251 }
3252
3253returnParseStatus::NoMatch;
3254}
3255
3256ParseStatus AMDGPUAsmParser::parseReg(OperandVector &Operands) {
3257if (!isRegister())
3258returnParseStatus::NoMatch;
3259
3260if (auto R = parseRegister()) {
3261assert(R->isReg());
3262Operands.push_back(std::move(R));
3263returnParseStatus::Success;
3264 }
3265returnParseStatus::Failure;
3266}
3267
3268ParseStatus AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands,
3269bool HasSP3AbsMod,bool HasLit) {
3270ParseStatus Res = parseReg(Operands);
3271if (!Res.isNoMatch())
3272return Res;
3273if (isModifier())
3274returnParseStatus::NoMatch;
3275return parseImm(Operands, HasSP3AbsMod, HasLit);
3276}
3277
3278bool
3279AMDGPUAsmParser::isNamedOperandModifier(constAsmToken &Token,constAsmToken &NextToken) const{
3280if (Token.is(AsmToken::Identifier) && NextToken.is(AsmToken::LParen)) {
3281constauto &str = Token.getString();
3282return str =="abs" || str =="neg" || str =="sext";
3283 }
3284returnfalse;
3285}
3286
3287bool
3288AMDGPUAsmParser::isOpcodeModifierWithVal(constAsmToken &Token,constAsmToken &NextToken) const{
3289return Token.is(AsmToken::Identifier) && NextToken.is(AsmToken::Colon);
3290}
3291
3292bool
3293AMDGPUAsmParser::isOperandModifier(constAsmToken &Token,constAsmToken &NextToken) const{
3294return isNamedOperandModifier(Token, NextToken) || Token.is(AsmToken::Pipe);
3295}
3296
3297bool
3298AMDGPUAsmParser::isRegOrOperandModifier(constAsmToken &Token,constAsmToken &NextToken) const{
3299return isRegister(Token, NextToken) || isOperandModifier(Token, NextToken);
3300}
3301
3302// Check if this is an operand modifier or an opcode modifier
3303// which may look like an expression but it is not. We should
3304// avoid parsing these modifiers as expressions. Currently
3305// recognized sequences are:
3306// |...|
3307// abs(...)
3308// neg(...)
3309// sext(...)
3310// -reg
3311// -|...|
3312// -abs(...)
3313// name:...
3314//
3315bool
3316AMDGPUAsmParser::isModifier() {
3317
3318AsmToken Tok = getToken();
3319AsmToken NextToken[2];
3320 peekTokens(NextToken);
3321
3322return isOperandModifier(Tok, NextToken[0]) ||
3323 (Tok.is(AsmToken::Minus) && isRegOrOperandModifier(NextToken[0], NextToken[1])) ||
3324 isOpcodeModifierWithVal(Tok, NextToken[0]);
3325}
3326
3327// Check if the current token is an SP3 'neg' modifier.
3328// Currently this modifier is allowed in the following context:
3329//
3330// 1. Before a register, e.g. "-v0", "-v[...]" or "-[v0,v1]".
3331// 2. Before an 'abs' modifier: -abs(...)
3332// 3. Before an SP3 'abs' modifier: -|...|
3333//
3334// In all other cases "-" is handled as a part
3335// of an expression that follows the sign.
3336//
3337// Note: When "-" is followed by an integer literal,
3338// this is interpreted as integer negation rather
3339// than a floating-point NEG modifier applied to N.
3340// Beside being contr-intuitive, such use of floating-point
3341// NEG modifier would have resulted in different meaning
3342// of integer literals used with VOP1/2/C and VOP3,
3343// for example:
3344// v_exp_f32_e32 v5, -1 // VOP1: src0 = 0xFFFFFFFF
3345// v_exp_f32_e64 v5, -1 // VOP3: src0 = 0x80000001
3346// Negative fp literals with preceding "-" are
3347// handled likewise for uniformity
3348//
3349bool
3350AMDGPUAsmParser::parseSP3NegModifier() {
3351
3352AsmToken NextToken[2];
3353 peekTokens(NextToken);
3354
3355if (isToken(AsmToken::Minus) &&
3356 (isRegister(NextToken[0], NextToken[1]) ||
3357 NextToken[0].is(AsmToken::Pipe) ||
3358 isId(NextToken[0],"abs"))) {
3359 lex();
3360returntrue;
3361 }
3362
3363returnfalse;
3364}
3365
3366ParseStatus
3367AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3368bool AllowImm) {
3369bool Neg, SP3Neg;
3370bool Abs, SP3Abs;
3371bool Lit;
3372SMLoc Loc;
3373
3374// Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
3375if (isToken(AsmToken::Minus) && peekToken().is(AsmToken::Minus))
3376returnError(getLoc(),"invalid syntax, expected 'neg' modifier");
3377
3378 SP3Neg = parseSP3NegModifier();
3379
3380 Loc = getLoc();
3381 Neg = trySkipId("neg");
3382if (Neg && SP3Neg)
3383returnError(Loc,"expected register or immediate");
3384if (Neg && !skipToken(AsmToken::LParen,"expected left paren after neg"))
3385returnParseStatus::Failure;
3386
3387 Abs = trySkipId("abs");
3388if (Abs && !skipToken(AsmToken::LParen,"expected left paren after abs"))
3389returnParseStatus::Failure;
3390
3391 Lit = trySkipId("lit");
3392if (Lit && !skipToken(AsmToken::LParen,"expected left paren after lit"))
3393returnParseStatus::Failure;
3394
3395 Loc = getLoc();
3396 SP3Abs = trySkipToken(AsmToken::Pipe);
3397if (Abs && SP3Abs)
3398returnError(Loc,"expected register or immediate");
3399
3400ParseStatus Res;
3401if (AllowImm) {
3402 Res = parseRegOrImm(Operands, SP3Abs, Lit);
3403 }else {
3404 Res = parseReg(Operands);
3405 }
3406if (!Res.isSuccess())
3407return (SP3Neg || Neg || SP3Abs || Abs || Lit) ?ParseStatus::Failure : Res;
3408
3409if (Lit && !Operands.back()->isImm())
3410Error(Loc,"expected immediate with lit modifier");
3411
3412if (SP3Abs && !skipToken(AsmToken::Pipe,"expected vertical bar"))
3413returnParseStatus::Failure;
3414if (Abs && !skipToken(AsmToken::RParen,"expected closing parentheses"))
3415returnParseStatus::Failure;
3416if (Neg && !skipToken(AsmToken::RParen,"expected closing parentheses"))
3417returnParseStatus::Failure;
3418if (Lit && !skipToken(AsmToken::RParen,"expected closing parentheses"))
3419returnParseStatus::Failure;
3420
3421 AMDGPUOperand::Modifiers Mods;
3422 Mods.Abs = Abs || SP3Abs;
3423 Mods.Neg = Neg || SP3Neg;
3424 Mods.Lit = Lit;
3425
3426if (Mods.hasFPModifiers() || Lit) {
3427 AMDGPUOperand &Op =static_cast<AMDGPUOperand &>(*Operands.back());
3428if (Op.isExpr())
3429returnError(Op.getStartLoc(),"expected an absolute expression");
3430Op.setModifiers(Mods);
3431 }
3432returnParseStatus::Success;
3433}
3434
3435ParseStatus
3436AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands,
3437bool AllowImm) {
3438bool Sext = trySkipId("sext");
3439if (Sext && !skipToken(AsmToken::LParen,"expected left paren after sext"))
3440returnParseStatus::Failure;
3441
3442ParseStatus Res;
3443if (AllowImm) {
3444 Res = parseRegOrImm(Operands);
3445 }else {
3446 Res = parseReg(Operands);
3447 }
3448if (!Res.isSuccess())
3449return Sext ?ParseStatus::Failure : Res;
3450
3451if (Sext && !skipToken(AsmToken::RParen,"expected closing parentheses"))
3452returnParseStatus::Failure;
3453
3454 AMDGPUOperand::Modifiers Mods;
3455 Mods.Sext = Sext;
3456
3457if (Mods.hasIntModifiers()) {
3458 AMDGPUOperand &Op =static_cast<AMDGPUOperand &>(*Operands.back());
3459if (Op.isExpr())
3460returnError(Op.getStartLoc(),"expected an absolute expression");
3461Op.setModifiers(Mods);
3462 }
3463
3464returnParseStatus::Success;
3465}
3466
3467ParseStatus AMDGPUAsmParser::parseRegWithFPInputMods(OperandVector &Operands) {
3468return parseRegOrImmWithFPInputMods(Operands,false);
3469}
3470
3471ParseStatus AMDGPUAsmParser::parseRegWithIntInputMods(OperandVector &Operands) {
3472return parseRegOrImmWithIntInputMods(Operands,false);
3473}
3474
3475ParseStatus AMDGPUAsmParser::parseVReg32OrOff(OperandVector &Operands) {
3476auto Loc = getLoc();
3477if (trySkipId("off")) {
3478Operands.push_back(AMDGPUOperand::CreateImm(this, 0, Loc,
3479 AMDGPUOperand::ImmTyOff,false));
3480returnParseStatus::Success;
3481 }
3482
3483if (!isRegister())
3484returnParseStatus::NoMatch;
3485
3486 std::unique_ptr<AMDGPUOperand>Reg = parseRegister();
3487if (Reg) {
3488Operands.push_back(std::move(Reg));
3489returnParseStatus::Success;
3490 }
3491
3492returnParseStatus::Failure;
3493}
3494
3495unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3496uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
3497
3498if ((getForcedEncodingSize() == 32 && (TSFlags &SIInstrFlags::VOP3)) ||
3499 (getForcedEncodingSize() == 64 && !(TSFlags &SIInstrFlags::VOP3)) ||
3500 (isForcedDPP() && !(TSFlags &SIInstrFlags::DPP)) ||
3501 (isForcedSDWA() && !(TSFlags &SIInstrFlags::SDWA)) )
3502return Match_InvalidOperand;
3503
3504if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
3505 Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
3506// v_mac_f32/16 allow only dst_sel == DWORD;
3507auto OpNum =
3508AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::dst_sel);
3509constauto &Op = Inst.getOperand(OpNum);
3510if (!Op.isImm() ||Op.getImm() != AMDGPU::SDWA::SdwaSel::DWORD) {
3511return Match_InvalidOperand;
3512 }
3513 }
3514
3515return Match_Success;
3516}
3517
3518staticArrayRef<unsigned>getAllVariants() {
3519staticconstunsigned Variants[] = {
3520AMDGPUAsmVariants::DEFAULT,AMDGPUAsmVariants::VOP3,
3521AMDGPUAsmVariants::SDWA,AMDGPUAsmVariants::SDWA9,
3522AMDGPUAsmVariants::DPP,AMDGPUAsmVariants::VOP3_DPP
3523 };
3524
3525returnArrayRef(Variants);
3526}
3527
3528// What asm variants we should check
3529ArrayRef<unsigned> AMDGPUAsmParser::getMatchedVariants() const{
3530if (isForcedDPP() && isForcedVOP3()) {
3531staticconstunsigned Variants[] = {AMDGPUAsmVariants::VOP3_DPP};
3532returnArrayRef(Variants);
3533 }
3534if (getForcedEncodingSize() == 32) {
3535staticconstunsigned Variants[] = {AMDGPUAsmVariants::DEFAULT};
3536returnArrayRef(Variants);
3537 }
3538
3539if (isForcedVOP3()) {
3540staticconstunsigned Variants[] = {AMDGPUAsmVariants::VOP3};
3541returnArrayRef(Variants);
3542 }
3543
3544if (isForcedSDWA()) {
3545staticconstunsigned Variants[] = {AMDGPUAsmVariants::SDWA,
3546AMDGPUAsmVariants::SDWA9};
3547returnArrayRef(Variants);
3548 }
3549
3550if (isForcedDPP()) {
3551staticconstunsigned Variants[] = {AMDGPUAsmVariants::DPP};
3552returnArrayRef(Variants);
3553 }
3554
3555returngetAllVariants();
3556}
3557
3558StringRef AMDGPUAsmParser::getMatchedVariantName() const{
3559if (isForcedDPP() && isForcedVOP3())
3560return"e64_dpp";
3561
3562if (getForcedEncodingSize() == 32)
3563return"e32";
3564
3565if (isForcedVOP3())
3566return"e64";
3567
3568if (isForcedSDWA())
3569return"sdwa";
3570
3571if (isForcedDPP())
3572return"dpp";
3573
3574return"";
3575}
3576
3577unsigned AMDGPUAsmParser::findImplicitSGPRReadInVOP(constMCInst &Inst) const{
3578constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
3579for (MCPhysReg Reg :Desc.implicit_uses()) {
3580switch (Reg) {
3581case AMDGPU::FLAT_SCR:
3582case AMDGPU::VCC:
3583case AMDGPU::VCC_LO:
3584case AMDGPU::VCC_HI:
3585case AMDGPU::M0:
3586returnReg;
3587default:
3588break;
3589 }
3590 }
3591return AMDGPU::NoRegister;
3592}
3593
3594// NB: This code is correct only when used to check constant
3595// bus limitations because GFX7 support no f16 inline constants.
3596// Note that there are no cases when a GFX7 opcode violates
3597// constant bus limitations due to the use of an f16 constant.
3598bool AMDGPUAsmParser::isInlineConstant(constMCInst &Inst,
3599unsigned OpIdx) const{
3600constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
3601
3602if (!AMDGPU::isSISrcOperand(Desc, OpIdx) ||
3603AMDGPU::isKImmOperand(Desc, OpIdx)) {
3604returnfalse;
3605 }
3606
3607constMCOperand &MO = Inst.getOperand(OpIdx);
3608
3609 int64_t Val = MO.getImm();
3610auto OpSize =AMDGPU::getOperandSize(Desc, OpIdx);
3611
3612switch (OpSize) {// expected operand size
3613case 8:
3614returnAMDGPU::isInlinableLiteral64(Val, hasInv2PiInlineImm());
3615case 4:
3616returnAMDGPU::isInlinableLiteral32(Val, hasInv2PiInlineImm());
3617case 2: {
3618constunsignedOperandType =Desc.operands()[OpIdx].OperandType;
3619if (OperandType ==AMDGPU::OPERAND_REG_IMM_INT16 ||
3620OperandType ==AMDGPU::OPERAND_REG_INLINE_C_INT16 ||
3621OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_INT16)
3622returnAMDGPU::isInlinableLiteralI16(Val, hasInv2PiInlineImm());
3623
3624if (OperandType ==AMDGPU::OPERAND_REG_INLINE_C_V2INT16 ||
3625OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_V2INT16 ||
3626OperandType ==AMDGPU::OPERAND_REG_IMM_V2INT16)
3627returnAMDGPU::isInlinableLiteralV2I16(Val);
3628
3629if (OperandType ==AMDGPU::OPERAND_REG_INLINE_C_V2FP16 ||
3630OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_V2FP16 ||
3631OperandType ==AMDGPU::OPERAND_REG_IMM_V2FP16)
3632returnAMDGPU::isInlinableLiteralV2F16(Val);
3633
3634if (OperandType ==AMDGPU::OPERAND_REG_INLINE_C_V2BF16 ||
3635OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_V2BF16 ||
3636OperandType ==AMDGPU::OPERAND_REG_IMM_V2BF16)
3637returnAMDGPU::isInlinableLiteralV2BF16(Val);
3638
3639if (OperandType ==AMDGPU::OPERAND_REG_IMM_FP16 ||
3640OperandType ==AMDGPU::OPERAND_REG_INLINE_C_FP16 ||
3641OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_FP16 ||
3642OperandType ==AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED)
3643returnAMDGPU::isInlinableLiteralFP16(Val, hasInv2PiInlineImm());
3644
3645if (OperandType ==AMDGPU::OPERAND_REG_IMM_BF16 ||
3646OperandType ==AMDGPU::OPERAND_REG_INLINE_C_BF16 ||
3647OperandType ==AMDGPU::OPERAND_REG_INLINE_AC_BF16 ||
3648OperandType ==AMDGPU::OPERAND_REG_IMM_BF16_DEFERRED)
3649returnAMDGPU::isInlinableLiteralBF16(Val, hasInv2PiInlineImm());
3650
3651llvm_unreachable("invalid operand type");
3652 }
3653default:
3654llvm_unreachable("invalid operand size");
3655 }
3656}
3657
3658unsigned AMDGPUAsmParser::getConstantBusLimit(unsigned Opcode) const{
3659if (!isGFX10Plus())
3660return 1;
3661
3662switch (Opcode) {
3663// 64-bit shift instructions can use only one scalar value input
3664case AMDGPU::V_LSHLREV_B64_e64:
3665case AMDGPU::V_LSHLREV_B64_gfx10:
3666case AMDGPU::V_LSHLREV_B64_e64_gfx11:
3667case AMDGPU::V_LSHLREV_B64_e32_gfx12:
3668case AMDGPU::V_LSHLREV_B64_e64_gfx12:
3669case AMDGPU::V_LSHRREV_B64_e64:
3670case AMDGPU::V_LSHRREV_B64_gfx10:
3671case AMDGPU::V_LSHRREV_B64_e64_gfx11:
3672case AMDGPU::V_LSHRREV_B64_e64_gfx12:
3673case AMDGPU::V_ASHRREV_I64_e64:
3674case AMDGPU::V_ASHRREV_I64_gfx10:
3675case AMDGPU::V_ASHRREV_I64_e64_gfx11:
3676case AMDGPU::V_ASHRREV_I64_e64_gfx12:
3677case AMDGPU::V_LSHL_B64_e64:
3678case AMDGPU::V_LSHR_B64_e64:
3679case AMDGPU::V_ASHR_I64_e64:
3680return 1;
3681default:
3682return 2;
3683 }
3684}
3685
3686constexprunsignedMAX_SRC_OPERANDS_NUM = 6;
3687usingOperandIndices =SmallVector<int16_t, MAX_SRC_OPERANDS_NUM>;
3688
3689// Get regular operand indices in the same order as specified
3690// in the instruction (but append mandatory literals to the end).
3691staticOperandIndicesgetSrcOperandIndices(unsigned Opcode,
3692bool AddMandatoryLiterals =false) {
3693
3694 int16_t ImmIdx =
3695 AddMandatoryLiterals ?getNamedOperandIdx(Opcode, OpName::imm) : -1;
3696
3697if (isVOPD(Opcode)) {
3698 int16_t ImmDeferredIdx =
3699 AddMandatoryLiterals ?getNamedOperandIdx(Opcode, OpName::immDeferred)
3700 : -1;
3701
3702return {getNamedOperandIdx(Opcode, OpName::src0X),
3703getNamedOperandIdx(Opcode, OpName::vsrc1X),
3704getNamedOperandIdx(Opcode, OpName::src0Y),
3705getNamedOperandIdx(Opcode, OpName::vsrc1Y),
3706 ImmDeferredIdx,
3707 ImmIdx};
3708 }
3709
3710return {getNamedOperandIdx(Opcode, OpName::src0),
3711getNamedOperandIdx(Opcode, OpName::src1),
3712getNamedOperandIdx(Opcode, OpName::src2), ImmIdx};
3713}
3714
3715bool AMDGPUAsmParser::usesConstantBus(constMCInst &Inst,unsigned OpIdx) {
3716constMCOperand &MO = Inst.getOperand(OpIdx);
3717if (MO.isImm())
3718return !isInlineConstant(Inst, OpIdx);
3719if (MO.isReg()) {
3720autoReg = MO.getReg();
3721if (!Reg)
3722returnfalse;
3723constMCRegisterInfo *TRI = getContext().getRegisterInfo();
3724auto PReg =mc2PseudoReg(Reg);
3725returnisSGPR(PReg,TRI) && PReg != SGPR_NULL;
3726 }
3727returntrue;
3728}
3729
3730// Based on the comment for `AMDGPUInstructionSelector::selectWritelane`:
3731// Writelane is special in that it can use SGPR and M0 (which would normally
3732// count as using the constant bus twice - but in this case it is allowed since
3733// the lane selector doesn't count as a use of the constant bus). However, it is
3734// still required to abide by the 1 SGPR rule.
3735staticboolcheckWriteLane(constMCInst &Inst) {
3736constunsigned Opcode = Inst.getOpcode();
3737if (Opcode != V_WRITELANE_B32_gfx6_gfx7 && Opcode != V_WRITELANE_B32_vi)
3738returnfalse;
3739constMCOperand &LaneSelOp = Inst.getOperand(2);
3740if (!LaneSelOp.isReg())
3741returnfalse;
3742auto LaneSelReg =mc2PseudoReg(LaneSelOp.getReg());
3743return LaneSelReg ==M0 || LaneSelReg == M0_gfxpre11;
3744}
3745
3746bool AMDGPUAsmParser::validateConstantBusLimitations(
3747constMCInst &Inst,constOperandVector &Operands) {
3748constunsigned Opcode = Inst.getOpcode();
3749constMCInstrDesc &Desc = MII.get(Opcode);
3750MCRegister LastSGPR;
3751unsigned ConstantBusUseCount = 0;
3752unsigned NumLiterals = 0;
3753unsigned LiteralSize;
3754
3755if (!(Desc.TSFlags &
3756 (SIInstrFlags::VOPC |SIInstrFlags::VOP1 |SIInstrFlags::VOP2 |
3757SIInstrFlags::VOP3 |SIInstrFlags::VOP3P |SIInstrFlags::SDWA)) &&
3758 !isVOPD(Opcode))
3759returntrue;
3760
3761if (checkWriteLane(Inst))
3762returntrue;
3763
3764// Check special imm operands (used by madmk, etc)
3765if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::imm)) {
3766 ++NumLiterals;
3767 LiteralSize = 4;
3768 }
3769
3770SmallDenseSet<unsigned> SGPRsUsed;
3771unsigned SGPRUsed = findImplicitSGPRReadInVOP(Inst);
3772if (SGPRUsed != AMDGPU::NoRegister) {
3773 SGPRsUsed.insert(SGPRUsed);
3774 ++ConstantBusUseCount;
3775 }
3776
3777OperandIndices OpIndices =getSrcOperandIndices(Opcode);
3778
3779for (int OpIdx : OpIndices) {
3780if (OpIdx == -1)
3781continue;
3782
3783constMCOperand &MO = Inst.getOperand(OpIdx);
3784if (usesConstantBus(Inst, OpIdx)) {
3785if (MO.isReg()) {
3786 LastSGPR =mc2PseudoReg(MO.getReg());
3787// Pairs of registers with a partial intersections like these
3788// s0, s[0:1]
3789// flat_scratch_lo, flat_scratch
3790// flat_scratch_lo, flat_scratch_hi
3791// are theoretically valid but they are disabled anyway.
3792// Note that this code mimics SIInstrInfo::verifyInstruction
3793if (SGPRsUsed.insert(LastSGPR).second) {
3794 ++ConstantBusUseCount;
3795 }
3796 }else {// Expression or a literal
3797
3798if (Desc.operands()[OpIdx].OperandType ==MCOI::OPERAND_IMMEDIATE)
3799continue;// special operand like VINTERP attr_chan
3800
3801// An instruction may use only one literal.
3802// This has been validated on the previous step.
3803// See validateVOPLiteral.
3804// This literal may be used as more than one operand.
3805// If all these operands are of the same size,
3806// this literal counts as one scalar value.
3807// Otherwise it counts as 2 scalar values.
3808// See "GFX10 Shader Programming", section 3.6.2.3.
3809
3810unsignedSize =AMDGPU::getOperandSize(Desc, OpIdx);
3811if (Size < 4)
3812Size = 4;
3813
3814if (NumLiterals == 0) {
3815 NumLiterals = 1;
3816 LiteralSize =Size;
3817 }elseif (LiteralSize !=Size) {
3818 NumLiterals = 2;
3819 }
3820 }
3821 }
3822 }
3823 ConstantBusUseCount += NumLiterals;
3824
3825if (ConstantBusUseCount <= getConstantBusLimit(Opcode))
3826returntrue;
3827
3828SMLoc LitLoc = getLitLoc(Operands);
3829SMLoc RegLoc = getRegLoc(LastSGPR,Operands);
3830SMLoc Loc = (LitLoc.getPointer() < RegLoc.getPointer()) ? RegLoc : LitLoc;
3831Error(Loc,"invalid operand (violates constant bus restrictions)");
3832returnfalse;
3833}
3834
3835bool AMDGPUAsmParser::validateVOPDRegBankConstraints(
3836constMCInst &Inst,constOperandVector &Operands) {
3837
3838constunsigned Opcode = Inst.getOpcode();
3839if (!isVOPD(Opcode))
3840returntrue;
3841
3842constMCRegisterInfo *TRI = getContext().getRegisterInfo();
3843
3844auto getVRegIdx = [&](unsigned,unsigned OperandIdx) {
3845constMCOperand &Opr = Inst.getOperand(OperandIdx);
3846return (Opr.isReg() && !isSGPR(mc2PseudoReg(Opr.getReg()),TRI))
3847 ? Opr.getReg()
3848 :MCRegister();
3849 };
3850
3851// On GFX12 if both OpX and OpY are V_MOV_B32 then OPY uses SRC2 source-cache.
3852bool SkipSrc = Opcode == AMDGPU::V_DUAL_MOV_B32_e32_X_MOV_B32_e32_gfx12;
3853
3854constauto &InstInfo =getVOPDInstInfo(Opcode, &MII);
3855auto InvalidCompOprIdx =
3856 InstInfo.getInvalidCompOperandIndex(getVRegIdx, SkipSrc);
3857if (!InvalidCompOprIdx)
3858returntrue;
3859
3860auto CompOprIdx = *InvalidCompOprIdx;
3861auto ParsedIdx =
3862 std::max(InstInfo[VOPD::X].getIndexInParsedOperands(CompOprIdx),
3863 InstInfo[VOPD::Y].getIndexInParsedOperands(CompOprIdx));
3864assert(ParsedIdx > 0 && ParsedIdx <Operands.size());
3865
3866auto Loc = ((AMDGPUOperand &)*Operands[ParsedIdx]).getStartLoc();
3867if (CompOprIdx == VOPD::Component::DST) {
3868Error(Loc,"one dst register must be even and the other odd");
3869 }else {
3870auto CompSrcIdx = CompOprIdx - VOPD::Component::DST_NUM;
3871Error(Loc,Twine("src") +Twine(CompSrcIdx) +
3872" operands must use different VGPR banks");
3873 }
3874
3875returnfalse;
3876}
3877
3878bool AMDGPUAsmParser::validateIntClampSupported(constMCInst &Inst) {
3879
3880constunsigned Opc = Inst.getOpcode();
3881constMCInstrDesc &Desc = MII.get(Opc);
3882
3883if ((Desc.TSFlags &SIInstrFlags::IntClamp) != 0 && !hasIntClamp()) {
3884int ClampIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::clamp);
3885assert(ClampIdx != -1);
3886return Inst.getOperand(ClampIdx).getImm() == 0;
3887 }
3888
3889returntrue;
3890}
3891
3892constexpruint64_tMIMGFlags =
3893SIInstrFlags::MIMG |SIInstrFlags::VIMAGE |SIInstrFlags::VSAMPLE;
3894
3895bool AMDGPUAsmParser::validateMIMGDataSize(constMCInst &Inst,
3896constSMLoc &IDLoc) {
3897
3898constunsigned Opc = Inst.getOpcode();
3899constMCInstrDesc &Desc = MII.get(Opc);
3900
3901if ((Desc.TSFlags &MIMGFlags) == 0)
3902returntrue;
3903
3904int VDataIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdata);
3905int DMaskIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
3906int TFEIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::tfe);
3907
3908if (VDataIdx == -1 &&isGFX10Plus())// no return image_sample
3909returntrue;
3910
3911if ((DMaskIdx == -1 || TFEIdx == -1) &&isGFX10_AEncoding())// intersect_ray
3912returntrue;
3913
3914unsigned VDataSize =AMDGPU::getRegOperandSize(getMRI(),Desc, VDataIdx);
3915unsigned TFESize = (TFEIdx != -1 && Inst.getOperand(TFEIdx).getImm()) ? 1 : 0;
3916unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
3917if (DMask == 0)
3918 DMask = 1;
3919
3920bool IsPackedD16 =false;
3921unsigned DataSize =
3922 (Desc.TSFlags &SIInstrFlags::Gather4) ? 4 :llvm::popcount(DMask);
3923if (hasPackedD16()) {
3924int D16Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::d16);
3925 IsPackedD16 = D16Idx >= 0;
3926if (IsPackedD16 && Inst.getOperand(D16Idx).getImm())
3927 DataSize = (DataSize + 1) / 2;
3928 }
3929
3930if ((VDataSize / 4) == DataSize + TFESize)
3931returntrue;
3932
3933StringRef Modifiers;
3934if (isGFX90A())
3935 Modifiers = IsPackedD16 ?"dmask and d16" :"dmask";
3936else
3937 Modifiers = IsPackedD16 ?"dmask, d16 and tfe" :"dmask and tfe";
3938
3939Error(IDLoc,Twine("image data size does not match ") + Modifiers);
3940returnfalse;
3941}
3942
3943bool AMDGPUAsmParser::validateMIMGAddrSize(constMCInst &Inst,
3944constSMLoc &IDLoc) {
3945constunsigned Opc = Inst.getOpcode();
3946constMCInstrDesc &Desc = MII.get(Opc);
3947
3948if ((Desc.TSFlags &MIMGFlags) == 0 || !isGFX10Plus())
3949returntrue;
3950
3951constAMDGPU::MIMGInfo *Info =AMDGPU::getMIMGInfo(Opc);
3952
3953constAMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
3954AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
3955int VAddr0Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vaddr0);
3956int RSrcOpName = (Desc.TSFlags &SIInstrFlags::MIMG) ? AMDGPU::OpName::srsrc
3957 : AMDGPU::OpName::rsrc;
3958int SrsrcIdx =AMDGPU::getNamedOperandIdx(Opc, RSrcOpName);
3959int DimIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dim);
3960int A16Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::a16);
3961
3962assert(VAddr0Idx != -1);
3963assert(SrsrcIdx != -1);
3964assert(SrsrcIdx > VAddr0Idx);
3965
3966bool IsA16 = (A16Idx != -1 && Inst.getOperand(A16Idx).getImm());
3967if (BaseOpcode->BVH) {
3968if (IsA16 == BaseOpcode->A16)
3969returntrue;
3970Error(IDLoc,"image address size does not match a16");
3971returnfalse;
3972 }
3973
3974unsigned Dim = Inst.getOperand(DimIdx).getImm();
3975constAMDGPU::MIMGDimInfo *DimInfo =AMDGPU::getMIMGDimInfoByEncoding(Dim);
3976bool IsNSA = SrsrcIdx - VAddr0Idx > 1;
3977unsigned ActualAddrSize =
3978 IsNSA ? SrsrcIdx - VAddr0Idx
3979 :AMDGPU::getRegOperandSize(getMRI(),Desc, VAddr0Idx) / 4;
3980
3981unsigned ExpectedAddrSize =
3982AMDGPU::getAddrSizeMIMGOp(BaseOpcode, DimInfo, IsA16,hasG16());
3983
3984if (IsNSA) {
3985if (hasPartialNSAEncoding() &&
3986 ExpectedAddrSize >
3987getNSAMaxSize(Desc.TSFlags &SIInstrFlags::VSAMPLE)) {
3988int VAddrLastIdx = SrsrcIdx - 1;
3989unsigned VAddrLastSize =
3990AMDGPU::getRegOperandSize(getMRI(),Desc, VAddrLastIdx) / 4;
3991
3992 ActualAddrSize = VAddrLastIdx - VAddr0Idx + VAddrLastSize;
3993 }
3994 }else {
3995if (ExpectedAddrSize > 12)
3996 ExpectedAddrSize = 16;
3997
3998// Allow oversized 8 VGPR vaddr when only 5/6/7 VGPRs are required.
3999// This provides backward compatibility for assembly created
4000// before 160b/192b/224b types were directly supported.
4001if (ActualAddrSize == 8 && (ExpectedAddrSize >= 5 && ExpectedAddrSize <= 7))
4002returntrue;
4003 }
4004
4005if (ActualAddrSize == ExpectedAddrSize)
4006returntrue;
4007
4008Error(IDLoc,"image address size does not match dim and a16");
4009returnfalse;
4010}
4011
4012bool AMDGPUAsmParser::validateMIMGAtomicDMask(constMCInst &Inst) {
4013
4014constunsigned Opc = Inst.getOpcode();
4015constMCInstrDesc &Desc = MII.get(Opc);
4016
4017if ((Desc.TSFlags &MIMGFlags) == 0)
4018returntrue;
4019if (!Desc.mayLoad() || !Desc.mayStore())
4020returntrue;// Not atomic
4021
4022int DMaskIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
4023unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
4024
4025// This is an incomplete check because image_atomic_cmpswap
4026// may only use 0x3 and 0xf while other atomic operations
4027// may use 0x1 and 0x3. However these limitations are
4028// verified when we check that dmask matches dst size.
4029return DMask == 0x1 || DMask == 0x3 || DMask == 0xf;
4030}
4031
4032bool AMDGPUAsmParser::validateMIMGGatherDMask(constMCInst &Inst) {
4033
4034constunsigned Opc = Inst.getOpcode();
4035constMCInstrDesc &Desc = MII.get(Opc);
4036
4037if ((Desc.TSFlags &SIInstrFlags::Gather4) == 0)
4038returntrue;
4039
4040int DMaskIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dmask);
4041unsigned DMask = Inst.getOperand(DMaskIdx).getImm() & 0xf;
4042
4043// GATHER4 instructions use dmask in a different fashion compared to
4044// other MIMG instructions. The only useful DMASK values are
4045// 1=red, 2=green, 4=blue, 8=alpha. (e.g. 1 returns
4046// (red,red,red,red) etc.) The ISA document doesn't mention
4047// this.
4048return DMask == 0x1 || DMask == 0x2 || DMask == 0x4 || DMask == 0x8;
4049}
4050
4051bool AMDGPUAsmParser::validateMIMGDim(constMCInst &Inst,
4052constOperandVector &Operands) {
4053if (!isGFX10Plus())
4054returntrue;
4055
4056constunsigned Opc = Inst.getOpcode();
4057constMCInstrDesc &Desc = MII.get(Opc);
4058
4059if ((Desc.TSFlags &MIMGFlags) == 0)
4060returntrue;
4061
4062// image_bvh_intersect_ray instructions do not have dim
4063if (AMDGPU::getMIMGBaseOpcode(Opc)->BVH)
4064returntrue;
4065
4066for (unsigned i = 1, e =Operands.size(); i != e; ++i) {
4067 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4068if (Op.isDim())
4069returntrue;
4070 }
4071returnfalse;
4072}
4073
4074bool AMDGPUAsmParser::validateMIMGMSAA(constMCInst &Inst) {
4075constunsigned Opc = Inst.getOpcode();
4076constMCInstrDesc &Desc = MII.get(Opc);
4077
4078if ((Desc.TSFlags &MIMGFlags) == 0)
4079returntrue;
4080
4081constAMDGPU::MIMGInfo *Info =AMDGPU::getMIMGInfo(Opc);
4082constAMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
4083AMDGPU::getMIMGBaseOpcodeInfo(Info->BaseOpcode);
4084
4085if (!BaseOpcode->MSAA)
4086returntrue;
4087
4088int DimIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dim);
4089assert(DimIdx != -1);
4090
4091unsigned Dim = Inst.getOperand(DimIdx).getImm();
4092constAMDGPU::MIMGDimInfo *DimInfo =AMDGPU::getMIMGDimInfoByEncoding(Dim);
4093
4094return DimInfo->MSAA;
4095}
4096
4097staticboolIsMovrelsSDWAOpcode(constunsigned Opcode)
4098{
4099switch (Opcode) {
4100case AMDGPU::V_MOVRELS_B32_sdwa_gfx10:
4101case AMDGPU::V_MOVRELSD_B32_sdwa_gfx10:
4102case AMDGPU::V_MOVRELSD_2_B32_sdwa_gfx10:
4103returntrue;
4104default:
4105returnfalse;
4106 }
4107}
4108
4109// movrels* opcodes should only allow VGPRS as src0.
4110// This is specified in .td description for vop1/vop3,
4111// but sdwa is handled differently. See isSDWAOperand.
4112bool AMDGPUAsmParser::validateMovrels(constMCInst &Inst,
4113constOperandVector &Operands) {
4114
4115constunsigned Opc = Inst.getOpcode();
4116constMCInstrDesc &Desc = MII.get(Opc);
4117
4118if ((Desc.TSFlags &SIInstrFlags::SDWA) == 0 || !IsMovrelsSDWAOpcode(Opc))
4119returntrue;
4120
4121constint Src0Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
4122assert(Src0Idx != -1);
4123
4124SMLoc ErrLoc;
4125constMCOperand &Src0 = Inst.getOperand(Src0Idx);
4126if (Src0.isReg()) {
4127autoReg =mc2PseudoReg(Src0.getReg());
4128constMCRegisterInfo *TRI = getContext().getRegisterInfo();
4129if (!isSGPR(Reg,TRI))
4130returntrue;
4131 ErrLoc = getRegLoc(Reg,Operands);
4132 }else {
4133 ErrLoc = getConstLoc(Operands);
4134 }
4135
4136Error(ErrLoc,"source operand must be a VGPR");
4137returnfalse;
4138}
4139
4140bool AMDGPUAsmParser::validateMAIAccWrite(constMCInst &Inst,
4141constOperandVector &Operands) {
4142
4143constunsigned Opc = Inst.getOpcode();
4144
4145if (Opc != AMDGPU::V_ACCVGPR_WRITE_B32_vi)
4146returntrue;
4147
4148constint Src0Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
4149assert(Src0Idx != -1);
4150
4151constMCOperand &Src0 = Inst.getOperand(Src0Idx);
4152if (!Src0.isReg())
4153returntrue;
4154
4155autoReg =mc2PseudoReg(Src0.getReg());
4156constMCRegisterInfo *TRI = getContext().getRegisterInfo();
4157if (!isGFX90A() &&isSGPR(Reg,TRI)) {
4158Error(getRegLoc(Reg,Operands),
4159"source operand must be either a VGPR or an inline constant");
4160returnfalse;
4161 }
4162
4163returntrue;
4164}
4165
4166bool AMDGPUAsmParser::validateMAISrc2(constMCInst &Inst,
4167constOperandVector &Operands) {
4168unsigned Opcode = Inst.getOpcode();
4169constMCInstrDesc &Desc = MII.get(Opcode);
4170
4171if (!(Desc.TSFlags &SIInstrFlags::IsMAI) ||
4172 !getFeatureBits()[FeatureMFMAInlineLiteralBug])
4173returntrue;
4174
4175constint Src2Idx =getNamedOperandIdx(Opcode, OpName::src2);
4176if (Src2Idx == -1)
4177returntrue;
4178
4179if (Inst.getOperand(Src2Idx).isImm() && isInlineConstant(Inst, Src2Idx)) {
4180Error(getConstLoc(Operands),
4181"inline constants are not allowed for this operand");
4182returnfalse;
4183 }
4184
4185returntrue;
4186}
4187
4188bool AMDGPUAsmParser::validateMFMA(constMCInst &Inst,
4189constOperandVector &Operands) {
4190constunsigned Opc = Inst.getOpcode();
4191constMCInstrDesc &Desc = MII.get(Opc);
4192
4193if ((Desc.TSFlags &SIInstrFlags::IsMAI) == 0)
4194returntrue;
4195
4196int BlgpIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::blgp);
4197if (BlgpIdx != -1) {
4198if (constMFMA_F8F6F4_Info *Info = AMDGPU::isMFMA_F8F6F4(Opc)) {
4199int CbszIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::cbsz);
4200
4201unsigned CBSZ = Inst.getOperand(CbszIdx).getImm();
4202unsigned BLGP = Inst.getOperand(BlgpIdx).getImm();
4203
4204// Validate the correct register size was used for the floating point
4205// format operands
4206
4207boolSuccess =true;
4208if (Info->NumRegsSrcA !=mfmaScaleF8F6F4FormatToNumRegs(CBSZ)) {
4209int Src0Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
4210Error(getRegLoc(mc2PseudoReg(Inst.getOperand(Src0Idx).getReg()),
4211Operands),
4212"wrong register tuple size for cbsz value " +Twine(CBSZ));
4213Success =false;
4214 }
4215
4216if (Info->NumRegsSrcB !=mfmaScaleF8F6F4FormatToNumRegs(BLGP)) {
4217int Src1Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
4218Error(getRegLoc(mc2PseudoReg(Inst.getOperand(Src1Idx).getReg()),
4219Operands),
4220"wrong register tuple size for blgp value " +Twine(BLGP));
4221Success =false;
4222 }
4223
4224returnSuccess;
4225 }
4226 }
4227
4228constint Src2Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2);
4229if (Src2Idx == -1)
4230returntrue;
4231
4232constMCOperand &Src2 = Inst.getOperand(Src2Idx);
4233if (!Src2.isReg())
4234returntrue;
4235
4236MCRegister Src2Reg = Src2.getReg();
4237MCRegister DstReg = Inst.getOperand(0).getReg();
4238if (Src2Reg == DstReg)
4239returntrue;
4240
4241constMCRegisterInfo *TRI = getContext().getRegisterInfo();
4242if (TRI->getRegClass(Desc.operands()[0].RegClass).getSizeInBits() <= 128)
4243returntrue;
4244
4245if (TRI->regsOverlap(Src2Reg, DstReg)) {
4246Error(getRegLoc(mc2PseudoReg(Src2Reg),Operands),
4247"source 2 operand must not partially overlap with dst");
4248returnfalse;
4249 }
4250
4251returntrue;
4252}
4253
4254bool AMDGPUAsmParser::validateDivScale(constMCInst &Inst) {
4255switch (Inst.getOpcode()) {
4256default:
4257returntrue;
4258case V_DIV_SCALE_F32_gfx6_gfx7:
4259case V_DIV_SCALE_F32_vi:
4260case V_DIV_SCALE_F32_gfx10:
4261case V_DIV_SCALE_F64_gfx6_gfx7:
4262case V_DIV_SCALE_F64_vi:
4263case V_DIV_SCALE_F64_gfx10:
4264break;
4265 }
4266
4267// TODO: Check that src0 = src1 or src2.
4268
4269for (autoName : {AMDGPU::OpName::src0_modifiers,
4270 AMDGPU::OpName::src2_modifiers,
4271 AMDGPU::OpName::src2_modifiers}) {
4272if (Inst.getOperand(AMDGPU::getNamedOperandIdx(Inst.getOpcode(),Name))
4273 .getImm() &
4274SISrcMods::ABS) {
4275returnfalse;
4276 }
4277 }
4278
4279returntrue;
4280}
4281
4282bool AMDGPUAsmParser::validateMIMGD16(constMCInst &Inst) {
4283
4284constunsigned Opc = Inst.getOpcode();
4285constMCInstrDesc &Desc = MII.get(Opc);
4286
4287if ((Desc.TSFlags &MIMGFlags) == 0)
4288returntrue;
4289
4290int D16Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::d16);
4291if (D16Idx >= 0 && Inst.getOperand(D16Idx).getImm()) {
4292if (isCI() ||isSI())
4293returnfalse;
4294 }
4295
4296returntrue;
4297}
4298
4299staticboolIsRevOpcode(constunsigned Opcode)
4300{
4301switch (Opcode) {
4302case AMDGPU::V_SUBREV_F32_e32:
4303case AMDGPU::V_SUBREV_F32_e64:
4304case AMDGPU::V_SUBREV_F32_e32_gfx10:
4305case AMDGPU::V_SUBREV_F32_e32_gfx6_gfx7:
4306case AMDGPU::V_SUBREV_F32_e32_vi:
4307case AMDGPU::V_SUBREV_F32_e64_gfx10:
4308case AMDGPU::V_SUBREV_F32_e64_gfx6_gfx7:
4309case AMDGPU::V_SUBREV_F32_e64_vi:
4310
4311case AMDGPU::V_SUBREV_CO_U32_e32:
4312case AMDGPU::V_SUBREV_CO_U32_e64:
4313case AMDGPU::V_SUBREV_I32_e32_gfx6_gfx7:
4314case AMDGPU::V_SUBREV_I32_e64_gfx6_gfx7:
4315
4316case AMDGPU::V_SUBBREV_U32_e32:
4317case AMDGPU::V_SUBBREV_U32_e64:
4318case AMDGPU::V_SUBBREV_U32_e32_gfx6_gfx7:
4319case AMDGPU::V_SUBBREV_U32_e32_vi:
4320case AMDGPU::V_SUBBREV_U32_e64_gfx6_gfx7:
4321case AMDGPU::V_SUBBREV_U32_e64_vi:
4322
4323case AMDGPU::V_SUBREV_U32_e32:
4324case AMDGPU::V_SUBREV_U32_e64:
4325case AMDGPU::V_SUBREV_U32_e32_gfx9:
4326case AMDGPU::V_SUBREV_U32_e32_vi:
4327case AMDGPU::V_SUBREV_U32_e64_gfx9:
4328case AMDGPU::V_SUBREV_U32_e64_vi:
4329
4330case AMDGPU::V_SUBREV_F16_e32:
4331case AMDGPU::V_SUBREV_F16_e64:
4332case AMDGPU::V_SUBREV_F16_e32_gfx10:
4333case AMDGPU::V_SUBREV_F16_e32_vi:
4334case AMDGPU::V_SUBREV_F16_e64_gfx10:
4335case AMDGPU::V_SUBREV_F16_e64_vi:
4336
4337case AMDGPU::V_SUBREV_U16_e32:
4338case AMDGPU::V_SUBREV_U16_e64:
4339case AMDGPU::V_SUBREV_U16_e32_vi:
4340case AMDGPU::V_SUBREV_U16_e64_vi:
4341
4342case AMDGPU::V_SUBREV_CO_U32_e32_gfx9:
4343case AMDGPU::V_SUBREV_CO_U32_e64_gfx10:
4344case AMDGPU::V_SUBREV_CO_U32_e64_gfx9:
4345
4346case AMDGPU::V_SUBBREV_CO_U32_e32_gfx9:
4347case AMDGPU::V_SUBBREV_CO_U32_e64_gfx9:
4348
4349case AMDGPU::V_SUBREV_NC_U32_e32_gfx10:
4350case AMDGPU::V_SUBREV_NC_U32_e64_gfx10:
4351
4352case AMDGPU::V_SUBREV_CO_CI_U32_e32_gfx10:
4353case AMDGPU::V_SUBREV_CO_CI_U32_e64_gfx10:
4354
4355case AMDGPU::V_LSHRREV_B32_e32:
4356case AMDGPU::V_LSHRREV_B32_e64:
4357case AMDGPU::V_LSHRREV_B32_e32_gfx6_gfx7:
4358case AMDGPU::V_LSHRREV_B32_e64_gfx6_gfx7:
4359case AMDGPU::V_LSHRREV_B32_e32_vi:
4360case AMDGPU::V_LSHRREV_B32_e64_vi:
4361case AMDGPU::V_LSHRREV_B32_e32_gfx10:
4362case AMDGPU::V_LSHRREV_B32_e64_gfx10:
4363
4364case AMDGPU::V_ASHRREV_I32_e32:
4365case AMDGPU::V_ASHRREV_I32_e64:
4366case AMDGPU::V_ASHRREV_I32_e32_gfx10:
4367case AMDGPU::V_ASHRREV_I32_e32_gfx6_gfx7:
4368case AMDGPU::V_ASHRREV_I32_e32_vi:
4369case AMDGPU::V_ASHRREV_I32_e64_gfx10:
4370case AMDGPU::V_ASHRREV_I32_e64_gfx6_gfx7:
4371case AMDGPU::V_ASHRREV_I32_e64_vi:
4372
4373case AMDGPU::V_LSHLREV_B32_e32:
4374case AMDGPU::V_LSHLREV_B32_e64:
4375case AMDGPU::V_LSHLREV_B32_e32_gfx10:
4376case AMDGPU::V_LSHLREV_B32_e32_gfx6_gfx7:
4377case AMDGPU::V_LSHLREV_B32_e32_vi:
4378case AMDGPU::V_LSHLREV_B32_e64_gfx10:
4379case AMDGPU::V_LSHLREV_B32_e64_gfx6_gfx7:
4380case AMDGPU::V_LSHLREV_B32_e64_vi:
4381
4382case AMDGPU::V_LSHLREV_B16_e32:
4383case AMDGPU::V_LSHLREV_B16_e64:
4384case AMDGPU::V_LSHLREV_B16_e32_vi:
4385case AMDGPU::V_LSHLREV_B16_e64_vi:
4386case AMDGPU::V_LSHLREV_B16_gfx10:
4387
4388case AMDGPU::V_LSHRREV_B16_e32:
4389case AMDGPU::V_LSHRREV_B16_e64:
4390case AMDGPU::V_LSHRREV_B16_e32_vi:
4391case AMDGPU::V_LSHRREV_B16_e64_vi:
4392case AMDGPU::V_LSHRREV_B16_gfx10:
4393
4394case AMDGPU::V_ASHRREV_I16_e32:
4395case AMDGPU::V_ASHRREV_I16_e64:
4396case AMDGPU::V_ASHRREV_I16_e32_vi:
4397case AMDGPU::V_ASHRREV_I16_e64_vi:
4398case AMDGPU::V_ASHRREV_I16_gfx10:
4399
4400case AMDGPU::V_LSHLREV_B64_e64:
4401case AMDGPU::V_LSHLREV_B64_gfx10:
4402case AMDGPU::V_LSHLREV_B64_vi:
4403
4404case AMDGPU::V_LSHRREV_B64_e64:
4405case AMDGPU::V_LSHRREV_B64_gfx10:
4406case AMDGPU::V_LSHRREV_B64_vi:
4407
4408case AMDGPU::V_ASHRREV_I64_e64:
4409case AMDGPU::V_ASHRREV_I64_gfx10:
4410case AMDGPU::V_ASHRREV_I64_vi:
4411
4412case AMDGPU::V_PK_LSHLREV_B16:
4413case AMDGPU::V_PK_LSHLREV_B16_gfx10:
4414case AMDGPU::V_PK_LSHLREV_B16_vi:
4415
4416case AMDGPU::V_PK_LSHRREV_B16:
4417case AMDGPU::V_PK_LSHRREV_B16_gfx10:
4418case AMDGPU::V_PK_LSHRREV_B16_vi:
4419case AMDGPU::V_PK_ASHRREV_I16:
4420case AMDGPU::V_PK_ASHRREV_I16_gfx10:
4421case AMDGPU::V_PK_ASHRREV_I16_vi:
4422returntrue;
4423default:
4424returnfalse;
4425 }
4426}
4427
4428std::optional<StringRef>
4429AMDGPUAsmParser::validateLdsDirect(constMCInst &Inst) {
4430
4431using namespaceSIInstrFlags;
4432constunsigned Opcode = Inst.getOpcode();
4433constMCInstrDesc &Desc = MII.get(Opcode);
4434
4435// lds_direct register is defined so that it can be used
4436// with 9-bit operands only. Ignore encodings which do not accept these.
4437constauto Enc =VOP1 |VOP2 |VOP3 |VOPC |VOP3P |SIInstrFlags::SDWA;
4438if ((Desc.TSFlags & Enc) == 0)
4439return std::nullopt;
4440
4441for (auto SrcName : {OpName::src0, OpName::src1, OpName::src2}) {
4442auto SrcIdx =getNamedOperandIdx(Opcode, SrcName);
4443if (SrcIdx == -1)
4444break;
4445constauto &Src = Inst.getOperand(SrcIdx);
4446if (Src.isReg() && Src.getReg() == LDS_DIRECT) {
4447
4448if (isGFX90A() ||isGFX11Plus())
4449returnStringRef("lds_direct is not supported on this GPU");
4450
4451if (IsRevOpcode(Opcode) || (Desc.TSFlags &SIInstrFlags::SDWA))
4452returnStringRef("lds_direct cannot be used with this instruction");
4453
4454if (SrcName != OpName::src0)
4455returnStringRef("lds_direct may be used as src0 only");
4456 }
4457 }
4458
4459return std::nullopt;
4460}
4461
4462SMLoc AMDGPUAsmParser::getFlatOffsetLoc(constOperandVector &Operands) const{
4463for (unsigned i = 1, e =Operands.size(); i != e; ++i) {
4464 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4465if (Op.isFlatOffset())
4466returnOp.getStartLoc();
4467 }
4468return getLoc();
4469}
4470
4471bool AMDGPUAsmParser::validateOffset(constMCInst &Inst,
4472constOperandVector &Operands) {
4473auto Opcode = Inst.getOpcode();
4474auto OpNum =AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4475if (OpNum == -1)
4476returntrue;
4477
4478uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4479if ((TSFlags &SIInstrFlags::FLAT))
4480return validateFlatOffset(Inst,Operands);
4481
4482if ((TSFlags &SIInstrFlags::SMRD))
4483return validateSMEMOffset(Inst,Operands);
4484
4485constauto &Op = Inst.getOperand(OpNum);
4486if (isGFX12Plus() &&
4487 (TSFlags & (SIInstrFlags::MUBUF |SIInstrFlags::MTBUF))) {
4488constunsigned OffsetSize = 24;
4489if (!isIntN(OffsetSize,Op.getImm())) {
4490Error(getFlatOffsetLoc(Operands),
4491Twine("expected a ") +Twine(OffsetSize) +"-bit signed offset");
4492returnfalse;
4493 }
4494 }else {
4495constunsigned OffsetSize = 16;
4496if (!isUIntN(OffsetSize,Op.getImm())) {
4497Error(getFlatOffsetLoc(Operands),
4498Twine("expected a ") +Twine(OffsetSize) +"-bit unsigned offset");
4499returnfalse;
4500 }
4501 }
4502returntrue;
4503}
4504
4505bool AMDGPUAsmParser::validateFlatOffset(constMCInst &Inst,
4506constOperandVector &Operands) {
4507uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4508if ((TSFlags &SIInstrFlags::FLAT) == 0)
4509returntrue;
4510
4511auto Opcode = Inst.getOpcode();
4512auto OpNum =AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4513assert(OpNum != -1);
4514
4515constauto &Op = Inst.getOperand(OpNum);
4516if (!hasFlatOffsets() &&Op.getImm() != 0) {
4517Error(getFlatOffsetLoc(Operands),
4518"flat offset modifier is not supported on this GPU");
4519returnfalse;
4520 }
4521
4522// For pre-GFX12 FLAT instructions the offset must be positive;
4523// MSB is ignored and forced to zero.
4524unsigned OffsetSize =AMDGPU::getNumFlatOffsetBits(getSTI());
4525bool AllowNegative =
4526 (TSFlags & (SIInstrFlags::FlatGlobal |SIInstrFlags::FlatScratch)) ||
4527isGFX12Plus();
4528if (!isIntN(OffsetSize,Op.getImm()) || (!AllowNegative &&Op.getImm() < 0)) {
4529Error(getFlatOffsetLoc(Operands),
4530Twine("expected a ") +
4531 (AllowNegative ?Twine(OffsetSize) +"-bit signed offset"
4532 :Twine(OffsetSize - 1) +"-bit unsigned offset"));
4533returnfalse;
4534 }
4535
4536returntrue;
4537}
4538
4539SMLoc AMDGPUAsmParser::getSMEMOffsetLoc(constOperandVector &Operands) const{
4540// Start with second operand because SMEM Offset cannot be dst or src0.
4541for (unsigned i = 2, e =Operands.size(); i != e; ++i) {
4542 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4543if (Op.isSMEMOffset() ||Op.isSMEMOffsetMod())
4544returnOp.getStartLoc();
4545 }
4546return getLoc();
4547}
4548
4549bool AMDGPUAsmParser::validateSMEMOffset(constMCInst &Inst,
4550constOperandVector &Operands) {
4551if (isCI() ||isSI())
4552returntrue;
4553
4554uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4555if ((TSFlags &SIInstrFlags::SMRD) == 0)
4556returntrue;
4557
4558auto Opcode = Inst.getOpcode();
4559auto OpNum =AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::offset);
4560if (OpNum == -1)
4561returntrue;
4562
4563constauto &Op = Inst.getOperand(OpNum);
4564if (!Op.isImm())
4565returntrue;
4566
4567uint64_tOffset =Op.getImm();
4568bool IsBuffer =AMDGPU::getSMEMIsBuffer(Opcode);
4569if (AMDGPU::isLegalSMRDEncodedUnsignedOffset(getSTI(),Offset) ||
4570AMDGPU::isLegalSMRDEncodedSignedOffset(getSTI(),Offset, IsBuffer))
4571returntrue;
4572
4573Error(getSMEMOffsetLoc(Operands),
4574isGFX12Plus() ?"expected a 24-bit signed offset"
4575 : (isVI() || IsBuffer) ?"expected a 20-bit unsigned offset"
4576 :"expected a 21-bit signed offset");
4577
4578returnfalse;
4579}
4580
4581bool AMDGPUAsmParser::validateSOPLiteral(constMCInst &Inst) const{
4582unsigned Opcode = Inst.getOpcode();
4583constMCInstrDesc &Desc = MII.get(Opcode);
4584if (!(Desc.TSFlags & (SIInstrFlags::SOP2 |SIInstrFlags::SOPC)))
4585returntrue;
4586
4587constint Src0Idx =AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src0);
4588constint Src1Idx =AMDGPU::getNamedOperandIdx(Opcode, AMDGPU::OpName::src1);
4589
4590constint OpIndices[] = { Src0Idx, Src1Idx };
4591
4592unsigned NumExprs = 0;
4593unsigned NumLiterals = 0;
4594uint32_tLiteralValue;
4595
4596for (int OpIdx : OpIndices) {
4597if (OpIdx == -1)break;
4598
4599constMCOperand &MO = Inst.getOperand(OpIdx);
4600// Exclude special imm operands (like that used by s_set_gpr_idx_on)
4601if (AMDGPU::isSISrcOperand(Desc, OpIdx)) {
4602if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
4603uint32_tValue =static_cast<uint32_t>(MO.getImm());
4604if (NumLiterals == 0 || LiteralValue !=Value) {
4605LiteralValue =Value;
4606 ++NumLiterals;
4607 }
4608 }elseif (MO.isExpr()) {
4609 ++NumExprs;
4610 }
4611 }
4612 }
4613
4614return NumLiterals + NumExprs <= 1;
4615}
4616
4617bool AMDGPUAsmParser::validateOpSel(constMCInst &Inst) {
4618constunsigned Opc = Inst.getOpcode();
4619if (isPermlane16(Opc)) {
4620int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4621unsignedOpSel = Inst.getOperand(OpSelIdx).getImm();
4622
4623if (OpSel & ~3)
4624returnfalse;
4625 }
4626
4627uint64_t TSFlags = MII.get(Opc).TSFlags;
4628
4629if (isGFX940() && (TSFlags &SIInstrFlags::IsDOT)) {
4630int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4631if (OpSelIdx != -1) {
4632if (Inst.getOperand(OpSelIdx).getImm() != 0)
4633returnfalse;
4634 }
4635int OpSelHiIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel_hi);
4636if (OpSelHiIdx != -1) {
4637if (Inst.getOperand(OpSelHiIdx).getImm() != -1)
4638returnfalse;
4639 }
4640 }
4641
4642// op_sel[0:1] must be 0 for v_dot2_bf16_bf16 and v_dot2_f16_f16 (VOP3 Dot).
4643if (isGFX11Plus() && (TSFlags &SIInstrFlags::IsDOT) &&
4644 (TSFlags &SIInstrFlags::VOP3) && !(TSFlags &SIInstrFlags::VOP3P)) {
4645int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
4646unsignedOpSel = Inst.getOperand(OpSelIdx).getImm();
4647if (OpSel & 3)
4648returnfalse;
4649 }
4650
4651returntrue;
4652}
4653
4654bool AMDGPUAsmParser::validateNeg(constMCInst &Inst,intOpName) {
4655assert(OpName == AMDGPU::OpName::neg_lo ||OpName == AMDGPU::OpName::neg_hi);
4656
4657constunsigned Opc = Inst.getOpcode();
4658uint64_t TSFlags = MII.get(Opc).TSFlags;
4659
4660// v_dot4 fp8/bf8 neg_lo/neg_hi not allowed on src0 and src1 (allowed on src2)
4661// v_wmma iu4/iu8 neg_lo not allowed on src2 (allowed on src0, src1)
4662// v_swmmac f16/bf16 neg_lo/neg_hi not allowed on src2 (allowed on src0, src1)
4663// other wmma/swmmac instructions don't have neg_lo/neg_hi operand.
4664if (!(TSFlags &SIInstrFlags::IsDOT) && !(TSFlags &SIInstrFlags::IsWMMA) &&
4665 !(TSFlags &SIInstrFlags::IsSWMMAC))
4666returntrue;
4667
4668int NegIdx =AMDGPU::getNamedOperandIdx(Opc,OpName);
4669if (NegIdx == -1)
4670returntrue;
4671
4672unsigned Neg = Inst.getOperand(NegIdx).getImm();
4673
4674// Instructions that have neg_lo or neg_hi operand but neg modifier is allowed
4675// on some src operands but not allowed on other.
4676// It is convenient that such instructions don't have src_modifiers operand
4677// for src operands that don't allow neg because they also don't allow opsel.
4678
4679int SrcMods[3] = {AMDGPU::OpName::src0_modifiers,
4680 AMDGPU::OpName::src1_modifiers,
4681 AMDGPU::OpName::src2_modifiers};
4682
4683for (unsigned i = 0; i < 3; ++i) {
4684if (!AMDGPU::hasNamedOperand(Opc, SrcMods[i])) {
4685if (Neg & (1 << i))
4686returnfalse;
4687 }
4688 }
4689
4690returntrue;
4691}
4692
4693bool AMDGPUAsmParser::validateDPP(constMCInst &Inst,
4694constOperandVector &Operands) {
4695constunsigned Opc = Inst.getOpcode();
4696int DppCtrlIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dpp_ctrl);
4697if (DppCtrlIdx >= 0) {
4698unsignedDppCtrl = Inst.getOperand(DppCtrlIdx).getImm();
4699
4700if (!AMDGPU::isLegalDPALU_DPPControl(DppCtrl) &&
4701AMDGPU::isDPALU_DPP(MII.get(Opc))) {
4702// DP ALU DPP is supported for row_newbcast only on GFX9*
4703SMLoc S = getImmLoc(AMDGPUOperand::ImmTyDppCtrl,Operands);
4704Error(S,"DP ALU dpp only supports row_newbcast");
4705returnfalse;
4706 }
4707 }
4708
4709int Dpp8Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::dpp8);
4710bool IsDPP = DppCtrlIdx >= 0 || Dpp8Idx >= 0;
4711
4712if (IsDPP && !hasDPPSrc1SGPR(getSTI())) {
4713int Src1Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src1);
4714if (Src1Idx >= 0) {
4715constMCOperand &Src1 = Inst.getOperand(Src1Idx);
4716constMCRegisterInfo *TRI = getContext().getRegisterInfo();
4717if (Src1.isReg() &&isSGPR(mc2PseudoReg(Src1.getReg()),TRI)) {
4718autoReg =mc2PseudoReg(Inst.getOperand(Src1Idx).getReg());
4719SMLoc S = getRegLoc(Reg,Operands);
4720Error(S,"invalid operand for instruction");
4721returnfalse;
4722 }
4723if (Src1.isImm()) {
4724Error(getInstLoc(Operands),
4725"src1 immediate operand invalid for instruction");
4726returnfalse;
4727 }
4728 }
4729 }
4730
4731returntrue;
4732}
4733
4734// Check if VCC register matches wavefront size
4735bool AMDGPUAsmParser::validateVccOperand(MCRegister Reg) const{
4736auto FB = getFeatureBits();
4737return (FB[AMDGPU::FeatureWavefrontSize64] && Reg == AMDGPU::VCC) ||
4738 (FB[AMDGPU::FeatureWavefrontSize32] &&Reg == AMDGPU::VCC_LO);
4739}
4740
4741// One unique literal can be used. VOP3 literal is only allowed in GFX10+
4742bool AMDGPUAsmParser::validateVOPLiteral(constMCInst &Inst,
4743constOperandVector &Operands) {
4744unsigned Opcode = Inst.getOpcode();
4745constMCInstrDesc &Desc = MII.get(Opcode);
4746bool HasMandatoryLiteral =getNamedOperandIdx(Opcode, OpName::imm) != -1;
4747if (!(Desc.TSFlags & (SIInstrFlags::VOP3 |SIInstrFlags::VOP3P)) &&
4748 !HasMandatoryLiteral && !isVOPD(Opcode))
4749returntrue;
4750
4751OperandIndices OpIndices =getSrcOperandIndices(Opcode, HasMandatoryLiteral);
4752
4753unsigned NumExprs = 0;
4754unsigned NumLiterals = 0;
4755uint32_tLiteralValue;
4756
4757for (int OpIdx : OpIndices) {
4758if (OpIdx == -1)
4759continue;
4760
4761constMCOperand &MO = Inst.getOperand(OpIdx);
4762if (!MO.isImm() && !MO.isExpr())
4763continue;
4764if (!isSISrcOperand(Desc, OpIdx))
4765continue;
4766
4767if (MO.isImm() && !isInlineConstant(Inst, OpIdx)) {
4768uint64_tValue =static_cast<uint64_t>(MO.getImm());
4769bool IsFP64 =AMDGPU::isSISrcFPOperand(Desc, OpIdx) &&
4770AMDGPU::getOperandSize(Desc.operands()[OpIdx]) == 8;
4771bool IsValid32Op =AMDGPU::isValid32BitLiteral(Value, IsFP64);
4772
4773if (!IsValid32Op && !isInt<32>(Value) && !isUInt<32>(Value)) {
4774Error(getLitLoc(Operands),"invalid operand for instruction");
4775returnfalse;
4776 }
4777
4778if (IsFP64 && IsValid32Op)
4779Value =Hi_32(Value);
4780
4781if (NumLiterals == 0 || LiteralValue !=Value) {
4782LiteralValue =Value;
4783 ++NumLiterals;
4784 }
4785 }elseif (MO.isExpr()) {
4786 ++NumExprs;
4787 }
4788 }
4789 NumLiterals += NumExprs;
4790
4791if (!NumLiterals)
4792returntrue;
4793
4794if (!HasMandatoryLiteral && !getFeatureBits()[FeatureVOP3Literal]) {
4795Error(getLitLoc(Operands),"literal operands are not supported");
4796returnfalse;
4797 }
4798
4799if (NumLiterals > 1) {
4800Error(getLitLoc(Operands,true),"only one unique literal operand is allowed");
4801returnfalse;
4802 }
4803
4804returntrue;
4805}
4806
4807// Returns -1 if not a register, 0 if VGPR and 1 if AGPR.
4808staticintIsAGPROperand(constMCInst &Inst,uint16_t NameIdx,
4809constMCRegisterInfo *MRI) {
4810int OpIdx =AMDGPU::getNamedOperandIdx(Inst.getOpcode(), NameIdx);
4811if (OpIdx < 0)
4812return -1;
4813
4814constMCOperand &Op = Inst.getOperand(OpIdx);
4815if (!Op.isReg())
4816return -1;
4817
4818MCRegister Sub =MRI->getSubReg(Op.getReg(), AMDGPU::sub0);
4819auto Reg = Sub ? Sub :Op.getReg();
4820constMCRegisterClass &AGPR32 =MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
4821return AGPR32.contains(Reg) ? 1 : 0;
4822}
4823
4824bool AMDGPUAsmParser::validateAGPRLdSt(constMCInst &Inst) const{
4825uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4826if ((TSFlags & (SIInstrFlags::FLAT |SIInstrFlags::MUBUF |
4827SIInstrFlags::MTBUF |SIInstrFlags::MIMG |
4828SIInstrFlags::DS)) == 0)
4829returntrue;
4830
4831uint16_t DataNameIdx = (TSFlags &SIInstrFlags::DS) ? AMDGPU::OpName::data0
4832 : AMDGPU::OpName::vdata;
4833
4834constMCRegisterInfo *MRI = getMRI();
4835int DstAreg =IsAGPROperand(Inst, AMDGPU::OpName::vdst,MRI);
4836int DataAreg =IsAGPROperand(Inst, DataNameIdx,MRI);
4837
4838if ((TSFlags &SIInstrFlags::DS) && DataAreg >= 0) {
4839int Data2Areg =IsAGPROperand(Inst, AMDGPU::OpName::data1,MRI);
4840if (Data2Areg >= 0 && Data2Areg != DataAreg)
4841returnfalse;
4842 }
4843
4844auto FB = getFeatureBits();
4845if (FB[AMDGPU::FeatureGFX90AInsts]) {
4846if (DataAreg < 0 || DstAreg < 0)
4847returntrue;
4848return DstAreg == DataAreg;
4849 }
4850
4851return DstAreg < 1 && DataAreg < 1;
4852}
4853
4854bool AMDGPUAsmParser::validateVGPRAlign(constMCInst &Inst) const{
4855auto FB = getFeatureBits();
4856if (!FB[AMDGPU::FeatureGFX90AInsts])
4857returntrue;
4858
4859constMCRegisterInfo *MRI = getMRI();
4860constMCRegisterClass &VGPR32 =MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
4861constMCRegisterClass &AGPR32 =MRI->getRegClass(AMDGPU::AGPR_32RegClassID);
4862for (unsignedI = 0, E = Inst.getNumOperands();I != E; ++I) {
4863constMCOperand &Op = Inst.getOperand(I);
4864if (!Op.isReg())
4865continue;
4866
4867MCRegister Sub =MRI->getSubReg(Op.getReg(), AMDGPU::sub0);
4868if (!Sub)
4869continue;
4870
4871if (VGPR32.contains(Sub) && ((Sub - AMDGPU::VGPR0) & 1))
4872returnfalse;
4873if (AGPR32.contains(Sub) && ((Sub - AMDGPU::AGPR0) & 1))
4874returnfalse;
4875 }
4876
4877returntrue;
4878}
4879
4880SMLoc AMDGPUAsmParser::getBLGPLoc(constOperandVector &Operands) const{
4881for (unsigned i = 1, e =Operands.size(); i != e; ++i) {
4882 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
4883if (Op.isBLGP())
4884returnOp.getStartLoc();
4885 }
4886returnSMLoc();
4887}
4888
4889bool AMDGPUAsmParser::validateBLGP(constMCInst &Inst,
4890constOperandVector &Operands) {
4891unsigned Opc = Inst.getOpcode();
4892int BlgpIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::blgp);
4893if (BlgpIdx == -1)
4894returntrue;
4895SMLoc BLGPLoc = getBLGPLoc(Operands);
4896if (!BLGPLoc.isValid())
4897returntrue;
4898bool IsNeg =StringRef(BLGPLoc.getPointer()).starts_with("neg:");
4899auto FB = getFeatureBits();
4900bool UsesNeg =false;
4901if (FB[AMDGPU::FeatureGFX940Insts]) {
4902switch (Opc) {
4903case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_acd:
4904case AMDGPU::V_MFMA_F64_16X16X4F64_gfx940_vcd:
4905case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_acd:
4906case AMDGPU::V_MFMA_F64_4X4X4F64_gfx940_vcd:
4907 UsesNeg =true;
4908 }
4909 }
4910
4911if (IsNeg == UsesNeg)
4912returntrue;
4913
4914Error(BLGPLoc,
4915 UsesNeg ?"invalid modifier: blgp is not supported"
4916 :"invalid modifier: neg is not supported");
4917
4918returnfalse;
4919}
4920
4921bool AMDGPUAsmParser::validateWaitCnt(constMCInst &Inst,
4922constOperandVector &Operands) {
4923if (!isGFX11Plus())
4924returntrue;
4925
4926unsigned Opc = Inst.getOpcode();
4927if (Opc != AMDGPU::S_WAITCNT_EXPCNT_gfx11 &&
4928 Opc != AMDGPU::S_WAITCNT_LGKMCNT_gfx11 &&
4929 Opc != AMDGPU::S_WAITCNT_VMCNT_gfx11 &&
4930 Opc != AMDGPU::S_WAITCNT_VSCNT_gfx11)
4931returntrue;
4932
4933int Src0Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::sdst);
4934assert(Src0Idx >= 0 && Inst.getOperand(Src0Idx).isReg());
4935autoReg =mc2PseudoReg(Inst.getOperand(Src0Idx).getReg());
4936if (Reg == AMDGPU::SGPR_NULL)
4937returntrue;
4938
4939SMLoc RegLoc = getRegLoc(Reg,Operands);
4940Error(RegLoc,"src0 must be null");
4941returnfalse;
4942}
4943
4944bool AMDGPUAsmParser::validateDS(constMCInst &Inst,
4945constOperandVector &Operands) {
4946uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
4947if ((TSFlags &SIInstrFlags::DS) == 0)
4948returntrue;
4949if (TSFlags &SIInstrFlags::GWS)
4950return validateGWS(Inst,Operands);
4951// Only validate GDS for non-GWS instructions.
4952if (hasGDS())
4953returntrue;
4954int GDSIdx =
4955AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::gds);
4956if (GDSIdx < 0)
4957returntrue;
4958unsigned GDS = Inst.getOperand(GDSIdx).getImm();
4959if (GDS) {
4960SMLoc S = getImmLoc(AMDGPUOperand::ImmTyGDS,Operands);
4961Error(S,"gds modifier is not supported on this GPU");
4962returnfalse;
4963 }
4964returntrue;
4965}
4966
4967// gfx90a has an undocumented limitation:
4968// DS_GWS opcodes must use even aligned registers.
4969bool AMDGPUAsmParser::validateGWS(constMCInst &Inst,
4970constOperandVector &Operands) {
4971if (!getFeatureBits()[AMDGPU::FeatureGFX90AInsts])
4972returntrue;
4973
4974int Opc = Inst.getOpcode();
4975if (Opc != AMDGPU::DS_GWS_INIT_vi && Opc != AMDGPU::DS_GWS_BARRIER_vi &&
4976 Opc != AMDGPU::DS_GWS_SEMA_BR_vi)
4977returntrue;
4978
4979constMCRegisterInfo *MRI = getMRI();
4980constMCRegisterClass &VGPR32 =MRI->getRegClass(AMDGPU::VGPR_32RegClassID);
4981int Data0Pos =
4982AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::data0);
4983assert(Data0Pos != -1);
4984autoReg = Inst.getOperand(Data0Pos).getReg();
4985auto RegIdx =Reg - (VGPR32.contains(Reg) ? AMDGPU::VGPR0 : AMDGPU::AGPR0);
4986if (RegIdx & 1) {
4987SMLoc RegLoc = getRegLoc(Reg,Operands);
4988Error(RegLoc,"vgpr must be even aligned");
4989returnfalse;
4990 }
4991
4992returntrue;
4993}
4994
4995bool AMDGPUAsmParser::validateCoherencyBits(constMCInst &Inst,
4996constOperandVector &Operands,
4997constSMLoc &IDLoc) {
4998int CPolPos =AMDGPU::getNamedOperandIdx(Inst.getOpcode(),
4999 AMDGPU::OpName::cpol);
5000if (CPolPos == -1)
5001returntrue;
5002
5003unsignedCPol = Inst.getOperand(CPolPos).getImm();
5004
5005if (isGFX12Plus())
5006return validateTHAndScopeBits(Inst,Operands, CPol);
5007
5008uint64_t TSFlags = MII.get(Inst.getOpcode()).TSFlags;
5009if (TSFlags &SIInstrFlags::SMRD) {
5010if (CPol && (isSI() ||isCI())) {
5011SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,Operands);
5012Error(S,"cache policy is not supported for SMRD instructions");
5013returnfalse;
5014 }
5015if (CPol & ~(AMDGPU::CPol::GLC |AMDGPU::CPol::DLC)) {
5016Error(IDLoc,"invalid cache policy for SMEM instruction");
5017returnfalse;
5018 }
5019 }
5020
5021if (isGFX90A() && !isGFX940() && (CPol &CPol::SCC)) {
5022constuint64_t AllowSCCModifier =SIInstrFlags::MUBUF |
5023SIInstrFlags::MTBUF |SIInstrFlags::MIMG |
5024SIInstrFlags::FLAT;
5025if (!(TSFlags & AllowSCCModifier)) {
5026SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,Operands);
5027StringRef CStr(S.getPointer());
5028 S =SMLoc::getFromPointer(&CStr.data()[CStr.find("scc")]);
5029Error(S,
5030"scc modifier is not supported for this instruction on this GPU");
5031returnfalse;
5032 }
5033 }
5034
5035if (!(TSFlags & (SIInstrFlags::IsAtomicNoRet |SIInstrFlags::IsAtomicRet)))
5036returntrue;
5037
5038if (TSFlags &SIInstrFlags::IsAtomicRet) {
5039if (!(TSFlags &SIInstrFlags::MIMG) && !(CPol &CPol::GLC)) {
5040Error(IDLoc,isGFX940() ?"instruction must use sc0"
5041 :"instruction must use glc");
5042returnfalse;
5043 }
5044 }else {
5045if (CPol &CPol::GLC) {
5046SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,Operands);
5047StringRef CStr(S.getPointer());
5048 S =SMLoc::getFromPointer(
5049 &CStr.data()[CStr.find(isGFX940() ?"sc0" :"glc")]);
5050Error(S,isGFX940() ?"instruction must not use sc0"
5051 :"instruction must not use glc");
5052returnfalse;
5053 }
5054 }
5055
5056returntrue;
5057}
5058
5059bool AMDGPUAsmParser::validateTHAndScopeBits(constMCInst &Inst,
5060constOperandVector &Operands,
5061constunsigned CPol) {
5062constunsignedTH =CPol &AMDGPU::CPol::TH;
5063constunsignedScope =CPol &AMDGPU::CPol::SCOPE;
5064
5065constunsigned Opcode = Inst.getOpcode();
5066constMCInstrDesc &TID = MII.get(Opcode);
5067
5068autoPrintError = [&](StringRef Msg) {
5069SMLoc S = getImmLoc(AMDGPUOperand::ImmTyCPol,Operands);
5070Error(S, Msg);
5071returnfalse;
5072 };
5073
5074if ((TID.TSFlags &SIInstrFlags::IsAtomicRet) &&
5075 (TID.TSFlags & (SIInstrFlags::FLAT |SIInstrFlags::MUBUF)) &&
5076 (!(TH &AMDGPU::CPol::TH_ATOMIC_RETURN)))
5077returnPrintError("instruction must use th:TH_ATOMIC_RETURN");
5078
5079if (TH == 0)
5080returntrue;
5081
5082if ((TID.TSFlags &SIInstrFlags::SMRD) &&
5083 ((TH ==AMDGPU::CPol::TH_NT_RT) || (TH ==AMDGPU::CPol::TH_RT_NT) ||
5084 (TH ==AMDGPU::CPol::TH_NT_HT)))
5085returnPrintError("invalid th value for SMEM instruction");
5086
5087if (TH ==AMDGPU::CPol::TH_BYPASS) {
5088if ((Scope !=AMDGPU::CPol::SCOPE_SYS &&
5089 CPol &AMDGPU::CPol::TH_REAL_BYPASS) ||
5090 (Scope ==AMDGPU::CPol::SCOPE_SYS &&
5091 !(CPol &AMDGPU::CPol::TH_REAL_BYPASS)))
5092returnPrintError("scope and th combination is not valid");
5093 }
5094
5095bool IsStore = TID.mayStore();
5096bool IsAtomic =
5097 TID.TSFlags & (SIInstrFlags::IsAtomicNoRet |SIInstrFlags::IsAtomicRet);
5098
5099if (IsAtomic) {
5100if (!(CPol &AMDGPU::CPol::TH_TYPE_ATOMIC))
5101returnPrintError("invalid th value for atomic instructions");
5102 }elseif (IsStore) {
5103if (!(CPol &AMDGPU::CPol::TH_TYPE_STORE))
5104returnPrintError("invalid th value for store instructions");
5105 }else {
5106if (!(CPol &AMDGPU::CPol::TH_TYPE_LOAD))
5107returnPrintError("invalid th value for load instructions");
5108 }
5109
5110returntrue;
5111}
5112
5113bool AMDGPUAsmParser::validateTFE(constMCInst &Inst,
5114constOperandVector &Operands) {
5115constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
5116if (Desc.mayStore() &&
5117 (Desc.TSFlags & (SIInstrFlags::MUBUF |SIInstrFlags::MTBUF))) {
5118SMLoc Loc = getImmLoc(AMDGPUOperand::ImmTyTFE,Operands);
5119if (Loc != getInstLoc(Operands)) {
5120Error(Loc,"TFE modifier has no meaning for store instructions");
5121returnfalse;
5122 }
5123 }
5124
5125returntrue;
5126}
5127
5128bool AMDGPUAsmParser::validateInstruction(constMCInst &Inst,
5129constSMLoc &IDLoc,
5130constOperandVector &Operands) {
5131if (auto ErrMsg = validateLdsDirect(Inst)) {
5132Error(getRegLoc(LDS_DIRECT,Operands), *ErrMsg);
5133returnfalse;
5134 }
5135if (!validateSOPLiteral(Inst)) {
5136Error(getLitLoc(Operands),
5137"only one unique literal operand is allowed");
5138returnfalse;
5139 }
5140if (!validateVOPLiteral(Inst,Operands)) {
5141returnfalse;
5142 }
5143if (!validateConstantBusLimitations(Inst,Operands)) {
5144returnfalse;
5145 }
5146if (!validateVOPDRegBankConstraints(Inst,Operands)) {
5147returnfalse;
5148 }
5149if (!validateIntClampSupported(Inst)) {
5150Error(getImmLoc(AMDGPUOperand::ImmTyClamp,Operands),
5151"integer clamping is not supported on this GPU");
5152returnfalse;
5153 }
5154if (!validateOpSel(Inst)) {
5155Error(getImmLoc(AMDGPUOperand::ImmTyOpSel,Operands),
5156"invalid op_sel operand");
5157returnfalse;
5158 }
5159if (!validateNeg(Inst, AMDGPU::OpName::neg_lo)) {
5160Error(getImmLoc(AMDGPUOperand::ImmTyNegLo,Operands),
5161"invalid neg_lo operand");
5162returnfalse;
5163 }
5164if (!validateNeg(Inst, AMDGPU::OpName::neg_hi)) {
5165Error(getImmLoc(AMDGPUOperand::ImmTyNegHi,Operands),
5166"invalid neg_hi operand");
5167returnfalse;
5168 }
5169if (!validateDPP(Inst,Operands)) {
5170returnfalse;
5171 }
5172// For MUBUF/MTBUF d16 is a part of opcode, so there is nothing to validate.
5173if (!validateMIMGD16(Inst)) {
5174Error(getImmLoc(AMDGPUOperand::ImmTyD16,Operands),
5175"d16 modifier is not supported on this GPU");
5176returnfalse;
5177 }
5178if (!validateMIMGDim(Inst,Operands)) {
5179Error(IDLoc,"missing dim operand");
5180returnfalse;
5181 }
5182if (!validateMIMGMSAA(Inst)) {
5183Error(getImmLoc(AMDGPUOperand::ImmTyDim,Operands),
5184"invalid dim; must be MSAA type");
5185returnfalse;
5186 }
5187if (!validateMIMGDataSize(Inst, IDLoc)) {
5188returnfalse;
5189 }
5190if (!validateMIMGAddrSize(Inst, IDLoc))
5191returnfalse;
5192if (!validateMIMGAtomicDMask(Inst)) {
5193Error(getImmLoc(AMDGPUOperand::ImmTyDMask,Operands),
5194"invalid atomic image dmask");
5195returnfalse;
5196 }
5197if (!validateMIMGGatherDMask(Inst)) {
5198Error(getImmLoc(AMDGPUOperand::ImmTyDMask,Operands),
5199"invalid image_gather dmask: only one bit must be set");
5200returnfalse;
5201 }
5202if (!validateMovrels(Inst,Operands)) {
5203returnfalse;
5204 }
5205if (!validateOffset(Inst,Operands)) {
5206returnfalse;
5207 }
5208if (!validateMAIAccWrite(Inst,Operands)) {
5209returnfalse;
5210 }
5211if (!validateMAISrc2(Inst,Operands)) {
5212returnfalse;
5213 }
5214if (!validateMFMA(Inst,Operands)) {
5215returnfalse;
5216 }
5217if (!validateCoherencyBits(Inst,Operands, IDLoc)) {
5218returnfalse;
5219 }
5220
5221if (!validateAGPRLdSt(Inst)) {
5222Error(IDLoc, getFeatureBits()[AMDGPU::FeatureGFX90AInsts]
5223 ?"invalid register class: data and dst should be all VGPR or AGPR"
5224 :"invalid register class: agpr loads and stores not supported on this GPU"
5225 );
5226returnfalse;
5227 }
5228if (!validateVGPRAlign(Inst)) {
5229Error(IDLoc,
5230"invalid register class: vgpr tuples must be 64 bit aligned");
5231returnfalse;
5232 }
5233if (!validateDS(Inst,Operands)) {
5234returnfalse;
5235 }
5236
5237if (!validateBLGP(Inst,Operands)) {
5238returnfalse;
5239 }
5240
5241if (!validateDivScale(Inst)) {
5242Error(IDLoc,"ABS not allowed in VOP3B instructions");
5243returnfalse;
5244 }
5245if (!validateWaitCnt(Inst,Operands)) {
5246returnfalse;
5247 }
5248if (!validateTFE(Inst,Operands)) {
5249returnfalse;
5250 }
5251
5252returntrue;
5253}
5254
5255static std::stringAMDGPUMnemonicSpellCheck(StringRef S,
5256constFeatureBitset &FBS,
5257unsigned VariantID = 0);
5258
5259staticboolAMDGPUCheckMnemonic(StringRef Mnemonic,
5260constFeatureBitset &AvailableFeatures,
5261unsigned VariantID);
5262
5263bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5264constFeatureBitset &FBS) {
5265return isSupportedMnemo(Mnemo, FBS,getAllVariants());
5266}
5267
5268bool AMDGPUAsmParser::isSupportedMnemo(StringRef Mnemo,
5269constFeatureBitset &FBS,
5270ArrayRef<unsigned> Variants) {
5271for (auto Variant : Variants) {
5272if (AMDGPUCheckMnemonic(Mnemo, FBS, Variant))
5273returntrue;
5274 }
5275
5276returnfalse;
5277}
5278
5279bool AMDGPUAsmParser::checkUnsupportedInstruction(StringRef Mnemo,
5280constSMLoc &IDLoc) {
5281FeatureBitset FBS = ComputeAvailableFeatures(getFeatureBits());
5282
5283// Check if requested instruction variant is supported.
5284if (isSupportedMnemo(Mnemo, FBS, getMatchedVariants()))
5285returnfalse;
5286
5287// This instruction is not supported.
5288// Clear any other pending errors because they are no longer relevant.
5289 getParser().clearPendingErrors();
5290
5291// Requested instruction variant is not supported.
5292// Check if any other variants are supported.
5293StringRef VariantName = getMatchedVariantName();
5294if (!VariantName.empty() && isSupportedMnemo(Mnemo, FBS)) {
5295returnError(IDLoc,
5296Twine(VariantName,
5297" variant of this instruction is not supported"));
5298 }
5299
5300// Check if this instruction may be used with a different wavesize.
5301if (isGFX10Plus() && getFeatureBits()[AMDGPU::FeatureWavefrontSize64] &&
5302 !getFeatureBits()[AMDGPU::FeatureWavefrontSize32]) {
5303
5304FeatureBitset FeaturesWS32 = getFeatureBits();
5305 FeaturesWS32.flip(AMDGPU::FeatureWavefrontSize64)
5306 .flip(AMDGPU::FeatureWavefrontSize32);
5307FeatureBitset AvailableFeaturesWS32 =
5308 ComputeAvailableFeatures(FeaturesWS32);
5309
5310if (isSupportedMnemo(Mnemo, AvailableFeaturesWS32, getMatchedVariants()))
5311returnError(IDLoc,"instruction requires wavesize=32");
5312 }
5313
5314// Finally check if this instruction is supported on any other GPU.
5315if (isSupportedMnemo(Mnemo,FeatureBitset().set())) {
5316returnError(IDLoc,"instruction not supported on this GPU");
5317 }
5318
5319// Instruction not supported on any GPU. Probably a typo.
5320 std::string Suggestion =AMDGPUMnemonicSpellCheck(Mnemo, FBS);
5321returnError(IDLoc,"invalid instruction" + Suggestion);
5322}
5323
5324staticboolisInvalidVOPDY(constOperandVector &Operands,
5325uint64_t InvalidOprIdx) {
5326assert(InvalidOprIdx <Operands.size());
5327constauto &Op = ((AMDGPUOperand &)*Operands[InvalidOprIdx]);
5328if (Op.isToken() && InvalidOprIdx > 1) {
5329constauto &PrevOp = ((AMDGPUOperand &)*Operands[InvalidOprIdx - 1]);
5330return PrevOp.isToken() && PrevOp.getToken() =="::";
5331 }
5332returnfalse;
5333}
5334
5335bool AMDGPUAsmParser::matchAndEmitInstruction(SMLoc IDLoc,unsigned &Opcode,
5336OperandVector &Operands,
5337MCStreamer &Out,
5338uint64_t &ErrorInfo,
5339bool MatchingInlineAsm) {
5340MCInst Inst;
5341unsignedResult = Match_Success;
5342for (auto Variant : getMatchedVariants()) {
5343uint64_t EI;
5344autoR = MatchInstructionImpl(Operands, Inst, EI, MatchingInlineAsm,
5345 Variant);
5346// We order match statuses from least to most specific. We use most specific
5347// status as resulting
5348// Match_MnemonicFail < Match_InvalidOperand < Match_MissingFeature
5349if (R == Match_Success || R == Match_MissingFeature ||
5350 (R == Match_InvalidOperand && Result != Match_MissingFeature) ||
5351 (R == Match_MnemonicFail && Result != Match_InvalidOperand &&
5352 Result != Match_MissingFeature)) {
5353Result =R;
5354ErrorInfo = EI;
5355 }
5356if (R == Match_Success)
5357break;
5358 }
5359
5360if (Result == Match_Success) {
5361if (!validateInstruction(Inst, IDLoc,Operands)) {
5362returntrue;
5363 }
5364 Inst.setLoc(IDLoc);
5365 Out.emitInstruction(Inst, getSTI());
5366returnfalse;
5367 }
5368
5369StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).getToken();
5370if (checkUnsupportedInstruction(Mnemo, IDLoc)) {
5371returntrue;
5372 }
5373
5374switch (Result) {
5375default:break;
5376case Match_MissingFeature:
5377// It has been verified that the specified instruction
5378// mnemonic is valid. A match was found but it requires
5379// features which are not supported on this GPU.
5380returnError(IDLoc,"operands are not valid for this GPU or mode");
5381
5382case Match_InvalidOperand: {
5383SMLoc ErrorLoc = IDLoc;
5384if (ErrorInfo != ~0ULL) {
5385if (ErrorInfo >=Operands.size()) {
5386returnError(IDLoc,"too few operands for instruction");
5387 }
5388 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
5389if (ErrorLoc ==SMLoc())
5390 ErrorLoc = IDLoc;
5391
5392if (isInvalidVOPDY(Operands,ErrorInfo))
5393returnError(ErrorLoc,"invalid VOPDY instruction");
5394 }
5395returnError(ErrorLoc,"invalid operand for instruction");
5396 }
5397
5398case Match_MnemonicFail:
5399llvm_unreachable("Invalid instructions should have been handled already");
5400 }
5401llvm_unreachable("Implement any new match types added!");
5402}
5403
5404bool AMDGPUAsmParser::ParseAsAbsoluteExpression(uint32_t &Ret) {
5405 int64_t Tmp = -1;
5406if (!isToken(AsmToken::Integer) && !isToken(AsmToken::Identifier)) {
5407returntrue;
5408 }
5409if (getParser().parseAbsoluteExpression(Tmp)) {
5410returntrue;
5411 }
5412Ret =static_cast<uint32_t>(Tmp);
5413returnfalse;
5414}
5415
5416bool AMDGPUAsmParser::ParseDirectiveAMDGCNTarget() {
5417if (getSTI().getTargetTriple().getArch() !=Triple::amdgcn)
5418return TokError("directive only supported for amdgcn architecture");
5419
5420 std::string TargetIDDirective;
5421SMLoc TargetStart = getTok().getLoc();
5422if (getParser().parseEscapedString(TargetIDDirective))
5423returntrue;
5424
5425SMRange TargetRange =SMRange(TargetStart, getTok().getLoc());
5426if (getTargetStreamer().getTargetID()->toString() != TargetIDDirective)
5427return getParser().Error(TargetRange.Start,
5428 (Twine(".amdgcn_target directive's target id ") +
5429Twine(TargetIDDirective) +
5430Twine(" does not match the specified target id ") +
5431Twine(getTargetStreamer().getTargetID()->toString())).str());
5432
5433returnfalse;
5434}
5435
5436bool AMDGPUAsmParser::OutOfRangeError(SMRangeRange) {
5437returnError(Range.Start,"value out of range",Range);
5438}
5439
5440bool AMDGPUAsmParser::calculateGPRBlocks(
5441constFeatureBitset &Features,constMCExpr *VCCUsed,
5442constMCExpr *FlatScrUsed,bool XNACKUsed,
5443 std::optional<bool> EnableWavefrontSize32,constMCExpr *NextFreeVGPR,
5444SMRange VGPRRange,constMCExpr *NextFreeSGPR,SMRange SGPRRange,
5445constMCExpr *&VGPRBlocks,constMCExpr *&SGPRBlocks) {
5446// TODO(scott.linder): These calculations are duplicated from
5447// AMDGPUAsmPrinter::getSIProgramInfo and could be unified.
5448IsaVersionVersion =getIsaVersion(getSTI().getCPU());
5449MCContext &Ctx = getContext();
5450
5451constMCExpr *NumSGPRs = NextFreeSGPR;
5452 int64_t EvaluatedSGPRs;
5453
5454if (Version.Major >= 10)
5455NumSGPRs =MCConstantExpr::create(0, Ctx);
5456else {
5457unsigned MaxAddressableNumSGPRs =
5458IsaInfo::getAddressableNumSGPRs(&getSTI());
5459
5460if (NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&Version.Major >= 8 &&
5461 !Features.test(FeatureSGPRInitBug) &&
5462static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5463return OutOfRangeError(SGPRRange);
5464
5465constMCExpr *ExtraSGPRs =
5466AMDGPUMCExpr::createExtraSGPRs(VCCUsed, FlatScrUsed, XNACKUsed, Ctx);
5467NumSGPRs =MCBinaryExpr::createAdd(NumSGPRs, ExtraSGPRs, Ctx);
5468
5469if (NumSGPRs->evaluateAsAbsolute(EvaluatedSGPRs) &&
5470 (Version.Major <= 7 || Features.test(FeatureSGPRInitBug)) &&
5471static_cast<uint64_t>(EvaluatedSGPRs) > MaxAddressableNumSGPRs)
5472return OutOfRangeError(SGPRRange);
5473
5474if (Features.test(FeatureSGPRInitBug))
5475NumSGPRs =
5476MCConstantExpr::create(IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG, Ctx);
5477 }
5478
5479// The MCExpr equivalent of getNumSGPRBlocks/getNumVGPRBlocks:
5480// (alignTo(max(1u, NumGPR), GPREncodingGranule) / GPREncodingGranule) - 1
5481auto GetNumGPRBlocks = [&Ctx](constMCExpr *NumGPR,
5482unsigned Granule) ->constMCExpr * {
5483constMCExpr *OneConst =MCConstantExpr::create(1ul, Ctx);
5484constMCExpr *GranuleConst =MCConstantExpr::create(Granule, Ctx);
5485constMCExpr *MaxNumGPR =AMDGPUMCExpr::createMax({NumGPR, OneConst}, Ctx);
5486constMCExpr *AlignToGPR =
5487AMDGPUMCExpr::createAlignTo(MaxNumGPR, GranuleConst, Ctx);
5488constMCExpr *DivGPR =
5489MCBinaryExpr::createDiv(AlignToGPR, GranuleConst, Ctx);
5490constMCExpr *SubGPR =MCBinaryExpr::createSub(DivGPR, OneConst, Ctx);
5491return SubGPR;
5492 };
5493
5494 VGPRBlocks = GetNumGPRBlocks(
5495 NextFreeVGPR,
5496IsaInfo::getVGPREncodingGranule(&getSTI(), EnableWavefrontSize32));
5497 SGPRBlocks =
5498 GetNumGPRBlocks(NumSGPRs,IsaInfo::getSGPREncodingGranule(&getSTI()));
5499
5500returnfalse;
5501}
5502
5503bool AMDGPUAsmParser::ParseDirectiveAMDHSAKernel() {
5504if (getSTI().getTargetTriple().getArch() !=Triple::amdgcn)
5505return TokError("directive only supported for amdgcn architecture");
5506
5507if (!isHsaAbi(getSTI()))
5508return TokError("directive only supported for amdhsa OS");
5509
5510StringRef KernelName;
5511if (getParser().parseIdentifier(KernelName))
5512returntrue;
5513
5514AMDGPU::MCKernelDescriptor KD =
5515AMDGPU::MCKernelDescriptor::getDefaultAmdhsaKernelDescriptor(
5516 &getSTI(), getContext());
5517
5518StringSet<> Seen;
5519
5520IsaVersion IVersion =getIsaVersion(getSTI().getCPU());
5521
5522constMCExpr *ZeroExpr =MCConstantExpr::create(0, getContext());
5523constMCExpr *OneExpr =MCConstantExpr::create(1, getContext());
5524
5525SMRange VGPRRange;
5526constMCExpr *NextFreeVGPR = ZeroExpr;
5527constMCExpr *AccumOffset =MCConstantExpr::create(0, getContext());
5528uint64_t SharedVGPRCount = 0;
5529uint64_t PreloadLength = 0;
5530uint64_t PreloadOffset = 0;
5531SMRange SGPRRange;
5532constMCExpr *NextFreeSGPR = ZeroExpr;
5533
5534// Count the number of user SGPRs implied from the enabled feature bits.
5535unsigned ImpliedUserSGPRCount = 0;
5536
5537// Track if the asm explicitly contains the directive for the user SGPR
5538// count.
5539 std::optional<unsigned> ExplicitUserSGPRCount;
5540constMCExpr *ReserveVCC = OneExpr;
5541constMCExpr *ReserveFlatScr = OneExpr;
5542 std::optional<bool> EnableWavefrontSize32;
5543
5544while (true) {
5545while (trySkipToken(AsmToken::EndOfStatement));
5546
5547StringRefID;
5548SMRange IDRange = getTok().getLocRange();
5549if (!parseId(ID,"expected .amdhsa_ directive or .end_amdhsa_kernel"))
5550returntrue;
5551
5552if (ID ==".end_amdhsa_kernel")
5553break;
5554
5555if (!Seen.insert(ID).second)
5556return TokError(".amdhsa_ directives cannot be repeated");
5557
5558SMLoc ValStart = getLoc();
5559constMCExpr *ExprVal;
5560if (getParser().parseExpression(ExprVal))
5561returntrue;
5562SMLoc ValEnd = getLoc();
5563SMRange ValRange =SMRange(ValStart, ValEnd);
5564
5565 int64_t IVal = 0;
5566uint64_t Val = IVal;
5567bool EvaluatableExpr;
5568if ((EvaluatableExpr = ExprVal->evaluateAsAbsolute(IVal))) {
5569if (IVal < 0)
5570return OutOfRangeError(ValRange);
5571 Val = IVal;
5572 }
5573
5574#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE) \
5575 if (!isUInt<ENTRY##_WIDTH>(Val)) \
5576 return OutOfRangeError(RANGE); \
5577 AMDGPU::MCKernelDescriptor::bits_set(FIELD, VALUE, ENTRY##_SHIFT, ENTRY, \
5578 getContext());
5579
5580// Some fields use the parsed value immediately which requires the expression to
5581// be solvable.
5582#define EXPR_RESOLVE_OR_ERROR(RESOLVED) \
5583 if (!(RESOLVED)) \
5584 return Error(IDRange.Start, "directive should have resolvable expression", \
5585 IDRange);
5586
5587if (ID ==".amdhsa_group_segment_fixed_size") {
5588if (!isUInt<sizeof(kernel_descriptor_t::group_segment_fixed_size) *
5589 CHAR_BIT>(Val))
5590return OutOfRangeError(ValRange);
5591 KD.group_segment_fixed_size = ExprVal;
5592 }elseif (ID ==".amdhsa_private_segment_fixed_size") {
5593if (!isUInt<sizeof(kernel_descriptor_t::private_segment_fixed_size) *
5594 CHAR_BIT>(Val))
5595return OutOfRangeError(ValRange);
5596 KD.private_segment_fixed_size = ExprVal;
5597 }elseif (ID ==".amdhsa_kernarg_size") {
5598if (!isUInt<sizeof(kernel_descriptor_t::kernarg_size) * CHAR_BIT>(Val))
5599return OutOfRangeError(ValRange);
5600 KD.kernarg_size = ExprVal;
5601 }elseif (ID ==".amdhsa_user_sgpr_count") {
5602EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5603 ExplicitUserSGPRCount = Val;
5604 }elseif (ID ==".amdhsa_user_sgpr_private_segment_buffer") {
5605EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5606if (hasArchitectedFlatScratch())
5607returnError(IDRange.Start,
5608"directive is not supported with architected flat scratch",
5609 IDRange);
5610PARSE_BITS_ENTRY(KD.kernel_code_properties,
5611 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_BUFFER,
5612 ExprVal, ValRange);
5613if (Val)
5614 ImpliedUserSGPRCount += 4;
5615 }elseif (ID ==".amdhsa_user_sgpr_kernarg_preload_length") {
5616EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5617if (!hasKernargPreload())
5618returnError(IDRange.Start,"directive requires gfx90a+", IDRange);
5619
5620if (Val >getMaxNumUserSGPRs())
5621return OutOfRangeError(ValRange);
5622PARSE_BITS_ENTRY(KD.kernarg_preload, KERNARG_PRELOAD_SPEC_LENGTH, ExprVal,
5623 ValRange);
5624if (Val) {
5625 ImpliedUserSGPRCount += Val;
5626 PreloadLength = Val;
5627 }
5628 }elseif (ID ==".amdhsa_user_sgpr_kernarg_preload_offset") {
5629EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5630if (!hasKernargPreload())
5631returnError(IDRange.Start,"directive requires gfx90a+", IDRange);
5632
5633if (Val >= 1024)
5634return OutOfRangeError(ValRange);
5635PARSE_BITS_ENTRY(KD.kernarg_preload, KERNARG_PRELOAD_SPEC_OFFSET, ExprVal,
5636 ValRange);
5637if (Val)
5638 PreloadOffset = Val;
5639 }elseif (ID ==".amdhsa_user_sgpr_dispatch_ptr") {
5640EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5641PARSE_BITS_ENTRY(KD.kernel_code_properties,
5642 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_PTR, ExprVal,
5643 ValRange);
5644if (Val)
5645 ImpliedUserSGPRCount += 2;
5646 }elseif (ID ==".amdhsa_user_sgpr_queue_ptr") {
5647EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5648PARSE_BITS_ENTRY(KD.kernel_code_properties,
5649 KERNEL_CODE_PROPERTY_ENABLE_SGPR_QUEUE_PTR, ExprVal,
5650 ValRange);
5651if (Val)
5652 ImpliedUserSGPRCount += 2;
5653 }elseif (ID ==".amdhsa_user_sgpr_kernarg_segment_ptr") {
5654EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5655PARSE_BITS_ENTRY(KD.kernel_code_properties,
5656 KERNEL_CODE_PROPERTY_ENABLE_SGPR_KERNARG_SEGMENT_PTR,
5657 ExprVal, ValRange);
5658if (Val)
5659 ImpliedUserSGPRCount += 2;
5660 }elseif (ID ==".amdhsa_user_sgpr_dispatch_id") {
5661EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5662PARSE_BITS_ENTRY(KD.kernel_code_properties,
5663 KERNEL_CODE_PROPERTY_ENABLE_SGPR_DISPATCH_ID, ExprVal,
5664 ValRange);
5665if (Val)
5666 ImpliedUserSGPRCount += 2;
5667 }elseif (ID ==".amdhsa_user_sgpr_flat_scratch_init") {
5668if (hasArchitectedFlatScratch())
5669returnError(IDRange.Start,
5670"directive is not supported with architected flat scratch",
5671 IDRange);
5672EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5673PARSE_BITS_ENTRY(KD.kernel_code_properties,
5674 KERNEL_CODE_PROPERTY_ENABLE_SGPR_FLAT_SCRATCH_INIT,
5675 ExprVal, ValRange);
5676if (Val)
5677 ImpliedUserSGPRCount += 2;
5678 }elseif (ID ==".amdhsa_user_sgpr_private_segment_size") {
5679EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5680PARSE_BITS_ENTRY(KD.kernel_code_properties,
5681 KERNEL_CODE_PROPERTY_ENABLE_SGPR_PRIVATE_SEGMENT_SIZE,
5682 ExprVal, ValRange);
5683if (Val)
5684 ImpliedUserSGPRCount += 1;
5685 }elseif (ID ==".amdhsa_wavefront_size32") {
5686EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5687if (IVersion.Major < 10)
5688returnError(IDRange.Start,"directive requires gfx10+", IDRange);
5689 EnableWavefrontSize32 = Val;
5690PARSE_BITS_ENTRY(KD.kernel_code_properties,
5691 KERNEL_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32, ExprVal,
5692 ValRange);
5693 }elseif (ID ==".amdhsa_uses_dynamic_stack") {
5694PARSE_BITS_ENTRY(KD.kernel_code_properties,
5695 KERNEL_CODE_PROPERTY_USES_DYNAMIC_STACK, ExprVal,
5696 ValRange);
5697 }elseif (ID ==".amdhsa_system_sgpr_private_segment_wavefront_offset") {
5698if (hasArchitectedFlatScratch())
5699returnError(IDRange.Start,
5700"directive is not supported with architected flat scratch",
5701 IDRange);
5702PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5703 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5704 ValRange);
5705 }elseif (ID ==".amdhsa_enable_private_segment") {
5706if (!hasArchitectedFlatScratch())
5707returnError(
5708 IDRange.Start,
5709"directive is not supported without architected flat scratch",
5710 IDRange);
5711PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5712 COMPUTE_PGM_RSRC2_ENABLE_PRIVATE_SEGMENT, ExprVal,
5713 ValRange);
5714 }elseif (ID ==".amdhsa_system_sgpr_workgroup_id_x") {
5715PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5716 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_X, ExprVal,
5717 ValRange);
5718 }elseif (ID ==".amdhsa_system_sgpr_workgroup_id_y") {
5719PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5720 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Y, ExprVal,
5721 ValRange);
5722 }elseif (ID ==".amdhsa_system_sgpr_workgroup_id_z") {
5723PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5724 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_ID_Z, ExprVal,
5725 ValRange);
5726 }elseif (ID ==".amdhsa_system_sgpr_workgroup_info") {
5727PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5728 COMPUTE_PGM_RSRC2_ENABLE_SGPR_WORKGROUP_INFO, ExprVal,
5729 ValRange);
5730 }elseif (ID ==".amdhsa_system_vgpr_workitem_id") {
5731PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5732 COMPUTE_PGM_RSRC2_ENABLE_VGPR_WORKITEM_ID, ExprVal,
5733 ValRange);
5734 }elseif (ID ==".amdhsa_next_free_vgpr") {
5735 VGPRRange = ValRange;
5736 NextFreeVGPR = ExprVal;
5737 }elseif (ID ==".amdhsa_next_free_sgpr") {
5738 SGPRRange = ValRange;
5739 NextFreeSGPR = ExprVal;
5740 }elseif (ID ==".amdhsa_accum_offset") {
5741if (!isGFX90A())
5742returnError(IDRange.Start,"directive requires gfx90a+", IDRange);
5743 AccumOffset = ExprVal;
5744 }elseif (ID ==".amdhsa_reserve_vcc") {
5745if (EvaluatableExpr && !isUInt<1>(Val))
5746return OutOfRangeError(ValRange);
5747 ReserveVCC = ExprVal;
5748 }elseif (ID ==".amdhsa_reserve_flat_scratch") {
5749if (IVersion.Major < 7)
5750returnError(IDRange.Start,"directive requires gfx7+", IDRange);
5751if (hasArchitectedFlatScratch())
5752returnError(IDRange.Start,
5753"directive is not supported with architected flat scratch",
5754 IDRange);
5755if (EvaluatableExpr && !isUInt<1>(Val))
5756return OutOfRangeError(ValRange);
5757 ReserveFlatScr = ExprVal;
5758 }elseif (ID ==".amdhsa_reserve_xnack_mask") {
5759if (IVersion.Major < 8)
5760returnError(IDRange.Start,"directive requires gfx8+", IDRange);
5761if (!isUInt<1>(Val))
5762return OutOfRangeError(ValRange);
5763if (Val != getTargetStreamer().getTargetID()->isXnackOnOrAny())
5764return getParser().Error(IDRange.Start,".amdhsa_reserve_xnack_mask does not match target id",
5765 IDRange);
5766 }elseif (ID ==".amdhsa_float_round_mode_32") {
5767PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5768 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_32, ExprVal,
5769 ValRange);
5770 }elseif (ID ==".amdhsa_float_round_mode_16_64") {
5771PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5772 COMPUTE_PGM_RSRC1_FLOAT_ROUND_MODE_16_64, ExprVal,
5773 ValRange);
5774 }elseif (ID ==".amdhsa_float_denorm_mode_32") {
5775PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5776 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_32, ExprVal,
5777 ValRange);
5778 }elseif (ID ==".amdhsa_float_denorm_mode_16_64") {
5779PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5780 COMPUTE_PGM_RSRC1_FLOAT_DENORM_MODE_16_64, ExprVal,
5781 ValRange);
5782 }elseif (ID ==".amdhsa_dx10_clamp") {
5783if (IVersion.Major >= 12)
5784returnError(IDRange.Start,"directive unsupported on gfx12+", IDRange);
5785PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5786 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_DX10_CLAMP, ExprVal,
5787 ValRange);
5788 }elseif (ID ==".amdhsa_ieee_mode") {
5789if (IVersion.Major >= 12)
5790returnError(IDRange.Start,"directive unsupported on gfx12+", IDRange);
5791PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5792 COMPUTE_PGM_RSRC1_GFX6_GFX11_ENABLE_IEEE_MODE, ExprVal,
5793 ValRange);
5794 }elseif (ID ==".amdhsa_fp16_overflow") {
5795if (IVersion.Major < 9)
5796returnError(IDRange.Start,"directive requires gfx9+", IDRange);
5797PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5798 COMPUTE_PGM_RSRC1_GFX9_PLUS_FP16_OVFL, ExprVal,
5799 ValRange);
5800 }elseif (ID ==".amdhsa_tg_split") {
5801if (!isGFX90A())
5802returnError(IDRange.Start,"directive requires gfx90a+", IDRange);
5803PARSE_BITS_ENTRY(KD.compute_pgm_rsrc3, COMPUTE_PGM_RSRC3_GFX90A_TG_SPLIT,
5804 ExprVal, ValRange);
5805 }elseif (ID ==".amdhsa_workgroup_processor_mode") {
5806if (IVersion.Major < 10)
5807returnError(IDRange.Start,"directive requires gfx10+", IDRange);
5808PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5809 COMPUTE_PGM_RSRC1_GFX10_PLUS_WGP_MODE, ExprVal,
5810 ValRange);
5811 }elseif (ID ==".amdhsa_memory_ordered") {
5812if (IVersion.Major < 10)
5813returnError(IDRange.Start,"directive requires gfx10+", IDRange);
5814PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5815 COMPUTE_PGM_RSRC1_GFX10_PLUS_MEM_ORDERED, ExprVal,
5816 ValRange);
5817 }elseif (ID ==".amdhsa_forward_progress") {
5818if (IVersion.Major < 10)
5819returnError(IDRange.Start,"directive requires gfx10+", IDRange);
5820PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5821 COMPUTE_PGM_RSRC1_GFX10_PLUS_FWD_PROGRESS, ExprVal,
5822 ValRange);
5823 }elseif (ID ==".amdhsa_shared_vgpr_count") {
5824EXPR_RESOLVE_OR_ERROR(EvaluatableExpr);
5825if (IVersion.Major < 10 || IVersion.Major >= 12)
5826returnError(IDRange.Start,"directive requires gfx10 or gfx11",
5827 IDRange);
5828 SharedVGPRCount = Val;
5829PARSE_BITS_ENTRY(KD.compute_pgm_rsrc3,
5830 COMPUTE_PGM_RSRC3_GFX10_GFX11_SHARED_VGPR_COUNT, ExprVal,
5831 ValRange);
5832 }elseif (ID ==".amdhsa_exception_fp_ieee_invalid_op") {
5833PARSE_BITS_ENTRY(
5834 KD.compute_pgm_rsrc2,
5835 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INVALID_OPERATION,
5836 ExprVal, ValRange);
5837 }elseif (ID ==".amdhsa_exception_fp_denorm_src") {
5838PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5839 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_FP_DENORMAL_SOURCE,
5840 ExprVal, ValRange);
5841 }elseif (ID ==".amdhsa_exception_fp_ieee_div_zero") {
5842PARSE_BITS_ENTRY(
5843 KD.compute_pgm_rsrc2,
5844 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_DIVISION_BY_ZERO,
5845 ExprVal, ValRange);
5846 }elseif (ID ==".amdhsa_exception_fp_ieee_overflow") {
5847PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5848 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_OVERFLOW,
5849 ExprVal, ValRange);
5850 }elseif (ID ==".amdhsa_exception_fp_ieee_underflow") {
5851PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5852 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_UNDERFLOW,
5853 ExprVal, ValRange);
5854 }elseif (ID ==".amdhsa_exception_fp_ieee_inexact") {
5855PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5856 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_IEEE_754_FP_INEXACT,
5857 ExprVal, ValRange);
5858 }elseif (ID ==".amdhsa_exception_int_div_zero") {
5859PARSE_BITS_ENTRY(KD.compute_pgm_rsrc2,
5860 COMPUTE_PGM_RSRC2_ENABLE_EXCEPTION_INT_DIVIDE_BY_ZERO,
5861 ExprVal, ValRange);
5862 }elseif (ID ==".amdhsa_round_robin_scheduling") {
5863if (IVersion.Major < 12)
5864returnError(IDRange.Start,"directive requires gfx12+", IDRange);
5865PARSE_BITS_ENTRY(KD.compute_pgm_rsrc1,
5866 COMPUTE_PGM_RSRC1_GFX12_PLUS_ENABLE_WG_RR_EN, ExprVal,
5867 ValRange);
5868 }else {
5869returnError(IDRange.Start,"unknown .amdhsa_kernel directive", IDRange);
5870 }
5871
5872#undef PARSE_BITS_ENTRY
5873 }
5874
5875if (!Seen.contains(".amdhsa_next_free_vgpr"))
5876return TokError(".amdhsa_next_free_vgpr directive is required");
5877
5878if (!Seen.contains(".amdhsa_next_free_sgpr"))
5879return TokError(".amdhsa_next_free_sgpr directive is required");
5880
5881unsigned UserSGPRCount = ExplicitUserSGPRCount.value_or(ImpliedUserSGPRCount);
5882
5883// Consider the case where the total number of UserSGPRs with trailing
5884// allocated preload SGPRs, is greater than the number of explicitly
5885// referenced SGPRs.
5886if (PreloadLength) {
5887MCContext &Ctx = getContext();
5888 NextFreeSGPR =AMDGPUMCExpr::createMax(
5889 {NextFreeSGPR,MCConstantExpr::create(UserSGPRCount, Ctx)}, Ctx);
5890 }
5891
5892constMCExpr *VGPRBlocks;
5893constMCExpr *SGPRBlocks;
5894if (calculateGPRBlocks(getFeatureBits(), ReserveVCC, ReserveFlatScr,
5895 getTargetStreamer().getTargetID()->isXnackOnOrAny(),
5896 EnableWavefrontSize32, NextFreeVGPR,
5897 VGPRRange, NextFreeSGPR, SGPRRange, VGPRBlocks,
5898 SGPRBlocks))
5899returntrue;
5900
5901 int64_t EvaluatedVGPRBlocks;
5902bool VGPRBlocksEvaluatable =
5903 VGPRBlocks->evaluateAsAbsolute(EvaluatedVGPRBlocks);
5904if (VGPRBlocksEvaluatable &&
5905 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_WIDTH>(
5906static_cast<uint64_t>(EvaluatedVGPRBlocks))) {
5907return OutOfRangeError(VGPRRange);
5908 }
5909AMDGPU::MCKernelDescriptor::bits_set(
5910 KD.compute_pgm_rsrc1, VGPRBlocks,
5911 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT_SHIFT,
5912 COMPUTE_PGM_RSRC1_GRANULATED_WORKITEM_VGPR_COUNT, getContext());
5913
5914 int64_t EvaluatedSGPRBlocks;
5915if (SGPRBlocks->evaluateAsAbsolute(EvaluatedSGPRBlocks) &&
5916 !isUInt<COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_WIDTH>(
5917static_cast<uint64_t>(EvaluatedSGPRBlocks)))
5918return OutOfRangeError(SGPRRange);
5919AMDGPU::MCKernelDescriptor::bits_set(
5920 KD.compute_pgm_rsrc1, SGPRBlocks,
5921 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT_SHIFT,
5922 COMPUTE_PGM_RSRC1_GRANULATED_WAVEFRONT_SGPR_COUNT, getContext());
5923
5924if (ExplicitUserSGPRCount && ImpliedUserSGPRCount > *ExplicitUserSGPRCount)
5925return TokError("amdgpu_user_sgpr_count smaller than than implied by "
5926"enabled user SGPRs");
5927
5928if (!isUInt<COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_WIDTH>(UserSGPRCount))
5929return TokError("too many user SGPRs enabled");
5930AMDGPU::MCKernelDescriptor::bits_set(
5931 KD.compute_pgm_rsrc2,MCConstantExpr::create(UserSGPRCount, getContext()),
5932 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT_SHIFT,
5933 COMPUTE_PGM_RSRC2_USER_SGPR_COUNT, getContext());
5934
5935 int64_t IVal = 0;
5936if (!KD.kernarg_size->evaluateAsAbsolute(IVal))
5937return TokError("Kernarg size should be resolvable");
5938uint64_t kernarg_size = IVal;
5939if (PreloadLength && kernarg_size &&
5940 (PreloadLength * 4 + PreloadOffset * 4 > kernarg_size))
5941return TokError("Kernarg preload length + offset is larger than the "
5942"kernarg segment size");
5943
5944if (isGFX90A()) {
5945if (!Seen.contains(".amdhsa_accum_offset"))
5946return TokError(".amdhsa_accum_offset directive is required");
5947 int64_t EvaluatedAccum;
5948bool AccumEvaluatable = AccumOffset->evaluateAsAbsolute(EvaluatedAccum);
5949uint64_t UEvaluatedAccum = EvaluatedAccum;
5950if (AccumEvaluatable &&
5951 (UEvaluatedAccum < 4 || UEvaluatedAccum > 256 || (UEvaluatedAccum & 3)))
5952return TokError("accum_offset should be in range [4..256] in "
5953"increments of 4");
5954
5955 int64_t EvaluatedNumVGPR;
5956if (NextFreeVGPR->evaluateAsAbsolute(EvaluatedNumVGPR) &&
5957 AccumEvaluatable &&
5958 UEvaluatedAccum >
5959alignTo(std::max((uint64_t)1, (uint64_t)EvaluatedNumVGPR), 4))
5960return TokError("accum_offset exceeds total VGPR allocation");
5961constMCExpr *AdjustedAccum =MCBinaryExpr::createSub(
5962MCBinaryExpr::createDiv(
5963 AccumOffset,MCConstantExpr::create(4, getContext()), getContext()),
5964MCConstantExpr::create(1, getContext()), getContext());
5965MCKernelDescriptor::bits_set(KD.compute_pgm_rsrc3, AdjustedAccum,
5966 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET_SHIFT,
5967 COMPUTE_PGM_RSRC3_GFX90A_ACCUM_OFFSET,
5968 getContext());
5969 }
5970
5971if (IVersion.Major >= 10 && IVersion.Major < 12) {
5972// SharedVGPRCount < 16 checked by PARSE_ENTRY_BITS
5973if (SharedVGPRCount && EnableWavefrontSize32 && *EnableWavefrontSize32) {
5974return TokError("shared_vgpr_count directive not valid on "
5975"wavefront size 32");
5976 }
5977
5978if (VGPRBlocksEvaluatable &&
5979 (SharedVGPRCount * 2 +static_cast<uint64_t>(EvaluatedVGPRBlocks) >
5980 63)) {
5981return TokError("shared_vgpr_count*2 + "
5982"compute_pgm_rsrc1.GRANULATED_WORKITEM_VGPR_COUNT cannot "
5983"exceed 63\n");
5984 }
5985 }
5986
5987 getTargetStreamer().EmitAmdhsaKernelDescriptor(getSTI(), KernelName, KD,
5988 NextFreeVGPR, NextFreeSGPR,
5989 ReserveVCC, ReserveFlatScr);
5990returnfalse;
5991}
5992
5993bool AMDGPUAsmParser::ParseDirectiveAMDHSACodeObjectVersion() {
5994uint32_tVersion;
5995if (ParseAsAbsoluteExpression(Version))
5996returntrue;
5997
5998 getTargetStreamer().EmitDirectiveAMDHSACodeObjectVersion(Version);
5999returnfalse;
6000}
6001
6002bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(StringRefID,
6003AMDGPUMCKernelCodeT &C) {
6004// max_scratch_backing_memory_byte_size is deprecated. Ignore it while parsing
6005// assembly for backwards compatibility.
6006if (ID =="max_scratch_backing_memory_byte_size") {
6007 Parser.eatToEndOfStatement();
6008returnfalse;
6009 }
6010
6011SmallString<40> ErrStr;
6012raw_svector_ostream Err(ErrStr);
6013if (!C.ParseKernelCodeT(ID, getParser(), Err)) {
6014return TokError(Err.str());
6015 }
6016 Lex();
6017
6018if (ID =="enable_wavefront_size32") {
6019if (C.code_properties &AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32) {
6020if (!isGFX10Plus())
6021return TokError("enable_wavefront_size32=1 is only allowed on GFX10+");
6022if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6023return TokError("enable_wavefront_size32=1 requires +WavefrontSize32");
6024 }else {
6025if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6026return TokError("enable_wavefront_size32=0 requires +WavefrontSize64");
6027 }
6028 }
6029
6030if (ID =="wavefront_size") {
6031if (C.wavefront_size == 5) {
6032if (!isGFX10Plus())
6033return TokError("wavefront_size=5 is only allowed on GFX10+");
6034if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize32])
6035return TokError("wavefront_size=5 requires +WavefrontSize32");
6036 }elseif (C.wavefront_size == 6) {
6037if (!getFeatureBits()[AMDGPU::FeatureWavefrontSize64])
6038return TokError("wavefront_size=6 requires +WavefrontSize64");
6039 }
6040 }
6041
6042returnfalse;
6043}
6044
6045bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
6046AMDGPUMCKernelCodeT KernelCode;
6047 KernelCode.initDefault(&getSTI(), getContext());
6048
6049while (true) {
6050// Lex EndOfStatement. This is in a while loop, because lexing a comment
6051// will set the current token to EndOfStatement.
6052while(trySkipToken(AsmToken::EndOfStatement));
6053
6054StringRefID;
6055if (!parseId(ID,"expected value identifier or .end_amd_kernel_code_t"))
6056returntrue;
6057
6058if (ID ==".end_amd_kernel_code_t")
6059break;
6060
6061if (ParseAMDKernelCodeTValue(ID, KernelCode))
6062returntrue;
6063 }
6064
6065 KernelCode.validate(&getSTI(), getContext());
6066 getTargetStreamer().EmitAMDKernelCodeT(KernelCode);
6067
6068returnfalse;
6069}
6070
6071bool AMDGPUAsmParser::ParseDirectiveAMDGPUHsaKernel() {
6072StringRef KernelName;
6073if (!parseId(KernelName,"expected symbol name"))
6074returntrue;
6075
6076 getTargetStreamer().EmitAMDGPUSymbolType(KernelName,
6077ELF::STT_AMDGPU_HSA_KERNEL);
6078
6079 KernelScope.initialize(getContext());
6080returnfalse;
6081}
6082
6083bool AMDGPUAsmParser::ParseDirectiveISAVersion() {
6084if (getSTI().getTargetTriple().getArch() !=Triple::amdgcn) {
6085returnError(getLoc(),
6086".amd_amdgpu_isa directive is not available on non-amdgcn "
6087"architectures");
6088 }
6089
6090auto TargetIDDirective = getLexer().getTok().getStringContents();
6091if (getTargetStreamer().getTargetID()->toString() != TargetIDDirective)
6092returnError(getParser().getTok().getLoc(),"target id must match options");
6093
6094 getTargetStreamer().EmitISAVersion();
6095 Lex();
6096
6097returnfalse;
6098}
6099
6100bool AMDGPUAsmParser::ParseDirectiveHSAMetadata() {
6101assert(isHsaAbi(getSTI()));
6102
6103 std::string HSAMetadataString;
6104if (ParseToEndDirective(HSAMD::V3::AssemblerDirectiveBegin,
6105HSAMD::V3::AssemblerDirectiveEnd, HSAMetadataString))
6106returntrue;
6107
6108if (!getTargetStreamer().EmitHSAMetadataV3(HSAMetadataString))
6109returnError(getLoc(),"invalid HSA metadata");
6110
6111returnfalse;
6112}
6113
6114/// Common code to parse out a block of text (typically YAML) between start and
6115/// end directives.
6116bool AMDGPUAsmParser::ParseToEndDirective(constchar *AssemblerDirectiveBegin,
6117constchar *AssemblerDirectiveEnd,
6118 std::string &CollectString) {
6119
6120raw_string_ostream CollectStream(CollectString);
6121
6122 getLexer().setSkipSpace(false);
6123
6124bool FoundEnd =false;
6125while (!isToken(AsmToken::Eof)) {
6126while (isToken(AsmToken::Space)) {
6127 CollectStream << getTokenStr();
6128 Lex();
6129 }
6130
6131if (trySkipId(AssemblerDirectiveEnd)) {
6132 FoundEnd =true;
6133break;
6134 }
6135
6136 CollectStream << Parser.parseStringToEndOfStatement()
6137 << getContext().getAsmInfo()->getSeparatorString();
6138
6139 Parser.eatToEndOfStatement();
6140 }
6141
6142 getLexer().setSkipSpace(true);
6143
6144if (isToken(AsmToken::Eof) && !FoundEnd) {
6145return TokError(Twine("expected directive ") +
6146Twine(AssemblerDirectiveEnd) +Twine(" not found"));
6147 }
6148
6149returnfalse;
6150}
6151
6152/// Parse the assembler directive for new MsgPack-format PAL metadata.
6153bool AMDGPUAsmParser::ParseDirectivePALMetadataBegin() {
6154 std::stringString;
6155if (ParseToEndDirective(AMDGPU::PALMD::AssemblerDirectiveBegin,
6156AMDGPU::PALMD::AssemblerDirectiveEnd,String))
6157returntrue;
6158
6159auto *PALMetadata = getTargetStreamer().getPALMetadata();
6160if (!PALMetadata->setFromString(String))
6161returnError(getLoc(),"invalid PAL metadata");
6162returnfalse;
6163}
6164
6165/// Parse the assembler directive for old linear-format PAL metadata.
6166bool AMDGPUAsmParser::ParseDirectivePALMetadata() {
6167if (getSTI().getTargetTriple().getOS() !=Triple::AMDPAL) {
6168returnError(getLoc(),
6169 (Twine(PALMD::AssemblerDirective) +Twine(" directive is "
6170"not available on non-amdpal OSes")).str());
6171 }
6172
6173auto *PALMetadata = getTargetStreamer().getPALMetadata();
6174 PALMetadata->setLegacy();
6175for (;;) {
6176uint32_tKey,Value;
6177if (ParseAsAbsoluteExpression(Key)) {
6178return TokError(Twine("invalid value in ") +
6179Twine(PALMD::AssemblerDirective));
6180 }
6181if (!trySkipToken(AsmToken::Comma)) {
6182return TokError(Twine("expected an even number of values in ") +
6183Twine(PALMD::AssemblerDirective));
6184 }
6185if (ParseAsAbsoluteExpression(Value)) {
6186return TokError(Twine("invalid value in ") +
6187Twine(PALMD::AssemblerDirective));
6188 }
6189 PALMetadata->setRegister(Key,Value);
6190if (!trySkipToken(AsmToken::Comma))
6191break;
6192 }
6193returnfalse;
6194}
6195
6196/// ParseDirectiveAMDGPULDS
6197/// ::= .amdgpu_lds identifier ',' size_expression [',' align_expression]
6198bool AMDGPUAsmParser::ParseDirectiveAMDGPULDS() {
6199if (getParser().checkForValidSection())
6200returntrue;
6201
6202StringRefName;
6203SMLoc NameLoc = getLoc();
6204if (getParser().parseIdentifier(Name))
6205return TokError("expected identifier in directive");
6206
6207MCSymbol *Symbol = getContext().getOrCreateSymbol(Name);
6208if (getParser().parseComma())
6209returntrue;
6210
6211unsigned LocalMemorySize =AMDGPU::IsaInfo::getLocalMemorySize(&getSTI());
6212
6213 int64_tSize;
6214SMLoc SizeLoc = getLoc();
6215if (getParser().parseAbsoluteExpression(Size))
6216returntrue;
6217if (Size < 0)
6218returnError(SizeLoc,"size must be non-negative");
6219if (Size > LocalMemorySize)
6220returnError(SizeLoc,"size is too large");
6221
6222 int64_t Alignment = 4;
6223if (trySkipToken(AsmToken::Comma)) {
6224SMLoc AlignLoc = getLoc();
6225if (getParser().parseAbsoluteExpression(Alignment))
6226returntrue;
6227if (Alignment < 0 || !isPowerOf2_64(Alignment))
6228returnError(AlignLoc,"alignment must be a power of two");
6229
6230// Alignment larger than the size of LDS is possible in theory, as long
6231// as the linker manages to place to symbol at address 0, but we do want
6232// to make sure the alignment fits nicely into a 32-bit integer.
6233if (Alignment >= 1u << 31)
6234returnError(AlignLoc,"alignment is too large");
6235 }
6236
6237if (parseEOL())
6238returntrue;
6239
6240Symbol->redefineIfPossible();
6241if (!Symbol->isUndefined())
6242returnError(NameLoc,"invalid symbol redefinition");
6243
6244 getTargetStreamer().emitAMDGPULDS(Symbol,Size,Align(Alignment));
6245returnfalse;
6246}
6247
6248bool AMDGPUAsmParser::ParseDirective(AsmToken DirectiveID) {
6249StringRef IDVal = DirectiveID.getString();
6250
6251if (isHsaAbi(getSTI())) {
6252if (IDVal ==".amdhsa_kernel")
6253return ParseDirectiveAMDHSAKernel();
6254
6255if (IDVal ==".amdhsa_code_object_version")
6256return ParseDirectiveAMDHSACodeObjectVersion();
6257
6258// TODO: Restructure/combine with PAL metadata directive.
6259if (IDVal ==AMDGPU::HSAMD::V3::AssemblerDirectiveBegin)
6260return ParseDirectiveHSAMetadata();
6261 }else {
6262if (IDVal ==".amd_kernel_code_t")
6263return ParseDirectiveAMDKernelCodeT();
6264
6265if (IDVal ==".amdgpu_hsa_kernel")
6266return ParseDirectiveAMDGPUHsaKernel();
6267
6268if (IDVal ==".amd_amdgpu_isa")
6269return ParseDirectiveISAVersion();
6270
6271if (IDVal ==AMDGPU::HSAMD::AssemblerDirectiveBegin) {
6272returnError(getLoc(), (Twine(HSAMD::AssemblerDirectiveBegin) +
6273Twine(" directive is "
6274"not available on non-amdhsa OSes"))
6275 .str());
6276 }
6277 }
6278
6279if (IDVal ==".amdgcn_target")
6280return ParseDirectiveAMDGCNTarget();
6281
6282if (IDVal ==".amdgpu_lds")
6283return ParseDirectiveAMDGPULDS();
6284
6285if (IDVal ==PALMD::AssemblerDirectiveBegin)
6286return ParseDirectivePALMetadataBegin();
6287
6288if (IDVal ==PALMD::AssemblerDirective)
6289return ParseDirectivePALMetadata();
6290
6291returntrue;
6292}
6293
6294bool AMDGPUAsmParser::subtargetHasRegister(constMCRegisterInfo &MRI,
6295MCRegister Reg) {
6296if (MRI.regsOverlap(TTMP12_TTMP13_TTMP14_TTMP15, Reg))
6297returnisGFX9Plus();
6298
6299// GFX10+ has 2 more SGPRs 104 and 105.
6300if (MRI.regsOverlap(SGPR104_SGPR105, Reg))
6301return hasSGPR104_SGPR105();
6302
6303switch (Reg.id()) {
6304case SRC_SHARED_BASE_LO:
6305case SRC_SHARED_BASE:
6306case SRC_SHARED_LIMIT_LO:
6307case SRC_SHARED_LIMIT:
6308case SRC_PRIVATE_BASE_LO:
6309case SRC_PRIVATE_BASE:
6310case SRC_PRIVATE_LIMIT_LO:
6311case SRC_PRIVATE_LIMIT:
6312returnisGFX9Plus();
6313case SRC_POPS_EXITING_WAVE_ID:
6314returnisGFX9Plus() && !isGFX11Plus();
6315case TBA:
6316case TBA_LO:
6317case TBA_HI:
6318case TMA:
6319case TMA_LO:
6320case TMA_HI:
6321return !isGFX9Plus();
6322case XNACK_MASK:
6323case XNACK_MASK_LO:
6324case XNACK_MASK_HI:
6325return (isVI() ||isGFX9()) && getTargetStreamer().getTargetID()->isXnackSupported();
6326case SGPR_NULL:
6327returnisGFX10Plus();
6328case SRC_EXECZ:
6329case SRC_VCCZ:
6330return !isGFX11Plus();
6331default:
6332break;
6333 }
6334
6335if (isCI())
6336returntrue;
6337
6338if (isSI() ||isGFX10Plus()) {
6339// No flat_scr on SI.
6340// On GFX10Plus flat scratch is not a valid register operand and can only be
6341// accessed with s_setreg/s_getreg.
6342switch (Reg.id()) {
6343case FLAT_SCR:
6344case FLAT_SCR_LO:
6345case FLAT_SCR_HI:
6346returnfalse;
6347default:
6348returntrue;
6349 }
6350 }
6351
6352// VI only has 102 SGPRs, so make sure we aren't trying to use the 2 more that
6353// SI/CI have.
6354if (MRI.regsOverlap(SGPR102_SGPR103, Reg))
6355return hasSGPR102_SGPR103();
6356
6357returntrue;
6358}
6359
6360ParseStatus AMDGPUAsmParser::parseOperand(OperandVector &Operands,
6361StringRef Mnemonic,
6362 OperandMode Mode) {
6363ParseStatus Res = parseVOPD(Operands);
6364if (Res.isSuccess() || Res.isFailure() || isToken(AsmToken::EndOfStatement))
6365return Res;
6366
6367// Try to parse with a custom parser
6368 Res = MatchOperandParserImpl(Operands, Mnemonic);
6369
6370// If we successfully parsed the operand or if there as an error parsing,
6371// we are done.
6372//
6373// If we are parsing after we reach EndOfStatement then this means we
6374// are appending default values to the Operands list. This is only done
6375// by custom parser, so we shouldn't continue on to the generic parsing.
6376if (Res.isSuccess() || Res.isFailure() || isToken(AsmToken::EndOfStatement))
6377return Res;
6378
6379SMLoc RBraceLoc;
6380SMLoc LBraceLoc = getLoc();
6381if (Mode == OperandMode_NSA && trySkipToken(AsmToken::LBrac)) {
6382unsignedPrefix =Operands.size();
6383
6384for (;;) {
6385auto Loc = getLoc();
6386 Res = parseReg(Operands);
6387if (Res.isNoMatch())
6388Error(Loc,"expected a register");
6389if (!Res.isSuccess())
6390returnParseStatus::Failure;
6391
6392 RBraceLoc = getLoc();
6393if (trySkipToken(AsmToken::RBrac))
6394break;
6395
6396if (!skipToken(AsmToken::Comma,
6397"expected a comma or a closing square bracket"))
6398returnParseStatus::Failure;
6399 }
6400
6401if (Operands.size() - Prefix > 1) {
6402Operands.insert(Operands.begin() + Prefix,
6403 AMDGPUOperand::CreateToken(this,"[", LBraceLoc));
6404Operands.push_back(AMDGPUOperand::CreateToken(this,"]", RBraceLoc));
6405 }
6406
6407returnParseStatus::Success;
6408 }
6409
6410return parseRegOrImm(Operands);
6411}
6412
6413StringRef AMDGPUAsmParser::parseMnemonicSuffix(StringRefName) {
6414// Clear any forced encodings from the previous instruction.
6415 setForcedEncodingSize(0);
6416 setForcedDPP(false);
6417 setForcedSDWA(false);
6418
6419if (Name.ends_with("_e64_dpp")) {
6420 setForcedDPP(true);
6421 setForcedEncodingSize(64);
6422returnName.substr(0,Name.size() - 8);
6423 }
6424if (Name.ends_with("_e64")) {
6425 setForcedEncodingSize(64);
6426returnName.substr(0,Name.size() - 4);
6427 }
6428if (Name.ends_with("_e32")) {
6429 setForcedEncodingSize(32);
6430returnName.substr(0,Name.size() - 4);
6431 }
6432if (Name.ends_with("_dpp")) {
6433 setForcedDPP(true);
6434returnName.substr(0,Name.size() - 4);
6435 }
6436if (Name.ends_with("_sdwa")) {
6437 setForcedSDWA(true);
6438returnName.substr(0,Name.size() - 5);
6439 }
6440returnName;
6441}
6442
6443staticvoidapplyMnemonicAliases(StringRef &Mnemonic,
6444constFeatureBitset &Features,
6445unsigned VariantID);
6446
6447bool AMDGPUAsmParser::parseInstruction(ParseInstructionInfo &Info,
6448StringRefName,SMLoc NameLoc,
6449OperandVector &Operands) {
6450// Add the instruction mnemonic
6451Name = parseMnemonicSuffix(Name);
6452
6453// If the target architecture uses MnemonicAlias, call it here to parse
6454// operands correctly.
6455applyMnemonicAliases(Name, getAvailableFeatures(), 0);
6456
6457Operands.push_back(AMDGPUOperand::CreateToken(this,Name, NameLoc));
6458
6459bool IsMIMG =Name.starts_with("image_");
6460
6461while (!trySkipToken(AsmToken::EndOfStatement)) {
6462 OperandMode Mode = OperandMode_Default;
6463if (IsMIMG &&isGFX10Plus() &&Operands.size() == 2)
6464 Mode = OperandMode_NSA;
6465ParseStatus Res = parseOperand(Operands,Name, Mode);
6466
6467if (!Res.isSuccess()) {
6468 checkUnsupportedInstruction(Name, NameLoc);
6469if (!Parser.hasPendingError()) {
6470// FIXME: use real operand location rather than the current location.
6471StringRef Msg = Res.isFailure() ?"failed parsing operand."
6472 :"not a valid operand.";
6473Error(getLoc(), Msg);
6474 }
6475while (!trySkipToken(AsmToken::EndOfStatement)) {
6476 lex();
6477 }
6478returntrue;
6479 }
6480
6481// Eat the comma or space if there is one.
6482 trySkipToken(AsmToken::Comma);
6483 }
6484
6485returnfalse;
6486}
6487
6488//===----------------------------------------------------------------------===//
6489// Utility functions
6490//===----------------------------------------------------------------------===//
6491
6492ParseStatus AMDGPUAsmParser::parseTokenOp(StringRefName,
6493OperandVector &Operands) {
6494SMLoc S = getLoc();
6495if (!trySkipId(Name))
6496returnParseStatus::NoMatch;
6497
6498Operands.push_back(AMDGPUOperand::CreateToken(this,Name, S));
6499returnParseStatus::Success;
6500}
6501
6502ParseStatus AMDGPUAsmParser::parseIntWithPrefix(constchar *Prefix,
6503 int64_t &IntVal) {
6504
6505if (!trySkipId(Prefix,AsmToken::Colon))
6506returnParseStatus::NoMatch;
6507
6508returnparseExpr(IntVal) ?ParseStatus::Success :ParseStatus::Failure;
6509}
6510
6511ParseStatus AMDGPUAsmParser::parseIntWithPrefix(
6512constchar *Prefix,OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6513 std::function<bool(int64_t &)> ConvertResult) {
6514SMLoc S = getLoc();
6515 int64_tValue = 0;
6516
6517ParseStatus Res = parseIntWithPrefix(Prefix,Value);
6518if (!Res.isSuccess())
6519return Res;
6520
6521if (ConvertResult && !ConvertResult(Value)) {
6522Error(S,"invalid " +StringRef(Prefix) +" value.");
6523 }
6524
6525Operands.push_back(AMDGPUOperand::CreateImm(this,Value, S, ImmTy));
6526returnParseStatus::Success;
6527}
6528
6529ParseStatus AMDGPUAsmParser::parseOperandArrayWithPrefix(
6530constchar *Prefix,OperandVector &Operands, AMDGPUOperand::ImmTy ImmTy,
6531bool (*ConvertResult)(int64_t &)) {
6532SMLoc S = getLoc();
6533if (!trySkipId(Prefix,AsmToken::Colon))
6534returnParseStatus::NoMatch;
6535
6536if (!skipToken(AsmToken::LBrac,"expected a left square bracket"))
6537returnParseStatus::Failure;
6538
6539unsigned Val = 0;
6540constunsigned MaxSize = 4;
6541
6542// FIXME: How to verify the number of elements matches the number of src
6543// operands?
6544for (intI = 0; ; ++I) {
6545 int64_tOp;
6546SMLoc Loc = getLoc();
6547if (!parseExpr(Op))
6548returnParseStatus::Failure;
6549
6550if (Op != 0 &&Op != 1)
6551returnError(Loc,"invalid " +StringRef(Prefix) +" value.");
6552
6553 Val |= (Op <<I);
6554
6555if (trySkipToken(AsmToken::RBrac))
6556break;
6557
6558if (I + 1 == MaxSize)
6559returnError(getLoc(),"expected a closing square bracket");
6560
6561if (!skipToken(AsmToken::Comma,"expected a comma"))
6562returnParseStatus::Failure;
6563 }
6564
6565Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S, ImmTy));
6566returnParseStatus::Success;
6567}
6568
6569ParseStatus AMDGPUAsmParser::parseNamedBit(StringRefName,
6570OperandVector &Operands,
6571 AMDGPUOperand::ImmTy ImmTy) {
6572 int64_tBit;
6573SMLoc S = getLoc();
6574
6575if (trySkipId(Name)) {
6576Bit = 1;
6577 }elseif (trySkipId("no",Name)) {
6578Bit = 0;
6579 }else {
6580returnParseStatus::NoMatch;
6581 }
6582
6583if (Name =="r128" && !hasMIMG_R128())
6584returnError(S,"r128 modifier is not supported on this GPU");
6585if (Name =="a16" && !hasA16())
6586returnError(S,"a16 modifier is not supported on this GPU");
6587
6588if (isGFX9() && ImmTy == AMDGPUOperand::ImmTyA16)
6589 ImmTy = AMDGPUOperand::ImmTyR128A16;
6590
6591Operands.push_back(AMDGPUOperand::CreateImm(this, Bit, S, ImmTy));
6592returnParseStatus::Success;
6593}
6594
6595unsigned AMDGPUAsmParser::getCPolKind(StringRef Id,StringRef Mnemo,
6596bool &Disabling) const{
6597 Disabling =Id.consume_front("no");
6598
6599if (isGFX940() && !Mnemo.starts_with("s_")) {
6600returnStringSwitch<unsigned>(Id)
6601 .Case("nt",AMDGPU::CPol::NT)
6602 .Case("sc0",AMDGPU::CPol::SC0)
6603 .Case("sc1",AMDGPU::CPol::SC1)
6604 .Default(0);
6605 }
6606
6607returnStringSwitch<unsigned>(Id)
6608 .Case("dlc",AMDGPU::CPol::DLC)
6609 .Case("glc",AMDGPU::CPol::GLC)
6610 .Case("scc",AMDGPU::CPol::SCC)
6611 .Case("slc",AMDGPU::CPol::SLC)
6612 .Default(0);
6613}
6614
6615ParseStatus AMDGPUAsmParser::parseCPol(OperandVector &Operands) {
6616if (isGFX12Plus()) {
6617SMLoc StringLoc = getLoc();
6618
6619 int64_t CPolVal = 0;
6620ParseStatus ResTH =ParseStatus::NoMatch;
6621ParseStatus ResScope =ParseStatus::NoMatch;
6622
6623for (;;) {
6624if (ResTH.isNoMatch()) {
6625 int64_tTH;
6626 ResTH = parseTH(Operands, TH);
6627if (ResTH.isFailure())
6628return ResTH;
6629if (ResTH.isSuccess()) {
6630 CPolVal |=TH;
6631continue;
6632 }
6633 }
6634
6635if (ResScope.isNoMatch()) {
6636 int64_tScope;
6637 ResScope = parseScope(Operands, Scope);
6638if (ResScope.isFailure())
6639return ResScope;
6640if (ResScope.isSuccess()) {
6641 CPolVal |=Scope;
6642continue;
6643 }
6644 }
6645
6646break;
6647 }
6648
6649if (ResTH.isNoMatch() && ResScope.isNoMatch())
6650returnParseStatus::NoMatch;
6651
6652Operands.push_back(AMDGPUOperand::CreateImm(this, CPolVal, StringLoc,
6653 AMDGPUOperand::ImmTyCPol));
6654returnParseStatus::Success;
6655 }
6656
6657StringRef Mnemo = ((AMDGPUOperand &)*Operands[0]).getToken();
6658SMLoc OpLoc = getLoc();
6659unsignedEnabled = 0, Seen = 0;
6660for (;;) {
6661SMLoc S = getLoc();
6662bool Disabling;
6663unsignedCPol = getCPolKind(getId(), Mnemo, Disabling);
6664if (!CPol)
6665break;
6666
6667 lex();
6668
6669if (!isGFX10Plus() && CPol ==AMDGPU::CPol::DLC)
6670returnError(S,"dlc modifier is not supported on this GPU");
6671
6672if (!isGFX90A() && CPol ==AMDGPU::CPol::SCC)
6673returnError(S,"scc modifier is not supported on this GPU");
6674
6675if (Seen & CPol)
6676returnError(S,"duplicate cache policy modifier");
6677
6678if (!Disabling)
6679Enabled |=CPol;
6680
6681 Seen |=CPol;
6682 }
6683
6684if (!Seen)
6685returnParseStatus::NoMatch;
6686
6687Operands.push_back(
6688 AMDGPUOperand::CreateImm(this,Enabled, OpLoc, AMDGPUOperand::ImmTyCPol));
6689returnParseStatus::Success;
6690}
6691
6692ParseStatus AMDGPUAsmParser::parseScope(OperandVector &Operands,
6693 int64_t &Scope) {
6694staticconstunsignedScopes[] = {CPol::SCOPE_CU,CPol::SCOPE_SE,
6695CPol::SCOPE_DEV,CPol::SCOPE_SYS};
6696
6697ParseStatus Res = parseStringOrIntWithPrefix(
6698Operands,"scope", {"SCOPE_CU","SCOPE_SE","SCOPE_DEV","SCOPE_SYS"},
6699Scope);
6700
6701if (Res.isSuccess())
6702Scope =Scopes[Scope];
6703
6704return Res;
6705}
6706
6707ParseStatus AMDGPUAsmParser::parseTH(OperandVector &Operands, int64_t &TH) {
6708TH =AMDGPU::CPol::TH_RT;// default
6709
6710StringRefValue;
6711SMLoc StringLoc;
6712ParseStatus Res = parseStringWithPrefix("th",Value, StringLoc);
6713if (!Res.isSuccess())
6714return Res;
6715
6716if (Value =="TH_DEFAULT")
6717TH =AMDGPU::CPol::TH_RT;
6718elseif (Value =="TH_STORE_LU" ||Value =="TH_LOAD_RT_WB" ||
6719Value =="TH_LOAD_NT_WB") {
6720returnError(StringLoc,"invalid th value");
6721 }elseif (Value.consume_front("TH_ATOMIC_")) {
6722TH =AMDGPU::CPol::TH_TYPE_ATOMIC;
6723 }elseif (Value.consume_front("TH_LOAD_")) {
6724TH =AMDGPU::CPol::TH_TYPE_LOAD;
6725 }elseif (Value.consume_front("TH_STORE_")) {
6726TH =AMDGPU::CPol::TH_TYPE_STORE;
6727 }else {
6728returnError(StringLoc,"invalid th value");
6729 }
6730
6731if (Value =="BYPASS")
6732TH |=AMDGPU::CPol::TH_REAL_BYPASS;
6733
6734if (TH != 0) {
6735if (TH &AMDGPU::CPol::TH_TYPE_ATOMIC)
6736TH |=StringSwitch<int64_t>(Value)
6737 .Case("RETURN",AMDGPU::CPol::TH_ATOMIC_RETURN)
6738 .Case("RT",AMDGPU::CPol::TH_RT)
6739 .Case("RT_RETURN",AMDGPU::CPol::TH_ATOMIC_RETURN)
6740 .Case("NT",AMDGPU::CPol::TH_ATOMIC_NT)
6741 .Case("NT_RETURN",AMDGPU::CPol::TH_ATOMIC_NT |
6742AMDGPU::CPol::TH_ATOMIC_RETURN)
6743 .Case("CASCADE_RT",AMDGPU::CPol::TH_ATOMIC_CASCADE)
6744 .Case("CASCADE_NT",AMDGPU::CPol::TH_ATOMIC_CASCADE |
6745AMDGPU::CPol::TH_ATOMIC_NT)
6746 .Default(0xffffffff);
6747else
6748TH |=StringSwitch<int64_t>(Value)
6749 .Case("RT",AMDGPU::CPol::TH_RT)
6750 .Case("NT",AMDGPU::CPol::TH_NT)
6751 .Case("HT",AMDGPU::CPol::TH_HT)
6752 .Case("LU",AMDGPU::CPol::TH_LU)
6753 .Case("RT_WB",AMDGPU::CPol::TH_RT_WB)
6754 .Case("NT_RT",AMDGPU::CPol::TH_NT_RT)
6755 .Case("RT_NT",AMDGPU::CPol::TH_RT_NT)
6756 .Case("NT_HT",AMDGPU::CPol::TH_NT_HT)
6757 .Case("NT_WB",AMDGPU::CPol::TH_NT_WB)
6758 .Case("BYPASS",AMDGPU::CPol::TH_BYPASS)
6759 .Default(0xffffffff);
6760 }
6761
6762if (TH == 0xffffffff)
6763returnError(StringLoc,"invalid th value");
6764
6765returnParseStatus::Success;
6766}
6767
6768staticvoidaddOptionalImmOperand(
6769MCInst& Inst,constOperandVector&Operands,
6770 AMDGPUAsmParser::OptionalImmIndexMap& OptionalIdx,
6771 AMDGPUOperand::ImmTy ImmT,
6772 int64_tDefault = 0) {
6773auto i = OptionalIdx.find(ImmT);
6774if (i != OptionalIdx.end()) {
6775unsignedIdx = i->second;
6776 ((AMDGPUOperand &)*Operands[Idx]).addImmOperands(Inst, 1);
6777 }else {
6778 Inst.addOperand(MCOperand::createImm(Default));
6779 }
6780}
6781
6782ParseStatus AMDGPUAsmParser::parseStringWithPrefix(StringRef Prefix,
6783StringRef &Value,
6784SMLoc &StringLoc) {
6785if (!trySkipId(Prefix,AsmToken::Colon))
6786returnParseStatus::NoMatch;
6787
6788 StringLoc = getLoc();
6789return parseId(Value,"expected an identifier") ?ParseStatus::Success
6790 :ParseStatus::Failure;
6791}
6792
6793ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
6794OperandVector &Operands,StringRefName,ArrayRef<const char *> Ids,
6795 int64_t &IntVal) {
6796if (!trySkipId(Name,AsmToken::Colon))
6797returnParseStatus::NoMatch;
6798
6799SMLoc StringLoc = getLoc();
6800
6801StringRefValue;
6802if (isToken(AsmToken::Identifier)) {
6803Value = getTokenStr();
6804 lex();
6805
6806for (IntVal = 0;IntVal < (int64_t)Ids.size(); ++IntVal)
6807if (Value == Ids[IntVal])
6808break;
6809 }elseif (!parseExpr(IntVal))
6810returnParseStatus::Failure;
6811
6812if (IntVal < 0 || IntVal >= (int64_t)Ids.size())
6813returnError(StringLoc,"invalid " +Twine(Name) +" value");
6814
6815returnParseStatus::Success;
6816}
6817
6818ParseStatus AMDGPUAsmParser::parseStringOrIntWithPrefix(
6819OperandVector &Operands,StringRefName,ArrayRef<const char *> Ids,
6820 AMDGPUOperand::ImmTyType) {
6821SMLoc S = getLoc();
6822 int64_tIntVal;
6823
6824ParseStatus Res = parseStringOrIntWithPrefix(Operands,Name, Ids, IntVal);
6825if (Res.isSuccess())
6826Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S,Type));
6827
6828return Res;
6829}
6830
6831//===----------------------------------------------------------------------===//
6832// MTBUF format
6833//===----------------------------------------------------------------------===//
6834
6835bool AMDGPUAsmParser::tryParseFmt(constchar *Pref,
6836 int64_t MaxVal,
6837 int64_t &Fmt) {
6838 int64_t Val;
6839SMLoc Loc = getLoc();
6840
6841auto Res = parseIntWithPrefix(Pref, Val);
6842if (Res.isFailure())
6843returnfalse;
6844if (Res.isNoMatch())
6845returntrue;
6846
6847if (Val < 0 || Val > MaxVal) {
6848Error(Loc,Twine("out of range ",StringRef(Pref)));
6849returnfalse;
6850 }
6851
6852 Fmt = Val;
6853returntrue;
6854}
6855
6856ParseStatus AMDGPUAsmParser::tryParseIndexKey(OperandVector &Operands,
6857 AMDGPUOperand::ImmTy ImmTy) {
6858constchar *Pref ="index_key";
6859 int64_t ImmVal = 0;
6860SMLoc Loc = getLoc();
6861auto Res = parseIntWithPrefix(Pref, ImmVal);
6862if (!Res.isSuccess())
6863return Res;
6864
6865if (ImmTy == AMDGPUOperand::ImmTyIndexKey16bit && (ImmVal < 0 || ImmVal > 1))
6866returnError(Loc,Twine("out of range ",StringRef(Pref)));
6867
6868if (ImmTy == AMDGPUOperand::ImmTyIndexKey8bit && (ImmVal < 0 || ImmVal > 3))
6869returnError(Loc,Twine("out of range ",StringRef(Pref)));
6870
6871Operands.push_back(AMDGPUOperand::CreateImm(this, ImmVal, Loc, ImmTy));
6872returnParseStatus::Success;
6873}
6874
6875ParseStatus AMDGPUAsmParser::parseIndexKey8bit(OperandVector &Operands) {
6876return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey8bit);
6877}
6878
6879ParseStatus AMDGPUAsmParser::parseIndexKey16bit(OperandVector &Operands) {
6880return tryParseIndexKey(Operands, AMDGPUOperand::ImmTyIndexKey16bit);
6881}
6882
6883// dfmt and nfmt (in a tbuffer instruction) are parsed as one to allow their
6884// values to live in a joint format operand in the MCInst encoding.
6885ParseStatus AMDGPUAsmParser::parseDfmtNfmt(int64_t &Format) {
6886using namespacellvm::AMDGPU::MTBUFFormat;
6887
6888 int64_t Dfmt =DFMT_UNDEF;
6889 int64_t Nfmt =NFMT_UNDEF;
6890
6891// dfmt and nfmt can appear in either order, and each is optional.
6892for (intI = 0;I < 2; ++I) {
6893if (Dfmt == DFMT_UNDEF && !tryParseFmt("dfmt", DFMT_MAX, Dfmt))
6894returnParseStatus::Failure;
6895
6896if (Nfmt == NFMT_UNDEF && !tryParseFmt("nfmt", NFMT_MAX, Nfmt))
6897returnParseStatus::Failure;
6898
6899// Skip optional comma between dfmt/nfmt
6900// but guard against 2 commas following each other.
6901if ((Dfmt == DFMT_UNDEF) != (Nfmt == NFMT_UNDEF) &&
6902 !peekToken().is(AsmToken::Comma)) {
6903 trySkipToken(AsmToken::Comma);
6904 }
6905 }
6906
6907if (Dfmt == DFMT_UNDEF && Nfmt == NFMT_UNDEF)
6908returnParseStatus::NoMatch;
6909
6910 Dfmt = (Dfmt ==DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6911 Nfmt = (Nfmt ==NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6912
6913Format =encodeDfmtNfmt(Dfmt, Nfmt);
6914returnParseStatus::Success;
6915}
6916
6917ParseStatus AMDGPUAsmParser::parseUfmt(int64_t &Format) {
6918using namespacellvm::AMDGPU::MTBUFFormat;
6919
6920 int64_t Fmt =UFMT_UNDEF;
6921
6922if (!tryParseFmt("format", UFMT_MAX, Fmt))
6923returnParseStatus::Failure;
6924
6925if (Fmt == UFMT_UNDEF)
6926returnParseStatus::NoMatch;
6927
6928Format = Fmt;
6929returnParseStatus::Success;
6930}
6931
6932bool AMDGPUAsmParser::matchDfmtNfmt(int64_t &Dfmt,
6933 int64_t &Nfmt,
6934StringRef FormatStr,
6935SMLoc Loc) {
6936using namespacellvm::AMDGPU::MTBUFFormat;
6937 int64_tFormat;
6938
6939Format =getDfmt(FormatStr);
6940if (Format != DFMT_UNDEF) {
6941 Dfmt =Format;
6942returntrue;
6943 }
6944
6945Format =getNfmt(FormatStr, getSTI());
6946if (Format != NFMT_UNDEF) {
6947 Nfmt =Format;
6948returntrue;
6949 }
6950
6951Error(Loc,"unsupported format");
6952returnfalse;
6953}
6954
6955ParseStatus AMDGPUAsmParser::parseSymbolicSplitFormat(StringRef FormatStr,
6956SMLoc FormatLoc,
6957 int64_t &Format) {
6958using namespacellvm::AMDGPU::MTBUFFormat;
6959
6960 int64_t Dfmt =DFMT_UNDEF;
6961 int64_t Nfmt =NFMT_UNDEF;
6962if (!matchDfmtNfmt(Dfmt, Nfmt, FormatStr, FormatLoc))
6963returnParseStatus::Failure;
6964
6965if (trySkipToken(AsmToken::Comma)) {
6966StringRef Str;
6967SMLoc Loc = getLoc();
6968if (!parseId(Str,"expected a format string") ||
6969 !matchDfmtNfmt(Dfmt, Nfmt, Str, Loc))
6970returnParseStatus::Failure;
6971if (Dfmt == DFMT_UNDEF)
6972returnError(Loc,"duplicate numeric format");
6973if (Nfmt == NFMT_UNDEF)
6974returnError(Loc,"duplicate data format");
6975 }
6976
6977 Dfmt = (Dfmt ==DFMT_UNDEF) ? DFMT_DEFAULT : Dfmt;
6978 Nfmt = (Nfmt ==NFMT_UNDEF) ? NFMT_DEFAULT : Nfmt;
6979
6980if (isGFX10Plus()) {
6981auto Ufmt =convertDfmtNfmt2Ufmt(Dfmt, Nfmt, getSTI());
6982if (Ufmt == UFMT_UNDEF)
6983returnError(FormatLoc,"unsupported format");
6984Format = Ufmt;
6985 }else {
6986Format =encodeDfmtNfmt(Dfmt, Nfmt);
6987 }
6988
6989returnParseStatus::Success;
6990}
6991
6992ParseStatus AMDGPUAsmParser::parseSymbolicUnifiedFormat(StringRef FormatStr,
6993SMLoc Loc,
6994 int64_t &Format) {
6995using namespacellvm::AMDGPU::MTBUFFormat;
6996
6997autoId =getUnifiedFormat(FormatStr, getSTI());
6998if (Id == UFMT_UNDEF)
6999returnParseStatus::NoMatch;
7000
7001if (!isGFX10Plus())
7002returnError(Loc,"unified format is not supported on this GPU");
7003
7004Format =Id;
7005returnParseStatus::Success;
7006}
7007
7008ParseStatus AMDGPUAsmParser::parseNumericFormat(int64_t &Format) {
7009using namespacellvm::AMDGPU::MTBUFFormat;
7010SMLoc Loc = getLoc();
7011
7012if (!parseExpr(Format))
7013returnParseStatus::Failure;
7014if (!isValidFormatEncoding(Format, getSTI()))
7015returnError(Loc,"out of range format");
7016
7017returnParseStatus::Success;
7018}
7019
7020ParseStatus AMDGPUAsmParser::parseSymbolicOrNumericFormat(int64_t &Format) {
7021using namespacellvm::AMDGPU::MTBUFFormat;
7022
7023if (!trySkipId("format",AsmToken::Colon))
7024returnParseStatus::NoMatch;
7025
7026if (trySkipToken(AsmToken::LBrac)) {
7027StringRef FormatStr;
7028SMLoc Loc = getLoc();
7029if (!parseId(FormatStr,"expected a format string"))
7030returnParseStatus::Failure;
7031
7032auto Res = parseSymbolicUnifiedFormat(FormatStr, Loc, Format);
7033if (Res.isNoMatch())
7034 Res = parseSymbolicSplitFormat(FormatStr, Loc, Format);
7035if (!Res.isSuccess())
7036return Res;
7037
7038if (!skipToken(AsmToken::RBrac,"expected a closing square bracket"))
7039returnParseStatus::Failure;
7040
7041returnParseStatus::Success;
7042 }
7043
7044return parseNumericFormat(Format);
7045}
7046
7047ParseStatus AMDGPUAsmParser::parseFORMAT(OperandVector &Operands) {
7048using namespacellvm::AMDGPU::MTBUFFormat;
7049
7050 int64_tFormat =getDefaultFormatEncoding(getSTI());
7051ParseStatus Res;
7052SMLoc Loc = getLoc();
7053
7054// Parse legacy format syntax.
7055 Res =isGFX10Plus() ? parseUfmt(Format) : parseDfmtNfmt(Format);
7056if (Res.isFailure())
7057return Res;
7058
7059bool FormatFound = Res.isSuccess();
7060
7061Operands.push_back(
7062 AMDGPUOperand::CreateImm(this, Format, Loc, AMDGPUOperand::ImmTyFORMAT));
7063
7064if (FormatFound)
7065 trySkipToken(AsmToken::Comma);
7066
7067if (isToken(AsmToken::EndOfStatement)) {
7068// We are expecting an soffset operand,
7069// but let matcher handle the error.
7070returnParseStatus::Success;
7071 }
7072
7073// Parse soffset.
7074 Res = parseRegOrImm(Operands);
7075if (!Res.isSuccess())
7076return Res;
7077
7078 trySkipToken(AsmToken::Comma);
7079
7080if (!FormatFound) {
7081 Res = parseSymbolicOrNumericFormat(Format);
7082if (Res.isFailure())
7083return Res;
7084if (Res.isSuccess()) {
7085autoSize =Operands.size();
7086 AMDGPUOperand &Op =static_cast<AMDGPUOperand &>(*Operands[Size - 2]);
7087assert(Op.isImm() &&Op.getImmTy() == AMDGPUOperand::ImmTyFORMAT);
7088Op.setImm(Format);
7089 }
7090returnParseStatus::Success;
7091 }
7092
7093if (isId("format") && peekToken().is(AsmToken::Colon))
7094returnError(getLoc(),"duplicate format");
7095returnParseStatus::Success;
7096}
7097
7098ParseStatus AMDGPUAsmParser::parseFlatOffset(OperandVector &Operands) {
7099ParseStatus Res =
7100 parseIntWithPrefix("offset",Operands, AMDGPUOperand::ImmTyOffset);
7101if (Res.isNoMatch()) {
7102 Res = parseIntWithPrefix("inst_offset",Operands,
7103 AMDGPUOperand::ImmTyInstOffset);
7104 }
7105return Res;
7106}
7107
7108ParseStatus AMDGPUAsmParser::parseR128A16(OperandVector &Operands) {
7109ParseStatus Res =
7110 parseNamedBit("r128",Operands, AMDGPUOperand::ImmTyR128A16);
7111if (Res.isNoMatch())
7112 Res = parseNamedBit("a16",Operands, AMDGPUOperand::ImmTyA16);
7113return Res;
7114}
7115
7116ParseStatus AMDGPUAsmParser::parseBLGP(OperandVector &Operands) {
7117ParseStatus Res =
7118 parseIntWithPrefix("blgp",Operands, AMDGPUOperand::ImmTyBLGP);
7119if (Res.isNoMatch()) {
7120 Res =
7121 parseOperandArrayWithPrefix("neg",Operands, AMDGPUOperand::ImmTyBLGP);
7122 }
7123return Res;
7124}
7125
7126//===----------------------------------------------------------------------===//
7127// Exp
7128//===----------------------------------------------------------------------===//
7129
7130void AMDGPUAsmParser::cvtExp(MCInst &Inst,constOperandVector &Operands) {
7131 OptionalImmIndexMap OptionalIdx;
7132
7133unsigned OperandIdx[4];
7134unsigned EnMask = 0;
7135int SrcIdx = 0;
7136
7137for (unsigned i = 1, e =Operands.size(); i != e; ++i) {
7138 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
7139
7140// Add the register arguments
7141if (Op.isReg()) {
7142assert(SrcIdx < 4);
7143 OperandIdx[SrcIdx] = Inst.size();
7144Op.addRegOperands(Inst, 1);
7145 ++SrcIdx;
7146continue;
7147 }
7148
7149if (Op.isOff()) {
7150assert(SrcIdx < 4);
7151 OperandIdx[SrcIdx] = Inst.size();
7152 Inst.addOperand(MCOperand::createReg(MCRegister()));
7153 ++SrcIdx;
7154continue;
7155 }
7156
7157if (Op.isImm() &&Op.getImmTy() == AMDGPUOperand::ImmTyExpTgt) {
7158Op.addImmOperands(Inst, 1);
7159continue;
7160 }
7161
7162if (Op.isToken() && (Op.getToken() =="done" ||Op.getToken() =="row_en"))
7163continue;
7164
7165// Handle optional arguments
7166 OptionalIdx[Op.getImmTy()] = i;
7167 }
7168
7169assert(SrcIdx == 4);
7170
7171bool Compr =false;
7172if (OptionalIdx.find(AMDGPUOperand::ImmTyExpCompr) != OptionalIdx.end()) {
7173 Compr =true;
7174 Inst.getOperand(OperandIdx[1]) = Inst.getOperand(OperandIdx[2]);
7175 Inst.getOperand(OperandIdx[2]).setReg(MCRegister());
7176 Inst.getOperand(OperandIdx[3]).setReg(MCRegister());
7177 }
7178
7179for (auto i = 0; i < SrcIdx; ++i) {
7180if (Inst.getOperand(OperandIdx[i]).getReg()) {
7181 EnMask |= Compr? (0x3 << i * 2) : (0x1 << i);
7182 }
7183 }
7184
7185addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyExpVM);
7186addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyExpCompr);
7187
7188 Inst.addOperand(MCOperand::createImm(EnMask));
7189}
7190
7191//===----------------------------------------------------------------------===//
7192// s_waitcnt
7193//===----------------------------------------------------------------------===//
7194
7195staticbool
7196encodeCnt(
7197constAMDGPU::IsaVersion ISA,
7198 int64_t &IntVal,
7199 int64_t CntVal,
7200bool Saturate,
7201unsigned (*encode)(constIsaVersion &Version,unsigned,unsigned),
7202unsigned (*decode)(constIsaVersion &Version,unsigned))
7203{
7204boolFailed =false;
7205
7206 IntVal =encode(ISA, IntVal, CntVal);
7207if (CntVal !=decode(ISA, IntVal)) {
7208if (Saturate) {
7209 IntVal =encode(ISA, IntVal, -1);
7210 }else {
7211Failed =true;
7212 }
7213 }
7214returnFailed;
7215}
7216
7217bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
7218
7219SMLoc CntLoc = getLoc();
7220StringRef CntName = getTokenStr();
7221
7222if (!skipToken(AsmToken::Identifier,"expected a counter name") ||
7223 !skipToken(AsmToken::LParen,"expected a left parenthesis"))
7224returnfalse;
7225
7226 int64_t CntVal;
7227SMLoc ValLoc = getLoc();
7228if (!parseExpr(CntVal))
7229returnfalse;
7230
7231AMDGPU::IsaVersionISA =AMDGPU::getIsaVersion(getSTI().getCPU());
7232
7233boolFailed =true;
7234bool Sat = CntName.ends_with("_sat");
7235
7236if (CntName =="vmcnt" || CntName =="vmcnt_sat") {
7237Failed =encodeCnt(ISA, IntVal, CntVal, Sat,encodeVmcnt,decodeVmcnt);
7238 }elseif (CntName =="expcnt" || CntName =="expcnt_sat") {
7239Failed =encodeCnt(ISA, IntVal, CntVal, Sat,encodeExpcnt,decodeExpcnt);
7240 }elseif (CntName =="lgkmcnt" || CntName =="lgkmcnt_sat") {
7241Failed =encodeCnt(ISA, IntVal, CntVal, Sat,encodeLgkmcnt,decodeLgkmcnt);
7242 }else {
7243Error(CntLoc,"invalid counter name " + CntName);
7244returnfalse;
7245 }
7246
7247if (Failed) {
7248Error(ValLoc,"too large value for " + CntName);
7249returnfalse;
7250 }
7251
7252if (!skipToken(AsmToken::RParen,"expected a closing parenthesis"))
7253returnfalse;
7254
7255if (trySkipToken(AsmToken::Amp) || trySkipToken(AsmToken::Comma)) {
7256if (isToken(AsmToken::EndOfStatement)) {
7257Error(getLoc(),"expected a counter name");
7258returnfalse;
7259 }
7260 }
7261
7262returntrue;
7263}
7264
7265ParseStatus AMDGPUAsmParser::parseSWaitCnt(OperandVector &Operands) {
7266AMDGPU::IsaVersionISA =AMDGPU::getIsaVersion(getSTI().getCPU());
7267 int64_tWaitcnt =getWaitcntBitMask(ISA);
7268SMLoc S = getLoc();
7269
7270if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
7271while (!isToken(AsmToken::EndOfStatement)) {
7272if (!parseCnt(Waitcnt))
7273returnParseStatus::Failure;
7274 }
7275 }else {
7276if (!parseExpr(Waitcnt))
7277returnParseStatus::Failure;
7278 }
7279
7280Operands.push_back(AMDGPUOperand::CreateImm(this,Waitcnt, S));
7281returnParseStatus::Success;
7282}
7283
7284bool AMDGPUAsmParser::parseDelay(int64_t &Delay) {
7285SMLoc FieldLoc = getLoc();
7286StringRef FieldName = getTokenStr();
7287if (!skipToken(AsmToken::Identifier,"expected a field name") ||
7288 !skipToken(AsmToken::LParen,"expected a left parenthesis"))
7289returnfalse;
7290
7291SMLoc ValueLoc = getLoc();
7292StringRefValueName = getTokenStr();
7293if (!skipToken(AsmToken::Identifier,"expected a value name") ||
7294 !skipToken(AsmToken::RParen,"expected a right parenthesis"))
7295returnfalse;
7296
7297unsigned Shift;
7298if (FieldName =="instid0") {
7299 Shift = 0;
7300 }elseif (FieldName =="instskip") {
7301 Shift = 4;
7302 }elseif (FieldName =="instid1") {
7303 Shift = 7;
7304 }else {
7305Error(FieldLoc,"invalid field name " + FieldName);
7306returnfalse;
7307 }
7308
7309intValue;
7310if (Shift == 4) {
7311// Parse values for instskip.
7312Value =StringSwitch<int>(ValueName)
7313 .Case("SAME", 0)
7314 .Case("NEXT", 1)
7315 .Case("SKIP_1", 2)
7316 .Case("SKIP_2", 3)
7317 .Case("SKIP_3", 4)
7318 .Case("SKIP_4", 5)
7319 .Default(-1);
7320 }else {
7321// Parse values for instid0 and instid1.
7322Value =StringSwitch<int>(ValueName)
7323 .Case("NO_DEP", 0)
7324 .Case("VALU_DEP_1", 1)
7325 .Case("VALU_DEP_2", 2)
7326 .Case("VALU_DEP_3", 3)
7327 .Case("VALU_DEP_4", 4)
7328 .Case("TRANS32_DEP_1", 5)
7329 .Case("TRANS32_DEP_2", 6)
7330 .Case("TRANS32_DEP_3", 7)
7331 .Case("FMA_ACCUM_CYCLE_1", 8)
7332 .Case("SALU_CYCLE_1", 9)
7333 .Case("SALU_CYCLE_2", 10)
7334 .Case("SALU_CYCLE_3", 11)
7335 .Default(-1);
7336 }
7337if (Value < 0) {
7338Error(ValueLoc,"invalid value name " +ValueName);
7339returnfalse;
7340 }
7341
7342 Delay |=Value << Shift;
7343returntrue;
7344}
7345
7346ParseStatus AMDGPUAsmParser::parseSDelayALU(OperandVector &Operands) {
7347 int64_t Delay = 0;
7348SMLoc S = getLoc();
7349
7350if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
7351do {
7352if (!parseDelay(Delay))
7353returnParseStatus::Failure;
7354 }while (trySkipToken(AsmToken::Pipe));
7355 }else {
7356if (!parseExpr(Delay))
7357returnParseStatus::Failure;
7358 }
7359
7360Operands.push_back(AMDGPUOperand::CreateImm(this, Delay, S));
7361returnParseStatus::Success;
7362}
7363
7364bool
7365AMDGPUOperand::isSWaitCnt() const{
7366returnisImm();
7367}
7368
7369bool AMDGPUOperand::isSDelayALU() const{returnisImm(); }
7370
7371//===----------------------------------------------------------------------===//
7372// DepCtr
7373//===----------------------------------------------------------------------===//
7374
7375void AMDGPUAsmParser::depCtrError(SMLoc Loc,int ErrorId,
7376StringRef DepCtrName) {
7377switch (ErrorId) {
7378caseOPR_ID_UNKNOWN:
7379Error(Loc,Twine("invalid counter name ", DepCtrName));
7380return;
7381caseOPR_ID_UNSUPPORTED:
7382Error(Loc,Twine(DepCtrName," is not supported on this GPU"));
7383return;
7384caseOPR_ID_DUPLICATE:
7385Error(Loc,Twine("duplicate counter name ", DepCtrName));
7386return;
7387caseOPR_VAL_INVALID:
7388Error(Loc,Twine("invalid value for ", DepCtrName));
7389return;
7390default:
7391assert(false);
7392 }
7393}
7394
7395bool AMDGPUAsmParser::parseDepCtr(int64_t &DepCtr,unsigned &UsedOprMask) {
7396
7397using namespacellvm::AMDGPU::DepCtr;
7398
7399SMLoc DepCtrLoc = getLoc();
7400StringRef DepCtrName = getTokenStr();
7401
7402if (!skipToken(AsmToken::Identifier,"expected a counter name") ||
7403 !skipToken(AsmToken::LParen,"expected a left parenthesis"))
7404returnfalse;
7405
7406 int64_t ExprVal;
7407if (!parseExpr(ExprVal))
7408returnfalse;
7409
7410unsigned PrevOprMask = UsedOprMask;
7411int CntVal =encodeDepCtr(DepCtrName, ExprVal, UsedOprMask, getSTI());
7412
7413if (CntVal < 0) {
7414 depCtrError(DepCtrLoc, CntVal, DepCtrName);
7415returnfalse;
7416 }
7417
7418if (!skipToken(AsmToken::RParen,"expected a closing parenthesis"))
7419returnfalse;
7420
7421if (trySkipToken(AsmToken::Amp) || trySkipToken(AsmToken::Comma)) {
7422if (isToken(AsmToken::EndOfStatement)) {
7423Error(getLoc(),"expected a counter name");
7424returnfalse;
7425 }
7426 }
7427
7428unsigned CntValMask = PrevOprMask ^ UsedOprMask;
7429 DepCtr = (DepCtr & ~CntValMask) | CntVal;
7430returntrue;
7431}
7432
7433ParseStatus AMDGPUAsmParser::parseDepCtr(OperandVector &Operands) {
7434using namespacellvm::AMDGPU::DepCtr;
7435
7436 int64_t DepCtr =getDefaultDepCtrEncoding(getSTI());
7437SMLoc Loc = getLoc();
7438
7439if (isToken(AsmToken::Identifier) && peekToken().is(AsmToken::LParen)) {
7440unsigned UsedOprMask = 0;
7441while (!isToken(AsmToken::EndOfStatement)) {
7442if (!parseDepCtr(DepCtr, UsedOprMask))
7443returnParseStatus::Failure;
7444 }
7445 }else {
7446if (!parseExpr(DepCtr))
7447returnParseStatus::Failure;
7448 }
7449
7450Operands.push_back(AMDGPUOperand::CreateImm(this, DepCtr, Loc));
7451returnParseStatus::Success;
7452}
7453
7454bool AMDGPUOperand::isDepCtr() const{return isS16Imm(); }
7455
7456//===----------------------------------------------------------------------===//
7457// hwreg
7458//===----------------------------------------------------------------------===//
7459
7460ParseStatus AMDGPUAsmParser::parseHwregFunc(OperandInfoTy &HwReg,
7461 OperandInfoTy &Offset,
7462 OperandInfoTy &Width) {
7463using namespacellvm::AMDGPU::Hwreg;
7464
7465if (!trySkipId("hwreg",AsmToken::LParen))
7466returnParseStatus::NoMatch;
7467
7468// The register may be specified by name or using a numeric code
7469 HwReg.Loc = getLoc();
7470if (isToken(AsmToken::Identifier) &&
7471 (HwReg.Val =getHwregId(getTokenStr(), getSTI())) !=OPR_ID_UNKNOWN) {
7472 HwReg.IsSymbolic =true;
7473 lex();// skip register name
7474 }elseif (!parseExpr(HwReg.Val,"a register name")) {
7475returnParseStatus::Failure;
7476 }
7477
7478if (trySkipToken(AsmToken::RParen))
7479returnParseStatus::Success;
7480
7481// parse optional params
7482if (!skipToken(AsmToken::Comma,"expected a comma or a closing parenthesis"))
7483returnParseStatus::Failure;
7484
7485Offset.Loc = getLoc();
7486if (!parseExpr(Offset.Val))
7487returnParseStatus::Failure;
7488
7489if (!skipToken(AsmToken::Comma,"expected a comma"))
7490returnParseStatus::Failure;
7491
7492 Width.Loc = getLoc();
7493if (!parseExpr(Width.Val) ||
7494 !skipToken(AsmToken::RParen,"expected a closing parenthesis"))
7495returnParseStatus::Failure;
7496
7497returnParseStatus::Success;
7498}
7499
7500ParseStatus AMDGPUAsmParser::parseHwreg(OperandVector &Operands) {
7501using namespacellvm::AMDGPU::Hwreg;
7502
7503 int64_t ImmVal = 0;
7504SMLoc Loc = getLoc();
7505
7506 StructuredOpField HwReg("id","hardware register", HwregId::Width,
7507 HwregId::Default);
7508 StructuredOpFieldOffset("offset","bit offset", HwregOffset::Width,
7509 HwregOffset::Default);
7510 struct : StructuredOpField {
7511usingStructuredOpField::StructuredOpField;
7512boolvalidate(AMDGPUAsmParser &Parser) const override{
7513if (!isUIntN(Width, Val - 1))
7514returnError(Parser,"only values from 1 to 32 are legal");
7515returntrue;
7516 }
7517 } Width("size","bitfield width", HwregSize::Width, HwregSize::Default);
7518ParseStatus Res = parseStructuredOpFields({&HwReg, &Offset, &Width});
7519
7520if (Res.isNoMatch())
7521 Res = parseHwregFunc(HwReg,Offset, Width);
7522
7523if (Res.isSuccess()) {
7524if (!validateStructuredOpFields({&HwReg, &Offset, &Width}))
7525returnParseStatus::Failure;
7526 ImmVal = HwregEncoding::encode(HwReg.Val,Offset.Val, Width.Val);
7527 }
7528
7529if (Res.isNoMatch() &&
7530parseExpr(ImmVal,"a hwreg macro, structured immediate"))
7531 Res =ParseStatus::Success;
7532
7533if (!Res.isSuccess())
7534returnParseStatus::Failure;
7535
7536if (!isUInt<16>(ImmVal))
7537returnError(Loc,"invalid immediate: only 16-bit values are legal");
7538Operands.push_back(
7539 AMDGPUOperand::CreateImm(this, ImmVal, Loc, AMDGPUOperand::ImmTyHwreg));
7540returnParseStatus::Success;
7541}
7542
7543bool AMDGPUOperand::isHwreg() const{
7544return isImmTy(ImmTyHwreg);
7545}
7546
7547//===----------------------------------------------------------------------===//
7548// sendmsg
7549//===----------------------------------------------------------------------===//
7550
7551bool
7552AMDGPUAsmParser::parseSendMsgBody(OperandInfoTy &Msg,
7553 OperandInfoTy &Op,
7554 OperandInfoTy &Stream) {
7555using namespacellvm::AMDGPU::SendMsg;
7556
7557 Msg.Loc = getLoc();
7558if (isToken(AsmToken::Identifier) &&
7559 (Msg.Val =getMsgId(getTokenStr(), getSTI())) !=OPR_ID_UNKNOWN) {
7560 Msg.IsSymbolic =true;
7561 lex();// skip message name
7562 }elseif (!parseExpr(Msg.Val,"a message name")) {
7563returnfalse;
7564 }
7565
7566if (trySkipToken(AsmToken::Comma)) {
7567Op.IsDefined =true;
7568Op.Loc = getLoc();
7569if (isToken(AsmToken::Identifier) &&
7570 (Op.Val =getMsgOpId(Msg.Val, getTokenStr(), getSTI())) !=
7571OPR_ID_UNKNOWN) {
7572 lex();// skip operation name
7573 }elseif (!parseExpr(Op.Val,"an operation name")) {
7574returnfalse;
7575 }
7576
7577if (trySkipToken(AsmToken::Comma)) {
7578 Stream.IsDefined =true;
7579 Stream.Loc = getLoc();
7580if (!parseExpr(Stream.Val))
7581returnfalse;
7582 }
7583 }
7584
7585return skipToken(AsmToken::RParen,"expected a closing parenthesis");
7586}
7587
7588bool
7589AMDGPUAsmParser::validateSendMsg(const OperandInfoTy &Msg,
7590const OperandInfoTy &Op,
7591const OperandInfoTy &Stream) {
7592using namespacellvm::AMDGPU::SendMsg;
7593
7594// Validation strictness depends on whether message is specified
7595// in a symbolic or in a numeric form. In the latter case
7596// only encoding possibility is checked.
7597boolStrict = Msg.IsSymbolic;
7598
7599if (Strict) {
7600if (Msg.Val ==OPR_ID_UNSUPPORTED) {
7601Error(Msg.Loc,"specified message id is not supported on this GPU");
7602returnfalse;
7603 }
7604 }else {
7605if (!isValidMsgId(Msg.Val, getSTI())) {
7606Error(Msg.Loc,"invalid message id");
7607returnfalse;
7608 }
7609 }
7610if (Strict && (msgRequiresOp(Msg.Val, getSTI()) !=Op.IsDefined)) {
7611if (Op.IsDefined) {
7612Error(Op.Loc,"message does not support operations");
7613 }else {
7614Error(Msg.Loc,"missing message operation");
7615 }
7616returnfalse;
7617 }
7618if (!isValidMsgOp(Msg.Val,Op.Val, getSTI(), Strict)) {
7619if (Op.Val ==OPR_ID_UNSUPPORTED)
7620Error(Op.Loc,"specified operation id is not supported on this GPU");
7621else
7622Error(Op.Loc,"invalid operation id");
7623returnfalse;
7624 }
7625if (Strict && !msgSupportsStream(Msg.Val,Op.Val, getSTI()) &&
7626 Stream.IsDefined) {
7627Error(Stream.Loc,"message operation does not support streams");
7628returnfalse;
7629 }
7630if (!isValidMsgStream(Msg.Val,Op.Val, Stream.Val, getSTI(), Strict)) {
7631Error(Stream.Loc,"invalid message stream id");
7632returnfalse;
7633 }
7634returntrue;
7635}
7636
7637ParseStatus AMDGPUAsmParser::parseSendMsg(OperandVector &Operands) {
7638using namespacellvm::AMDGPU::SendMsg;
7639
7640 int64_t ImmVal = 0;
7641SMLoc Loc = getLoc();
7642
7643if (trySkipId("sendmsg",AsmToken::LParen)) {
7644 OperandInfoTy Msg(OPR_ID_UNKNOWN);
7645 OperandInfoTyOp(OP_NONE_);
7646 OperandInfoTy Stream(STREAM_ID_NONE_);
7647if (parseSendMsgBody(Msg,Op, Stream) &&
7648 validateSendMsg(Msg,Op, Stream)) {
7649 ImmVal =encodeMsg(Msg.Val,Op.Val, Stream.Val);
7650 }else {
7651returnParseStatus::Failure;
7652 }
7653 }elseif (parseExpr(ImmVal,"a sendmsg macro")) {
7654if (ImmVal < 0 || !isUInt<16>(ImmVal))
7655returnError(Loc,"invalid immediate: only 16-bit values are legal");
7656 }else {
7657returnParseStatus::Failure;
7658 }
7659
7660Operands.push_back(AMDGPUOperand::CreateImm(this, ImmVal, Loc, AMDGPUOperand::ImmTySendMsg));
7661returnParseStatus::Success;
7662}
7663
7664bool AMDGPUOperand::isSendMsg() const{
7665return isImmTy(ImmTySendMsg);
7666}
7667
7668//===----------------------------------------------------------------------===//
7669// v_interp
7670//===----------------------------------------------------------------------===//
7671
7672ParseStatus AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) {
7673StringRef Str;
7674SMLoc S = getLoc();
7675
7676if (!parseId(Str))
7677returnParseStatus::NoMatch;
7678
7679intSlot =StringSwitch<int>(Str)
7680 .Case("p10", 0)
7681 .Case("p20", 1)
7682 .Case("p0", 2)
7683 .Default(-1);
7684
7685if (Slot == -1)
7686returnError(S,"invalid interpolation slot");
7687
7688Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S,
7689 AMDGPUOperand::ImmTyInterpSlot));
7690returnParseStatus::Success;
7691}
7692
7693ParseStatus AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) {
7694StringRef Str;
7695SMLoc S = getLoc();
7696
7697if (!parseId(Str))
7698returnParseStatus::NoMatch;
7699
7700if (!Str.starts_with("attr"))
7701returnError(S,"invalid interpolation attribute");
7702
7703StringRef Chan = Str.take_back(2);
7704int AttrChan =StringSwitch<int>(Chan)
7705 .Case(".x", 0)
7706 .Case(".y", 1)
7707 .Case(".z", 2)
7708 .Case(".w", 3)
7709 .Default(-1);
7710if (AttrChan == -1)
7711returnError(S,"invalid or missing interpolation attribute channel");
7712
7713 Str = Str.drop_back(2).drop_front(4);
7714
7715uint8_t Attr;
7716if (Str.getAsInteger(10, Attr))
7717returnError(S,"invalid or missing interpolation attribute number");
7718
7719if (Attr > 32)
7720returnError(S,"out of bounds interpolation attribute number");
7721
7722SMLoc SChan =SMLoc::getFromPointer(Chan.data());
7723
7724Operands.push_back(AMDGPUOperand::CreateImm(this, Attr, S,
7725 AMDGPUOperand::ImmTyInterpAttr));
7726Operands.push_back(AMDGPUOperand::CreateImm(
7727this, AttrChan, SChan, AMDGPUOperand::ImmTyInterpAttrChan));
7728returnParseStatus::Success;
7729}
7730
7731//===----------------------------------------------------------------------===//
7732// exp
7733//===----------------------------------------------------------------------===//
7734
7735ParseStatus AMDGPUAsmParser::parseExpTgt(OperandVector &Operands) {
7736using namespacellvm::AMDGPU::Exp;
7737
7738StringRef Str;
7739SMLoc S = getLoc();
7740
7741if (!parseId(Str))
7742returnParseStatus::NoMatch;
7743
7744unsignedId =getTgtId(Str);
7745if (Id == ET_INVALID || !isSupportedTgtId(Id, getSTI()))
7746returnError(S, (Id == ET_INVALID)
7747 ?"invalid exp target"
7748 :"exp target is not supported on this GPU");
7749
7750Operands.push_back(AMDGPUOperand::CreateImm(this,Id, S,
7751 AMDGPUOperand::ImmTyExpTgt));
7752returnParseStatus::Success;
7753}
7754
7755//===----------------------------------------------------------------------===//
7756// parser helpers
7757//===----------------------------------------------------------------------===//
7758
7759bool
7760AMDGPUAsmParser::isId(constAsmToken &Token,constStringRefId) const{
7761return Token.is(AsmToken::Identifier) && Token.getString() ==Id;
7762}
7763
7764bool
7765AMDGPUAsmParser::isId(constStringRefId) const{
7766return isId(getToken(),Id);
7767}
7768
7769bool
7770AMDGPUAsmParser::isToken(constAsmToken::TokenKind Kind) const{
7771return getTokenKind() ==Kind;
7772}
7773
7774StringRef AMDGPUAsmParser::getId() const{
7775return isToken(AsmToken::Identifier) ? getTokenStr() :StringRef();
7776}
7777
7778bool
7779AMDGPUAsmParser::trySkipId(constStringRefId) {
7780if (isId(Id)) {
7781 lex();
7782returntrue;
7783 }
7784returnfalse;
7785}
7786
7787bool
7788AMDGPUAsmParser::trySkipId(constStringRef Pref,constStringRefId) {
7789if (isToken(AsmToken::Identifier)) {
7790StringRef Tok = getTokenStr();
7791if (Tok.starts_with(Pref) && Tok.drop_front(Pref.size()) ==Id) {
7792 lex();
7793returntrue;
7794 }
7795 }
7796returnfalse;
7797}
7798
7799bool
7800AMDGPUAsmParser::trySkipId(constStringRefId,constAsmToken::TokenKind Kind) {
7801if (isId(Id) && peekToken().is(Kind)) {
7802 lex();
7803 lex();
7804returntrue;
7805 }
7806returnfalse;
7807}
7808
7809bool
7810AMDGPUAsmParser::trySkipToken(constAsmToken::TokenKind Kind) {
7811if (isToken(Kind)) {
7812 lex();
7813returntrue;
7814 }
7815returnfalse;
7816}
7817
7818bool
7819AMDGPUAsmParser::skipToken(constAsmToken::TokenKind Kind,
7820constStringRef ErrMsg) {
7821if (!trySkipToken(Kind)) {
7822Error(getLoc(), ErrMsg);
7823returnfalse;
7824 }
7825returntrue;
7826}
7827
7828bool
7829AMDGPUAsmParser::parseExpr(int64_t &Imm,StringRefExpected) {
7830SMLoc S = getLoc();
7831
7832constMCExpr *Expr;
7833if (Parser.parseExpression(Expr))
7834returnfalse;
7835
7836if (Expr->evaluateAsAbsolute(Imm))
7837returntrue;
7838
7839if (Expected.empty()) {
7840Error(S,"expected absolute expression");
7841 }else {
7842Error(S,Twine("expected ",Expected) +
7843Twine(" or an absolute expression"));
7844 }
7845returnfalse;
7846}
7847
7848bool
7849AMDGPUAsmParser::parseExpr(OperandVector &Operands) {
7850SMLoc S = getLoc();
7851
7852constMCExpr *Expr;
7853if (Parser.parseExpression(Expr))
7854returnfalse;
7855
7856 int64_tIntVal;
7857if (Expr->evaluateAsAbsolute(IntVal)) {
7858Operands.push_back(AMDGPUOperand::CreateImm(this, IntVal, S));
7859 }else {
7860Operands.push_back(AMDGPUOperand::CreateExpr(this, Expr, S));
7861 }
7862returntrue;
7863}
7864
7865bool
7866AMDGPUAsmParser::parseString(StringRef &Val,constStringRef ErrMsg) {
7867if (isToken(AsmToken::String)) {
7868 Val = getToken().getStringContents();
7869 lex();
7870returntrue;
7871 }
7872Error(getLoc(), ErrMsg);
7873returnfalse;
7874}
7875
7876bool
7877AMDGPUAsmParser::parseId(StringRef &Val,constStringRef ErrMsg) {
7878if (isToken(AsmToken::Identifier)) {
7879 Val = getTokenStr();
7880 lex();
7881returntrue;
7882 }
7883if (!ErrMsg.empty())
7884Error(getLoc(), ErrMsg);
7885returnfalse;
7886}
7887
7888AsmToken
7889AMDGPUAsmParser::getToken() const{
7890return Parser.getTok();
7891}
7892
7893AsmToken AMDGPUAsmParser::peekToken(bool ShouldSkipSpace) {
7894return isToken(AsmToken::EndOfStatement)
7895 ? getToken()
7896 : getLexer().peekTok(ShouldSkipSpace);
7897}
7898
7899void
7900AMDGPUAsmParser::peekTokens(MutableArrayRef<AsmToken> Tokens) {
7901auto TokCount = getLexer().peekTokens(Tokens);
7902
7903for (autoIdx = TokCount;Idx < Tokens.size(); ++Idx)
7904 Tokens[Idx] =AsmToken(AsmToken::Error,"");
7905}
7906
7907AsmToken::TokenKind
7908AMDGPUAsmParser::getTokenKind() const{
7909return getLexer().getKind();
7910}
7911
7912SMLoc
7913AMDGPUAsmParser::getLoc() const{
7914return getToken().getLoc();
7915}
7916
7917StringRef
7918AMDGPUAsmParser::getTokenStr() const{
7919return getToken().getString();
7920}
7921
7922void
7923AMDGPUAsmParser::lex() {
7924 Parser.Lex();
7925}
7926
7927SMLoc AMDGPUAsmParser::getInstLoc(constOperandVector &Operands) const{
7928return ((AMDGPUOperand &)*Operands[0]).getStartLoc();
7929}
7930
7931SMLoc
7932AMDGPUAsmParser::getOperandLoc(std::function<bool(const AMDGPUOperand&)>Test,
7933constOperandVector &Operands) const{
7934for (unsigned i =Operands.size() - 1; i > 0; --i) {
7935 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
7936if (Test(Op))
7937returnOp.getStartLoc();
7938 }
7939return getInstLoc(Operands);
7940}
7941
7942SMLoc
7943AMDGPUAsmParser::getImmLoc(AMDGPUOperand::ImmTyType,
7944constOperandVector &Operands) const{
7945autoTest = [=](const AMDGPUOperand&Op) {returnOp.isImmTy(Type); };
7946return getOperandLoc(Test,Operands);
7947}
7948
7949SMLoc AMDGPUAsmParser::getRegLoc(MCRegister Reg,
7950constOperandVector &Operands) const{
7951autoTest = [=](const AMDGPUOperand&Op) {
7952returnOp.isRegKind() &&Op.getReg() ==Reg;
7953 };
7954return getOperandLoc(Test,Operands);
7955}
7956
7957SMLoc AMDGPUAsmParser::getLitLoc(constOperandVector &Operands,
7958bool SearchMandatoryLiterals) const{
7959autoTest = [](const AMDGPUOperand&Op) {
7960returnOp.IsImmKindLiteral() ||Op.isExpr();
7961 };
7962SMLoc Loc = getOperandLoc(Test,Operands);
7963if (SearchMandatoryLiterals && Loc == getInstLoc(Operands))
7964 Loc = getMandatoryLitLoc(Operands);
7965return Loc;
7966}
7967
7968SMLoc AMDGPUAsmParser::getMandatoryLitLoc(constOperandVector &Operands) const{
7969autoTest = [](const AMDGPUOperand &Op) {
7970returnOp.IsImmKindMandatoryLiteral();
7971 };
7972return getOperandLoc(Test,Operands);
7973}
7974
7975SMLoc
7976AMDGPUAsmParser::getConstLoc(constOperandVector &Operands) const{
7977autoTest = [](const AMDGPUOperand&Op) {
7978returnOp.isImmKindConst();
7979 };
7980return getOperandLoc(Test,Operands);
7981}
7982
7983ParseStatus
7984AMDGPUAsmParser::parseStructuredOpFields(ArrayRef<StructuredOpField *> Fields) {
7985if (!trySkipToken(AsmToken::LCurly))
7986returnParseStatus::NoMatch;
7987
7988boolFirst =true;
7989while (!trySkipToken(AsmToken::RCurly)) {
7990if (!First &&
7991 !skipToken(AsmToken::Comma,"comma or closing brace expected"))
7992returnParseStatus::Failure;
7993
7994StringRefId = getTokenStr();
7995SMLoc IdLoc = getLoc();
7996if (!skipToken(AsmToken::Identifier,"field name expected") ||
7997 !skipToken(AsmToken::Colon,"colon expected"))
7998returnParseStatus::Failure;
7999
8000constauto *I =
8001find_if(Fields, [Id](StructuredOpField *F) {returnF->Id ==Id; });
8002if (I == Fields.end())
8003returnError(IdLoc,"unknown field");
8004if ((*I)->IsDefined)
8005returnError(IdLoc,"duplicate field");
8006
8007// TODO: Support symbolic values.
8008 (*I)->Loc = getLoc();
8009if (!parseExpr((*I)->Val))
8010returnParseStatus::Failure;
8011 (*I)->IsDefined =true;
8012
8013First =false;
8014 }
8015returnParseStatus::Success;
8016}
8017
8018bool AMDGPUAsmParser::validateStructuredOpFields(
8019ArrayRef<const StructuredOpField *> Fields) {
8020returnall_of(Fields, [this](const StructuredOpField *F) {
8021returnF->validate(*this);
8022 });
8023}
8024
8025//===----------------------------------------------------------------------===//
8026// swizzle
8027//===----------------------------------------------------------------------===//
8028
8029LLVM_READNONE
8030staticunsigned
8031encodeBitmaskPerm(constunsigned AndMask,
8032constunsigned OrMask,
8033constunsigned XorMask) {
8034using namespacellvm::AMDGPU::Swizzle;
8035
8036return BITMASK_PERM_ENC |
8037 (AndMask << BITMASK_AND_SHIFT) |
8038 (OrMask << BITMASK_OR_SHIFT) |
8039 (XorMask << BITMASK_XOR_SHIFT);
8040}
8041
8042bool AMDGPUAsmParser::parseSwizzleOperand(int64_t &Op,constunsigned MinVal,
8043constunsigned MaxVal,
8044constTwine &ErrMsg,SMLoc &Loc) {
8045if (!skipToken(AsmToken::Comma,"expected a comma")) {
8046returnfalse;
8047 }
8048 Loc = getLoc();
8049if (!parseExpr(Op)) {
8050returnfalse;
8051 }
8052if (Op < MinVal || Op > MaxVal) {
8053Error(Loc, ErrMsg);
8054returnfalse;
8055 }
8056
8057returntrue;
8058}
8059
8060bool
8061AMDGPUAsmParser::parseSwizzleOperands(constunsigned OpNum, int64_t*Op,
8062constunsigned MinVal,
8063constunsigned MaxVal,
8064constStringRef ErrMsg) {
8065SMLoc Loc;
8066for (unsigned i = 0; i < OpNum; ++i) {
8067if (!parseSwizzleOperand(Op[i], MinVal, MaxVal, ErrMsg, Loc))
8068returnfalse;
8069 }
8070
8071returntrue;
8072}
8073
8074bool
8075AMDGPUAsmParser::parseSwizzleQuadPerm(int64_t &Imm) {
8076using namespacellvm::AMDGPU::Swizzle;
8077
8078 int64_t Lane[LANE_NUM];
8079if (parseSwizzleOperands(LANE_NUM, Lane, 0, LANE_MAX,
8080"expected a 2-bit lane id")) {
8081Imm =QUAD_PERM_ENC;
8082for (unsignedI = 0;I <LANE_NUM; ++I) {
8083Imm |= Lane[I] << (LANE_SHIFT *I);
8084 }
8085returntrue;
8086 }
8087returnfalse;
8088}
8089
8090bool
8091AMDGPUAsmParser::parseSwizzleBroadcast(int64_t &Imm) {
8092using namespacellvm::AMDGPU::Swizzle;
8093
8094SMLoc Loc;
8095 int64_t GroupSize;
8096 int64_t LaneIdx;
8097
8098if (!parseSwizzleOperand(GroupSize,
8099 2, 32,
8100"group size must be in the interval [2,32]",
8101 Loc)) {
8102returnfalse;
8103 }
8104if (!isPowerOf2_64(GroupSize)) {
8105Error(Loc,"group size must be a power of two");
8106returnfalse;
8107 }
8108if (parseSwizzleOperand(LaneIdx,
8109 0, GroupSize - 1,
8110"lane id must be in the interval [0,group size - 1]",
8111 Loc)) {
8112Imm =encodeBitmaskPerm(BITMASK_MAX - GroupSize + 1, LaneIdx, 0);
8113returntrue;
8114 }
8115returnfalse;
8116}
8117
8118bool
8119AMDGPUAsmParser::parseSwizzleReverse(int64_t &Imm) {
8120using namespacellvm::AMDGPU::Swizzle;
8121
8122SMLoc Loc;
8123 int64_t GroupSize;
8124
8125if (!parseSwizzleOperand(GroupSize,
8126 2, 32,
8127"group size must be in the interval [2,32]",
8128 Loc)) {
8129returnfalse;
8130 }
8131if (!isPowerOf2_64(GroupSize)) {
8132Error(Loc,"group size must be a power of two");
8133returnfalse;
8134 }
8135
8136Imm =encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize - 1);
8137returntrue;
8138}
8139
8140bool
8141AMDGPUAsmParser::parseSwizzleSwap(int64_t &Imm) {
8142using namespacellvm::AMDGPU::Swizzle;
8143
8144SMLoc Loc;
8145 int64_t GroupSize;
8146
8147if (!parseSwizzleOperand(GroupSize,
8148 1, 16,
8149"group size must be in the interval [1,16]",
8150 Loc)) {
8151returnfalse;
8152 }
8153if (!isPowerOf2_64(GroupSize)) {
8154Error(Loc,"group size must be a power of two");
8155returnfalse;
8156 }
8157
8158Imm =encodeBitmaskPerm(BITMASK_MAX, 0, GroupSize);
8159returntrue;
8160}
8161
8162bool
8163AMDGPUAsmParser::parseSwizzleBitmaskPerm(int64_t &Imm) {
8164using namespacellvm::AMDGPU::Swizzle;
8165
8166if (!skipToken(AsmToken::Comma,"expected a comma")) {
8167returnfalse;
8168 }
8169
8170StringRef Ctl;
8171SMLoc StrLoc = getLoc();
8172if (!parseString(Ctl)) {
8173returnfalse;
8174 }
8175if (Ctl.size() != BITMASK_WIDTH) {
8176Error(StrLoc,"expected a 5-character mask");
8177returnfalse;
8178 }
8179
8180unsigned AndMask = 0;
8181unsigned OrMask = 0;
8182unsigned XorMask = 0;
8183
8184for (size_t i = 0; i < Ctl.size(); ++i) {
8185unsignedMask = 1 << (BITMASK_WIDTH - 1 - i);
8186switch(Ctl[i]) {
8187default:
8188Error(StrLoc,"invalid mask");
8189returnfalse;
8190case'0':
8191break;
8192case'1':
8193 OrMask |=Mask;
8194break;
8195case'p':
8196 AndMask |=Mask;
8197break;
8198case'i':
8199 AndMask |=Mask;
8200 XorMask |=Mask;
8201break;
8202 }
8203 }
8204
8205Imm =encodeBitmaskPerm(AndMask, OrMask, XorMask);
8206returntrue;
8207}
8208
8209bool AMDGPUAsmParser::parseSwizzleFFT(int64_t &Imm) {
8210using namespacellvm::AMDGPU::Swizzle;
8211
8212if (!AMDGPU::isGFX9Plus(getSTI())) {
8213Error(getLoc(),"FFT mode swizzle not supported on this GPU");
8214returnfalse;
8215 }
8216
8217 int64_t Swizzle;
8218SMLoc Loc;
8219if (!parseSwizzleOperand(Swizzle, 0, FFT_SWIZZLE_MAX,
8220"FFT swizzle must be in the interval [0," +
8221Twine(FFT_SWIZZLE_MAX) +Twine(']'),
8222 Loc))
8223returnfalse;
8224
8225Imm =FFT_MODE_ENC | Swizzle;
8226returntrue;
8227}
8228
8229bool AMDGPUAsmParser::parseSwizzleRotate(int64_t &Imm) {
8230using namespacellvm::AMDGPU::Swizzle;
8231
8232if (!AMDGPU::isGFX9Plus(getSTI())) {
8233Error(getLoc(),"Rotate mode swizzle not supported on this GPU");
8234returnfalse;
8235 }
8236
8237SMLoc Loc;
8238 int64_tDirection;
8239
8240if (!parseSwizzleOperand(Direction, 0, 1,
8241"direction must be 0 (left) or 1 (right)", Loc))
8242returnfalse;
8243
8244 int64_t RotateSize;
8245if (!parseSwizzleOperand(
8246 RotateSize, 0, ROTATE_MAX_SIZE,
8247"number of threads to rotate must be in the interval [0," +
8248Twine(ROTATE_MAX_SIZE) +Twine(']'),
8249 Loc))
8250returnfalse;
8251
8252Imm =ROTATE_MODE_ENC | (Direction <<ROTATE_DIR_SHIFT) |
8253 (RotateSize << ROTATE_SIZE_SHIFT);
8254returntrue;
8255}
8256
8257bool
8258AMDGPUAsmParser::parseSwizzleOffset(int64_t &Imm) {
8259
8260SMLoc OffsetLoc = getLoc();
8261
8262if (!parseExpr(Imm,"a swizzle macro")) {
8263returnfalse;
8264 }
8265if (!isUInt<16>(Imm)) {
8266Error(OffsetLoc,"expected a 16-bit offset");
8267returnfalse;
8268 }
8269returntrue;
8270}
8271
8272bool
8273AMDGPUAsmParser::parseSwizzleMacro(int64_t &Imm) {
8274using namespacellvm::AMDGPU::Swizzle;
8275
8276if (skipToken(AsmToken::LParen,"expected a left parentheses")) {
8277
8278SMLoc ModeLoc = getLoc();
8279bool Ok =false;
8280
8281if (trySkipId(IdSymbolic[ID_QUAD_PERM])) {
8282 Ok = parseSwizzleQuadPerm(Imm);
8283 }elseif (trySkipId(IdSymbolic[ID_BITMASK_PERM])) {
8284 Ok = parseSwizzleBitmaskPerm(Imm);
8285 }elseif (trySkipId(IdSymbolic[ID_BROADCAST])) {
8286 Ok = parseSwizzleBroadcast(Imm);
8287 }elseif (trySkipId(IdSymbolic[ID_SWAP])) {
8288 Ok = parseSwizzleSwap(Imm);
8289 }elseif (trySkipId(IdSymbolic[ID_REVERSE])) {
8290 Ok = parseSwizzleReverse(Imm);
8291 }elseif (trySkipId(IdSymbolic[ID_FFT])) {
8292 Ok = parseSwizzleFFT(Imm);
8293 }elseif (trySkipId(IdSymbolic[ID_ROTATE])) {
8294 Ok = parseSwizzleRotate(Imm);
8295 }else {
8296Error(ModeLoc,"expected a swizzle mode");
8297 }
8298
8299return Ok && skipToken(AsmToken::RParen,"expected a closing parentheses");
8300 }
8301
8302returnfalse;
8303}
8304
8305ParseStatus AMDGPUAsmParser::parseSwizzle(OperandVector &Operands) {
8306SMLoc S = getLoc();
8307 int64_tImm = 0;
8308
8309if (trySkipId("offset")) {
8310
8311bool Ok =false;
8312if (skipToken(AsmToken::Colon,"expected a colon")) {
8313if (trySkipId("swizzle")) {
8314 Ok = parseSwizzleMacro(Imm);
8315 }else {
8316 Ok = parseSwizzleOffset(Imm);
8317 }
8318 }
8319
8320Operands.push_back(AMDGPUOperand::CreateImm(this,Imm, S, AMDGPUOperand::ImmTySwizzle));
8321
8322return Ok ?ParseStatus::Success :ParseStatus::Failure;
8323 }
8324returnParseStatus::NoMatch;
8325}
8326
8327bool
8328AMDGPUOperand::isSwizzle() const{
8329return isImmTy(ImmTySwizzle);
8330}
8331
8332//===----------------------------------------------------------------------===//
8333// VGPR Index Mode
8334//===----------------------------------------------------------------------===//
8335
8336int64_t AMDGPUAsmParser::parseGPRIdxMacro() {
8337
8338using namespacellvm::AMDGPU::VGPRIndexMode;
8339
8340if (trySkipToken(AsmToken::RParen)) {
8341returnOFF;
8342 }
8343
8344 int64_tImm = 0;
8345
8346while (true) {
8347unsignedMode = 0;
8348SMLoc S = getLoc();
8349
8350for (unsigned ModeId = ID_MIN; ModeId <=ID_MAX; ++ModeId) {
8351if (trySkipId(IdSymbolic[ModeId])) {
8352Mode = 1 << ModeId;
8353break;
8354 }
8355 }
8356
8357if (Mode == 0) {
8358Error(S, (Imm == 0)?
8359"expected a VGPR index mode or a closing parenthesis" :
8360"expected a VGPR index mode");
8361returnUNDEF;
8362 }
8363
8364if (Imm & Mode) {
8365Error(S,"duplicate VGPR index mode");
8366returnUNDEF;
8367 }
8368Imm |=Mode;
8369
8370if (trySkipToken(AsmToken::RParen))
8371break;
8372if (!skipToken(AsmToken::Comma,
8373"expected a comma or a closing parenthesis"))
8374returnUNDEF;
8375 }
8376
8377returnImm;
8378}
8379
8380ParseStatus AMDGPUAsmParser::parseGPRIdxMode(OperandVector &Operands) {
8381
8382using namespacellvm::AMDGPU::VGPRIndexMode;
8383
8384 int64_tImm = 0;
8385SMLoc S = getLoc();
8386
8387if (trySkipId("gpr_idx",AsmToken::LParen)) {
8388Imm = parseGPRIdxMacro();
8389if (Imm == UNDEF)
8390returnParseStatus::Failure;
8391 }else {
8392if (getParser().parseAbsoluteExpression(Imm))
8393returnParseStatus::Failure;
8394if (Imm < 0 || !isUInt<4>(Imm))
8395returnError(S,"invalid immediate: only 4-bit values are legal");
8396 }
8397
8398Operands.push_back(
8399 AMDGPUOperand::CreateImm(this,Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
8400returnParseStatus::Success;
8401}
8402
8403bool AMDGPUOperand::isGPRIdxMode() const{
8404return isImmTy(ImmTyGprIdxMode);
8405}
8406
8407//===----------------------------------------------------------------------===//
8408// sopp branch targets
8409//===----------------------------------------------------------------------===//
8410
8411ParseStatus AMDGPUAsmParser::parseSOPPBrTarget(OperandVector &Operands) {
8412
8413// Make sure we are not parsing something
8414// that looks like a label or an expression but is not.
8415// This will improve error messages.
8416if (isRegister() || isModifier())
8417returnParseStatus::NoMatch;
8418
8419if (!parseExpr(Operands))
8420returnParseStatus::Failure;
8421
8422 AMDGPUOperand &Opr = ((AMDGPUOperand &)*Operands[Operands.size() - 1]);
8423assert(Opr.isImm() || Opr.isExpr());
8424SMLoc Loc = Opr.getStartLoc();
8425
8426// Currently we do not support arbitrary expressions as branch targets.
8427// Only labels and absolute expressions are accepted.
8428if (Opr.isExpr() && !Opr.isSymbolRefExpr()) {
8429Error(Loc,"expected an absolute expression or a label");
8430 }elseif (Opr.isImm() && !Opr.isS16Imm()) {
8431Error(Loc,"expected a 16-bit signed jump offset");
8432 }
8433
8434returnParseStatus::Success;
8435}
8436
8437//===----------------------------------------------------------------------===//
8438// Boolean holding registers
8439//===----------------------------------------------------------------------===//
8440
8441ParseStatus AMDGPUAsmParser::parseBoolReg(OperandVector &Operands) {
8442return parseReg(Operands);
8443}
8444
8445//===----------------------------------------------------------------------===//
8446// mubuf
8447//===----------------------------------------------------------------------===//
8448
8449void AMDGPUAsmParser::cvtMubufImpl(MCInst &Inst,
8450constOperandVector &Operands,
8451bool IsAtomic) {
8452 OptionalImmIndexMap OptionalIdx;
8453unsigned FirstOperandIdx = 1;
8454bool IsAtomicReturn =false;
8455
8456if (IsAtomic) {
8457 IsAtomicReturn = MII.get(Inst.getOpcode()).TSFlags &
8458SIInstrFlags::IsAtomicRet;
8459 }
8460
8461for (unsigned i = FirstOperandIdx, e =Operands.size(); i != e; ++i) {
8462 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
8463
8464// Add the register arguments
8465if (Op.isReg()) {
8466Op.addRegOperands(Inst, 1);
8467// Insert a tied src for atomic return dst.
8468// This cannot be postponed as subsequent calls to
8469// addImmOperands rely on correct number of MC operands.
8470if (IsAtomicReturn && i == FirstOperandIdx)
8471Op.addRegOperands(Inst, 1);
8472continue;
8473 }
8474
8475// Handle the case where soffset is an immediate
8476if (Op.isImm() &&Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
8477Op.addImmOperands(Inst, 1);
8478continue;
8479 }
8480
8481// Handle tokens like 'offen' which are sometimes hard-coded into the
8482// asm string. There are no MCInst operands for these.
8483if (Op.isToken()) {
8484continue;
8485 }
8486assert(Op.isImm());
8487
8488// Handle optional arguments
8489 OptionalIdx[Op.getImmTy()] = i;
8490 }
8491
8492addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyOffset);
8493addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyCPol, 0);
8494}
8495
8496//===----------------------------------------------------------------------===//
8497// smrd
8498//===----------------------------------------------------------------------===//
8499
8500bool AMDGPUOperand::isSMRDOffset8() const{
8501return isImmLiteral() && isUInt<8>(getImm());
8502}
8503
8504bool AMDGPUOperand::isSMEMOffset() const{
8505// Offset range is checked later by validator.
8506return isImmLiteral();
8507}
8508
8509bool AMDGPUOperand::isSMRDLiteralOffset() const{
8510// 32-bit literals are only supported on CI and we only want to use them
8511// when the offset is > 8-bits.
8512return isImmLiteral() && !isUInt<8>(getImm()) && isUInt<32>(getImm());
8513}
8514
8515//===----------------------------------------------------------------------===//
8516// vop3
8517//===----------------------------------------------------------------------===//
8518
8519staticboolConvertOmodMul(int64_t &Mul) {
8520if (Mul != 1 &&Mul != 2 &&Mul != 4)
8521returnfalse;
8522
8523Mul >>= 1;
8524returntrue;
8525}
8526
8527staticboolConvertOmodDiv(int64_t &Div) {
8528if (Div == 1) {
8529 Div = 0;
8530returntrue;
8531 }
8532
8533if (Div == 2) {
8534 Div = 3;
8535returntrue;
8536 }
8537
8538returnfalse;
8539}
8540
8541// For pre-gfx11 targets, both bound_ctrl:0 and bound_ctrl:1 are encoded as 1.
8542// This is intentional and ensures compatibility with sp3.
8543// See bug 35397 for details.
8544bool AMDGPUAsmParser::convertDppBoundCtrl(int64_t &BoundCtrl) {
8545if (BoundCtrl == 0 || BoundCtrl == 1) {
8546if (!isGFX11Plus())
8547 BoundCtrl = 1;
8548returntrue;
8549 }
8550returnfalse;
8551}
8552
8553void AMDGPUAsmParser::onBeginOfFile() {
8554if (!getParser().getStreamer().getTargetStreamer() ||
8555 getSTI().getTargetTriple().getArch() ==Triple::r600)
8556return;
8557
8558if (!getTargetStreamer().getTargetID())
8559 getTargetStreamer().initializeTargetID(getSTI(),
8560 getSTI().getFeatureString());
8561
8562if (isHsaAbi(getSTI()))
8563 getTargetStreamer().EmitDirectiveAMDGCNTarget();
8564}
8565
8566/// Parse AMDGPU specific expressions.
8567///
8568/// expr ::= or(expr, ...) |
8569/// max(expr, ...)
8570///
8571bool AMDGPUAsmParser::parsePrimaryExpr(constMCExpr *&Res,SMLoc &EndLoc) {
8572usingAGVK =AMDGPUMCExpr::VariantKind;
8573
8574if (isToken(AsmToken::Identifier)) {
8575StringRef TokenId = getTokenStr();
8576 AGVK VK =StringSwitch<AGVK>(TokenId)
8577 .Case("max", AGVK::AGVK_Max)
8578 .Case("or", AGVK::AGVK_Or)
8579 .Case("extrasgprs", AGVK::AGVK_ExtraSGPRs)
8580 .Case("totalnumvgprs", AGVK::AGVK_TotalNumVGPRs)
8581 .Case("alignto", AGVK::AGVK_AlignTo)
8582 .Case("occupancy", AGVK::AGVK_Occupancy)
8583 .Default(AGVK::AGVK_None);
8584
8585if (VK != AGVK::AGVK_None && peekToken().is(AsmToken::LParen)) {
8586SmallVector<const MCExpr *, 4> Exprs;
8587uint64_t CommaCount = 0;
8588 lex();// Eat Arg ('or', 'max', 'occupancy', etc.)
8589 lex();// Eat '('
8590while (true) {
8591if (trySkipToken(AsmToken::RParen)) {
8592if (Exprs.empty()) {
8593Error(getToken().getLoc(),
8594"empty " +Twine(TokenId) +" expression");
8595returntrue;
8596 }
8597if (CommaCount + 1 != Exprs.size()) {
8598Error(getToken().getLoc(),
8599"mismatch of commas in " +Twine(TokenId) +" expression");
8600returntrue;
8601 }
8602 Res =AMDGPUMCExpr::create(VK, Exprs, getContext());
8603returnfalse;
8604 }
8605constMCExpr *Expr;
8606if (getParser().parseExpression(Expr, EndLoc))
8607returntrue;
8608 Exprs.push_back(Expr);
8609bool LastTokenWasComma = trySkipToken(AsmToken::Comma);
8610if (LastTokenWasComma)
8611 CommaCount++;
8612if (!LastTokenWasComma && !isToken(AsmToken::RParen)) {
8613Error(getToken().getLoc(),
8614"unexpected token in " +Twine(TokenId) +" expression");
8615returntrue;
8616 }
8617 }
8618 }
8619 }
8620return getParser().parsePrimaryExpr(Res, EndLoc,nullptr);
8621}
8622
8623ParseStatus AMDGPUAsmParser::parseOModSI(OperandVector &Operands) {
8624StringRefName = getTokenStr();
8625if (Name =="mul") {
8626return parseIntWithPrefix("mul",Operands,
8627 AMDGPUOperand::ImmTyOModSI,ConvertOmodMul);
8628 }
8629
8630if (Name =="div") {
8631return parseIntWithPrefix("div",Operands,
8632 AMDGPUOperand::ImmTyOModSI,ConvertOmodDiv);
8633 }
8634
8635returnParseStatus::NoMatch;
8636}
8637
8638// Determines which bit DST_OP_SEL occupies in the op_sel operand according to
8639// the number of src operands present, then copies that bit into src0_modifiers.
8640staticvoidcvtVOP3DstOpSelOnly(MCInst &Inst,constMCRegisterInfo &MRI) {
8641int Opc = Inst.getOpcode();
8642int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8643if (OpSelIdx == -1)
8644return;
8645
8646int SrcNum;
8647constint Ops[] = { AMDGPU::OpName::src0,
8648 AMDGPU::OpName::src1,
8649 AMDGPU::OpName::src2 };
8650for (SrcNum = 0; SrcNum < 3 &&AMDGPU::hasNamedOperand(Opc, Ops[SrcNum]);
8651 ++SrcNum)
8652 ;
8653assert(SrcNum > 0);
8654
8655unsigned OpSel = Inst.getOperand(OpSelIdx).getImm();
8656
8657int DstIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst);
8658if (DstIdx == -1)
8659return;
8660
8661constMCOperand &DstOp = Inst.getOperand(DstIdx);
8662int ModIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0_modifiers);
8663uint32_t ModVal = Inst.getOperand(ModIdx).getImm();
8664if (DstOp.isReg() &&
8665MRI.getRegClass(AMDGPU::VGPR_16RegClassID).contains(DstOp.getReg())) {
8666if (AMDGPU::isHi16Reg(DstOp.getReg(),MRI))
8667 ModVal |=SISrcMods::DST_OP_SEL;
8668 }else {
8669if ((OpSel & (1 << SrcNum)) != 0)
8670 ModVal |=SISrcMods::DST_OP_SEL;
8671 }
8672 Inst.getOperand(ModIdx).setImm(ModVal);
8673}
8674
8675void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,
8676constOperandVector &Operands) {
8677 cvtVOP3P(Inst,Operands);
8678cvtVOP3DstOpSelOnly(Inst, *getMRI());
8679}
8680
8681void AMDGPUAsmParser::cvtVOP3OpSel(MCInst &Inst,constOperandVector &Operands,
8682 OptionalImmIndexMap &OptionalIdx) {
8683 cvtVOP3P(Inst,Operands, OptionalIdx);
8684cvtVOP3DstOpSelOnly(Inst, *getMRI());
8685}
8686
8687staticboolisRegOrImmWithInputMods(constMCInstrDesc &Desc,unsigned OpNum) {
8688return
8689// 1. This operand is input modifiers
8690Desc.operands()[OpNum].OperandType ==AMDGPU::OPERAND_INPUT_MODS
8691// 2. This is not last operand
8692 &&Desc.NumOperands > (OpNum + 1)
8693// 3. Next operand is register class
8694 &&Desc.operands()[OpNum + 1].RegClass != -1
8695// 4. Next register is not tied to any other operand
8696 &&Desc.getOperandConstraint(OpNum + 1,
8697 MCOI::OperandConstraint::TIED_TO) == -1;
8698}
8699
8700void AMDGPUAsmParser::cvtVOP3Interp(MCInst &Inst,constOperandVector &Operands)
8701{
8702 OptionalImmIndexMap OptionalIdx;
8703unsigned Opc = Inst.getOpcode();
8704
8705unsignedI = 1;
8706constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
8707for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
8708 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8709 }
8710
8711for (unsigned E =Operands.size();I != E; ++I) {
8712 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8713if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8714Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8715 }elseif (Op.isInterpSlot() ||Op.isInterpAttr() ||
8716Op.isInterpAttrChan()) {
8717 Inst.addOperand(MCOperand::createImm(Op.getImm()));
8718 }elseif (Op.isImmModifier()) {
8719 OptionalIdx[Op.getImmTy()] =I;
8720 }else {
8721llvm_unreachable("unhandled operand type");
8722 }
8723 }
8724
8725if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::high))
8726addOptionalImmOperand(Inst,Operands, OptionalIdx,
8727 AMDGPUOperand::ImmTyHigh);
8728
8729if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
8730addOptionalImmOperand(Inst,Operands, OptionalIdx,
8731 AMDGPUOperand::ImmTyClamp);
8732
8733if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
8734addOptionalImmOperand(Inst,Operands, OptionalIdx,
8735 AMDGPUOperand::ImmTyOModSI);
8736}
8737
8738void AMDGPUAsmParser::cvtVINTERP(MCInst &Inst,constOperandVector &Operands)
8739{
8740 OptionalImmIndexMap OptionalIdx;
8741unsigned Opc = Inst.getOpcode();
8742
8743unsignedI = 1;
8744constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
8745for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
8746 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8747 }
8748
8749for (unsigned E =Operands.size();I != E; ++I) {
8750 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8751if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8752Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8753 }elseif (Op.isImmModifier()) {
8754 OptionalIdx[Op.getImmTy()] =I;
8755 }else {
8756llvm_unreachable("unhandled operand type");
8757 }
8758 }
8759
8760addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyClamp);
8761
8762int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8763if (OpSelIdx != -1)
8764addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyOpSel);
8765
8766addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyWaitEXP);
8767
8768if (OpSelIdx == -1)
8769return;
8770
8771constint Ops[] = { AMDGPU::OpName::src0,
8772 AMDGPU::OpName::src1,
8773 AMDGPU::OpName::src2 };
8774constint ModOps[] = { AMDGPU::OpName::src0_modifiers,
8775 AMDGPU::OpName::src1_modifiers,
8776 AMDGPU::OpName::src2_modifiers };
8777
8778unsignedOpSel = Inst.getOperand(OpSelIdx).getImm();
8779
8780for (int J = 0; J < 3; ++J) {
8781int OpIdx =AMDGPU::getNamedOperandIdx(Opc, Ops[J]);
8782if (OpIdx == -1)
8783break;
8784
8785int ModIdx =AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
8786uint32_t ModVal = Inst.getOperand(ModIdx).getImm();
8787
8788if ((OpSel & (1 << J)) != 0)
8789 ModVal |=SISrcMods::OP_SEL_0;
8790if (ModOps[J] == AMDGPU::OpName::src0_modifiers &&
8791 (OpSel & (1 << 3)) != 0)
8792 ModVal |=SISrcMods::DST_OP_SEL;
8793
8794 Inst.getOperand(ModIdx).setImm(ModVal);
8795 }
8796}
8797
8798void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,constOperandVector &Operands,
8799 OptionalImmIndexMap &OptionalIdx) {
8800unsigned Opc = Inst.getOpcode();
8801
8802unsignedI = 1;
8803constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
8804for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
8805 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
8806 }
8807
8808for (unsigned E =Operands.size();I != E; ++I) {
8809 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
8810if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
8811Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
8812 }elseif (Op.isImmModifier()) {
8813 OptionalIdx[Op.getImmTy()] =I;
8814 }else {
8815Op.addRegOrImmOperands(Inst, 1);
8816 }
8817 }
8818
8819if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::byte_sel)) {
8820if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vdst_in))
8821 Inst.addOperand(Inst.getOperand(0));
8822addOptionalImmOperand(Inst,Operands, OptionalIdx,
8823 AMDGPUOperand::ImmTyByteSel);
8824 }
8825
8826if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
8827addOptionalImmOperand(Inst,Operands, OptionalIdx,
8828 AMDGPUOperand::ImmTyClamp);
8829
8830if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
8831addOptionalImmOperand(Inst,Operands, OptionalIdx,
8832 AMDGPUOperand::ImmTyOModSI);
8833
8834// Special case v_mac_{f16, f32} and v_fmac_{f16, f32} (gfx906/gfx10+):
8835// it has src2 register operand that is tied to dst operand
8836// we don't allow modifiers for this operand in assembler so src2_modifiers
8837// should be 0.
8838if (isMAC(Opc)) {
8839auto *it = Inst.begin();
8840 std::advance(it,AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers));
8841 it = Inst.insert(it,MCOperand::createImm(0));// no modifiers for src2
8842 ++it;
8843// Copy the operand to ensure it's not invalidated when Inst grows.
8844 Inst.insert(it,MCOperand(Inst.getOperand(0)));// src2 = dst
8845 }
8846}
8847
8848void AMDGPUAsmParser::cvtVOP3(MCInst &Inst,constOperandVector &Operands) {
8849 OptionalImmIndexMap OptionalIdx;
8850 cvtVOP3(Inst,Operands, OptionalIdx);
8851}
8852
8853void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,constOperandVector &Operands,
8854 OptionalImmIndexMap &OptIdx) {
8855constint Opc = Inst.getOpcode();
8856constMCInstrDesc &Desc = MII.get(Opc);
8857
8858constboolIsPacked = (Desc.TSFlags &SIInstrFlags::IsPacked) != 0;
8859
8860if (Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_F16_vi ||
8861 Opc == AMDGPU::V_CVT_SCALEF32_PK_FP4_BF16_vi ||
8862 Opc == AMDGPU::V_CVT_SR_BF8_F32_vi ||
8863 Opc == AMDGPU::V_CVT_SR_FP8_F32_vi ||
8864 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_gfx12 ||
8865 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_gfx12) {
8866 Inst.addOperand(MCOperand::createImm(0));// Placeholder for src2_mods
8867 Inst.addOperand(Inst.getOperand(0));
8868 }
8869
8870// Adding vdst_in operand is already covered for these DPP instructions in
8871// cvtVOP3DPP.
8872if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::vdst_in) &&
8873 !(Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp_gfx12 ||
8874 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp_gfx12 ||
8875 Opc == AMDGPU::V_CVT_PK_BF8_F32_e64_dpp8_gfx12 ||
8876 Opc == AMDGPU::V_CVT_PK_FP8_F32_e64_dpp8_gfx12 ||
8877 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12 ||
8878 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
8879 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
8880 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12)) {
8881 Inst.addOperand(Inst.getOperand(0));
8882 }
8883
8884int BitOp3Idx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::bitop3);
8885if (BitOp3Idx != -1) {
8886addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyBitOp3);
8887 }
8888
8889// FIXME: This is messy. Parse the modifiers as if it was a normal VOP3
8890// instruction, and then figure out where to actually put the modifiers
8891
8892int OpSelIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel);
8893if (OpSelIdx != -1) {
8894addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyOpSel);
8895 }
8896
8897int OpSelHiIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::op_sel_hi);
8898if (OpSelHiIdx != -1) {
8899intDefaultVal =IsPacked ? -1 : 0;
8900addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyOpSelHi,
8901DefaultVal);
8902 }
8903
8904int NegLoIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_lo);
8905if (NegLoIdx != -1)
8906addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyNegLo);
8907
8908int NegHiIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::neg_hi);
8909if (NegHiIdx != -1)
8910addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyNegHi);
8911
8912constint Ops[] = { AMDGPU::OpName::src0,
8913 AMDGPU::OpName::src1,
8914 AMDGPU::OpName::src2 };
8915constint ModOps[] = { AMDGPU::OpName::src0_modifiers,
8916 AMDGPU::OpName::src1_modifiers,
8917 AMDGPU::OpName::src2_modifiers };
8918
8919unsignedOpSel = 0;
8920unsigned OpSelHi = 0;
8921unsigned NegLo = 0;
8922unsigned NegHi = 0;
8923
8924if (OpSelIdx != -1)
8925OpSel = Inst.getOperand(OpSelIdx).getImm();
8926
8927if (OpSelHiIdx != -1)
8928 OpSelHi = Inst.getOperand(OpSelHiIdx).getImm();
8929
8930if (NegLoIdx != -1)
8931 NegLo = Inst.getOperand(NegLoIdx).getImm();
8932
8933if (NegHiIdx != -1)
8934 NegHi = Inst.getOperand(NegHiIdx).getImm();
8935
8936for (int J = 0; J < 3; ++J) {
8937int OpIdx =AMDGPU::getNamedOperandIdx(Opc, Ops[J]);
8938if (OpIdx == -1)
8939break;
8940
8941int ModIdx =AMDGPU::getNamedOperandIdx(Opc, ModOps[J]);
8942
8943if (ModIdx == -1)
8944continue;
8945
8946uint32_t ModVal = 0;
8947
8948constMCOperand &SrcOp = Inst.getOperand(OpIdx);
8949if (SrcOp.isReg() && getMRI()
8950 ->getRegClass(AMDGPU::VGPR_16RegClassID)
8951 .contains(SrcOp.getReg())) {
8952bool VGPRSuffixIsHi =AMDGPU::isHi16Reg(SrcOp.getReg(), *getMRI());
8953if (VGPRSuffixIsHi)
8954 ModVal |=SISrcMods::OP_SEL_0;
8955 }else {
8956if ((OpSel & (1 << J)) != 0)
8957 ModVal |=SISrcMods::OP_SEL_0;
8958 }
8959
8960if ((OpSelHi & (1 << J)) != 0)
8961 ModVal |=SISrcMods::OP_SEL_1;
8962
8963if ((NegLo & (1 << J)) != 0)
8964 ModVal |=SISrcMods::NEG;
8965
8966if ((NegHi & (1 << J)) != 0)
8967 ModVal |=SISrcMods::NEG_HI;
8968
8969 Inst.getOperand(ModIdx).setImm(Inst.getOperand(ModIdx).getImm() | ModVal);
8970 }
8971}
8972
8973void AMDGPUAsmParser::cvtVOP3P(MCInst &Inst,constOperandVector &Operands) {
8974 OptionalImmIndexMap OptIdx;
8975 cvtVOP3(Inst,Operands, OptIdx);
8976 cvtVOP3P(Inst,Operands, OptIdx);
8977}
8978
8979staticvoidaddSrcModifiersAndSrc(MCInst &Inst,constOperandVector &Operands,
8980unsigned i,unsigned Opc,unsignedOpName) {
8981if (AMDGPU::getNamedOperandIdx(Opc,OpName) != -1)
8982 ((AMDGPUOperand &)*Operands[i]).addRegOrImmWithFPInputModsOperands(Inst, 2);
8983else
8984 ((AMDGPUOperand &)*Operands[i]).addRegOperands(Inst, 1);
8985}
8986
8987void AMDGPUAsmParser::cvtSWMMAC(MCInst &Inst,constOperandVector &Operands) {
8988unsigned Opc = Inst.getOpcode();
8989
8990 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
8991addSrcModifiersAndSrc(Inst,Operands, 2, Opc, AMDGPU::OpName::src0_modifiers);
8992addSrcModifiersAndSrc(Inst,Operands, 3, Opc, AMDGPU::OpName::src1_modifiers);
8993 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);// srcTiedDef
8994 ((AMDGPUOperand &)*Operands[4]).addRegOperands(Inst, 1);// src2
8995
8996 OptionalImmIndexMap OptIdx;
8997for (unsigned i = 5; i <Operands.size(); ++i) {
8998 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
8999 OptIdx[Op.getImmTy()] = i;
9000 }
9001
9002if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::index_key_8bit))
9003addOptionalImmOperand(Inst,Operands, OptIdx,
9004 AMDGPUOperand::ImmTyIndexKey8bit);
9005
9006if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::index_key_16bit))
9007addOptionalImmOperand(Inst,Operands, OptIdx,
9008 AMDGPUOperand::ImmTyIndexKey16bit);
9009
9010if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
9011addOptionalImmOperand(Inst,Operands, OptIdx, AMDGPUOperand::ImmTyClamp);
9012
9013 cvtVOP3P(Inst,Operands, OptIdx);
9014}
9015
9016//===----------------------------------------------------------------------===//
9017// VOPD
9018//===----------------------------------------------------------------------===//
9019
9020ParseStatus AMDGPUAsmParser::parseVOPD(OperandVector &Operands) {
9021if (!hasVOPD(getSTI()))
9022returnParseStatus::NoMatch;
9023
9024if (isToken(AsmToken::Colon) && peekToken(false).is(AsmToken::Colon)) {
9025SMLoc S = getLoc();
9026 lex();
9027 lex();
9028Operands.push_back(AMDGPUOperand::CreateToken(this,"::", S));
9029SMLoc OpYLoc = getLoc();
9030StringRef OpYName;
9031if (isToken(AsmToken::Identifier) && !Parser.parseIdentifier(OpYName)) {
9032Operands.push_back(AMDGPUOperand::CreateToken(this, OpYName, OpYLoc));
9033returnParseStatus::Success;
9034 }
9035returnError(OpYLoc,"expected a VOPDY instruction after ::");
9036 }
9037returnParseStatus::NoMatch;
9038}
9039
9040// Create VOPD MCInst operands using parsed assembler operands.
9041void AMDGPUAsmParser::cvtVOPD(MCInst &Inst,constOperandVector &Operands) {
9042auto addOp = [&](uint16_t ParsedOprIdx) {// NOLINT:function pointer
9043 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[ParsedOprIdx]);
9044if (Op.isReg()) {
9045Op.addRegOperands(Inst, 1);
9046return;
9047 }
9048if (Op.isImm()) {
9049Op.addImmOperands(Inst, 1);
9050return;
9051 }
9052llvm_unreachable("Unhandled operand type in cvtVOPD");
9053 };
9054
9055constauto &InstInfo =getVOPDInstInfo(Inst.getOpcode(), &MII);
9056
9057// MCInst operands are ordered as follows:
9058// dstX, dstY, src0X [, other OpX operands], src0Y [, other OpY operands]
9059
9060for (auto CompIdx :VOPD::COMPONENTS) {
9061 addOp(InstInfo[CompIdx].getIndexOfDstInParsedOperands());
9062 }
9063
9064for (auto CompIdx :VOPD::COMPONENTS) {
9065constauto &CInfo = InstInfo[CompIdx];
9066auto CompSrcOperandsNum = InstInfo[CompIdx].getCompParsedSrcOperandsNum();
9067for (unsigned CompSrcIdx = 0; CompSrcIdx < CompSrcOperandsNum; ++CompSrcIdx)
9068 addOp(CInfo.getIndexOfSrcInParsedOperands(CompSrcIdx));
9069if (CInfo.hasSrc2Acc())
9070 addOp(CInfo.getIndexOfDstInParsedOperands());
9071 }
9072}
9073
9074//===----------------------------------------------------------------------===//
9075// dpp
9076//===----------------------------------------------------------------------===//
9077
9078bool AMDGPUOperand::isDPP8() const{
9079return isImmTy(ImmTyDPP8);
9080}
9081
9082bool AMDGPUOperand::isDPPCtrl() const{
9083using namespaceAMDGPU::DPP;
9084
9085bool result =isImm() && getImmTy() == ImmTyDppCtrl && isUInt<9>(getImm());
9086if (result) {
9087 int64_tImm = getImm();
9088return (Imm >= DppCtrl::QUAD_PERM_FIRST &&Imm <= DppCtrl::QUAD_PERM_LAST) ||
9089 (Imm >= DppCtrl::ROW_SHL_FIRST &&Imm <= DppCtrl::ROW_SHL_LAST) ||
9090 (Imm >= DppCtrl::ROW_SHR_FIRST &&Imm <= DppCtrl::ROW_SHR_LAST) ||
9091 (Imm >= DppCtrl::ROW_ROR_FIRST &&Imm <= DppCtrl::ROW_ROR_LAST) ||
9092 (Imm == DppCtrl::WAVE_SHL1) ||
9093 (Imm == DppCtrl::WAVE_ROL1) ||
9094 (Imm == DppCtrl::WAVE_SHR1) ||
9095 (Imm == DppCtrl::WAVE_ROR1) ||
9096 (Imm == DppCtrl::ROW_MIRROR) ||
9097 (Imm == DppCtrl::ROW_HALF_MIRROR) ||
9098 (Imm == DppCtrl::BCAST15) ||
9099 (Imm == DppCtrl::BCAST31) ||
9100 (Imm >= DppCtrl::ROW_SHARE_FIRST &&Imm <= DppCtrl::ROW_SHARE_LAST) ||
9101 (Imm >= DppCtrl::ROW_XMASK_FIRST &&Imm <= DppCtrl::ROW_XMASK_LAST);
9102 }
9103returnfalse;
9104}
9105
9106//===----------------------------------------------------------------------===//
9107// mAI
9108//===----------------------------------------------------------------------===//
9109
9110bool AMDGPUOperand::isBLGP() const{
9111returnisImm() && getImmTy() == ImmTyBLGP && isUInt<3>(getImm());
9112}
9113
9114bool AMDGPUOperand::isS16Imm() const{
9115return isImmLiteral() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
9116}
9117
9118bool AMDGPUOperand::isU16Imm() const{
9119return isImmLiteral() && isUInt<16>(getImm());
9120}
9121
9122//===----------------------------------------------------------------------===//
9123// dim
9124//===----------------------------------------------------------------------===//
9125
9126bool AMDGPUAsmParser::parseDimId(unsigned &Encoding) {
9127// We want to allow "dim:1D" etc.,
9128// but the initial 1 is tokenized as an integer.
9129 std::string Token;
9130if (isToken(AsmToken::Integer)) {
9131SMLoc Loc = getToken().getEndLoc();
9132 Token = std::string(getTokenStr());
9133 lex();
9134if (getLoc() != Loc)
9135returnfalse;
9136 }
9137
9138StringRef Suffix;
9139if (!parseId(Suffix))
9140returnfalse;
9141 Token += Suffix;
9142
9143StringRef DimId = Token;
9144if (DimId.starts_with("SQ_RSRC_IMG_"))
9145 DimId = DimId.drop_front(12);
9146
9147constAMDGPU::MIMGDimInfo *DimInfo =AMDGPU::getMIMGDimInfoByAsmSuffix(DimId);
9148if (!DimInfo)
9149returnfalse;
9150
9151 Encoding = DimInfo->Encoding;
9152returntrue;
9153}
9154
9155ParseStatus AMDGPUAsmParser::parseDim(OperandVector &Operands) {
9156if (!isGFX10Plus())
9157returnParseStatus::NoMatch;
9158
9159SMLoc S = getLoc();
9160
9161if (!trySkipId("dim",AsmToken::Colon))
9162returnParseStatus::NoMatch;
9163
9164unsigned Encoding;
9165SMLoc Loc = getLoc();
9166if (!parseDimId(Encoding))
9167returnError(Loc,"invalid dim value");
9168
9169Operands.push_back(AMDGPUOperand::CreateImm(this, Encoding, S,
9170 AMDGPUOperand::ImmTyDim));
9171returnParseStatus::Success;
9172}
9173
9174//===----------------------------------------------------------------------===//
9175// dpp
9176//===----------------------------------------------------------------------===//
9177
9178ParseStatus AMDGPUAsmParser::parseDPP8(OperandVector &Operands) {
9179SMLoc S = getLoc();
9180
9181if (!isGFX10Plus() || !trySkipId("dpp8",AsmToken::Colon))
9182returnParseStatus::NoMatch;
9183
9184// dpp8:[%d,%d,%d,%d,%d,%d,%d,%d]
9185
9186 int64_t Sels[8];
9187
9188if (!skipToken(AsmToken::LBrac,"expected an opening square bracket"))
9189returnParseStatus::Failure;
9190
9191for (size_t i = 0; i < 8; ++i) {
9192if (i > 0 && !skipToken(AsmToken::Comma,"expected a comma"))
9193returnParseStatus::Failure;
9194
9195SMLoc Loc = getLoc();
9196if (getParser().parseAbsoluteExpression(Sels[i]))
9197returnParseStatus::Failure;
9198if (0 > Sels[i] || 7 < Sels[i])
9199returnError(Loc,"expected a 3-bit value");
9200 }
9201
9202if (!skipToken(AsmToken::RBrac,"expected a closing square bracket"))
9203returnParseStatus::Failure;
9204
9205unsigned DPP8 = 0;
9206for (size_t i = 0; i < 8; ++i)
9207 DPP8 |= (Sels[i] << (i * 3));
9208
9209Operands.push_back(AMDGPUOperand::CreateImm(this, DPP8, S, AMDGPUOperand::ImmTyDPP8));
9210returnParseStatus::Success;
9211}
9212
9213bool
9214AMDGPUAsmParser::isSupportedDPPCtrl(StringRef Ctrl,
9215constOperandVector &Operands) {
9216if (Ctrl =="row_newbcast")
9217returnisGFX90A();
9218
9219if (Ctrl =="row_share" ||
9220 Ctrl =="row_xmask")
9221returnisGFX10Plus();
9222
9223if (Ctrl =="wave_shl" ||
9224 Ctrl =="wave_shr" ||
9225 Ctrl =="wave_rol" ||
9226 Ctrl =="wave_ror" ||
9227 Ctrl =="row_bcast")
9228returnisVI() ||isGFX9();
9229
9230returnCtrl =="row_mirror" ||
9231Ctrl =="row_half_mirror" ||
9232Ctrl =="quad_perm" ||
9233Ctrl =="row_shl" ||
9234Ctrl =="row_shr" ||
9235Ctrl =="row_ror";
9236}
9237
9238int64_t
9239AMDGPUAsmParser::parseDPPCtrlPerm() {
9240// quad_perm:[%d,%d,%d,%d]
9241
9242if (!skipToken(AsmToken::LBrac,"expected an opening square bracket"))
9243return -1;
9244
9245 int64_t Val = 0;
9246for (int i = 0; i < 4; ++i) {
9247if (i > 0 && !skipToken(AsmToken::Comma,"expected a comma"))
9248return -1;
9249
9250 int64_t Temp;
9251SMLoc Loc = getLoc();
9252if (getParser().parseAbsoluteExpression(Temp))
9253return -1;
9254if (Temp < 0 || Temp > 3) {
9255Error(Loc,"expected a 2-bit value");
9256return -1;
9257 }
9258
9259 Val += (Temp << i * 2);
9260 }
9261
9262if (!skipToken(AsmToken::RBrac,"expected a closing square bracket"))
9263return -1;
9264
9265return Val;
9266}
9267
9268int64_t
9269AMDGPUAsmParser::parseDPPCtrlSel(StringRef Ctrl) {
9270using namespaceAMDGPU::DPP;
9271
9272// sel:%d
9273
9274 int64_t Val;
9275SMLoc Loc = getLoc();
9276
9277if (getParser().parseAbsoluteExpression(Val))
9278return -1;
9279
9280structDppCtrlCheck {
9281 int64_tCtrl;
9282intLo;
9283intHi;
9284 };
9285
9286 DppCtrlCheckCheck =StringSwitch<DppCtrlCheck>(Ctrl)
9287 .Case("wave_shl", {DppCtrl::WAVE_SHL1, 1, 1})
9288 .Case("wave_rol", {DppCtrl::WAVE_ROL1, 1, 1})
9289 .Case("wave_shr", {DppCtrl::WAVE_SHR1, 1, 1})
9290 .Case("wave_ror", {DppCtrl::WAVE_ROR1, 1, 1})
9291 .Case("row_shl", {DppCtrl::ROW_SHL0, 1, 15})
9292 .Case("row_shr", {DppCtrl::ROW_SHR0, 1, 15})
9293 .Case("row_ror", {DppCtrl::ROW_ROR0, 1, 15})
9294 .Case("row_share", {DppCtrl::ROW_SHARE_FIRST, 0, 15})
9295 .Case("row_xmask", {DppCtrl::ROW_XMASK_FIRST, 0, 15})
9296 .Case("row_newbcast", {DppCtrl::ROW_NEWBCAST_FIRST, 0, 15})
9297 .Default({-1, 0, 0});
9298
9299bool Valid;
9300if (Check.Ctrl == -1) {
9301 Valid = (Ctrl =="row_bcast" && (Val == 15 || Val == 31));
9302 Val = (Val == 15)? DppCtrl::BCAST15 : DppCtrl::BCAST31;
9303 }else {
9304 Valid =Check.Lo <= Val && Val <=Check.Hi;
9305 Val = (Check.Lo ==Check.Hi) ?Check.Ctrl : (Check.Ctrl | Val);
9306 }
9307
9308if (!Valid) {
9309Error(Loc,Twine("invalid ", Ctrl) +Twine(" value"));
9310return -1;
9311 }
9312
9313return Val;
9314}
9315
9316ParseStatus AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
9317using namespaceAMDGPU::DPP;
9318
9319if (!isToken(AsmToken::Identifier) ||
9320 !isSupportedDPPCtrl(getTokenStr(),Operands))
9321returnParseStatus::NoMatch;
9322
9323SMLoc S = getLoc();
9324 int64_t Val = -1;
9325StringRefCtrl;
9326
9327 parseId(Ctrl);
9328
9329if (Ctrl =="row_mirror") {
9330 Val = DppCtrl::ROW_MIRROR;
9331 }elseif (Ctrl =="row_half_mirror") {
9332 Val = DppCtrl::ROW_HALF_MIRROR;
9333 }else {
9334if (skipToken(AsmToken::Colon,"expected a colon")) {
9335if (Ctrl =="quad_perm") {
9336 Val = parseDPPCtrlPerm();
9337 }else {
9338 Val = parseDPPCtrlSel(Ctrl);
9339 }
9340 }
9341 }
9342
9343if (Val == -1)
9344returnParseStatus::Failure;
9345
9346Operands.push_back(
9347 AMDGPUOperand::CreateImm(this, Val, S, AMDGPUOperand::ImmTyDppCtrl));
9348returnParseStatus::Success;
9349}
9350
9351void AMDGPUAsmParser::cvtVOP3DPP(MCInst &Inst,constOperandVector &Operands,
9352bool IsDPP8) {
9353 OptionalImmIndexMap OptionalIdx;
9354unsigned Opc = Inst.getOpcode();
9355constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
9356
9357// MAC instructions are special because they have 'old'
9358// operand which is not tied to dst (but assumed to be).
9359// They also have dummy unused src2_modifiers.
9360int OldIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::old);
9361int Src2ModIdx =
9362AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2_modifiers);
9363bool IsMAC = OldIdx != -1 && Src2ModIdx != -1 &&
9364Desc.getOperandConstraint(OldIdx,MCOI::TIED_TO) == -1;
9365
9366unsignedI = 1;
9367for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
9368 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
9369 }
9370
9371int Fi = 0;
9372for (unsigned E =Operands.size();I != E; ++I) {
9373
9374if (IsMAC) {
9375int NumOperands = Inst.getNumOperands();
9376if (OldIdx == NumOperands) {
9377// Handle old operand
9378constexprint DST_IDX = 0;
9379 Inst.addOperand(Inst.getOperand(DST_IDX));
9380 }elseif (Src2ModIdx == NumOperands) {
9381// Add unused dummy src2_modifiers
9382 Inst.addOperand(MCOperand::createImm(0));
9383 }
9384 }
9385
9386int VdstInIdx =AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::vdst_in);
9387if (VdstInIdx ==static_cast<int>(Inst.getNumOperands())) {
9388 Inst.addOperand(Inst.getOperand(0));
9389 }
9390
9391bool IsVOP3CvtSrDpp =
9392 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp8_gfx12 ||
9393 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp8_gfx12 ||
9394 Opc == AMDGPU::V_CVT_SR_BF8_F32_gfx12_e64_dpp_gfx12 ||
9395 Opc == AMDGPU::V_CVT_SR_FP8_F32_gfx12_e64_dpp_gfx12;
9396if (IsVOP3CvtSrDpp) {
9397if (Src2ModIdx ==static_cast<int>(Inst.getNumOperands())) {
9398 Inst.addOperand(MCOperand::createImm(0));
9399 Inst.addOperand(MCOperand::createReg(MCRegister()));
9400 }
9401 }
9402
9403auto TiedTo =Desc.getOperandConstraint(Inst.getNumOperands(),
9404MCOI::TIED_TO);
9405if (TiedTo != -1) {
9406assert((unsigned)TiedTo < Inst.getNumOperands());
9407// handle tied old or src2 for MAC instructions
9408 Inst.addOperand(Inst.getOperand(TiedTo));
9409 }
9410 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
9411// Add the register arguments
9412if (IsDPP8 &&Op.isDppFI()) {
9413 Fi =Op.getImm();
9414 }elseif (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
9415Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
9416 }elseif (Op.isReg()) {
9417Op.addRegOperands(Inst, 1);
9418 }elseif (Op.isImm() &&
9419Desc.operands()[Inst.getNumOperands()].RegClass != -1) {
9420assert(!Op.IsImmKindLiteral() &&"Cannot use literal with DPP");
9421Op.addImmOperands(Inst, 1);
9422 }elseif (Op.isImm()) {
9423 OptionalIdx[Op.getImmTy()] =I;
9424 }else {
9425llvm_unreachable("unhandled operand type");
9426 }
9427 }
9428
9429if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::byte_sel))
9430addOptionalImmOperand(Inst,Operands, OptionalIdx,
9431 AMDGPUOperand::ImmTyByteSel);
9432
9433if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
9434addOptionalImmOperand(Inst,Operands, OptionalIdx,
9435 AMDGPUOperand::ImmTyClamp);
9436
9437if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
9438addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI);
9439
9440if (Desc.TSFlags &SIInstrFlags::VOP3P)
9441 cvtVOP3P(Inst,Operands, OptionalIdx);
9442elseif (Desc.TSFlags &SIInstrFlags::VOP3)
9443 cvtVOP3OpSel(Inst,Operands, OptionalIdx);
9444elseif (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::op_sel)) {
9445addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyOpSel);
9446 }
9447
9448if (IsDPP8) {
9449addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDPP8);
9450using namespacellvm::AMDGPU::DPP;
9451 Inst.addOperand(MCOperand::createImm(Fi? DPP8_FI_1 : DPP8_FI_0));
9452 }else {
9453addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppCtrl, 0xe4);
9454addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
9455addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
9456addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
9457
9458if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::fi))
9459addOptionalImmOperand(Inst,Operands, OptionalIdx,
9460 AMDGPUOperand::ImmTyDppFI);
9461 }
9462}
9463
9464void AMDGPUAsmParser::cvtDPP(MCInst &Inst,constOperandVector &Operands,bool IsDPP8) {
9465 OptionalImmIndexMap OptionalIdx;
9466
9467unsignedI = 1;
9468constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
9469for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
9470 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
9471 }
9472
9473int Fi = 0;
9474for (unsigned E =Operands.size();I != E; ++I) {
9475auto TiedTo =Desc.getOperandConstraint(Inst.getNumOperands(),
9476MCOI::TIED_TO);
9477if (TiedTo != -1) {
9478assert((unsigned)TiedTo < Inst.getNumOperands());
9479// handle tied old or src2 for MAC instructions
9480 Inst.addOperand(Inst.getOperand(TiedTo));
9481 }
9482 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
9483// Add the register arguments
9484if (Op.isReg() && validateVccOperand(Op.getReg())) {
9485// VOP2b (v_add_u32, v_sub_u32 ...) dpp use "vcc" token.
9486// Skip it.
9487continue;
9488 }
9489
9490if (IsDPP8) {
9491if (Op.isDPP8()) {
9492Op.addImmOperands(Inst, 1);
9493 }elseif (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
9494Op.addRegWithFPInputModsOperands(Inst, 2);
9495 }elseif (Op.isDppFI()) {
9496 Fi =Op.getImm();
9497 }elseif (Op.isReg()) {
9498Op.addRegOperands(Inst, 1);
9499 }else {
9500llvm_unreachable("Invalid operand type");
9501 }
9502 }else {
9503if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
9504Op.addRegWithFPInputModsOperands(Inst, 2);
9505 }elseif (Op.isReg()) {
9506Op.addRegOperands(Inst, 1);
9507 }elseif (Op.isDPPCtrl()) {
9508Op.addImmOperands(Inst, 1);
9509 }elseif (Op.isImm()) {
9510// Handle optional arguments
9511 OptionalIdx[Op.getImmTy()] =I;
9512 }else {
9513llvm_unreachable("Invalid operand type");
9514 }
9515 }
9516 }
9517
9518if (IsDPP8) {
9519using namespacellvm::AMDGPU::DPP;
9520 Inst.addOperand(MCOperand::createImm(Fi? DPP8_FI_1 : DPP8_FI_0));
9521 }else {
9522addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppRowMask, 0xf);
9523addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBankMask, 0xf);
9524addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyDppBoundCtrl);
9525if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::fi)) {
9526addOptionalImmOperand(Inst,Operands, OptionalIdx,
9527 AMDGPUOperand::ImmTyDppFI);
9528 }
9529 }
9530}
9531
9532//===----------------------------------------------------------------------===//
9533// sdwa
9534//===----------------------------------------------------------------------===//
9535
9536ParseStatus AMDGPUAsmParser::parseSDWASel(OperandVector &Operands,
9537StringRef Prefix,
9538 AMDGPUOperand::ImmTyType) {
9539return parseStringOrIntWithPrefix(
9540Operands, Prefix,
9541 {"BYTE_0","BYTE_1","BYTE_2","BYTE_3","WORD_0","WORD_1","DWORD"},
9542Type);
9543}
9544
9545ParseStatus AMDGPUAsmParser::parseSDWADstUnused(OperandVector &Operands) {
9546return parseStringOrIntWithPrefix(
9547Operands,"dst_unused", {"UNUSED_PAD","UNUSED_SEXT","UNUSED_PRESERVE"},
9548 AMDGPUOperand::ImmTySDWADstUnused);
9549}
9550
9551void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst,constOperandVector &Operands) {
9552 cvtSDWA(Inst,Operands,SIInstrFlags::VOP1);
9553}
9554
9555void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst,constOperandVector &Operands) {
9556 cvtSDWA(Inst,Operands,SIInstrFlags::VOP2);
9557}
9558
9559void AMDGPUAsmParser::cvtSdwaVOP2b(MCInst &Inst,constOperandVector &Operands) {
9560 cvtSDWA(Inst,Operands,SIInstrFlags::VOP2,true,true);
9561}
9562
9563void AMDGPUAsmParser::cvtSdwaVOP2e(MCInst &Inst,constOperandVector &Operands) {
9564 cvtSDWA(Inst,Operands,SIInstrFlags::VOP2,false,true);
9565}
9566
9567void AMDGPUAsmParser::cvtSdwaVOPC(MCInst &Inst,constOperandVector &Operands) {
9568 cvtSDWA(Inst,Operands,SIInstrFlags::VOPC,isVI());
9569}
9570
9571void AMDGPUAsmParser::cvtSDWA(MCInst &Inst,constOperandVector &Operands,
9572uint64_t BasicInstType,
9573bool SkipDstVcc,
9574bool SkipSrcVcc) {
9575using namespacellvm::AMDGPU::SDWA;
9576
9577 OptionalImmIndexMap OptionalIdx;
9578bool SkipVcc = SkipDstVcc || SkipSrcVcc;
9579bool SkippedVcc =false;
9580
9581unsignedI = 1;
9582constMCInstrDesc &Desc = MII.get(Inst.getOpcode());
9583for (unsigned J = 0; J <Desc.getNumDefs(); ++J) {
9584 ((AMDGPUOperand &)*Operands[I++]).addRegOperands(Inst, 1);
9585 }
9586
9587for (unsigned E =Operands.size();I != E; ++I) {
9588 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
9589if (SkipVcc && !SkippedVcc &&Op.isReg() &&
9590 (Op.getReg() == AMDGPU::VCC ||Op.getReg() == AMDGPU::VCC_LO)) {
9591// VOP2b (v_add_u32, v_sub_u32 ...) sdwa use "vcc" token as dst.
9592// Skip it if it's 2nd (e.g. v_add_i32_sdwa v1, vcc, v2, v3)
9593// or 4th (v_addc_u32_sdwa v1, vcc, v2, v3, vcc) operand.
9594// Skip VCC only if we didn't skip it on previous iteration.
9595// Note that src0 and src1 occupy 2 slots each because of modifiers.
9596if (BasicInstType ==SIInstrFlags::VOP2 &&
9597 ((SkipDstVcc && Inst.getNumOperands() == 1) ||
9598 (SkipSrcVcc && Inst.getNumOperands() == 5))) {
9599 SkippedVcc =true;
9600continue;
9601 }
9602if (BasicInstType ==SIInstrFlags::VOPC && Inst.getNumOperands() == 0) {
9603 SkippedVcc =true;
9604continue;
9605 }
9606 }
9607if (isRegOrImmWithInputMods(Desc, Inst.getNumOperands())) {
9608Op.addRegOrImmWithInputModsOperands(Inst, 2);
9609 }elseif (Op.isImm()) {
9610// Handle optional arguments
9611 OptionalIdx[Op.getImmTy()] =I;
9612 }else {
9613llvm_unreachable("Invalid operand type");
9614 }
9615 SkippedVcc =false;
9616 }
9617
9618constunsigned Opc = Inst.getOpcode();
9619if (Opc != AMDGPU::V_NOP_sdwa_gfx10 && Opc != AMDGPU::V_NOP_sdwa_gfx9 &&
9620 Opc != AMDGPU::V_NOP_sdwa_vi) {
9621// v_nop_sdwa_sdwa_vi/gfx9 has no optional sdwa arguments
9622switch (BasicInstType) {
9623caseSIInstrFlags::VOP1:
9624if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::clamp))
9625addOptionalImmOperand(Inst,Operands, OptionalIdx,
9626 AMDGPUOperand::ImmTyClamp, 0);
9627
9628if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::omod))
9629addOptionalImmOperand(Inst,Operands, OptionalIdx,
9630 AMDGPUOperand::ImmTyOModSI, 0);
9631
9632if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::dst_sel))
9633addOptionalImmOperand(Inst,Operands, OptionalIdx,
9634 AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9635
9636if (AMDGPU::hasNamedOperand(Opc, AMDGPU::OpName::dst_unused))
9637addOptionalImmOperand(Inst,Operands, OptionalIdx,
9638 AMDGPUOperand::ImmTySDWADstUnused,
9639 DstUnused::UNUSED_PRESERVE);
9640
9641addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9642break;
9643
9644caseSIInstrFlags::VOP2:
9645addOptionalImmOperand(Inst,Operands, OptionalIdx,
9646 AMDGPUOperand::ImmTyClamp, 0);
9647
9648if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::omod))
9649addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTyOModSI, 0);
9650
9651addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstSel, SdwaSel::DWORD);
9652addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWADstUnused, DstUnused::UNUSED_PRESERVE);
9653addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9654addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
9655break;
9656
9657caseSIInstrFlags::VOPC:
9658if (AMDGPU::hasNamedOperand(Inst.getOpcode(), AMDGPU::OpName::clamp))
9659addOptionalImmOperand(Inst,Operands, OptionalIdx,
9660 AMDGPUOperand::ImmTyClamp, 0);
9661addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc0Sel, SdwaSel::DWORD);
9662addOptionalImmOperand(Inst,Operands, OptionalIdx, AMDGPUOperand::ImmTySDWASrc1Sel, SdwaSel::DWORD);
9663break;
9664
9665default:
9666llvm_unreachable("Invalid instruction type. Only VOP1, VOP2 and VOPC allowed");
9667 }
9668 }
9669
9670// special case v_mac_{f16, f32}:
9671// it has src2 register operand that is tied to dst operand
9672if (Inst.getOpcode() == AMDGPU::V_MAC_F32_sdwa_vi ||
9673 Inst.getOpcode() == AMDGPU::V_MAC_F16_sdwa_vi) {
9674auto *it = Inst.begin();
9675 std::advance(
9676 it,AMDGPU::getNamedOperandIdx(Inst.getOpcode(), AMDGPU::OpName::src2));
9677 Inst.insert(it, Inst.getOperand(0));// src2 = dst
9678 }
9679}
9680
9681/// Force static initialization.
9682extern"C"LLVM_EXTERNAL_VISIBILITYvoidLLVMInitializeAMDGPUAsmParser() {
9683RegisterMCAsmParser<AMDGPUAsmParser>A(getTheR600Target());
9684RegisterMCAsmParser<AMDGPUAsmParser>B(getTheGCNTarget());
9685}
9686
9687#define GET_REGISTER_MATCHER
9688#define GET_MATCHER_IMPLEMENTATION
9689#define GET_MNEMONIC_SPELL_CHECKER
9690#define GET_MNEMONIC_CHECKER
9691#include "AMDGPUGenAsmMatcher.inc"
9692
9693ParseStatus AMDGPUAsmParser::parseCustomOperand(OperandVector &Operands,
9694unsigned MCK) {
9695switch (MCK) {
9696case MCK_addr64:
9697return parseTokenOp("addr64",Operands);
9698case MCK_done:
9699return parseTokenOp("done",Operands);
9700case MCK_idxen:
9701return parseTokenOp("idxen",Operands);
9702case MCK_lds:
9703return parseTokenOp("lds",Operands);
9704case MCK_offen:
9705return parseTokenOp("offen",Operands);
9706case MCK_off:
9707return parseTokenOp("off",Operands);
9708case MCK_row_95_en:
9709return parseTokenOp("row_en",Operands);
9710case MCK_gds:
9711return parseNamedBit("gds",Operands, AMDGPUOperand::ImmTyGDS);
9712case MCK_tfe:
9713return parseNamedBit("tfe",Operands, AMDGPUOperand::ImmTyTFE);
9714 }
9715return tryCustomParseOperand(Operands, MCK);
9716}
9717
9718// This function should be defined after auto-generated include so that we have
9719// MatchClassKind enum defined
9720unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
9721unsigned Kind) {
9722// Tokens like "glc" would be parsed as immediate operands in ParseOperand().
9723// But MatchInstructionImpl() expects to meet token and fails to validate
9724// operand. This method checks if we are given immediate operand but expect to
9725// get corresponding token.
9726 AMDGPUOperand &Operand = (AMDGPUOperand&)Op;
9727switch (Kind) {
9728case MCK_addr64:
9729return Operand.isAddr64() ? Match_Success : Match_InvalidOperand;
9730case MCK_gds:
9731return Operand.isGDS() ? Match_Success : Match_InvalidOperand;
9732case MCK_lds:
9733return Operand.isLDS() ? Match_Success : Match_InvalidOperand;
9734case MCK_idxen:
9735return Operand.isIdxen() ? Match_Success : Match_InvalidOperand;
9736case MCK_offen:
9737return Operand.isOffen() ? Match_Success : Match_InvalidOperand;
9738case MCK_tfe:
9739return Operand.isTFE() ? Match_Success : Match_InvalidOperand;
9740case MCK_SSrc_b32:
9741// When operands have expression values, they will return true for isToken,
9742// because it is not possible to distinguish between a token and an
9743// expression at parse time. MatchInstructionImpl() will always try to
9744// match an operand as a token, when isToken returns true, and when the
9745// name of the expression is not a valid token, the match will fail,
9746// so we need to handle it here.
9747return Operand.isSSrc_b32() ? Match_Success : Match_InvalidOperand;
9748case MCK_SSrc_f32:
9749return Operand.isSSrc_f32() ? Match_Success : Match_InvalidOperand;
9750case MCK_SOPPBrTarget:
9751return Operand.isSOPPBrTarget() ? Match_Success : Match_InvalidOperand;
9752case MCK_VReg32OrOff:
9753return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
9754case MCK_InterpSlot:
9755return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
9756case MCK_InterpAttr:
9757return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
9758case MCK_InterpAttrChan:
9759return Operand.isInterpAttrChan() ? Match_Success : Match_InvalidOperand;
9760case MCK_SReg_64:
9761case MCK_SReg_64_XEXEC:
9762// Null is defined as a 32-bit register but
9763// it should also be enabled with 64-bit operands or larger.
9764// The following code enables it for SReg_64 and larger operands
9765// used as source and destination. Remaining source
9766// operands are handled in isInlinableImm.
9767case MCK_SReg_96:
9768case MCK_SReg_128:
9769case MCK_SReg_256:
9770case MCK_SReg_512:
9771return Operand.isNull() ? Match_Success : Match_InvalidOperand;
9772default:
9773return Match_InvalidOperand;
9774 }
9775}
9776
9777//===----------------------------------------------------------------------===//
9778// endpgm
9779//===----------------------------------------------------------------------===//
9780
9781ParseStatus AMDGPUAsmParser::parseEndpgm(OperandVector &Operands) {
9782SMLoc S = getLoc();
9783 int64_tImm = 0;
9784
9785if (!parseExpr(Imm)) {
9786// The operand is optional, if not present default to 0
9787Imm = 0;
9788 }
9789
9790if (!isUInt<16>(Imm))
9791returnError(S,"expected a 16-bit value");
9792
9793Operands.push_back(
9794 AMDGPUOperand::CreateImm(this,Imm, S, AMDGPUOperand::ImmTyEndpgm));
9795returnParseStatus::Success;
9796}
9797
9798bool AMDGPUOperand::isEndpgm() const{return isImmTy(ImmTyEndpgm); }
9799
9800//===----------------------------------------------------------------------===//
9801// Split Barrier
9802//===----------------------------------------------------------------------===//
9803
9804bool AMDGPUOperand::isSplitBarrier() const{return isInlinableImm(MVT::i32); }
SubReg
unsigned SubReg
Definition:AArch64AdvSIMDScalarPass.cpp:104
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
Success
#define Success
Definition:AArch64Disassembler.cpp:220
none
@ none
Definition:AArch64StackTagging.cpp:81
LLVMInitializeAMDGPUAsmParser
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
Definition:AMDGPUAsmParser.cpp:9682
checkWriteLane
static bool checkWriteLane(const MCInst &Inst)
Definition:AMDGPUAsmParser.cpp:3735
getRegNum
static bool getRegNum(StringRef Str, unsigned &Num)
Definition:AMDGPUAsmParser.cpp:2797
RegularRegisters
static constexpr RegInfo RegularRegisters[]
Definition:AMDGPUAsmParser.cpp:2775
getRegularRegInfo
static const RegInfo * getRegularRegInfo(StringRef Str)
Definition:AMDGPUAsmParser.cpp:2790
getAllVariants
static ArrayRef< unsigned > getAllVariants()
Definition:AMDGPUAsmParser.cpp:3518
getSrcOperandIndices
static OperandIndices getSrcOperandIndices(unsigned Opcode, bool AddMandatoryLiterals=false)
Definition:AMDGPUAsmParser.cpp:3691
IsMovrelsSDWAOpcode
static bool IsMovrelsSDWAOpcode(const unsigned Opcode)
Definition:AMDGPUAsmParser.cpp:4097
getFltSemantics
static const fltSemantics * getFltSemantics(unsigned Size)
Definition:AMDGPUAsmParser.cpp:1928
isRegularReg
static bool isRegularReg(RegisterKind Kind)
Definition:AMDGPUAsmParser.cpp:2783
ConvertOmodMul
static bool ConvertOmodMul(int64_t &Mul)
Definition:AMDGPUAsmParser.cpp:8519
PARSE_BITS_ENTRY
#define PARSE_BITS_ENTRY(FIELD, ENTRY, VALUE, RANGE)
isInlineableLiteralOp16
static bool isInlineableLiteralOp16(int64_t Val, MVT VT, bool HasInv2Pi)
Definition:AMDGPUAsmParser.cpp:2023
canLosslesslyConvertToFPType
static bool canLosslesslyConvertToFPType(APFloat &FPLiteral, MVT VT)
Definition:AMDGPUAsmParser.cpp:2001
MIMGFlags
constexpr uint64_t MIMGFlags
Definition:AMDGPUAsmParser.cpp:3892
AMDGPUCheckMnemonic
static bool AMDGPUCheckMnemonic(StringRef Mnemonic, const FeatureBitset &AvailableFeatures, unsigned VariantID)
applyMnemonicAliases
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
MAX_SRC_OPERANDS_NUM
constexpr unsigned MAX_SRC_OPERANDS_NUM
Definition:AMDGPUAsmParser.cpp:3686
EXPR_RESOLVE_OR_ERROR
#define EXPR_RESOLVE_OR_ERROR(RESOLVED)
ConvertOmodDiv
static bool ConvertOmodDiv(int64_t &Div)
Definition:AMDGPUAsmParser.cpp:8527
addSrcModifiersAndSrc
static void addSrcModifiersAndSrc(MCInst &Inst, const OperandVector &Operands, unsigned i, unsigned Opc, unsigned OpName)
Definition:AMDGPUAsmParser.cpp:8979
IsRevOpcode
static bool IsRevOpcode(const unsigned Opcode)
Definition:AMDGPUAsmParser.cpp:4299
getRegClass
static int getRegClass(RegisterKind Is, unsigned RegWidth)
Definition:AMDGPUAsmParser.cpp:2533
addOptionalImmOperand
static void addOptionalImmOperand(MCInst &Inst, const OperandVector &Operands, AMDGPUAsmParser::OptionalImmIndexMap &OptionalIdx, AMDGPUOperand::ImmTy ImmT, int64_t Default=0)
Definition:AMDGPUAsmParser.cpp:6768
encodeCnt
static bool encodeCnt(const AMDGPU::IsaVersion ISA, int64_t &IntVal, int64_t CntVal, bool Saturate, unsigned(*encode)(const IsaVersion &Version, unsigned, unsigned), unsigned(*decode)(const IsaVersion &Version, unsigned))
Definition:AMDGPUAsmParser.cpp:7196
getSpecialRegForName
static MCRegister getSpecialRegForName(StringRef RegName)
Definition:AMDGPUAsmParser.cpp:2646
cvtVOP3DstOpSelOnly
static void cvtVOP3DstOpSelOnly(MCInst &Inst, const MCRegisterInfo &MRI)
Definition:AMDGPUAsmParser.cpp:8640
isRegOrImmWithInputMods
static bool isRegOrImmWithInputMods(const MCInstrDesc &Desc, unsigned OpNum)
Definition:AMDGPUAsmParser.cpp:8687
getOpFltSemantics
static const fltSemantics * getOpFltSemantics(uint8_t OperandType)
Definition:AMDGPUAsmParser.cpp:1945
isInvalidVOPDY
static bool isInvalidVOPDY(const OperandVector &Operands, uint64_t InvalidOprIdx)
Definition:AMDGPUAsmParser.cpp:5324
AMDGPUMnemonicSpellCheck
static std::string AMDGPUMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
encodeBitmaskPerm
static LLVM_READNONE unsigned encodeBitmaskPerm(const unsigned AndMask, const unsigned OrMask, const unsigned XorMask)
Definition:AMDGPUAsmParser.cpp:8031
isSafeTruncation
static bool isSafeTruncation(int64_t Val, unsigned Size)
Definition:AMDGPUAsmParser.cpp:2019
IsAGPROperand
static int IsAGPROperand(const MCInst &Inst, uint16_t NameIdx, const MCRegisterInfo *MRI)
Definition:AMDGPUAsmParser.cpp:4808
AMDGPUAsmUtils.h
AMDGPUBaseInfo.h
AMDGPUInstPrinter.h
AMDGPUMCExpr.h
AMDGPUMCKernelDescriptor.h
AMDHSA kernel descriptor MCExpr struct for use in MC layer.
AMDGPUMCTargetDesc.h
Provides AMDGPU specific target descriptions.
AMDGPUMetadata.h
AMDGPU metadata definitions and in-memory representations.
AMDGPUTargetInfo.h
AMDGPUTargetStreamer.h
AMDHSAKernelDescriptor.h
AMDHSA kernel descriptor definitions.
parseExpr
static bool parseExpr(MCAsmParser &MCParser, const MCExpr *&Value, raw_ostream &Err)
Definition:AMDKernelCodeTUtils.cpp:323
AMDKernelCodeTUtils.h
MC layer struct for AMDGPUMCKernelCodeT, provides MCExpr functionality where required.
AMDKernelCodeT.h
AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
@ AMD_CODE_PROPERTY_ENABLE_WAVEFRONT_SIZE32
Definition:AMDKernelCodeT.h:127
APFloat.h
This file declares a class to represent arbitrary precision floating point values and provide a varie...
print
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
Definition:ArchiveWriter.cpp:205
ELF.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
Casting.h
LLVM_READNONE
#define LLVM_READNONE
Definition:Compiler.h:299
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition:Compiler.h:128
Idx
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Definition:DeadArgumentElimination.cpp:353
Default
@ Default
Definition:DwarfDebug.cpp:87
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Sym
Symbol * Sym
Definition:ELF_riscv.cpp:479
getOperandSize
static unsigned getOperandSize(MachineInstr &MI, unsigned Idx, MachineRegisterInfo &MRI)
Definition:GCNDPPCombine.cpp:199
Check
#define Check(C,...)
Definition:GenericConvergenceVerifierImpl.h:34
decode
static llvm::Expected< InlineInfo > decode(DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr)
Decode an InlineInfo in Data at the specified offset.
Definition:InlineInfo.cpp:179
RegName
#define RegName(no)
Options
static LVOptions Options
Definition:LVOptions.cpp:25
MCAsmInfo.h
MCAsmLexer.h
MCAsmParser.h
MCContext.h
MCExpr.h
MCInst.h
MCInstrDesc.h
MCParsedAsmOperand.h
MCSymbol.h
MCTargetAsmParser.h
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
Operands
mir Rename Register Operands
Definition:MIRNamerPass.cpp:74
TRI
unsigned const TargetRegisterInfo * TRI
Definition:MachineSink.cpp:2029
MachineValueType.h
MathExtras.h
getReg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Definition:MipsDisassembler.cpp:520
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition:MipsInstPrinter.cpp:31
Range
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
P
#define P(N)
SIDefines.h
SIInstrInfo.h
Interface definition for SIInstrInfo.
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
isImm
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
Definition:SPIRVInstructionSelector.cpp:2719
DefaultVal
unsigned unsigned DefaultVal
Definition:SPIRVModuleAnalysis.cpp:64
OS
raw_pwrite_stream & OS
Definition:SampleProfWriter.cpp:51
contains
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition:Value.cpp:469
SmallBitVector.h
This file implements the SmallBitVector class.
Enabled
static bool Enabled
Definition:Statistic.cpp:46
StringSet.h
StringSet - A set-like wrapper for the StringMap.
initialize
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
Definition:TargetLibraryInfo.cpp:917
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
Int
@ Int
Definition:TargetLibraryInfo.cpp:65
TargetParser.h
TargetRegistry.h
Twine.h
Mul
BinaryOperator * Mul
Definition:X86PartialReduction.cpp:68
Lo
support::ulittle16_t & Lo
Definition:aarch32.cpp:204
Hi
support::ulittle16_t & Hi
Definition:aarch32.cpp:203
llvm::AMDGPUInstPrinter::getRegisterName
static const char * getRegisterName(MCRegister Reg)
llvm::AMDGPUMCExpr::createMax
static const AMDGPUMCExpr * createMax(ArrayRef< const MCExpr * > Args, MCContext &Ctx)
Definition:AMDGPUMCExpr.h:69
llvm::AMDGPUMCExpr::create
static const AMDGPUMCExpr * create(VariantKind Kind, ArrayRef< const MCExpr * > Args, MCContext &Ctx)
Definition:AMDGPUMCExpr.cpp:45
llvm::AMDGPUMCExpr::createExtraSGPRs
static const AMDGPUMCExpr * createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, bool XNACKUsed, MCContext &Ctx)
Allow delayed MCExpr resolve of ExtraSGPRs (in case VCCUsed or FlatScrUsed are unresolvable but neede...
Definition:AMDGPUMCExpr.cpp:266
llvm::AMDGPUMCExpr::createAlignTo
static const AMDGPUMCExpr * createAlignTo(const MCExpr *Value, const MCExpr *Align, MCContext &Ctx)
Definition:AMDGPUMCExpr.h:83
llvm::AMDGPUMCExpr::VariantKind
VariantKind
Definition:AMDGPUMCExpr.h:32
llvm::AMDGPUTargetStreamer
Definition:AMDGPUTargetStreamer.h:31
llvm::APFloat
Definition:APFloat.h:904
llvm::APFloat::convert
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, bool *losesInfo)
Definition:APFloat.cpp:5463
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ArrayRef::end
iterator end() const
Definition:ArrayRef.h:157
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition:ArrayRef.h:168
llvm::AsmToken
Target independent representation for an assembler token.
Definition:MCAsmMacro.h:21
llvm::AsmToken::getString
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
Definition:MCAsmMacro.h:110
llvm::AsmToken::is
bool is(TokenKind K) const
Definition:MCAsmMacro.h:82
llvm::AsmToken::getKind
TokenKind getKind() const
Definition:MCAsmMacro.h:81
llvm::AsmToken::TokenKind
TokenKind
Definition:MCAsmMacro.h:23
llvm::AsmToken::Minus
@ Minus
Definition:MCAsmMacro.h:45
llvm::AsmToken::Eof
@ Eof
Definition:MCAsmMacro.h:25
llvm::AsmToken::String
@ String
Definition:MCAsmMacro.h:29
llvm::AsmToken::Error
@ Error
Definition:MCAsmMacro.h:25
llvm::AsmToken::Space
@ Space
Definition:MCAsmMacro.h:44
llvm::AsmToken::Integer
@ Integer
Definition:MCAsmMacro.h:32
llvm::AsmToken::RBrac
@ RBrac
Definition:MCAsmMacro.h:48
llvm::AsmToken::Colon
@ Colon
Definition:MCAsmMacro.h:43
llvm::AsmToken::LBrac
@ LBrac
Definition:MCAsmMacro.h:48
llvm::AsmToken::RCurly
@ RCurly
Definition:MCAsmMacro.h:48
llvm::AsmToken::Pipe
@ Pipe
Definition:MCAsmMacro.h:51
llvm::AsmToken::Identifier
@ Identifier
Definition:MCAsmMacro.h:28
llvm::AsmToken::Amp
@ Amp
Definition:MCAsmMacro.h:52
llvm::AsmToken::LParen
@ LParen
Definition:MCAsmMacro.h:48
llvm::AsmToken::LCurly
@ LCurly
Definition:MCAsmMacro.h:48
llvm::AsmToken::RParen
@ RParen
Definition:MCAsmMacro.h:48
llvm::AsmToken::Comma
@ Comma
Definition:MCAsmMacro.h:49
llvm::AsmToken::Real
@ Real
Definition:MCAsmMacro.h:36
llvm::AsmToken::EndOfStatement
@ EndOfStatement
Definition:MCAsmMacro.h:42
llvm::DWARFExpression::Operation
This class represents an Operation in the Expression.
Definition:DWARFExpression.h:32
llvm::DstOp
Definition:MachineIRBuilder.h:70
llvm::DstOp::getReg
Register getReg() const
Definition:MachineIRBuilder.h:121
llvm::ErrorInfo
Base class for user error types.
Definition:Error.h:355
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expression
Class representing an expression and its matching format.
Definition:FileCheckImpl.h:189
llvm::FeatureBitset
Container class for subtarget features.
Definition:SubtargetFeature.h:41
llvm::FeatureBitset::test
constexpr bool test(unsigned I) const
Definition:SubtargetFeature.h:82
llvm::FeatureBitset::flip
constexpr FeatureBitset & flip(unsigned I)
Definition:SubtargetFeature.h:72
llvm::MCAsmParserExtension::Initialize
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Definition:MCAsmParserExtension.cpp:21
llvm::MCAsmParserExtension::getContext
MCContext & getContext()
Definition:MCAsmParserExtension.h:54
llvm::MCAsmParserExtension::getParser
MCAsmParser & getParser()
Definition:MCAsmParserExtension.h:61
llvm::MCAsmParser
Generic assembler parser interface, for use by target specific assembly parsers.
Definition:MCAsmParser.h:123
llvm::MCAsmParser::getStreamer
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
llvm::MCBinaryExpr::createAdd
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition:MCExpr.h:537
llvm::MCBinaryExpr::createDiv
static const MCBinaryExpr * createDiv(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition:MCExpr.h:547
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition:MCExpr.h:622
llvm::MCConstantExpr::create
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition:MCExpr.cpp:222
llvm::MCContext
Context object for machine code objects.
Definition:MCContext.h:83
llvm::MCContext::getRegisterInfo
const MCRegisterInfo * getRegisterInfo() const
Definition:MCContext.h:414
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition:MCContext.cpp:212
llvm::MCContext::getSubtargetInfo
const MCSubtargetInfo * getSubtargetInfo() const
Definition:MCContext.h:418
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition:MCExpr.h:34
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition:MCInst.h:185
llvm::MCInst::getNumOperands
unsigned getNumOperands() const
Definition:MCInst.h:209
llvm::MCInst::getLoc
SMLoc getLoc() const
Definition:MCInst.h:205
llvm::MCInst::setLoc
void setLoc(SMLoc loc)
Definition:MCInst.h:204
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition:MCInst.h:199
llvm::MCInst::insert
iterator insert(iterator I, const MCOperand &Op)
Definition:MCInst.h:225
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition:MCInst.h:211
llvm::MCInst::begin
iterator begin()
Definition:MCInst.h:220
llvm::MCInst::size
size_t size() const
Definition:MCInst.h:219
llvm::MCInst::getOperand
const MCOperand & getOperand(unsigned i) const
Definition:MCInst.h:207
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition:MCInstrDesc.h:198
llvm::MCInstrDesc::mayStore
bool mayStore() const
Return true if this instruction could possibly modify memory.
Definition:MCInstrDesc.h:444
llvm::MCInstrDesc::TSFlags
uint64_t TSFlags
Definition:MCInstrDesc.h:215
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition:MCInstrInfo.h:26
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition:MCInstrInfo.h:63
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition:MCInst.h:37
llvm::MCOperand::setImm
void setImm(int64_t Val)
Definition:MCInst.h:86
llvm::MCOperand::createExpr
static MCOperand createExpr(const MCExpr *Val)
Definition:MCInst.h:163
llvm::MCOperand::getImm
int64_t getImm() const
Definition:MCInst.h:81
llvm::MCOperand::createReg
static MCOperand createReg(MCRegister Reg)
Definition:MCInst.h:135
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition:MCInst.h:142
llvm::MCOperand::isImm
bool isImm() const
Definition:MCInst.h:63
llvm::MCOperand::setReg
void setReg(MCRegister Reg)
Set the register number.
Definition:MCInst.h:76
llvm::MCOperand::isReg
bool isReg() const
Definition:MCInst.h:62
llvm::MCOperand::getReg
MCRegister getReg() const
Returns the register number.
Definition:MCInst.h:70
llvm::MCOperand::isExpr
bool isExpr() const
Definition:MCInst.h:66
llvm::MCParsedAsmOperand
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
Definition:MCParsedAsmOperand.h:25
llvm::MCParsedAsmOperand::isReg
virtual bool isReg() const =0
isReg - Is this a register operand?
llvm::MCParsedAsmOperand::isMem
virtual bool isMem() const =0
isMem - Is this a memory operand?
llvm::MCParsedAsmOperand::getReg
virtual MCRegister getReg() const =0
llvm::MCParsedAsmOperand::isToken
virtual bool isToken() const =0
isToken - Is this a token operand?
llvm::MCParsedAsmOperand::isImm
virtual bool isImm() const =0
isImm - Is this an immediate operand?
llvm::MCRegisterClass
MCRegisterClass - Base class of TargetRegisterClass.
Definition:MCRegisterInfo.h:35
llvm::MCRegisterClass::getNumRegs
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
Definition:MCRegisterInfo.h:62
llvm::MCRegisterClass::getRegister
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
Definition:MCRegisterInfo.h:66
llvm::MCRegisterClass::contains
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
Definition:MCRegisterInfo.h:73
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition:MCRegisterInfo.h:149
llvm::MCRegister
Wrapper class representing physical registers. Should be passed by value.
Definition:MCRegister.h:33
llvm::MCRegister::isValid
constexpr bool isValid() const
Definition:MCRegister.h:85
llvm::MCStreamer
Streaming machine code generation interface.
Definition:MCStreamer.h:213
llvm::MCStreamer::emitInstruction
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Definition:MCStreamer.cpp:1145
llvm::MCStreamer::getTargetStreamer
MCTargetStreamer * getTargetStreamer()
Definition:MCStreamer.h:309
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition:MCSubtargetInfo.h:76
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition:MCSubtargetInfo.h:114
llvm::MCSubtargetInfo::ToggleFeature
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Definition:MCSubtargetInfo.cpp:261
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition:MCSymbol.h:41
llvm::MCSymbol::setVariableValue
void setVariableValue(const MCExpr *Value)
Definition:MCSymbol.cpp:47
llvm::MCTargetAsmParser
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Definition:MCTargetAsmParser.h:352
llvm::MCTargetAsmParser::parseInstruction
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
llvm::MCTargetAsmParser::copySTI
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
Definition:MCTargetAsmParser.cpp:22
llvm::MCTargetAsmParser::parseRegister
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
llvm::MCTargetAsmParser::ParseDirective
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
Definition:MCTargetAsmParser.h:460
llvm::MCTargetAsmParser::tryParseRegister
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
llvm::MCTargetAsmParser::matchAndEmitInstruction
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
llvm::MCTargetAsmParser::MII
const MCInstrInfo & MII
Definition:MCTargetAsmParser.h:387
llvm::MCTargetAsmParser::setAvailableFeatures
void setAvailableFeatures(const FeatureBitset &Value)
Definition:MCTargetAsmParser.h:400
llvm::MCTargetAsmParser::getSTI
const MCSubtargetInfo & getSTI() const
Definition:MCTargetAsmParser.cpp:28
llvm::MCTargetAsmParser::validateTargetOperandClass
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Definition:MCTargetAsmParser.h:492
llvm::MCTargetAsmParser::checkTargetMatchPredicate
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
Definition:MCTargetAsmParser.h:506
llvm::MCTargetOptions
Definition:MCTargetOptions.h:39
llvm::MCTargetStreamer
Target specific streamer interface.
Definition:MCStreamer.h:94
llvm::MVT
Machine Value Type.
Definition:MachineValueType.h:35
llvm::MVT::SimpleTy
SimpleValueType SimpleTy
Definition:MachineValueType.h:55
llvm::MVT::getScalarSizeInBits
uint64_t getScalarSizeInBits() const
Definition:MachineValueType.h:346
llvm::MVT::getSizeInBits
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
Definition:MachineValueType.h:308
llvm::MVT::getScalarType
MVT getScalarType() const
If this is a vector, return the element type, otherwise return this.
Definition:MachineValueType.h:259
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition:ArrayRef.h:310
llvm::ParseStatus
Ternary parse status returned by various parse* methods.
Definition:MCTargetAsmParser.h:132
llvm::ParseStatus::isFailure
constexpr bool isFailure() const
Definition:MCTargetAsmParser.h:153
llvm::ParseStatus::Failure
static constexpr StatusTy Failure
Definition:MCTargetAsmParser.h:140
llvm::ParseStatus::isSuccess
constexpr bool isSuccess() const
Definition:MCTargetAsmParser.h:152
llvm::ParseStatus::Success
static constexpr StatusTy Success
Definition:MCTargetAsmParser.h:139
llvm::ParseStatus::NoMatch
static constexpr StatusTy NoMatch
Definition:MCTargetAsmParser.h:141
llvm::ParseStatus::isNoMatch
constexpr bool isNoMatch() const
Definition:MCTargetAsmParser.h:154
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::SMLoc
Represents a location in source code.
Definition:SMLoc.h:23
llvm::SMLoc::getFromPointer
static SMLoc getFromPointer(const char *Ptr)
Definition:SMLoc.h:36
llvm::SMLoc::getPointer
constexpr const char * getPointer() const
Definition:SMLoc.h:34
llvm::SMLoc::isValid
constexpr bool isValid() const
Definition:SMLoc.h:29
llvm::SMRange
Represents a range in source code.
Definition:SMLoc.h:48
llvm::SMRange::Start
SMLoc Start
Definition:SMLoc.h:50
llvm::SmallDenseSet
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition:DenseSet.h:298
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::pop_back_val
T pop_back_val()
Definition:SmallVector.h:673
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::SrcOp
Definition:MachineIRBuilder.h:142
llvm::SrcOp::getReg
Register getReg() const
Definition:MachineIRBuilder.h:194
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition:StringRef.h:853
llvm::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition:StringMapEntry.h:102
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::consume_back
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition:StringRef.h:655
llvm::StringRef::starts_with
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition:StringRef.h:265
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition:StringRef.h:609
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::data
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition:StringRef.h:144
llvm::StringRef::ends_with
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition:StringRef.h:277
llvm::StringSet
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition:StringSet.h:23
llvm::StringSet::contains
bool contains(StringRef key) const
Check if the set contains the given key.
Definition:StringSet.h:55
llvm::StringSet::insert
std::pair< typename Base::iterator, bool > insert(StringRef key)
Definition:StringSet.h:38
llvm::StringSwitch
A switch()-like statement whose cases are string literals.
Definition:StringSwitch.h:44
llvm::StringSwitch::Case
StringSwitch & Case(StringLiteral S, T Value)
Definition:StringSwitch.h:69
llvm::StringSwitch::Default
R Default(T Value)
Definition:StringSwitch.h:182
llvm::Triple::AMDPAL
@ AMDPAL
Definition:Triple.h:233
llvm::Triple::r600
@ r600
Definition:Triple.h:73
llvm::Triple::amdgcn
@ amdgcn
Definition:Triple.h:74
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::Value
LLVM Value Representation.
Definition:Value.h:74
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition:DenseSet.h:213
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition:raw_ostream.h:52
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition:raw_ostream.h:661
llvm::raw_svector_ostream
A raw_ostream that writes to an SmallVector or SmallString.
Definition:raw_ostream.h:691
uint16_t
uint32_t
uint64_t
uint8_t
unsigned
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
OpName
Definition:R600Defines.h:62
llvm::AMDGPUAsmVariants::DPP
@ DPP
Definition:SIDefines.h:339
llvm::AMDGPUAsmVariants::VOP3_DPP
@ VOP3_DPP
Definition:SIDefines.h:340
llvm::AMDGPUAsmVariants::SDWA9
@ SDWA9
Definition:SIDefines.h:338
llvm::AMDGPUAsmVariants::SDWA
@ SDWA
Definition:SIDefines.h:337
llvm::AMDGPUAsmVariants::VOP3
@ VOP3
Definition:SIDefines.h:336
llvm::AMDGPUAsmVariants::DEFAULT
@ DEFAULT
Definition:SIDefines.h:335
llvm::AMDGPU::CPol::CPol
CPol
Definition:SIDefines.h:380
llvm::AMDGPU::CPol::TH_NT_WB
@ TH_NT_WB
Definition:SIDefines.h:403
llvm::AMDGPU::CPol::TH_TYPE_STORE
@ TH_TYPE_STORE
Definition:SIDefines.h:426
llvm::AMDGPU::CPol::TH_ATOMIC_NT
@ TH_ATOMIC_NT
Definition:SIDefines.h:410
llvm::AMDGPU::CPol::DLC
@ DLC
Definition:SIDefines.h:383
llvm::AMDGPU::CPol::TH_ATOMIC_RETURN
@ TH_ATOMIC_RETURN
Definition:SIDefines.h:409
llvm::AMDGPU::CPol::NT
@ NT
Definition:SIDefines.h:387
llvm::AMDGPU::CPol::TH_RT_NT
@ TH_RT_NT
Definition:SIDefines.h:401
llvm::AMDGPU::CPol::SC0
@ SC0
Definition:SIDefines.h:385
llvm::AMDGPU::CPol::SLC
@ SLC
Definition:SIDefines.h:382
llvm::AMDGPU::CPol::SC1
@ SC1
Definition:SIDefines.h:386
llvm::AMDGPU::CPol::SCOPE_CU
@ SCOPE_CU
Definition:SIDefines.h:415
llvm::AMDGPU::CPol::GLC
@ GLC
Definition:SIDefines.h:381
llvm::AMDGPU::CPol::SCOPE_SYS
@ SCOPE_SYS
Definition:SIDefines.h:418
llvm::AMDGPU::CPol::TH_NT_RT
@ TH_NT_RT
Definition:SIDefines.h:400
llvm::AMDGPU::CPol::TH_RT
@ TH_RT
Definition:SIDefines.h:395
llvm::AMDGPU::CPol::SCOPE_SE
@ SCOPE_SE
Definition:SIDefines.h:416
llvm::AMDGPU::CPol::TH_LU
@ TH_LU
Definition:SIDefines.h:398
llvm::AMDGPU::CPol::SCOPE_DEV
@ SCOPE_DEV
Definition:SIDefines.h:417
llvm::AMDGPU::CPol::TH_NT_HT
@ TH_NT_HT
Definition:SIDefines.h:402
llvm::AMDGPU::CPol::TH_BYPASS
@ TH_BYPASS
Definition:SIDefines.h:404
llvm::AMDGPU::CPol::SCOPE
@ SCOPE
Definition:SIDefines.h:414
llvm::AMDGPU::CPol::TH_NT
@ TH_NT
Definition:SIDefines.h:396
llvm::AMDGPU::CPol::TH_RT_WB
@ TH_RT_WB
Definition:SIDefines.h:399
llvm::AMDGPU::CPol::SCC
@ SCC
Definition:SIDefines.h:384
llvm::AMDGPU::CPol::TH_HT
@ TH_HT
Definition:SIDefines.h:397
llvm::AMDGPU::CPol::TH
@ TH
Definition:SIDefines.h:394
llvm::AMDGPU::CPol::TH_ATOMIC_CASCADE
@ TH_ATOMIC_CASCADE
Definition:SIDefines.h:411
llvm::AMDGPU::CPol::TH_TYPE_LOAD
@ TH_TYPE_LOAD
Definition:SIDefines.h:425
llvm::AMDGPU::CPol::TH_REAL_BYPASS
@ TH_REAL_BYPASS
Definition:SIDefines.h:428
llvm::AMDGPU::CPol::TH_TYPE_ATOMIC
@ TH_TYPE_ATOMIC
Definition:SIDefines.h:427
llvm::AMDGPU::DPP
Definition:SIDefines.h:936
llvm::AMDGPU::DPP::DppCtrl
DppCtrl
Definition:SIDefines.h:939
llvm::AMDGPU::DepCtr
Definition:AMDGPUAsmUtils.cpp:68
llvm::AMDGPU::DepCtr::encodeDepCtr
int encodeDepCtr(const StringRef Name, int64_t Val, unsigned &UsedOprMask, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1704
llvm::AMDGPU::DepCtr::getDefaultDepCtrEncoding
int getDefaultDepCtrEncoding(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1685
llvm::AMDGPU::EncValues::IS_VGPR
@ IS_VGPR
Definition:SIDefines.h:363
llvm::AMDGPU::Exp
Definition:SIDefines.h:994
llvm::AMDGPU::Exp::isSupportedTgtId
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1804
llvm::AMDGPU::Exp::getTgtId
unsigned getTgtId(const StringRef Name)
Definition:AMDGPUBaseInfo.cpp:1781
llvm::AMDGPU::HSAMD::Kernel::CodeProps::Key::NumSGPRs
constexpr char NumSGPRs[]
Key for Kernel::CodeProps::Metadata::mNumSGPRs.
Definition:AMDGPUMetadata.h:259
llvm::AMDGPU::HSAMD::Kernel::Key::SymbolName
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
Definition:AMDGPUMetadata.h:387
llvm::AMDGPU::HSAMD::V3::AssemblerDirectiveBegin
constexpr char AssemblerDirectiveBegin[]
HSA metadata beginning assembler directive.
Definition:AMDGPUMetadata.h:465
llvm::AMDGPU::HSAMD::V3::AssemblerDirectiveEnd
constexpr char AssemblerDirectiveEnd[]
HSA metadata ending assembler directive.
Definition:AMDGPUMetadata.h:467
llvm::AMDGPU::HSAMD::AssemblerDirectiveBegin
constexpr char AssemblerDirectiveBegin[]
Old HSA metadata beginning assembler directive for V2.
Definition:AMDGPUMetadata.h:56
llvm::AMDGPU::HWEncoding::IS_AGPR
@ IS_AGPR
Definition:SIDefines.h:373
llvm::AMDGPU::Hwreg
Definition:SIDefines.h:503
llvm::AMDGPU::Hwreg::Id
Id
Definition:SIDefines.h:505
llvm::AMDGPU::Hwreg::Offset
Offset
Definition:SIDefines.h:553
llvm::AMDGPU::Hwreg::getHwregId
int64_t getHwregId(StringRef Name, const MCSubtargetInfo &STI)
Definition:AMDGPUAsmUtils.cpp:232
llvm::AMDGPU::IsaInfo::getVGPREncodingGranule
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
Definition:AMDGPUBaseInfo.cpp:1157
llvm::AMDGPU::IsaInfo::getSGPREncodingGranule
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
Definition:AMDGPUBaseInfo.cpp:1040
llvm::AMDGPU::IsaInfo::getLocalMemorySize
unsigned getLocalMemorySize(const MCSubtargetInfo *STI)
Definition:AMDGPUBaseInfo.cpp:946
llvm::AMDGPU::IsaInfo::FIXED_NUM_SGPRS_FOR_INIT_BUG
@ FIXED_NUM_SGPRS_FOR_INIT_BUG
Definition:AMDGPUBaseInfo.h:129
llvm::AMDGPU::IsaInfo::getAddressableNumSGPRs
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
Definition:AMDGPUBaseInfo.cpp:1051
llvm::AMDGPU::MTBUFFormat
Definition:SIDefines.h:581
llvm::AMDGPU::MTBUFFormat::DFMT_UNDEF
@ DFMT_UNDEF
Definition:SIDefines.h:604
llvm::AMDGPU::MTBUFFormat::getDefaultFormatEncoding
unsigned getDefaultFormatEncoding(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1930
llvm::AMDGPU::MTBUFFormat::NFMT_UNDEF
@ NFMT_UNDEF
Definition:SIDefines.h:625
llvm::AMDGPU::MTBUFFormat::convertDfmtNfmt2Ufmt
int64_t convertDfmtNfmt2Ufmt(unsigned Dfmt, unsigned Nfmt, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1909
llvm::AMDGPU::MTBUFFormat::encodeDfmtNfmt
int64_t encodeDfmtNfmt(unsigned Dfmt, unsigned Nfmt)
Definition:AMDGPUBaseInfo.cpp:1875
llvm::AMDGPU::MTBUFFormat::getUnifiedFormat
int64_t getUnifiedFormat(const StringRef Name, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1884
llvm::AMDGPU::MTBUFFormat::isValidFormatEncoding
bool isValidFormatEncoding(unsigned Val, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1926
llvm::AMDGPU::MTBUFFormat::getNfmt
int64_t getNfmt(const StringRef Name, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1850
llvm::AMDGPU::MTBUFFormat::getDfmt
int64_t getDfmt(const StringRef Name)
Definition:AMDGPUBaseInfo.cpp:1829
llvm::AMDGPU::MTBUFFormat::UFMT_UNDEF
@ UFMT_UNDEF
Definition:SIDefines.h:645
llvm::AMDGPU::PALMD::AssemblerDirective
constexpr char AssemblerDirective[]
PAL metadata (old linear format) assembler directive.
Definition:AMDGPUMetadata.h:478
llvm::AMDGPU::PALMD::AssemblerDirectiveBegin
constexpr char AssemblerDirectiveBegin[]
PAL metadata (new MsgPack format) beginning assembler directive.
Definition:AMDGPUMetadata.h:481
llvm::AMDGPU::PALMD::AssemblerDirectiveEnd
constexpr char AssemblerDirectiveEnd[]
PAL metadata (new MsgPack format) ending assembler directive.
Definition:AMDGPUMetadata.h:484
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition:AMDGPUMetadata.h:487
llvm::AMDGPU::SDWA
Definition:SIDefines.h:901
llvm::AMDGPU::SendMsg
Definition:SIDefines.h:437
llvm::AMDGPU::SendMsg::getMsgOpId
int64_t getMsgOpId(int64_t MsgId, StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a sendmsg operation to the operation portion of the immediate encoding.
Definition:AMDGPUAsmUtils.cpp:147
llvm::AMDGPU::SendMsg::getMsgId
int64_t getMsgId(StringRef Name, const MCSubtargetInfo &STI)
Map from a symbolic name for a msg_id to the message portion of the immediate encoding.
Definition:AMDGPUAsmUtils.cpp:139
llvm::AMDGPU::SendMsg::encodeMsg
uint64_t encodeMsg(uint64_t MsgId, uint64_t OpId, uint64_t StreamId)
Definition:AMDGPUBaseInfo.cpp:2014
llvm::AMDGPU::SendMsg::msgSupportsStream
bool msgSupportsStream(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1995
llvm::AMDGPU::SendMsg::isValidMsgId
bool isValidMsgId(int64_t MsgId, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1948
llvm::AMDGPU::SendMsg::isValidMsgStream
bool isValidMsgStream(int64_t MsgId, int64_t OpId, int64_t StreamId, const MCSubtargetInfo &STI, bool Strict)
Definition:AMDGPUBaseInfo.cpp:1969
llvm::AMDGPU::SendMsg::msgRequiresOp
bool msgRequiresOp(int64_t MsgId, const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:1989
llvm::AMDGPU::SendMsg::isValidMsgOp
bool isValidMsgOp(int64_t MsgId, int64_t OpId, const MCSubtargetInfo &STI, bool Strict)
Definition:AMDGPUBaseInfo.cpp:1952
llvm::AMDGPU::Swizzle
Definition:SIDefines.h:837
llvm::AMDGPU::Swizzle::ROTATE_DIR_SHIFT
@ ROTATE_DIR_SHIFT
Definition:SIDefines.h:892
llvm::AMDGPU::Swizzle::ROTATE_MODE_ENC
@ ROTATE_MODE_ENC
Definition:SIDefines.h:862
llvm::AMDGPU::Swizzle::FFT_MODE_ENC
@ FFT_MODE_ENC
Definition:SIDefines.h:860
llvm::AMDGPU::Swizzle::QUAD_PERM_ENC
@ QUAD_PERM_ENC
Definition:SIDefines.h:854
llvm::AMDGPU::Swizzle::LANE_NUM
@ LANE_NUM
Definition:SIDefines.h:873
llvm::AMDGPU::Swizzle::LANE_SHIFT
@ LANE_SHIFT
Definition:SIDefines.h:872
llvm::AMDGPU::Swizzle::BITMASK_WIDTH
@ BITMASK_WIDTH
Definition:SIDefines.h:879
llvm::AMDGPU::UCVersion::getGFXVersions
ArrayRef< GFXVersion > getGFXVersions()
Definition:AMDGPUAsmUtils.cpp:677
llvm::AMDGPU::VGPRIndexMode
Definition:SIDefines.h:308
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition:SIDefines.h:310
llvm::AMDGPU::VGPRIndexMode::ID_MAX
@ ID_MAX
Definition:SIDefines.h:317
llvm::AMDGPU::VGPRIndexMode::OFF
@ OFF
Definition:SIDefines.h:321
llvm::AMDGPU::VOP3PEncoding::OpSel
OpSel
Definition:SIDefines.h:1026
llvm::AMDGPU::VOPD::X
@ X
Definition:AMDGPUBaseInfo.h:658
llvm::AMDGPU::VOPD::Y
@ Y
Definition:AMDGPUBaseInfo.h:658
llvm::AMDGPU::VOPD::COMPONENTS
constexpr unsigned COMPONENTS[]
Definition:AMDGPUBaseInfo.h:659
llvm::AMDGPU
Definition:AMDGPUMetadataVerifier.h:33
llvm::AMDGPU::isInlinableLiteralBF16
bool isInlinableLiteralBF16(int16_t Literal, bool HasInv2Pi)
Definition:AMDGPUBaseInfo.cpp:2642
llvm::AMDGPU::isGFX10_BEncoding
bool isGFX10_BEncoding(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2234
llvm::AMDGPU::getMIMGInfo
LLVM_READONLY const MIMGInfo * getMIMGInfo(unsigned Opc)
llvm::AMDGPU::getRegOperandSize
unsigned getRegOperandSize(const MCRegisterInfo *MRI, const MCInstrDesc &Desc, unsigned OpNo)
Get size of register operand.
Definition:AMDGPUBaseInfo.cpp:2592
llvm::AMDGPU::isInlinableLiteralFP16
bool isInlinableLiteralFP16(int16_t Literal, bool HasInv2Pi)
Definition:AMDGPUBaseInfo.cpp:2663
llvm::AMDGPU::isSGPR
bool isSGPR(MCRegister Reg, const MCRegisterInfo *TRI)
Is Reg - scalar register.
Definition:AMDGPUBaseInfo.cpp:2281
llvm::AMDGPU::getMCReg
MCRegister getMCReg(MCRegister Reg, const MCSubtargetInfo &STI)
If Reg is a pseudo reg, return the correct hardware register given STI otherwise return Reg.
Definition:AMDGPUBaseInfo.cpp:2349
llvm::AMDGPU::isLegalDPALU_DPPControl
LLVM_READNONE bool isLegalDPALU_DPPControl(unsigned DC)
Definition:AMDGPUBaseInfo.h:1549
llvm::AMDGPU::OPR_ID_UNSUPPORTED
const int OPR_ID_UNSUPPORTED
Definition:AMDGPUAsmUtils.h:24
llvm::AMDGPU::isInlinableLiteralV2I16
bool isInlinableLiteralV2I16(uint32_t Literal)
Definition:AMDGPUBaseInfo.cpp:2794
llvm::AMDGPU::isHi16Reg
bool isHi16Reg(MCRegister Reg, const MCRegisterInfo &MRI)
Definition:AMDGPUBaseInfo.cpp:2288
llvm::AMDGPU::getTotalNumVGPRs
int32_t getTotalNumVGPRs(bool has90AInsts, int32_t ArgNumAGPR, int32_t ArgNumVGPR)
Definition:AMDGPUBaseInfo.cpp:2274
llvm::AMDGPU::isGFX10
bool isGFX10(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2186
llvm::AMDGPU::getNamedOperandIdx
LLVM_READONLY int16_t getNamedOperandIdx(uint16_t Opcode, uint16_t NamedIdx)
llvm::AMDGPU::isInlinableLiteralV2BF16
bool isInlinableLiteralV2BF16(uint32_t Literal)
Definition:AMDGPUBaseInfo.cpp:2799
llvm::AMDGPU::getMaxNumUserSGPRs
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2146
llvm::AMDGPU::getNumFlatOffsetBits
unsigned getNumFlatOffsetBits(const MCSubtargetInfo &ST)
For pre-GFX12 FLAT instructions the offset must be positive; MSB is ignored and forced to zero.
Definition:AMDGPUBaseInfo.cpp:2946
llvm::AMDGPU::hasA16
bool hasA16(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2118
llvm::AMDGPU::isLegalSMRDEncodedSignedOffset
bool isLegalSMRDEncodedSignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset, bool IsBuffer)
Definition:AMDGPUBaseInfo.cpp:2883
llvm::AMDGPU::isGFX12Plus
bool isGFX12Plus(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2210
llvm::AMDGPU::getNSAMaxSize
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
Definition:AMDGPUBaseInfo.cpp:2135
llvm::AMDGPU::hasPackedD16
bool hasPackedD16(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2126
llvm::AMDGPU::isGFX940
bool isGFX940(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2250
llvm::AMDGPU::isInlinableLiteralV2F16
bool isInlinableLiteralV2F16(uint32_t Literal)
Definition:AMDGPUBaseInfo.cpp:2804
llvm::AMDGPU::isHsaAbi
bool isHsaAbi(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:168
llvm::AMDGPU::isGFX11
bool isGFX11(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2198
llvm::AMDGPU::OPR_VAL_INVALID
const int OPR_VAL_INVALID
Definition:AMDGPUAsmUtils.h:26
llvm::AMDGPU::getSMEMIsBuffer
bool getSMEMIsBuffer(unsigned Opc)
Definition:AMDGPUBaseInfo.cpp:502
llvm::AMDGPU::Imm
@ Imm
Definition:AMDGPURegBankLegalizeRules.h:105
llvm::AMDGPU::mfmaScaleF8F6F4FormatToNumRegs
uint8_t mfmaScaleF8F6F4FormatToNumRegs(unsigned EncodingVal)
Definition:AMDGPUBaseInfo.cpp:538
llvm::AMDGPU::getIsaVersion
IsaVersion getIsaVersion(StringRef GPU)
Definition:TargetParser.cpp:229
llvm::AMDGPU::isValid32BitLiteral
bool isValid32BitLiteral(uint64_t Val, bool IsFP64)
Definition:AMDGPUBaseInfo.cpp:2808
llvm::AMDGPU::isDPALU_DPP
bool isDPALU_DPP(const MCInstrDesc &OpDesc)
Definition:AMDGPUBaseInfo.cpp:3020
llvm::AMDGPU::isSI
bool isSI(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2148
llvm::AMDGPU::decodeLgkmcnt
unsigned decodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt)
Definition:AMDGPUBaseInfo.cpp:1467
llvm::AMDGPU::getWaitcntBitMask
unsigned getWaitcntBitMask(const IsaVersion &Version)
Definition:AMDGPUBaseInfo.cpp:1442
llvm::AMDGPU::isGFX9
bool isGFX9(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2160
llvm::AMDGPU::isGFX10_AEncoding
bool isGFX10_AEncoding(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2230
llvm::AMDGPU::isKImmOperand
bool isKImmOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this a KImm operand?
Definition:AMDGPUBaseInfo.cpp:2403
llvm::AMDGPU::isGFX90A
bool isGFX90A(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2246
llvm::AMDGPU::getMIMGDimInfoByEncoding
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByEncoding(uint8_t DimEnc)
llvm::AMDGPU::isInlinableLiteral32
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
Definition:AMDGPUBaseInfo.cpp:2616
llvm::AMDGPU::isGFX12
bool isGFX12(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2206
llvm::AMDGPU::encodeExpcnt
unsigned encodeExpcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Expcnt)
Definition:AMDGPUBaseInfo.cpp:1496
llvm::AMDGPU::isSISrcOperand
bool isSISrcOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this an AMDGPU specific source operand? These include registers, inline constants,...
Definition:AMDGPUBaseInfo.cpp:2396
llvm::AMDGPU::hasMAIInsts
bool hasMAIInsts(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2258
llvm::AMDGPU::hasNamedOperand
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, uint64_t NamedIdx)
Definition:AMDGPUBaseInfo.h:400
llvm::AMDGPU::isInlinableIntLiteral
LLVM_READNONE bool isInlinableIntLiteral(int64_t Literal)
Is this literal inlinable, and not one of the values intended for floating point values.
Definition:AMDGPUBaseInfo.h:1458
llvm::AMDGPU::getMIMGDimInfoByAsmSuffix
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfoByAsmSuffix(StringRef AsmSuffix)
llvm::AMDGPU::hasMIMG_R128
bool hasMIMG_R128(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2114
llvm::AMDGPU::hasG16
bool hasG16(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2122
llvm::AMDGPU::getAddrSizeMIMGOp
unsigned getAddrSizeMIMGOp(const MIMGBaseOpcodeInfo *BaseOpcode, const MIMGDimInfo *Dim, bool IsA16, bool IsG16Supported)
Definition:AMDGPUBaseInfo.cpp:293
llvm::AMDGPU::hasArchitectedFlatScratch
bool hasArchitectedFlatScratch(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2254
llvm::AMDGPU::isGFX11Plus
bool isGFX11Plus(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2202
llvm::AMDGPU::isInlineValue
bool isInlineValue(unsigned Reg)
Definition:AMDGPUBaseInfo.cpp:2367
llvm::AMDGPU::isSISrcFPOperand
bool isSISrcFPOperand(const MCInstrDesc &Desc, unsigned OpNo)
Is this floating-point operand?
Definition:AMDGPUBaseInfo.cpp:2410
llvm::AMDGPU::isGFX10Plus
bool isGFX10Plus(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2194
llvm::AMDGPU::OperandType
OperandType
Definition:SIDefines.h:198
llvm::AMDGPU::OPERAND_KIMM32
@ OPERAND_KIMM32
Operand with 32-bit immediate that uses the constant bus.
Definition:SIDefines.h:234
llvm::AMDGPU::OPERAND_REG_IMM_INT64
@ OPERAND_REG_IMM_INT64
Definition:SIDefines.h:201
llvm::AMDGPU::OPERAND_REG_IMM_V2FP16
@ OPERAND_REG_IMM_V2FP16
Definition:SIDefines.h:211
llvm::AMDGPU::OPERAND_REG_INLINE_C_V2INT32
@ OPERAND_REG_INLINE_C_V2INT32
Definition:SIDefines.h:227
llvm::AMDGPU::OPERAND_REG_INLINE_C_FP64
@ OPERAND_REG_INLINE_C_FP64
Definition:SIDefines.h:223
llvm::AMDGPU::OPERAND_REG_INLINE_C_BF16
@ OPERAND_REG_INLINE_C_BF16
Definition:SIDefines.h:220
llvm::AMDGPU::OPERAND_REG_INLINE_C_V2BF16
@ OPERAND_REG_INLINE_C_V2BF16
Definition:SIDefines.h:225
llvm::AMDGPU::OPERAND_REG_IMM_V2INT16
@ OPERAND_REG_IMM_V2INT16
Definition:SIDefines.h:212
llvm::AMDGPU::OPERAND_REG_IMM_BF16
@ OPERAND_REG_IMM_BF16
Definition:SIDefines.h:205
llvm::AMDGPU::OPERAND_REG_INLINE_AC_V2FP16
@ OPERAND_REG_INLINE_AC_V2FP16
Definition:SIDefines.h:246
llvm::AMDGPU::OPERAND_REG_IMM_INT32
@ OPERAND_REG_IMM_INT32
Operands with register or 32-bit immediate.
Definition:SIDefines.h:200
llvm::AMDGPU::OPERAND_REG_IMM_V2BF16
@ OPERAND_REG_IMM_V2BF16
Definition:SIDefines.h:210
llvm::AMDGPU::OPERAND_REG_IMM_BF16_DEFERRED
@ OPERAND_REG_IMM_BF16_DEFERRED
Definition:SIDefines.h:207
llvm::AMDGPU::OPERAND_REG_IMM_FP16
@ OPERAND_REG_IMM_FP16
Definition:SIDefines.h:206
llvm::AMDGPU::OPERAND_REG_INLINE_C_INT64
@ OPERAND_REG_INLINE_C_INT64
Definition:SIDefines.h:219
llvm::AMDGPU::OPERAND_KIMM16
@ OPERAND_KIMM16
Definition:SIDefines.h:235
llvm::AMDGPU::OPERAND_REG_INLINE_AC_BF16
@ OPERAND_REG_INLINE_AC_BF16
Definition:SIDefines.h:240
llvm::AMDGPU::OPERAND_REG_INLINE_C_INT16
@ OPERAND_REG_INLINE_C_INT16
Operands with register or inline constant.
Definition:SIDefines.h:217
llvm::AMDGPU::OPERAND_REG_INLINE_AC_INT16
@ OPERAND_REG_INLINE_AC_INT16
Operands with an AccVGPR register or inline constant.
Definition:SIDefines.h:238
llvm::AMDGPU::OPERAND_REG_IMM_FP64
@ OPERAND_REG_IMM_FP64
Definition:SIDefines.h:204
llvm::AMDGPU::OPERAND_REG_INLINE_C_V2FP16
@ OPERAND_REG_INLINE_C_V2FP16
Definition:SIDefines.h:226
llvm::AMDGPU::OPERAND_REG_INLINE_AC_V2INT16
@ OPERAND_REG_INLINE_AC_V2INT16
Definition:SIDefines.h:244
llvm::AMDGPU::OPERAND_REG_INLINE_AC_FP16
@ OPERAND_REG_INLINE_AC_FP16
Definition:SIDefines.h:241
llvm::AMDGPU::OPERAND_REG_INLINE_AC_INT32
@ OPERAND_REG_INLINE_AC_INT32
Definition:SIDefines.h:239
llvm::AMDGPU::OPERAND_REG_INLINE_AC_FP32
@ OPERAND_REG_INLINE_AC_FP32
Definition:SIDefines.h:242
llvm::AMDGPU::OPERAND_REG_INLINE_AC_V2BF16
@ OPERAND_REG_INLINE_AC_V2BF16
Definition:SIDefines.h:245
llvm::AMDGPU::OPERAND_REG_IMM_V2INT32
@ OPERAND_REG_IMM_V2INT32
Definition:SIDefines.h:213
llvm::AMDGPU::OPERAND_REG_IMM_FP32
@ OPERAND_REG_IMM_FP32
Definition:SIDefines.h:203
llvm::AMDGPU::OPERAND_INPUT_MODS
@ OPERAND_INPUT_MODS
Definition:SIDefines.h:251
llvm::AMDGPU::OPERAND_REG_INLINE_C_FP32
@ OPERAND_REG_INLINE_C_FP32
Definition:SIDefines.h:222
llvm::AMDGPU::OPERAND_REG_INLINE_C_INT32
@ OPERAND_REG_INLINE_C_INT32
Definition:SIDefines.h:218
llvm::AMDGPU::OPERAND_REG_INLINE_C_V2INT16
@ OPERAND_REG_INLINE_C_V2INT16
Definition:SIDefines.h:224
llvm::AMDGPU::OPERAND_REG_IMM_V2FP32
@ OPERAND_REG_IMM_V2FP32
Definition:SIDefines.h:214
llvm::AMDGPU::OPERAND_REG_INLINE_AC_FP64
@ OPERAND_REG_INLINE_AC_FP64
Definition:SIDefines.h:243
llvm::AMDGPU::OPERAND_REG_INLINE_C_FP16
@ OPERAND_REG_INLINE_C_FP16
Definition:SIDefines.h:221
llvm::AMDGPU::OPERAND_REG_IMM_INT16
@ OPERAND_REG_IMM_INT16
Definition:SIDefines.h:202
llvm::AMDGPU::OPERAND_REG_INLINE_C_V2FP32
@ OPERAND_REG_INLINE_C_V2FP32
Definition:SIDefines.h:228
llvm::AMDGPU::OPERAND_INLINE_SPLIT_BARRIER_INT32
@ OPERAND_INLINE_SPLIT_BARRIER_INT32
Definition:SIDefines.h:231
llvm::AMDGPU::OPERAND_REG_IMM_FP32_DEFERRED
@ OPERAND_REG_IMM_FP32_DEFERRED
Definition:SIDefines.h:209
llvm::AMDGPU::OPERAND_REG_IMM_FP16_DEFERRED
@ OPERAND_REG_IMM_FP16_DEFERRED
Definition:SIDefines.h:208
llvm::AMDGPU::hasGDS
bool hasGDS(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2131
llvm::AMDGPU::isLegalSMRDEncodedUnsignedOffset
bool isLegalSMRDEncodedUnsignedOffset(const MCSubtargetInfo &ST, int64_t EncodedOffset)
Definition:AMDGPUBaseInfo.cpp:2874
llvm::AMDGPU::isGFX9Plus
bool isGFX9Plus(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2180
llvm::AMDGPU::hasDPPSrc1SGPR
bool hasDPPSrc1SGPR(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2266
llvm::AMDGPU::OPR_ID_DUPLICATE
const int OPR_ID_DUPLICATE
Definition:AMDGPUAsmUtils.h:25
llvm::AMDGPU::isVOPD
bool isVOPD(unsigned Opc)
Definition:AMDGPUBaseInfo.cpp:582
llvm::AMDGPU::getVOPDInstInfo
VOPD::InstInfo getVOPDInstInfo(const MCInstrDesc &OpX, const MCInstrDesc &OpY)
Definition:AMDGPUBaseInfo.cpp:790
llvm::AMDGPU::encodeVmcnt
unsigned encodeVmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Vmcnt)
Definition:AMDGPUBaseInfo.cpp:1487
llvm::AMDGPU::decodeExpcnt
unsigned decodeExpcnt(const IsaVersion &Version, unsigned Waitcnt)
Definition:AMDGPUBaseInfo.cpp:1462
llvm::AMDGPU::getMIMGBaseOpcode
const MIMGBaseOpcodeInfo * getMIMGBaseOpcode(unsigned Opc)
Definition:AMDGPUBaseInfo.cpp:280
llvm::AMDGPU::isVI
bool isVI(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2156
llvm::AMDGPU::mc2PseudoReg
MCRegister mc2PseudoReg(MCRegister Reg)
Convert hardware register Reg to a pseudo register.
Definition:AMDGPUBaseInfo.cpp:2365
llvm::AMDGPU::hasKernargPreload
unsigned hasKernargPreload(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2270
llvm::AMDGPU::isMAC
bool isMAC(unsigned Opc)
Definition:AMDGPUBaseInfo.cpp:586
llvm::AMDGPU::getOperandSize
LLVM_READNONE unsigned getOperandSize(const MCOperandInfo &OpInfo)
Definition:AMDGPUBaseInfo.h:1398
llvm::AMDGPU::isCI
bool isCI(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2152
llvm::AMDGPU::encodeLgkmcnt
unsigned encodeLgkmcnt(const IsaVersion &Version, unsigned Waitcnt, unsigned Lgkmcnt)
Definition:AMDGPUBaseInfo.cpp:1502
llvm::AMDGPU::getMIMGBaseOpcodeInfo
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
llvm::AMDGPU::OPR_ID_UNKNOWN
const int OPR_ID_UNKNOWN
Definition:AMDGPUAsmUtils.h:23
llvm::AMDGPU::decodeVmcnt
unsigned decodeVmcnt(const IsaVersion &Version, unsigned Waitcnt)
Definition:AMDGPUBaseInfo.cpp:1454
llvm::AMDGPU::isInlinableLiteralI16
bool isInlinableLiteralI16(int32_t Literal, bool HasInv2Pi)
Definition:AMDGPUBaseInfo.cpp:2659
llvm::AMDGPU::hasVOPD
bool hasVOPD(const MCSubtargetInfo &STI)
Definition:AMDGPUBaseInfo.cpp:2262
llvm::AMDGPU::isInlinableLiteral64
bool isInlinableLiteral64(int64_t Literal, bool HasInv2Pi)
Is this literal inlinable.
Definition:AMDGPUBaseInfo.cpp:2599
llvm::AMDGPU::isPermlane16
bool isPermlane16(unsigned Opc)
Definition:AMDGPUBaseInfo.cpp:610
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition:ARMBuildAttributes.h:83
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition:BitmaskEnum.h:125
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition:CallingConv.h:24
llvm::ELF::STT_AMDGPU_HSA_KERNEL
@ STT_AMDGPU_HSA_KERNEL
Definition:ELF.h:1377
llvm::FPOpFusion::Strict
@ Strict
Definition:TargetOptions.h:39
llvm::ISD::UNDEF
@ UNDEF
UNDEF - An undefined node.
Definition:ISDOpcodes.h:218
llvm::IndexedCGData::Version
const uint64_t Version
Definition:CodeGenData.h:286
llvm::M68kBeads::Ctrl
@ Ctrl
Definition:M68kBaseInfo.h:98
llvm::M68k::MemAddrModeKind::u
@ u
llvm::MCOI::TIED_TO
@ TIED_TO
Definition:MCInstrDesc.h:36
llvm::MCOI::OPERAND_IMMEDIATE
@ OPERAND_IMMEDIATE
Definition:MCInstrDesc.h:60
llvm::MSP430Attrs::ISA
ISA
Definition:MSP430Attributes.h:36
llvm::MipsISD::Ret
@ Ret
Definition:MipsISelLowering.h:117
llvm::PPC::getPredicate
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
Definition:PPCPredicates.h:87
llvm::RISCVFeatures::validate
void validate(const Triple &TT, const FeatureBitset &FeatureBits)
Definition:RISCVBaseInfo.cpp:110
llvm::RISCVFenceField::R
@ R
Definition:RISCVBaseInfo.h:373
llvm::SIInstrFlags::IsAtomicRet
@ IsAtomicRet
Definition:SIDefines.h:163
llvm::SIInstrFlags::DPP
@ DPP
Definition:SIDefines.h:76
llvm::SIInstrFlags::MIMG
@ MIMG
Definition:SIDefines.h:83
llvm::SIInstrFlags::VOP1
@ VOP1
Definition:SIDefines.h:66
llvm::SIInstrFlags::GWS
@ GWS
Definition:SIDefines.h:175
llvm::SIInstrFlags::FlatGlobal
@ FlatGlobal
Definition:SIDefines.h:142
llvm::SIInstrFlags::Gather4
@ Gather4
Definition:SIDefines.h:107
llvm::SIInstrFlags::IsSWMMAC
@ IsSWMMAC
Definition:SIDefines.h:178
llvm::SIInstrFlags::SOP2
@ SOP2
Definition:SIDefines.h:60
llvm::SIInstrFlags::MUBUF
@ MUBUF
Definition:SIDefines.h:80
llvm::SIInstrFlags::SMRD
@ SMRD
Definition:SIDefines.h:82
llvm::SIInstrFlags::SDWA
@ SDWA
Definition:SIDefines.h:75
llvm::SIInstrFlags::VOPC
@ VOPC
Definition:SIDefines.h:68
llvm::SIInstrFlags::MTBUF
@ MTBUF
Definition:SIDefines.h:81
llvm::SIInstrFlags::VOP3P
@ VOP3P
Definition:SIDefines.h:72
llvm::SIInstrFlags::VOP2
@ VOP2
Definition:SIDefines.h:67
llvm::SIInstrFlags::VSAMPLE
@ VSAMPLE
Definition:SIDefines.h:85
llvm::SIInstrFlags::VOP3
@ VOP3
Definition:SIDefines.h:71
llvm::SIInstrFlags::DS
@ DS
Definition:SIDefines.h:88
llvm::SIInstrFlags::FlatScratch
@ FlatScratch
Definition:SIDefines.h:157
llvm::SIInstrFlags::IsAtomicNoRet
@ IsAtomicNoRet
Definition:SIDefines.h:160
llvm::SIInstrFlags::IsMAI
@ IsMAI
Definition:SIDefines.h:151
llvm::SIInstrFlags::IsPacked
@ IsPacked
Definition:SIDefines.h:136
llvm::SIInstrFlags::FLAT
@ FLAT
Definition:SIDefines.h:87
llvm::SIInstrFlags::IsDOT
@ IsDOT
Definition:SIDefines.h:154
llvm::SIInstrFlags::SOPC
@ SOPC
Definition:SIDefines.h:61
llvm::SIInstrFlags::IsWMMA
@ IsWMMA
Definition:SIDefines.h:166
llvm::SIInstrFlags::IntClamp
@ IntClamp
Definition:SIDefines.h:126
llvm::SIInstrFlags::VIMAGE
@ VIMAGE
Definition:SIDefines.h:84
llvm::SISrcMods::SEXT
@ SEXT
Definition:SIDefines.h:290
llvm::SISrcMods::ABS
@ ABS
Definition:SIDefines.h:289
llvm::SISrcMods::OP_SEL_0
@ OP_SEL_0
Definition:SIDefines.h:292
llvm::SISrcMods::DST_OP_SEL
@ DST_OP_SEL
Definition:SIDefines.h:294
llvm::SISrcMods::NEG_HI
@ NEG_HI
Definition:SIDefines.h:291
llvm::SISrcMods::OP_SEL_1
@ OP_SEL_1
Definition:SIDefines.h:293
llvm::SISrcMods::NEG
@ NEG
Definition:SIDefines.h:288
llvm::TailPredication::Mode
Mode
Definition:ARMTargetTransformInfo.h:43
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition:X86DisassemblerDecoder.h:621
llvm::amdhsa
Definition:AMDHSAKernelDescriptor.h:58
llvm::cl::Prefix
@ Prefix
Definition:CommandLine.h:158
llvm::jitlink::Scope
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
Definition:JITLink.h:412
llvm::lltok::Kind
Kind
Definition:LLToken.h:18
llvm::logicalview::LVCompareKind::Scopes
@ Scopes
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::pdb::PDB_LocType::Slot
@ Slot
llvm::pdb::PDB_ColorItem::LiteralValue
@ LiteralValue
llvm::remarks::Format
Format
The format used for serializing/deserializing remarks.
Definition:RemarkFormat.h:25
llvm::tgtok::Bit
@ Bit
Definition:TGLexer.h:78
llvm::tgtok::IntVal
@ IntVal
Definition:TGLexer.h:62
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::errorToBool
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Definition:Error.h:1099
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::Length
@ Length
Definition:DWP.cpp:480
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1739
llvm::popcount
int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition:bit.h:385
llvm::encode
unsigned encode(MaybeAlign A)
Returns a representation of the alignment that encodes undefined as 0.
Definition:Alignment.h:217
llvm::isUIntN
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Definition:MathExtras.h:256
llvm::getCPU
static StringRef getCPU(StringRef CPU)
Processes a CPU name.
Definition:AVRTargetMachine.cpp:33
llvm::Failed
testing::Matcher< const detail::ErrorHolder & > Failed()
Definition:Error.h:198
llvm::PrintError
void PrintError(const Twine &Msg)
Definition:Error.cpp:104
llvm::isPowerOf2_64
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition:MathExtras.h:297
llvm::bit_ceil
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition:bit.h:342
llvm::getTheR600Target
Target & getTheR600Target()
The target for R600 GPUs.
Definition:AMDGPUTargetInfo.cpp:19
llvm::Hi_32
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition:MathExtras.h:155
llvm::isUInt
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition:MathExtras.h:194
llvm::Lo_32
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition:MathExtras.h:160
llvm::divideCeil
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition:MathExtras.h:404
llvm::IRMemLocation::First
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
llvm::getTheGCNTarget
Target & getTheGCNTarget()
The target for GCN GPUs.
Definition:AMDGPUTargetInfo.cpp:25
llvm::isIntN
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition:MathExtras.h:261
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::Op
DWARFExpression::Operation Op
Definition:DWARFExpression.cpp:22
llvm::ReplacementType::Literal
@ Literal
llvm::operator<<
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition:APFixedPoint.h:303
llvm::M0
unsigned M0(unsigned Val)
Definition:VE.h:375
llvm::HighlightColor::Warning
@ Warning
llvm::HighlightColor::String
@ String
llvm::find_if
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition:STLExtras.h:1766
llvm::toString
const char * toString(DWARFSectionKind Kind)
Definition:DWARFUnitIndex.h:67
llvm::PGSOQueryType::Test
@ Test
N
#define N
RegInfo
Definition:AMDGPUAsmParser.cpp:2770
RegInfo::Kind
RegisterKind Kind
Definition:AMDGPUAsmParser.cpp:2772
RegInfo::Name
StringLiteral Name
Definition:AMDGPUAsmParser.cpp:2771
Status
Definition:SIModeRegister.cpp:29
llvm::AMDGPU::AMDGPUMCKernelCodeT
Definition:AMDKernelCodeTUtils.h:33
llvm::AMDGPU::AMDGPUMCKernelCodeT::validate
void validate(const MCSubtargetInfo *STI, MCContext &Ctx)
Definition:AMDKernelCodeTUtils.cpp:403
llvm::AMDGPU::AMDGPUMCKernelCodeT::initDefault
void initDefault(const MCSubtargetInfo *STI, MCContext &Ctx, bool InitMCExpr=true)
Definition:AMDKernelCodeTUtils.cpp:384
llvm::AMDGPU::IsaVersion
Instruction set architecture version.
Definition:TargetParser.h:130
llvm::AMDGPU::IsaVersion::Major
unsigned Major
Definition:TargetParser.h:131
llvm::AMDGPU::MCKernelDescriptor
Definition:AMDGPUMCKernelDescriptor.h:27
llvm::AMDGPU::MCKernelDescriptor::compute_pgm_rsrc2
const MCExpr * compute_pgm_rsrc2
Definition:AMDGPUMCKernelDescriptor.h:33
llvm::AMDGPU::MCKernelDescriptor::kernarg_size
const MCExpr * kernarg_size
Definition:AMDGPUMCKernelDescriptor.h:30
llvm::AMDGPU::MCKernelDescriptor::kernarg_preload
const MCExpr * kernarg_preload
Definition:AMDGPUMCKernelDescriptor.h:35
llvm::AMDGPU::MCKernelDescriptor::compute_pgm_rsrc3
const MCExpr * compute_pgm_rsrc3
Definition:AMDGPUMCKernelDescriptor.h:31
llvm::AMDGPU::MCKernelDescriptor::private_segment_fixed_size
const MCExpr * private_segment_fixed_size
Definition:AMDGPUMCKernelDescriptor.h:29
llvm::AMDGPU::MCKernelDescriptor::compute_pgm_rsrc1
const MCExpr * compute_pgm_rsrc1
Definition:AMDGPUMCKernelDescriptor.h:32
llvm::AMDGPU::MCKernelDescriptor::bits_set
static void bits_set(const MCExpr *&Dst, const MCExpr *Value, uint32_t Shift, uint32_t Mask, MCContext &Ctx)
Definition:AMDGPUMCKernelDescriptor.cpp:82
llvm::AMDGPU::MCKernelDescriptor::group_segment_fixed_size
const MCExpr * group_segment_fixed_size
Definition:AMDGPUMCKernelDescriptor.h:28
llvm::AMDGPU::MCKernelDescriptor::getDefaultAmdhsaKernelDescriptor
static MCKernelDescriptor getDefaultAmdhsaKernelDescriptor(const MCSubtargetInfo *STI, MCContext &Ctx)
Definition:AMDGPUMCKernelDescriptor.cpp:21
llvm::AMDGPU::MCKernelDescriptor::kernel_code_properties
const MCExpr * kernel_code_properties
Definition:AMDGPUMCKernelDescriptor.h:34
llvm::AMDGPU::MFMA_F8F6F4_Info
Definition:AMDGPUBaseInfo.h:101
llvm::AMDGPU::MIMGBaseOpcodeInfo
Definition:AMDGPUBaseInfo.h:407
llvm::AMDGPU::MIMGBaseOpcodeInfo::MSAA
bool MSAA
Definition:AMDGPUBaseInfo.h:421
llvm::AMDGPU::MIMGBaseOpcodeInfo::A16
bool A16
Definition:AMDGPUBaseInfo.h:423
llvm::AMDGPU::MIMGBaseOpcodeInfo::BVH
bool BVH
Definition:AMDGPUBaseInfo.h:422
llvm::AMDGPU::MIMGDimInfo
Definition:AMDGPUBaseInfo.h:433
llvm::AMDGPU::MIMGDimInfo::MSAA
bool MSAA
Definition:AMDGPUBaseInfo.h:437
llvm::AMDGPU::MIMGDimInfo::Encoding
uint8_t Encoding
Definition:AMDGPUBaseInfo.h:439
llvm::AMDGPU::MIMGInfo
Definition:AMDGPUBaseInfo.h:509
llvm::AMDGPU::Waitcnt
Represents the counter values to wait for in an s_waitcnt instruction.
Definition:AMDGPUBaseInfo.h:967
llvm::APFloatBase::IEEEsingle
static const fltSemantics & IEEEsingle() LLVM_READNONE
Definition:APFloat.cpp:257
llvm::APFloatBase::IEEEhalf
static const fltSemantics & IEEEhalf() LLVM_READNONE
Definition:APFloat.cpp:255
llvm::APFloatBase::BFloat
static const fltSemantics & BFloat() LLVM_READNONE
Definition:APFloat.cpp:256
llvm::APFloatBase::opStatus
opStatus
IEEE-754R 7: Default exception handling.
Definition:APFloat.h:318
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39
llvm::DWARFExpression::Operation::Description
Description of the encoding of one expression Op.
Definition:DWARFExpression.h:66
llvm::Loop::LoopBounds::Direction
Direction
An enum for the direction of the loop.
Definition:LoopInfo.h:215
llvm::ParseInstructionInfo
Definition:MCTargetAsmParser.h:117
llvm::RegisterMCAsmParser
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Definition:TargetRegistry.h:1290
llvm::amdhsa::kernel_descriptor_t::group_segment_fixed_size
uint32_t group_segment_fixed_size
Definition:AMDHSAKernelDescriptor.h:244
llvm::amdhsa::kernel_descriptor_t::private_segment_fixed_size
uint32_t private_segment_fixed_size
Definition:AMDHSAKernelDescriptor.h:245
llvm::amdhsa::kernel_descriptor_t::kernarg_size
uint32_t kernarg_size
Definition:AMDHSAKernelDescriptor.h:246
llvm::fltSemantics
Definition:APFloat.cpp:103

Generated on Thu Jul 17 2025 14:14:17 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp