@@ -815,6 +815,24 @@ class KernelParser : GenParser
815815 int m_sendSrcLens[2 ]; // send message lengths
816816 Loc m_sendSrcLenLocs[2 ]; // locations so we can referee
817817 bool m_implicitExBSO; // send src1 suffixed with length implies exBSO, but ensure the inst opt is given
818+
819+ private:
820+ // A helper function to add ARF_NULL src to given src operand
821+ void addNullSrc (int srcOpIx, bool isImmOrLbl) {
822+ // For instructions those have implicit types, match the type to
823+ // the expected one. Otherwise, ARF_NULL operand should have Type::INVALID
824+ Type type = Type::INVALID;
825+ m_opSpec->implicitSrcTypeVal (srcOpIx, isImmOrLbl, type);
826+ m_builder.InstSrcOpRegDirect (
827+ srcOpIx,
828+ m_srcLocs[srcOpIx],
829+ SrcModifier::NONE,
830+ RegName::ARF_NULL,
831+ REGREF_ZERO_ZERO,
832+ Region::SRC010,
833+ type);
834+ }
835+
818836public:
819837 KernelParser (
820838 const Model &model,
@@ -1993,9 +2011,9 @@ class KernelParser : GenParser
19932011 // e.g. [a0.4, 16]
19942012 // or [a0.4 + 16]
19952013 // or [a0.4 - 16]
1996- void ParseIndOpArgs (RegRef &addrRegRef, int &addrOff) {
2014+ void ParseIndOpArgs (RegRef &addrRegRef, int &addrOff, RegName& regName ) {
19972015 ConsumeOrFail (LBRACK, " expected [" );
1998- if (!ParseAddrRegRefOpt (addrRegRef)) {
2016+ if (!ParseAddrRegRefOpt (addrRegRef, regName )) {
19992017 FailT (" expected address subregister" );
20002018 }
20012019 Loc addrOffLoc = NextLoc ();
@@ -2037,7 +2055,8 @@ class KernelParser : GenParser
20372055 // [a0.4,16]
20382056 int addrOff;
20392057 RegRef addrRegRef;
2040- ParseIndOpArgs (addrRegRef, addrOff);
2058+ RegName regName = RegName::INVALID;
2059+ ParseIndOpArgs (addrRegRef, addrOff, regName);
20412060 addrOff += baseAddr;
20422061 //
20432062 // <1>
@@ -2080,14 +2099,18 @@ class KernelParser : GenParser
20802099
20812100
20822101 // E.g. 3 in "a0.3"
2083- bool ParseAddrRegRefOpt (RegRef& addrReg) {
2102+ bool ParseAddrRegRefOpt (RegRef& addrReg, RegName& regName ) {
20842103 const RegInfo *ri;
20852104 int regNum;
2105+ regName = RegName::INVALID;
20862106 if (!ConsumeReg (ri, regNum)) {
20872107 return false ;
20882108 }
2089- if (ri->regName != RegName::ARF_A && regNum != 0 ) {
2090- FailT (" expected a0" );
2109+ regName = ri->regName ;
2110+ if (regNum != 0 ||
2111+ (ri->regName != RegName::ARF_A
2112+ )) {
2113+ FailT (" expected address register for indirect access (a0)" );
20912114 }
20922115 if (!Consume (DOT)) {
20932116 FailT (" expected ." );
@@ -2261,7 +2284,8 @@ class KernelParser : GenParser
22612284 // [a0.4 + 16]
22622285 int addrOff;
22632286 RegRef addrRegRef;
2264- ParseIndOpArgs (addrRegRef, addrOff);
2287+ RegName regName = RegName::INVALID;
2288+ ParseIndOpArgs (addrRegRef, addrOff, regName);
22652289 addrOff += baseOff;
22662290
22672291 // regioning... <V;W,H> or <V,H>
@@ -2270,8 +2294,9 @@ class KernelParser : GenParser
22702294 // :t
22712295 Type sty = ParseSrcOpTypeWithDefault (srcOpIx, true );
22722296
2297+ IGA_ASSERT (regName != RegName::INVALID, " SrcOpInd must not have INVALID register name" );
22732298 m_builder.InstSrcOpRegIndirect (
2274- srcOpIx, opStart, srcMods, addrRegRef, addrOff, rgn, sty);
2299+ srcOpIx, opStart, srcMods, regName, addrRegRef, addrOff, rgn, sty);
22752300 }
22762301
22772302
@@ -2916,7 +2941,6 @@ class KernelParser : GenParser
29162941 void ParseSendSrc1OpWithOptLen (int &src1Len) {
29172942 m_srcLocs[1 ] = NextLoc ();
29182943 src1Len = -1 ;
2919-
29202944 const Token regnameTk = Next ();
29212945 const RegInfo *regInfo;
29222946 int regNum;
@@ -3201,7 +3225,9 @@ class KernelParser : GenParser
32013225 void ParseSendDescsWithOptSrc1Len (int src1Length) {
32023226 const Loc exDescLoc = NextLoc ();
32033227 SendDesc exDesc;
3204- if (ParseAddrRegRefOpt (exDesc.reg )) { // ExDesc is register
3228+ RegName regName = RegName::INVALID;
3229+ if (ParseAddrRegRefOpt (exDesc.reg , regName)) { // ExDesc is register
3230+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send exDesc must be ARF_A" );
32053231 exDesc.type = SendDesc::Kind::REG32A;
32063232 if (src1Length >= 0 ) {
32073233 m_implicitExBSO = true ;
@@ -3275,7 +3301,8 @@ class KernelParser : GenParser
32753301 //
32763302 const Loc descLoc = NextLoc ();
32773303 SendDesc desc;
3278- if (ParseAddrRegRefOpt (desc.reg )) {
3304+ if (ParseAddrRegRefOpt (desc.reg , regName)) {
3305+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send desc must be ARF_A" );
32793306 desc.type = SendDesc::Kind::REG32A;
32803307 } else {
32813308 // constant integral expression
@@ -3302,7 +3329,9 @@ class KernelParser : GenParser
33023329
33033330 SendDesc ParseDesc (const char *which) {
33043331 SendDesc sd;
3305- if (ParseAddrRegRefOpt (sd.reg )) { // ExDesc is register
3332+ RegName regName = RegName::INVALID;
3333+ if (ParseAddrRegRefOpt (sd.reg , regName)) { // ExDesc is register
3334+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send Desc must be ARF_A" );
33063335 sd.type = SendDesc::Kind::REG32A;
33073336
33083337 } else { // ExDesc is imm
@@ -3329,7 +3358,9 @@ class KernelParser : GenParser
33293358
33303359 const Loc exDescLoc = NextLoc ();
33313360 SendDesc exDesc;
3332- if (ParseAddrRegRefOpt (exDesc.reg )) {
3361+ RegName regName = RegName::INVALID;
3362+ if (ParseAddrRegRefOpt (exDesc.reg , regName)) {
3363+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send exDesc must be ARF_A" );
33333364 exDesc.type = SendDesc::Kind::REG32A;
33343365 if (platform () < Platform::XE)
33353366 m_builder.InstSubfunction (SFID::A0REG);
@@ -3363,7 +3394,8 @@ class KernelParser : GenParser
33633394
33643395 const Loc descLoc = NextLoc ();
33653396 SendDesc desc;
3366- if (ParseAddrRegRefOpt (desc.reg )) {
3397+ if (ParseAddrRegRefOpt (desc.reg , regName)) {
3398+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send Desc must be ARF_A" );
33673399 desc.type = SendDesc::Kind::REG32A;
33683400 } else {
33693401 // constant integral expression
@@ -3406,7 +3438,8 @@ class KernelParser : GenParser
34063438 // TODO: sink this into the instop parsing once we remerge
34073439 // that with KernelParser... (after we rip out the legacy ld/st tables)
34083440 bool src1LengthSuffixSet = m_sendSrcLens[1 ] != -1 ;
3409- if (instOpts.contains (InstOpt::EXBSO) && !src1LengthSuffixSet) {
3441+ if (instOpts.contains (InstOpt::EXBSO) && !src1LengthSuffixSet
3442+ ) {
34103443 // GOOD: send ... r10:2 a0.# ... {ExBSO}
34113444 // ERROR: send ... r10 a0.# ... {ExBSO}
34123445 // Src1.Length comes from EU bits a0.# holds 26b offset
@@ -3433,7 +3466,9 @@ class KernelParser : GenParser
34333466 }
34343467
34353468 m_builder.InstOptsAdd (instOpts);
3436- if (m_implicitExBSO && !instOpts.contains (InstOpt::EXBSO)) {
3469+
3470+ if (m_implicitExBSO && !instOpts.contains (InstOpt::EXBSO)
3471+ ) {
34373472 WarningAtT (m_mnemonicLoc, " send src1 length implicitly added "
34383473 " (include {ExBSO})" );
34393474 }
@@ -3621,11 +3656,11 @@ class KernelParser : GenParser
36213656 };
36223657 //
36233658 bool parsedNamedPipe =
3624- tryParsePipe (" F" , SWSB::DistType::REG_DIST_FLOAT)
3625- || tryParsePipe (" I" , SWSB::DistType::REG_DIST_INT)
3626- || tryParsePipe (" L" , SWSB::DistType::REG_DIST_LONG)
3627- || tryParsePipe (" A" , SWSB::DistType::REG_DIST_ALL)
3628- || tryParsePipe (" M" , SWSB::DistType::REG_DIST_MATH);
3659+ tryParsePipe (" F" , SWSB::DistType::REG_DIST_FLOAT) ||
3660+ tryParsePipe (" I" , SWSB::DistType::REG_DIST_INT) ||
3661+ tryParsePipe (" L" , SWSB::DistType::REG_DIST_LONG) ||
3662+ tryParsePipe (" A" , SWSB::DistType::REG_DIST_ALL) ||
3663+ tryParsePipe (" M" , SWSB::DistType::REG_DIST_MATH);
36293664 if (parsedNamedPipe && m_model.supportsHwDeps ()) {
36303665 FailAtT (loc,
36313666 " software dependencies not supported on this platform" );
@@ -4214,7 +4249,9 @@ bool KernelParser::ParseLdStInst()
42144249 auto parseA0RegOrImm = [&] () {
42154250 SendDesc surf;
42164251 ConsumeOrFail (LBRACK, " expected [" );
4217- if (ParseAddrRegRefOpt (surf.reg )) {
4252+ RegName regName = RegName::INVALID;
4253+ if (ParseAddrRegRefOpt (surf.reg , regName)) {
4254+ IGA_ASSERT (regName == RegName::ARF_A, " Indirect send Desc must be ARF_A" );
42184255 // surface is a register
42194256 surf.type = SendDesc::Kind::REG32A;
42204257 if (surf.reg .subRegNum & 1 ) {
0 commit comments