41 struct OptionalOperand;
51 SMLoc StartLoc, EndLoc;
96 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
104 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
108 void addRegOrImmOperands(
MCInst &Inst,
unsigned N)
const {
110 addRegOperands(Inst, N);
112 addImmOperands(Inst, N);
115 void addRegWithInputModsOperands(
MCInst &Inst,
unsigned N)
const {
117 Reg.Modifiers == -1 ? 0 :
Reg.Modifiers));
118 addRegOperands(Inst, N);
121 void addSoppBrTargetOperands(
MCInst &Inst,
unsigned N)
const {
123 addImmOperands(Inst, N);
130 bool defaultTokenHasSuffix()
const {
133 return Token.endswith(
"_e32") || Token.endswith(
"_e64");
136 bool isToken()
const override {
137 return Kind == Token;
140 bool isImm()
const override {
141 return Kind == Immediate;
144 bool isInlineImm()
const {
147 return isImm() && ((Imm.Val <= 64 && Imm.Val >= -16) ||
148 (F == 0.0 || F == 0.5 || F == -0.5 || F == 1.0 || F == -1.0 ||
149 F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0));
152 bool isDSOffset0()
const {
154 return Imm.Type == ImmTyDSOffset0;
157 bool isDSOffset1()
const {
159 return Imm.Type == ImmTyDSOffset1;
162 int64_t getImm()
const {
166 enum ImmTy getImmTy()
const {
171 bool isRegKind()
const {
175 bool isReg()
const override {
179 bool isRegWithInputMods()
const {
183 void setModifiers(
unsigned Mods) {
185 Reg.Modifiers = Mods;
188 bool hasModifiers()
const {
190 return Reg.Modifiers != -1;
193 unsigned getReg()
const override {
197 bool isRegOrImm()
const {
198 return isReg() || isImm();
201 bool isRegClass(
unsigned RCID)
const {
202 return Reg.TRI->getRegClass(RCID).contains(
getReg());
205 bool isSCSrc32()
const {
206 return isInlineImm() || (
isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
209 bool isSSrc32()
const {
210 return isImm() || (
isReg() && isRegClass(AMDGPU::SReg_32RegClassID));
213 bool isSSrc64()
const {
214 return isImm() || isInlineImm() ||
215 (
isReg() && isRegClass(AMDGPU::SReg_64RegClassID));
218 bool isVCSrc32()
const {
219 return isInlineImm() || (
isReg() && isRegClass(AMDGPU::VS_32RegClassID));
222 bool isVCSrc64()
const {
223 return isInlineImm() || (
isReg() && isRegClass(AMDGPU::VS_64RegClassID));
226 bool isVSrc32()
const {
227 return isImm() || (
isReg() && isRegClass(AMDGPU::VS_32RegClassID));
230 bool isVSrc64()
const {
231 return isImm() || (
isReg() && isRegClass(AMDGPU::VS_64RegClassID));
234 bool isMem()
const override {
238 bool isExpr()
const {
239 return Kind == Expression;
242 bool isSoppBrTarget()
const {
243 return isExpr() || isImm();
246 SMLoc getStartLoc()
const override {
250 SMLoc getEndLoc()
const override {
256 static std::unique_ptr<AMDGPUOperand> CreateImm(int64_t Val,
SMLoc Loc,
257 enum ImmTy
Type = ImmTyNone,
258 bool IsFPImm =
false) {
259 auto Op = llvm::make_unique<AMDGPUOperand>(Immediate);
261 Op->Imm.IsFPImm = IsFPImm;
268 static std::unique_ptr<AMDGPUOperand> CreateToken(
StringRef Str,
SMLoc Loc,
269 bool HasExplicitEncodingSize =
true) {
270 auto Res = llvm::make_unique<AMDGPUOperand>(Token);
271 Res->Tok.Data = Str.
data();
272 Res->Tok.Length = Str.
size();
278 static std::unique_ptr<AMDGPUOperand> CreateReg(
unsigned RegNo,
SMLoc S,
282 auto Op = llvm::make_unique<AMDGPUOperand>(
Register);
283 Op->Reg.RegNo = RegNo;
285 Op->Reg.Modifiers = -1;
286 Op->Reg.IsForcedVOP3 = ForceVOP3;
292 static std::unique_ptr<AMDGPUOperand> CreateExpr(
const class MCExpr *Expr,
SMLoc S) {
293 auto Op = llvm::make_unique<AMDGPUOperand>(Expression);
300 bool isDSOffset()
const;
301 bool isDSOffset01()
const;
302 bool isSWaitCnt()
const;
303 bool isMubufOffset()
const;
311 unsigned ForcedEncodingSize;
315 #define GET_ASSEMBLER_HEADER
316 #include "AMDGPUGenAsmMatcher.inc"
321 bool ParseDirectiveMajorMinor(uint32_t &Major, uint32_t &Minor);
322 bool ParseDirectiveHSACodeObjectVersion();
323 bool ParseDirectiveHSACodeObjectISA();
325 bool ParseDirectiveAMDKernelCodeT();
332 ForcedEncodingSize(0){
339 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
347 unsigned getForcedEncodingSize()
const {
348 return ForcedEncodingSize;
351 void setForcedEncodingSize(
unsigned Size) {
352 ForcedEncodingSize = Size;
355 bool isForcedVOP3()
const {
356 return ForcedEncodingSize == 64;
359 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
360 unsigned checkTargetMatchPredicate(
MCInst &Inst)
override;
361 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
364 bool MatchingInlineAsm)
override;
365 bool ParseDirective(
AsmToken DirectiveID)
override;
370 OperandMatchResultTy parseIntWithPrefix(
const char *
Prefix, int64_t &
Int,
372 OperandMatchResultTy parseIntWithPrefix(
const char *
Prefix,
374 enum AMDGPUOperand::ImmTy ImmTy =
375 AMDGPUOperand::ImmTyNone);
377 enum AMDGPUOperand::ImmTy ImmTy =
378 AMDGPUOperand::ImmTyNone);
379 OperandMatchResultTy parseOptionalOps(
390 bool parseCnt(int64_t &
IntVal);
413 struct OptionalOperand {
415 AMDGPUOperand::ImmTy
Type;
418 bool (*ConvertResult)(int64_t&);
427 case 1:
return AMDGPU::VGPR_32RegClassID;
428 case 2:
return AMDGPU::VReg_64RegClassID;
429 case 3:
return AMDGPU::VReg_96RegClassID;
430 case 4:
return AMDGPU::VReg_128RegClassID;
431 case 8:
return AMDGPU::VReg_256RegClassID;
432 case 16:
return AMDGPU::VReg_512RegClassID;
438 case 1:
return AMDGPU::SGPR_32RegClassID;
439 case 2:
return AMDGPU::SGPR_64RegClassID;
440 case 4:
return AMDGPU::SReg_128RegClassID;
441 case 8:
return AMDGPU::SReg_256RegClassID;
442 case 16:
return AMDGPU::SReg_512RegClassID;
449 .Case(
"exec", AMDGPU::EXEC)
450 .
Case(
"vcc", AMDGPU::VCC)
451 .
Case(
"flat_scr", AMDGPU::FLAT_SCR)
452 .
Case(
"m0", AMDGPU::M0)
453 .
Case(
"scc", AMDGPU::SCC)
454 .
Case(
"flat_scr_lo", AMDGPU::FLAT_SCR_LO)
455 .
Case(
"flat_scr_hi", AMDGPU::FLAT_SCR_HI)
456 .
Case(
"vcc_lo", AMDGPU::VCC_LO)
457 .
Case(
"vcc_hi", AMDGPU::VCC_HI)
458 .
Case(
"exec_lo", AMDGPU::EXEC_LO)
459 .
Case(
"exec_hi", AMDGPU::EXEC_HI)
463 bool AMDGPUAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc) {
464 const AsmToken Tok = Parser.getTok();
476 if (RegName[0] !=
's' && RegName[0] !=
'v')
479 bool IsVgpr = RegName[0] ==
'v';
481 unsigned RegIndexInClass;
482 if (RegName.
size() > 1) {
491 int64_t RegLo, RegHi;
497 if (getParser().parseAbsoluteExpression(RegLo))
504 if (getParser().parseAbsoluteExpression(RegHi))
511 RegWidth = (RegHi - RegLo) + 1;
514 RegIndexInClass = RegLo;
517 RegIndexInClass = RegLo /
std::min(RegWidth, 4u);
529 unsigned AMDGPUAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
535 return Match_InvalidOperand;
537 return Match_Success;
541 bool AMDGPUAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
545 bool MatchingInlineAsm) {
548 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
554 case Match_MissingFeature:
555 return Error(IDLoc,
"instruction not supported on this GPU");
557 case Match_MnemonicFail:
558 return Error(IDLoc,
"unrecognized instruction mnemonic");
560 case Match_InvalidOperand: {
561 SMLoc ErrorLoc = IDLoc;
562 if (ErrorInfo != ~0ULL) {
563 if (ErrorInfo >= Operands.
size()) {
564 if (isForcedVOP3()) {
568 AMDGPUOperand &LastOp =
569 ((AMDGPUOperand &)*Operands[Operands.
size() - 1]);
570 if (LastOp.isRegKind() ||
572 LastOp.getImmTy() != AMDGPUOperand::ImmTyNone)) {
573 SMLoc S = Parser.getTok().getLoc();
574 Operands.
push_back(AMDGPUOperand::CreateImm(0, S,
575 AMDGPUOperand::ImmTyClamp));
576 Operands.
push_back(AMDGPUOperand::CreateImm(0, S,
577 AMDGPUOperand::ImmTyOMod));
578 bool Res = MatchAndEmitInstruction(IDLoc, Opcode, Operands,
586 return Error(IDLoc,
"too few operands for instruction");
589 ErrorLoc = ((AMDGPUOperand &)*Operands[ErrorInfo]).getStartLoc();
590 if (ErrorLoc ==
SMLoc())
593 return Error(ErrorLoc,
"invalid operand for instruction");
599 bool AMDGPUAsmParser::ParseDirectiveMajorMinor(uint32_t &Major,
602 return TokError(
"invalid major version");
604 Major = getLexer().getTok().getIntVal();
608 return TokError(
"minor version number required, comma expected");
612 return TokError(
"invalid minor version");
614 Minor = getLexer().getTok().getIntVal();
620 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectVersion() {
625 if (ParseDirectiveMajorMinor(Major, Minor))
628 getTargetStreamer().EmitDirectiveHSACodeObjectVersion(Major, Minor);
632 bool AMDGPUAsmParser::ParseDirectiveHSACodeObjectISA() {
644 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Isa.
Major, Isa.
Minor,
651 if (ParseDirectiveMajorMinor(Major, Minor))
655 return TokError(
"stepping version number required, comma expected");
659 return TokError(
"invalid stepping version");
661 Stepping = getLexer().getTok().getIntVal();
665 return TokError(
"vendor name required, comma expected");
669 return TokError(
"invalid vendor name");
671 VendorName = getLexer().getTok().getStringContents();
675 return TokError(
"arch name required, comma expected");
679 return TokError(
"invalid arch name");
681 ArchName = getLexer().getTok().getStringContents();
684 getTargetStreamer().EmitDirectiveHSACodeObjectISA(Major, Minor, Stepping,
685 VendorName, ArchName);
689 bool AMDGPUAsmParser::ParseAMDKernelCodeTValue(
StringRef ID,
693 return TokError(
"expected '='");
697 return TokError(
"amd_kernel_code_t values must be integers");
699 uint64_t
Value = getLexer().getTok().getIntVal();
702 if (ID ==
"kernel_code_version_major")
704 else if (ID ==
"kernel_code_version_minor")
706 else if (ID ==
"machine_kind")
708 else if (ID ==
"machine_version_major")
710 else if (ID ==
"machine_version_minor")
712 else if (ID ==
"machine_version_stepping")
714 else if (ID ==
"kernel_code_entry_byte_offset")
716 else if (ID ==
"kernel_code_prefetch_byte_size")
718 else if (ID ==
"max_scratch_backing_memory_byte_size")
720 else if (ID ==
"compute_pgm_rsrc1_vgprs")
722 else if (ID ==
"compute_pgm_rsrc1_sgprs")
724 else if (ID ==
"compute_pgm_rsrc1_priority")
726 else if (ID ==
"compute_pgm_rsrc1_float_mode")
728 else if (ID ==
"compute_pgm_rsrc1_priv")
730 else if (ID ==
"compute_pgm_rsrc1_dx10_clamp")
732 else if (ID ==
"compute_pgm_rsrc1_debug_mode")
734 else if (ID ==
"compute_pgm_rsrc1_ieee_mode")
736 else if (ID ==
"compute_pgm_rsrc2_scratch_en")
738 else if (ID ==
"compute_pgm_rsrc2_user_sgpr")
740 else if (ID ==
"compute_pgm_rsrc2_tgid_x_en")
742 else if (ID ==
"compute_pgm_rsrc2_tgid_y_en")
744 else if (ID ==
"compute_pgm_rsrc2_tgid_z_en")
746 else if (ID ==
"compute_pgm_rsrc2_tg_size_en")
748 else if (ID ==
"compute_pgm_rsrc2_tidig_comp_cnt")
751 else if (ID ==
"compute_pgm_rsrc2_excp_en_msb")
754 else if (ID ==
"compute_pgm_rsrc2_lds_size")
756 else if (ID ==
"compute_pgm_rsrc2_excp_en")
758 else if (ID ==
"compute_pgm_resource_registers")
760 else if (ID ==
"enable_sgpr_private_segment_buffer")
763 else if (ID ==
"enable_sgpr_dispatch_ptr")
766 else if (ID ==
"enable_sgpr_queue_ptr")
769 else if (ID ==
"enable_sgpr_kernarg_segment_ptr")
772 else if (ID ==
"enable_sgpr_dispatch_id")
775 else if (ID ==
"enable_sgpr_flat_scratch_init")
778 else if (ID ==
"enable_sgpr_private_segment_size")
781 else if (ID ==
"enable_sgpr_grid_workgroup_count_x")
784 else if (ID ==
"enable_sgpr_grid_workgroup_count_y")
787 else if (ID ==
"enable_sgpr_grid_workgroup_count_z")
790 else if (ID ==
"enable_ordered_append_gds")
793 else if (ID ==
"private_element_size")
796 else if (ID ==
"is_ptr64")
799 else if (ID ==
"is_dynamic_callstack")
802 else if (ID ==
"is_debug_enabled")
805 else if (ID ==
"is_xnack_enabled")
808 else if (ID ==
"workitem_private_segment_byte_size")
810 else if (ID ==
"workgroup_group_segment_byte_size")
812 else if (ID ==
"gds_segment_byte_size")
814 else if (ID ==
"kernarg_segment_byte_size")
816 else if (ID ==
"workgroup_fbarrier_count")
818 else if (ID ==
"wavefront_sgpr_count")
820 else if (ID ==
"workitem_vgpr_count")
822 else if (ID ==
"reserved_vgpr_first")
824 else if (ID ==
"reserved_vgpr_count")
826 else if (ID ==
"reserved_sgpr_first")
828 else if (ID ==
"reserved_sgpr_count")
830 else if (ID ==
"debug_wavefront_private_segment_offset_sgpr")
832 else if (ID ==
"debug_private_segment_buffer_sgpr")
834 else if (ID ==
"kernarg_segment_alignment")
836 else if (ID ==
"group_segment_alignment")
838 else if (ID ==
"private_segment_alignment")
840 else if (ID ==
"wavefront_size")
842 else if (ID ==
"call_convention")
844 else if (ID ==
"runtime_loader_kernel_symbol")
847 return TokError(
"amd_kernel_code_t value not recognized.");
852 bool AMDGPUAsmParser::ParseDirectiveAMDKernelCodeT() {
860 return TokError(
"amd_kernel_code_t values must begin on a new line");
868 return TokError(
"expected value identifier or .end_amd_kernel_code_t");
870 StringRef ID = getLexer().getTok().getIdentifier();
873 if (ID ==
".end_amd_kernel_code_t")
876 if (ParseAMDKernelCodeTValue(ID, Header))
880 getTargetStreamer().EmitAMDKernelCodeT(Header);
885 bool AMDGPUAsmParser::ParseDirective(
AsmToken DirectiveID) {
888 if (IDVal ==
".hsa_code_object_version")
889 return ParseDirectiveHSACodeObjectVersion();
891 if (IDVal ==
".hsa_code_object_isa")
892 return ParseDirectiveHSACodeObjectISA();
894 if (IDVal ==
".amd_kernel_code_t")
895 return ParseDirectiveAMDKernelCodeT();
902 for (
unsigned i = 0, e = Operands.
size(); i != e; ++i) {
903 const AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
904 if (Op.isRegKind() && Op.hasModifiers())
906 if (Op.isImm() && (Op.getImmTy() == AMDGPUOperand::ImmTyOMod ||
907 Op.getImmTy() == AMDGPUOperand::ImmTyClamp))
913 AMDGPUAsmParser::OperandMatchResultTy
917 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
925 if (ResTy == MatchOperand_Success || ResTy == MatchOperand_ParseFail ||
929 bool Negate =
false, Abs =
false;
940 switch(getLexer().getKind()) {
942 SMLoc S = Parser.getTok().getLoc();
944 if (getParser().parseAbsoluteExpression(IntVal))
945 return MatchOperand_ParseFail;
946 APInt IntVal32(32, IntVal);
947 if (IntVal32.getSExtValue() !=
IntVal) {
948 Error(S,
"invalid immediate: only 32-bit values are legal");
949 return MatchOperand_ParseFail;
952 IntVal = IntVal32.getSExtValue();
955 Operands.
push_back(AMDGPUOperand::CreateImm(IntVal, S));
956 return MatchOperand_Success;
961 SMLoc S = Parser.getTok().getLoc();
963 if (getParser().parseAbsoluteExpression(IntVal))
964 return MatchOperand_ParseFail;
970 AMDGPUOperand::CreateImm(F.bitcastToAPInt().getZExtValue(), S));
971 return MatchOperand_Success;
976 if (!ParseRegister(RegNo, S, E)) {
979 unsigned Modifiers = 0;
986 return MatchOperand_ParseFail;
991 if (Modifiers && !HasModifiers) {
995 for (
unsigned PrevRegIdx = Operands.
size() - 1; PrevRegIdx > 1;
998 AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[PrevRegIdx]);
999 RegOp.setModifiers(0);
1004 Operands.
push_back(AMDGPUOperand::CreateReg(
1005 RegNo, S, E, getContext().getRegisterInfo(),
1008 if (HasModifiers || Modifiers) {
1009 AMDGPUOperand &RegOp = ((AMDGPUOperand&)*Operands[Operands.
size() - 1]);
1010 RegOp.setModifiers(Modifiers);
1014 Operands.
push_back(AMDGPUOperand::CreateToken(Parser.getTok().getString(),
1018 return MatchOperand_Success;
1021 return MatchOperand_NoMatch;
1030 setForcedEncodingSize(0);
1033 setForcedEncodingSize(64);
1035 setForcedEncodingSize(32);
1038 Operands.
push_back(AMDGPUOperand::CreateToken(Name, NameLoc));
1041 AMDGPUAsmParser::OperandMatchResultTy Res = parseOperand(Operands, Name);
1048 case MatchOperand_Success:
break;
1049 case MatchOperand_ParseFail:
return Error(getLexer().getLoc(),
1050 "failed parsing operand.");
1051 case MatchOperand_NoMatch:
return Error(getLexer().getLoc(),
1052 "not a valid operand.");
1058 AMDGPUAsmParser::OperandMatchResultTy Res;
1059 while ((Res = parseOperand(Operands, Name)) != MatchOperand_NoMatch) {
1060 if (Res != MatchOperand_Success)
1061 return Error(getLexer().getLoc(),
"failed parsing operand.");
1070 AMDGPUAsmParser::OperandMatchResultTy
1071 AMDGPUAsmParser::parseIntWithPrefix(
const char *
Prefix, int64_t &Int,
1078 return MatchOperand_Success;
1081 switch(getLexer().getKind()) {
1082 default:
return MatchOperand_NoMatch;
1084 StringRef OffsetName = Parser.getTok().getString();
1085 if (!OffsetName.
equals(Prefix))
1086 return MatchOperand_NoMatch;
1090 return MatchOperand_ParseFail;
1094 return MatchOperand_ParseFail;
1096 if (getParser().parseAbsoluteExpression(Int))
1097 return MatchOperand_ParseFail;
1101 return MatchOperand_Success;
1104 AMDGPUAsmParser::OperandMatchResultTy
1105 AMDGPUAsmParser::parseIntWithPrefix(
const char *Prefix,
OperandVector &Operands,
1106 enum AMDGPUOperand::ImmTy ImmTy) {
1108 SMLoc S = Parser.getTok().getLoc();
1111 AMDGPUAsmParser::OperandMatchResultTy Res = parseIntWithPrefix(Prefix, Offset);
1112 if (Res != MatchOperand_Success)
1115 Operands.
push_back(AMDGPUOperand::CreateImm(Offset, S, ImmTy));
1116 return MatchOperand_Success;
1119 AMDGPUAsmParser::OperandMatchResultTy
1120 AMDGPUAsmParser::parseNamedBit(
const char *Name,
OperandVector &Operands,
1121 enum AMDGPUOperand::ImmTy ImmTy) {
1123 SMLoc S = Parser.getTok().getLoc();
1128 switch(getLexer().getKind()) {
1138 return MatchOperand_NoMatch;
1143 return MatchOperand_NoMatch;
1147 Operands.
push_back(AMDGPUOperand::CreateImm(Bit, S, ImmTy));
1148 return MatchOperand_Success;
1152 const OptionalOperand &OOp) {
1153 for (
unsigned i = 0; i < Operands.
size(); i++) {
1154 const AMDGPUOperand &ParsedOp = ((
const AMDGPUOperand &)*Operands[i]);
1155 if ((ParsedOp.isImm() && ParsedOp.getImmTy() == OOp.Type) ||
1156 (ParsedOp.isToken() && ParsedOp.getToken() == OOp.Name))
1163 AMDGPUAsmParser::OperandMatchResultTy
1166 SMLoc S = Parser.getTok().getLoc();
1167 for (
const OptionalOperand &Op : OptionalOps) {
1170 AMDGPUAsmParser::OperandMatchResultTy Res;
1173 Res = parseNamedBit(Op.Name, Operands, Op.Type);
1174 if (Res == MatchOperand_NoMatch)
1179 Res = parseIntWithPrefix(Op.Name, Value, Op.Default);
1181 if (Res == MatchOperand_NoMatch)
1184 if (Res != MatchOperand_Success)
1187 if (Op.ConvertResult && !Op.ConvertResult(Value)) {
1188 return MatchOperand_ParseFail;
1191 Operands.
push_back(AMDGPUOperand::CreateImm(Value, S, Op.Type));
1192 return MatchOperand_Success;
1194 return MatchOperand_NoMatch;
1202 {
"offset", AMDGPUOperand::ImmTyOffset,
false, 0,
nullptr},
1203 {
"gds", AMDGPUOperand::ImmTyGDS,
true, 0,
nullptr}
1207 {
"offset0", AMDGPUOperand::ImmTyDSOffset0,
false, 0,
nullptr},
1208 {
"offset1", AMDGPUOperand::ImmTyDSOffset1,
false, 0,
nullptr},
1209 {
"gds", AMDGPUOperand::ImmTyGDS,
true, 0,
nullptr}
1212 AMDGPUAsmParser::OperandMatchResultTy
1213 AMDGPUAsmParser::parseDSOptionalOps(
OperandVector &Operands) {
1216 AMDGPUAsmParser::OperandMatchResultTy
1217 AMDGPUAsmParser::parseDSOff01OptionalOps(
OperandVector &Operands) {
1221 AMDGPUAsmParser::OperandMatchResultTy
1222 AMDGPUAsmParser::parseDSOffsetOptional(
OperandVector &Operands) {
1223 SMLoc S = Parser.getTok().getLoc();
1224 AMDGPUAsmParser::OperandMatchResultTy Res =
1225 parseIntWithPrefix(
"offset", Operands, AMDGPUOperand::ImmTyOffset);
1226 if (Res == MatchOperand_NoMatch) {
1227 Operands.
push_back(AMDGPUOperand::CreateImm(0, S,
1228 AMDGPUOperand::ImmTyOffset));
1229 Res = MatchOperand_Success;
1234 bool AMDGPUOperand::isDSOffset()
const {
1238 bool AMDGPUOperand::isDSOffset01()
const {
1242 void AMDGPUAsmParser::cvtDSOffset01(
MCInst &Inst,
1245 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1247 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
1248 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1252 Op.addRegOperands(Inst, 1);
1257 OptionalIdx[Op.getImmTy()] = i;
1260 unsigned Offset0Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset0];
1261 unsigned Offset1Idx = OptionalIdx[AMDGPUOperand::ImmTyDSOffset1];
1262 unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];
1264 ((AMDGPUOperand &)*Operands[Offset0Idx]).addImmOperands(Inst, 1);
1265 ((AMDGPUOperand &)*Operands[Offset1Idx]).addImmOperands(Inst, 1);
1266 ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1);
1272 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1273 bool GDSOnly =
false;
1275 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
1276 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1280 Op.addRegOperands(Inst, 1);
1284 if (Op.isToken() && Op.getToken() ==
"gds") {
1290 OptionalIdx[Op.getImmTy()] = i;
1293 unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
1294 ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1);
1297 unsigned GDSIdx = OptionalIdx[AMDGPUOperand::ImmTyGDS];
1298 ((AMDGPUOperand &)*Operands[GDSIdx]).addImmOperands(Inst, 1);
1308 bool AMDGPUAsmParser::parseCnt(int64_t &IntVal) {
1309 StringRef CntName = Parser.getTok().getString();
1320 if (getParser().parseAbsoluteExpression(CntVal))
1333 if (CntName ==
"vmcnt") {
1336 }
else if (CntName ==
"expcnt") {
1339 }
else if (CntName ==
"lgkmcnt") {
1346 IntVal &= ~(CntMask << CntShift);
1347 IntVal |= (CntVal << CntShift);
1351 AMDGPUAsmParser::OperandMatchResultTy
1352 AMDGPUAsmParser::parseSWaitCntOps(
OperandVector &Operands) {
1357 int64_t CntVal = 0x77f;
1358 SMLoc S = Parser.getTok().getLoc();
1360 switch(getLexer().getKind()) {
1361 default:
return MatchOperand_ParseFail;
1364 if (getParser().parseAbsoluteExpression(CntVal))
1365 return MatchOperand_ParseFail;
1370 if (parseCnt(CntVal))
1371 return MatchOperand_ParseFail;
1375 Operands.
push_back(AMDGPUOperand::CreateImm(CntVal, S));
1376 return MatchOperand_Success;
1379 bool AMDGPUOperand::isSWaitCnt()
const {
1387 AMDGPUAsmParser::OperandMatchResultTy
1388 AMDGPUAsmParser::parseSOppBrTarget(
OperandVector &Operands) {
1389 SMLoc S = Parser.getTok().getLoc();
1391 switch (getLexer().getKind()) {
1392 default:
return MatchOperand_ParseFail;
1395 if (getParser().parseAbsoluteExpression(Imm))
1396 return MatchOperand_ParseFail;
1397 Operands.
push_back(AMDGPUOperand::CreateImm(Imm, S));
1398 return MatchOperand_Success;
1402 Operands.
push_back(AMDGPUOperand::CreateExpr(
1404 Parser.getTok().getString()), getContext()), S));
1406 return MatchOperand_Success;
1415 {
"glc", AMDGPUOperand::ImmTyGLC,
true, 0,
nullptr},
1416 {
"slc", AMDGPUOperand::ImmTySLC,
true, 0,
nullptr},
1417 {
"tfe", AMDGPUOperand::ImmTyTFE,
true, 0,
nullptr}
1421 {
"slc", AMDGPUOperand::ImmTySLC,
true, 0,
nullptr},
1422 {
"tfe", AMDGPUOperand::ImmTyTFE,
true, 0,
nullptr}
1425 AMDGPUAsmParser::OperandMatchResultTy
1426 AMDGPUAsmParser::parseFlatOptionalOps(
OperandVector &Operands) {
1430 AMDGPUAsmParser::OperandMatchResultTy
1431 AMDGPUAsmParser::parseFlatAtomicOptionalOps(
OperandVector &Operands) {
1435 void AMDGPUAsmParser::cvtFlat(
MCInst &Inst,
1437 std::map<AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1439 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
1440 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1444 Op.addRegOperands(Inst, 1);
1454 OptionalIdx[Op.getImmTy()] = i;
1459 if (OptionalIdx.count(AMDGPUOperand::ImmTyGLC)) {
1460 unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
1461 ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
1464 unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
1465 unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];
1467 ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
1468 ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
1476 {
"offset", AMDGPUOperand::ImmTyOffset,
false, 0,
nullptr},
1477 {
"glc", AMDGPUOperand::ImmTyGLC,
true, 0,
nullptr},
1478 {
"slc", AMDGPUOperand::ImmTySLC,
true, 0,
nullptr},
1479 {
"tfe", AMDGPUOperand::ImmTyTFE,
true, 0,
nullptr}
1482 AMDGPUAsmParser::OperandMatchResultTy
1483 AMDGPUAsmParser::parseMubufOptionalOps(
OperandVector &Operands) {
1487 AMDGPUAsmParser::OperandMatchResultTy
1489 return parseIntWithPrefix(
"offset", Operands);
1492 AMDGPUAsmParser::OperandMatchResultTy
1494 return parseNamedBit(
"glc", Operands);
1497 AMDGPUAsmParser::OperandMatchResultTy
1499 return parseNamedBit(
"slc", Operands);
1502 AMDGPUAsmParser::OperandMatchResultTy
1504 return parseNamedBit(
"tfe", Operands);
1507 bool AMDGPUOperand::isMubufOffset()
const {
1508 return isImm() && isUInt<12>(getImm());
1511 void AMDGPUAsmParser::cvtMubuf(
MCInst &Inst,
1513 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1515 for (
unsigned i = 1, e = Operands.
size(); i != e; ++i) {
1516 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1520 Op.addRegOperands(Inst, 1);
1525 if (Op.isImm() && Op.getImmTy() == AMDGPUOperand::ImmTyNone) {
1526 Op.addImmOperands(Inst, 1);
1538 OptionalIdx[Op.getImmTy()] = i;
1541 assert(OptionalIdx.size() == 4);
1543 unsigned OffsetIdx = OptionalIdx[AMDGPUOperand::ImmTyOffset];
1544 unsigned GLCIdx = OptionalIdx[AMDGPUOperand::ImmTyGLC];
1545 unsigned SLCIdx = OptionalIdx[AMDGPUOperand::ImmTySLC];
1546 unsigned TFEIdx = OptionalIdx[AMDGPUOperand::ImmTyTFE];
1548 ((AMDGPUOperand &)*Operands[OffsetIdx]).addImmOperands(Inst, 1);
1549 ((AMDGPUOperand &)*Operands[GLCIdx]).addImmOperands(Inst, 1);
1550 ((AMDGPUOperand &)*Operands[SLCIdx]).addImmOperands(Inst, 1);
1551 ((AMDGPUOperand &)*Operands[TFEIdx]).addImmOperands(Inst, 1);
1558 AMDGPUAsmParser::OperandMatchResultTy
1560 return parseIntWithPrefix(
"dmask", Operands);
1563 AMDGPUAsmParser::OperandMatchResultTy
1565 return parseNamedBit(
"unorm", Operands);
1568 AMDGPUAsmParser::OperandMatchResultTy
1570 return parseNamedBit(
"r128", Operands);
1578 if (Mul != 1 && Mul != 2 && Mul != 4)
1600 {
"clamp", AMDGPUOperand::ImmTyClamp,
true, 0,
nullptr},
1609 AMDGPUOperand &DstOp = ((AMDGPUOperand&)*Operands[1]);
1611 if (DstOp.isReg() && DstOp.isRegClass(AMDGPU::SGPR_64RegClassID))
1614 if (Operands.
size() >= 5)
1617 if (Operands.
size() > 3) {
1618 AMDGPUOperand &Src1Op = ((AMDGPUOperand&)*Operands[3]);
1619 if (Src1Op.getReg() && (Src1Op.isRegClass(AMDGPU::SReg_32RegClassID) ||
1620 Src1Op.isRegClass(AMDGPU::SReg_64RegClassID)))
1626 AMDGPUAsmParser::OperandMatchResultTy
1627 AMDGPUAsmParser::parseVOP3OptionalOps(
OperandVector &Operands) {
1633 bool IsVOP3 =
isVOP3(Operands);
1634 if (HasModifiers || IsVOP3 ||
1636 getForcedEncodingSize() == 64) {
1638 AMDGPUAsmParser::OperandMatchResultTy Res =
1641 if (!HasModifiers && Res == MatchOperand_Success) {
1644 for (
unsigned i = 2, e = Operands.
size(); i != e; ++i) {
1645 AMDGPUOperand &Op = ((AMDGPUOperand&)*Operands[i]);
1652 return MatchOperand_NoMatch;
1656 ((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
1659 std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
1662 for (
unsigned e = Operands.
size(); i != e; ++i) {
1663 AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[i]);
1665 if (Op.isRegWithInputMods()) {
1666 ((AMDGPUOperand &)*Operands[i]).addRegWithInputModsOperands(Inst, 2);
1669 OptionalIdx[Op.getImmTy()] = i;
1672 unsigned ClampIdx = OptionalIdx[AMDGPUOperand::ImmTyClamp];
1673 unsigned OModIdx = OptionalIdx[AMDGPUOperand::ImmTyOMod];
1675 ((AMDGPUOperand &)*Operands[ClampIdx]).addImmOperands(Inst, 1);
1676 ((AMDGPUOperand &)*Operands[OModIdx]).addImmOperands(Inst, 1);
1678 for (
unsigned e = Operands.
size(); i != e; ++i)
1679 ((AMDGPUOperand &)*Operands[i]).addRegOrImmOperands(Inst, 1);
1689 #define GET_REGISTER_MATCHER
1690 #define GET_MATCHER_IMPLEMENTATION
1691 #include "AMDGPUGenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
bool isUInt< 8 >(uint64_t x)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
void push_back(const T &Elt)
static const OptionalOperand DSOptionalOpsOff01[]
#define S_00B848_VGPRS(x)
static bool isVOP3(OperandVector &Operands)
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
size_t size() const
size - Get the string size.
Generic assembler parser interface, for use by target specific assembly parsers.
Target TheGCNTarget
The target for GCN GPUs.
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static const OptionalOperand FlatOptionalOps[]
Indicate if the generated ISA is using a dynamically sized call stack.
bool endswith(StringRef Suffix) const
Check if this string ends with the given Suffix.
Target specific streamer interface.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
float BitsToFloat(uint32_t Bits)
BitsToFloat - This function takes a 32-bit integer and returns the bit equivalent float...
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
#define S_00B84C_SCRATCH_EN(x)
#define S_00B84C_TG_SIZE_EN(x)
#define S_00B848_DX10_CLAMP(x)
StringSwitch & Case(const char(&S)[N], const T &Value)
static bool ConvertOmodDiv(int64_t &Div)
static const OptionalOperand VOP3OptionalOps[]
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Target TheAMDGPUTarget
The target which suports all AMD GPUs.
uint32_t amd_kernel_code_version_major
uint32_t code_properties
Code properties.
static MCOperand createReg(unsigned Reg)
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
AMD Kernel Code Object (amd_kernel_code_t).
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
uint16_t amd_machine_version_major
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
uint16_t reserved_sgpr_first
If reserved_sgpr_count is 0 then must be 0.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
#define S_00B84C_TGID_Y_EN(x)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
Context object for machine code objects.
#define S_00B848_FLOAT_MODE(x)
uint8_t kernarg_segment_alignment
The maximum byte alignment of variables used by the kernel in the specified memory segment...
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
uint8_t group_segment_alignment
Indicate if code generated has support for debugging.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
uint16_t amd_machine_version_minor
uint32_t amd_kernel_code_version_minor
uint64_t runtime_loader_kernel_symbol
uint64_t compute_pgm_resource_registers
Shader program settings for CS.
Instances of this class represent a single low-level machine instruction.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
#define S_00B848_IEEE_MODE(x)
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
uint16_t wavefront_sgpr_count
Number of scalar registers used by a wavefront.
IsaVersion getIsaVersion(const FeatureBitset &Features)
The instances of the Type class are immutable: once they are created, they are never changed...
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
uint32_t gds_segment_byte_size
Number of byte of GDS required by kernel dispatch.
#define S_00B84C_TIDIG_COMP_CNT(x)
Interface to description of machine instruction set.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint8_t private_segment_alignment
This file declares a class to represent arbitrary precision floating point values and provide a varie...
#define S_00B84C_EXCP_EN_MSB(x)
#define S_00B84C_TGID_Z_EN(x)
#define S_00B84C_LDS_SIZE(x)
void initDefaultAMDKernelCodeT(amd_kernel_code_t &Header, const FeatureBitset &Features)
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
static unsigned getRegClass(bool IsVgpr, unsigned RegWidth)
#define S_00B84C_EXCP_EN(x)
Are global memory addresses 64 bits.
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
uint64_t kernarg_segment_byte_size
The size in bytes of the kernarg segment that holds the values of the arguments to the kernel...
static const OptionalOperand FlatAtomicOptionalOps[]
uint16_t debug_wavefront_private_segment_offset_sgpr
If is_debug_supported is 0 then must be 0.
Promote Memory to Register
static const OptionalOperand MubufOptionalOps[]
uint16_t amd_machine_version_stepping
static bool ConvertOmodMul(int64_t &Mul)
uint16_t workitem_vgpr_count
Number of vector registers used by each work-item.
uint8_t wavefront_size
Wavefront size expressed as a power of two.
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
static bool operandsHaveModifiers(const OperandVector &Operands)
#define S_00B848_DEBUG_MODE(x)
double BitsToDouble(uint64_t Bits)
BitsToDouble - This function takes a 64-bit integer and returns the bit equivalent double...
R Default(const T &Value) const
#define S_00B84C_TGID_X_EN(x)
void LLVMInitializeAMDGPUAsmParser()
Force static initialization.
uint32_t workgroup_group_segment_byte_size
The amount of group segment memory required by a work-group in bytes.
unsigned getOpcode() const
Class for arbitrary precision integers.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
The interleave (swizzle) element size in bytes required by the code for private memory.
Provides AMDGPU specific target descriptions.
Enable the setup of the SGPR user data registers (AMD_CODE_PROPERTY_ENABLE_SGPR_*), see documentation of amd_kernel_code_t for initial register state.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
static const OptionalOperand DSOptionalOps[]
#define S_00B848_SGPRS(x)
uint32_t workitem_private_segment_byte_size
The amount of memory required for the combined private, spill and arg segments for a work-item in byt...
#define S_00B84C_USER_SGPR(x)
MCSubtargetInfo - Generic base class for all target subtargets.
uint64_t kernel_code_prefetch_byte_size
static bool isMem(const MachineInstr *MI, unsigned Op)
Control wave ID base counter for GDS ordered-append.
int64_t kernel_code_entry_byte_offset
Byte offset (possibly negative) from start of amd_kernel_code_t object to kernel's entry point instru...
const ARM::ArchExtKind Kind
static unsigned getRegForName(const StringRef &RegName)
#define S_00B848_PRIORITY(x)
LLVM Value Representation.
bool isUInt< 16 >(uint64_t x)
This class implements an extremely fast bulk output stream that can only output to a stream...
uint16_t amd_machine_kind
uint32_t workgroup_fbarrier_count
Number of fbarrier's used in the kernel and all functions it calls.
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
static bool operandsHasOptionalOp(const OperandVector &Operands, const OptionalOperand &OOp)
Represents a location in source code.
uint16_t debug_private_segment_buffer_sgpr
If is_debug_supported is 0 then must be 0.
uint16_t reserved_vgpr_count
The number of consecutive VGPRs reserved by the client.
static MCOperand createImm(int64_t Val)
uint64_t max_scratch_backing_memory_byte_size
Number of bytes of scratch backing memory required for full occupancy of target chip.
uint16_t reserved_vgpr_first
If reserved_vgpr_count is 0 then must be 0.
uint16_t reserved_sgpr_count
The number of consecutive SGPRs reserved by the client.