@@ -815,6 +815,24 @@ class KernelParser : GenParser
815
815
int m_sendSrcLens[2 ]; // send message lengths
816
816
Loc m_sendSrcLenLocs[2 ]; // locations so we can referee
817
817
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
+
818
836
public:
819
837
KernelParser (
820
838
const Model &model,
@@ -1993,9 +2011,9 @@ class KernelParser : GenParser
1993
2011
// e.g. [a0.4, 16]
1994
2012
// or [a0.4 + 16]
1995
2013
// or [a0.4 - 16]
1996
- void ParseIndOpArgs (RegRef &addrRegRef, int &addrOff) {
2014
+ void ParseIndOpArgs (RegRef &addrRegRef, int &addrOff, RegName& regName ) {
1997
2015
ConsumeOrFail (LBRACK, " expected [" );
1998
- if (!ParseAddrRegRefOpt (addrRegRef)) {
2016
+ if (!ParseAddrRegRefOpt (addrRegRef, regName )) {
1999
2017
FailT (" expected address subregister" );
2000
2018
}
2001
2019
Loc addrOffLoc = NextLoc ();
@@ -2037,7 +2055,8 @@ class KernelParser : GenParser
2037
2055
// [a0.4,16]
2038
2056
int addrOff;
2039
2057
RegRef addrRegRef;
2040
- ParseIndOpArgs (addrRegRef, addrOff);
2058
+ RegName regName = RegName::INVALID;
2059
+ ParseIndOpArgs (addrRegRef, addrOff, regName);
2041
2060
addrOff += baseAddr;
2042
2061
//
2043
2062
// <1>
@@ -2080,14 +2099,18 @@ class KernelParser : GenParser
2080
2099
2081
2100
2082
2101
// E.g. 3 in "a0.3"
2083
- bool ParseAddrRegRefOpt (RegRef& addrReg) {
2102
+ bool ParseAddrRegRefOpt (RegRef& addrReg, RegName& regName ) {
2084
2103
const RegInfo *ri;
2085
2104
int regNum;
2105
+ regName = RegName::INVALID;
2086
2106
if (!ConsumeReg (ri, regNum)) {
2087
2107
return false ;
2088
2108
}
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)" );
2091
2114
}
2092
2115
if (!Consume (DOT)) {
2093
2116
FailT (" expected ." );
@@ -2261,7 +2284,8 @@ class KernelParser : GenParser
2261
2284
// [a0.4 + 16]
2262
2285
int addrOff;
2263
2286
RegRef addrRegRef;
2264
- ParseIndOpArgs (addrRegRef, addrOff);
2287
+ RegName regName = RegName::INVALID;
2288
+ ParseIndOpArgs (addrRegRef, addrOff, regName);
2265
2289
addrOff += baseOff;
2266
2290
2267
2291
// regioning... <V;W,H> or <V,H>
@@ -2270,8 +2294,9 @@ class KernelParser : GenParser
2270
2294
// :t
2271
2295
Type sty = ParseSrcOpTypeWithDefault (srcOpIx, true );
2272
2296
2297
+ IGA_ASSERT (regName != RegName::INVALID, " SrcOpInd must not have INVALID register name" );
2273
2298
m_builder.InstSrcOpRegIndirect (
2274
- srcOpIx, opStart, srcMods, addrRegRef, addrOff, rgn, sty);
2299
+ srcOpIx, opStart, srcMods, regName, addrRegRef, addrOff, rgn, sty);
2275
2300
}
2276
2301
2277
2302
@@ -2916,7 +2941,6 @@ class KernelParser : GenParser
2916
2941
void ParseSendSrc1OpWithOptLen (int &src1Len) {
2917
2942
m_srcLocs[1 ] = NextLoc ();
2918
2943
src1Len = -1 ;
2919
-
2920
2944
const Token regnameTk = Next ();
2921
2945
const RegInfo *regInfo;
2922
2946
int regNum;
@@ -3201,7 +3225,9 @@ class KernelParser : GenParser
3201
3225
void ParseSendDescsWithOptSrc1Len (int src1Length) {
3202
3226
const Loc exDescLoc = NextLoc ();
3203
3227
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" );
3205
3231
exDesc.type = SendDesc::Kind::REG32A;
3206
3232
if (src1Length >= 0 ) {
3207
3233
m_implicitExBSO = true ;
@@ -3275,7 +3301,8 @@ class KernelParser : GenParser
3275
3301
//
3276
3302
const Loc descLoc = NextLoc ();
3277
3303
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" );
3279
3306
desc.type = SendDesc::Kind::REG32A;
3280
3307
} else {
3281
3308
// constant integral expression
@@ -3302,7 +3329,9 @@ class KernelParser : GenParser
3302
3329
3303
3330
SendDesc ParseDesc (const char *which) {
3304
3331
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" );
3306
3335
sd.type = SendDesc::Kind::REG32A;
3307
3336
3308
3337
} else { // ExDesc is imm
@@ -3329,7 +3358,9 @@ class KernelParser : GenParser
3329
3358
3330
3359
const Loc exDescLoc = NextLoc ();
3331
3360
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" );
3333
3364
exDesc.type = SendDesc::Kind::REG32A;
3334
3365
if (platform () < Platform::XE)
3335
3366
m_builder.InstSubfunction (SFID::A0REG);
@@ -3363,7 +3394,8 @@ class KernelParser : GenParser
3363
3394
3364
3395
const Loc descLoc = NextLoc ();
3365
3396
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" );
3367
3399
desc.type = SendDesc::Kind::REG32A;
3368
3400
} else {
3369
3401
// constant integral expression
@@ -3406,7 +3438,8 @@ class KernelParser : GenParser
3406
3438
// TODO: sink this into the instop parsing once we remerge
3407
3439
// that with KernelParser... (after we rip out the legacy ld/st tables)
3408
3440
bool src1LengthSuffixSet = m_sendSrcLens[1 ] != -1 ;
3409
- if (instOpts.contains (InstOpt::EXBSO) && !src1LengthSuffixSet) {
3441
+ if (instOpts.contains (InstOpt::EXBSO) && !src1LengthSuffixSet
3442
+ ) {
3410
3443
// GOOD: send ... r10:2 a0.# ... {ExBSO}
3411
3444
// ERROR: send ... r10 a0.# ... {ExBSO}
3412
3445
// Src1.Length comes from EU bits a0.# holds 26b offset
@@ -3433,7 +3466,9 @@ class KernelParser : GenParser
3433
3466
}
3434
3467
3435
3468
m_builder.InstOptsAdd (instOpts);
3436
- if (m_implicitExBSO && !instOpts.contains (InstOpt::EXBSO)) {
3469
+
3470
+ if (m_implicitExBSO && !instOpts.contains (InstOpt::EXBSO)
3471
+ ) {
3437
3472
WarningAtT (m_mnemonicLoc, " send src1 length implicitly added "
3438
3473
" (include {ExBSO})" );
3439
3474
}
@@ -3621,11 +3656,11 @@ class KernelParser : GenParser
3621
3656
};
3622
3657
//
3623
3658
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);
3629
3664
if (parsedNamedPipe && m_model.supportsHwDeps ()) {
3630
3665
FailAtT (loc,
3631
3666
" software dependencies not supported on this platform" );
@@ -4214,7 +4249,9 @@ bool KernelParser::ParseLdStInst()
4214
4249
auto parseA0RegOrImm = [&] () {
4215
4250
SendDesc surf;
4216
4251
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" );
4218
4255
// surface is a register
4219
4256
surf.type = SendDesc::Kind::REG32A;
4220
4257
if (surf.reg .subRegNum & 1 ) {
0 commit comments