@@ -81,6 +81,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
81
81
bool Neg = false ;
82
82
bool Sext = false ;
83
83
bool Lit = false ;
84
+ bool Lit64 = false ;
84
85
85
86
bool hasFPModifiers () const { return Abs || Neg; }
86
87
bool hasIntModifiers () const { return Sext; }
@@ -480,7 +481,10 @@ class AMDGPUOperand : public MCParsedAsmOperand {
480
481
bool isSSrc_b64 () const {
481
482
// TODO: Find out how SALU supports extension of 32-bit literals to 64 bits.
482
483
// See isVSrc64().
483
- return isSCSrc_b64 () || isLiteralImm (MVT::i64 );
484
+ return isSCSrc_b64 () || isLiteralImm (MVT::i64 ) ||
485
+ (((const MCTargetAsmParser *)AsmParser)
486
+ ->getAvailableFeatures ()[AMDGPU::Feature64BitLiterals] &&
487
+ isExpr ());
484
488
}
485
489
486
490
bool isSSrc_f32 () const {
@@ -1537,6 +1541,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
1537
1541
return getFeatureBits ()[AMDGPU::FeatureInv2PiInlineImm];
1538
1542
}
1539
1543
1544
+ bool has64BitLiterals () const {
1545
+ return getFeatureBits ()[AMDGPU::Feature64BitLiterals];
1546
+ }
1547
+
1540
1548
bool hasFlatOffsets () const {
1541
1549
return getFeatureBits ()[AMDGPU::FeatureFlatInstOffsets];
1542
1550
}
@@ -1663,10 +1671,10 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
1663
1671
bool isOpcodeModifierWithVal (const AsmToken &Token, const AsmToken &NextToken) const ;
1664
1672
bool parseSP3NegModifier ();
1665
1673
ParseStatus parseImm (OperandVector &Operands, bool HasSP3AbsModifier = false ,
1666
- bool HasLit = false );
1674
+ bool HasLit = false , bool HasLit64 = false );
1667
1675
ParseStatus parseReg (OperandVector &Operands);
1668
1676
ParseStatus parseRegOrImm (OperandVector &Operands, bool HasSP3AbsMod = false ,
1669
- bool HasLit = false );
1677
+ bool HasLit = false , bool HasLit64 = false );
1670
1678
ParseStatus parseRegOrImmWithFPInputMods (OperandVector &Operands,
1671
1679
bool AllowImm = true );
1672
1680
ParseStatus parseRegOrImmWithIntInputMods (OperandVector &Operands,
@@ -2123,6 +2131,9 @@ bool AMDGPUOperand::isLiteralImm(MVT type) const {
2123
2131
return false ;
2124
2132
}
2125
2133
2134
+ bool Allow64Bit =
2135
+ (type == MVT::i64 || type == MVT::f64 ) && AsmParser->has64BitLiterals ();
2136
+
2126
2137
if (!Imm.IsFPImm ) {
2127
2138
// We got int literal token.
2128
2139
@@ -2134,8 +2145,11 @@ bool AMDGPUOperand::isLiteralImm(MVT type) const {
2134
2145
}
2135
2146
2136
2147
unsigned Size = type.getSizeInBits ();
2137
- if (Size == 64 )
2148
+ if (Size == 64 ) {
2149
+ if (Allow64Bit && !AMDGPU::isValid32BitLiteral (Imm.Val , false ))
2150
+ return true ;
2138
2151
Size = 32 ;
2152
+ }
2139
2153
2140
2154
// FIXME: 64-bit operands can zero extend, sign extend, or pad zeroes for FP
2141
2155
// types.
@@ -2287,12 +2301,18 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
2287
2301
}
2288
2302
2289
2303
// Non-inlineable
2290
- if (AMDGPU::isSISrcFPOperand (InstDesc, OpNum)) { // Expected 64-bit fp operand
2304
+ if (AMDGPU::isSISrcFPOperand (InstDesc,
2305
+ OpNum)) { // Expected 64-bit fp operand
2306
+ bool HasMandatoryLiteral =
2307
+ AMDGPU::hasNamedOperand (Inst.getOpcode (), AMDGPU::OpName::imm);
2291
2308
// For fp operands we check if low 32 bits are zeros
2292
- if (Literal.getLoBits (32 ) != 0 ) {
2293
- const_cast <AMDGPUAsmParser *>(AsmParser)->Warning (Inst.getLoc (),
2294
- " Can't encode literal as exact 64-bit floating-point operand. "
2295
- " Low 32-bits will be set to zero" );
2309
+ if (Literal.getLoBits (32 ) != 0 &&
2310
+ (InstDesc.getSize () != 4 || !AsmParser->has64BitLiterals ()) &&
2311
+ !HasMandatoryLiteral) {
2312
+ const_cast <AMDGPUAsmParser *>(AsmParser)->Warning (
2313
+ Inst.getLoc (),
2314
+ " Can't encode literal as exact 64-bit floating-point operand. "
2315
+ " Low 32-bits will be set to zero" );
2296
2316
Val &= 0xffffffff00000000u ;
2297
2317
}
2298
2318
@@ -2392,8 +2412,25 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
2392
2412
return ;
2393
2413
2394
2414
case AMDGPU::OPERAND_REG_IMM_INT64:
2395
- case AMDGPU::OPERAND_REG_IMM_FP64:
2396
2415
case AMDGPU::OPERAND_REG_INLINE_C_INT64:
2416
+ if (AMDGPU::isInlinableLiteral64 (Val, AsmParser->hasInv2PiInlineImm ())) {
2417
+ Inst.addOperand (MCOperand::createImm (Val));
2418
+ setImmKindConst ();
2419
+ return ;
2420
+ }
2421
+
2422
+ // When the 32 MSBs are not zero (effectively means it can't be safely
2423
+ // truncated to uint32_t), if the target doesn't support 64-bit literals, or
2424
+ // the lit modifier is explicitly used, we need to truncate it to the 32
2425
+ // LSBs.
2426
+ if (!AsmParser->has64BitLiterals () || getModifiers ().Lit )
2427
+ Val = Lo_32 (Val);
2428
+
2429
+ Inst.addOperand (MCOperand::createImm (Val));
2430
+ setImmKindLiteral ();
2431
+ return ;
2432
+
2433
+ case AMDGPU::OPERAND_REG_IMM_FP64:
2397
2434
case AMDGPU::OPERAND_REG_INLINE_C_FP64:
2398
2435
case AMDGPU::OPERAND_REG_INLINE_AC_FP64:
2399
2436
if (AMDGPU::isInlinableLiteral64 (Val, AsmParser->hasInv2PiInlineImm ())) {
@@ -2402,8 +2439,20 @@ void AMDGPUOperand::addLiteralImmOperand(MCInst &Inst, int64_t Val, bool ApplyMo
2402
2439
return ;
2403
2440
}
2404
2441
2405
- Val = AMDGPU::isSISrcFPOperand (InstDesc, OpNum) ? (uint64_t )Val << 32
2406
- : Lo_32 (Val);
2442
+ // If the target doesn't support 64-bit literals, we need to use the
2443
+ // constant as the high 32 MSBs of a double-precision floating point value.
2444
+ if (!AsmParser->has64BitLiterals ()) {
2445
+ Val = static_cast <uint64_t >(Val) << 32 ;
2446
+ } else {
2447
+ // Now the target does support 64-bit literals, there are two cases
2448
+ // where we still want to use src_literal encoding:
2449
+ // 1) explicitly forced by using lit modifier;
2450
+ // 2) the value is a valid 32-bit representation (signed or unsigned),
2451
+ // meanwhile not forced by lit64 modifier.
2452
+ if (getModifiers ().Lit ||
2453
+ (!getModifiers ().Lit64 && (isInt<32 >(Val) || isUInt<32 >(Val))))
2454
+ Val = static_cast <uint64_t >(Val) << 32 ;
2455
+ }
2407
2456
2408
2457
Inst.addOperand (MCOperand::createImm (Val));
2409
2458
setImmKindLiteral ();
@@ -3151,19 +3200,20 @@ AMDGPUAsmParser::parseRegister(bool RestoreOnFailure) {
3151
3200
}
3152
3201
3153
3202
ParseStatus AMDGPUAsmParser::parseImm (OperandVector &Operands,
3154
- bool HasSP3AbsModifier, bool HasLit) {
3203
+ bool HasSP3AbsModifier, bool HasLit,
3204
+ bool HasLit64) {
3155
3205
// TODO: add syntactic sugar for 1/(2*PI)
3156
3206
3157
- if (isRegister ())
3207
+ if (isRegister () || isModifier () )
3158
3208
return ParseStatus::NoMatch;
3159
- assert (!isModifier ());
3160
3209
3161
- if (!HasLit) {
3162
- HasLit = trySkipId (" lit" );
3163
- if (HasLit) {
3210
+ if (!HasLit && !HasLit64) {
3211
+ HasLit64 = trySkipId (" lit64" );
3212
+ HasLit = !HasLit64 && trySkipId (" lit" );
3213
+ if (HasLit || HasLit64) {
3164
3214
if (!skipToken (AsmToken::LParen, " expected left paren after lit" ))
3165
3215
return ParseStatus::Failure;
3166
- ParseStatus S = parseImm (Operands, HasSP3AbsModifier, HasLit);
3216
+ ParseStatus S = parseImm (Operands, HasSP3AbsModifier, HasLit, HasLit64 );
3167
3217
if (S.isSuccess () &&
3168
3218
!skipToken (AsmToken::RParen, " expected closing parentheses" ))
3169
3219
return ParseStatus::Failure;
@@ -3185,6 +3235,7 @@ ParseStatus AMDGPUAsmParser::parseImm(OperandVector &Operands,
3185
3235
3186
3236
AMDGPUOperand::Modifiers Mods;
3187
3237
Mods.Lit = HasLit;
3238
+ Mods.Lit64 = HasLit64;
3188
3239
3189
3240
if (IsReal) {
3190
3241
// Floating-point expressions are not supported.
@@ -3235,7 +3286,7 @@ ParseStatus AMDGPUAsmParser::parseImm(OperandVector &Operands,
3235
3286
AMDGPUOperand &Op = static_cast <AMDGPUOperand &>(*Operands.back ());
3236
3287
Op.setModifiers (Mods);
3237
3288
} else {
3238
- if (HasLit)
3289
+ if (HasLit || HasLit64 )
3239
3290
return ParseStatus::NoMatch;
3240
3291
Operands.push_back (AMDGPUOperand::CreateExpr (this , Expr, S));
3241
3292
}
@@ -3259,13 +3310,14 @@ ParseStatus AMDGPUAsmParser::parseReg(OperandVector &Operands) {
3259
3310
}
3260
3311
3261
3312
ParseStatus AMDGPUAsmParser::parseRegOrImm (OperandVector &Operands,
3262
- bool HasSP3AbsMod, bool HasLit) {
3313
+ bool HasSP3AbsMod, bool HasLit,
3314
+ bool HasLit64) {
3263
3315
ParseStatus Res = parseReg (Operands);
3264
3316
if (!Res.isNoMatch ())
3265
3317
return Res;
3266
3318
if (isModifier ())
3267
3319
return ParseStatus::NoMatch;
3268
- return parseImm (Operands, HasSP3AbsMod, HasLit);
3320
+ return parseImm (Operands, HasSP3AbsMod, HasLit, HasLit64 );
3269
3321
}
3270
3322
3271
3323
bool
@@ -3361,7 +3413,7 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3361
3413
bool AllowImm) {
3362
3414
bool Neg, SP3Neg;
3363
3415
bool Abs, SP3Abs;
3364
- bool Lit;
3416
+ bool Lit64, Lit;
3365
3417
SMLoc Loc;
3366
3418
3367
3419
// Disable ambiguous constructs like '--1' etc. Should use neg(-1) instead.
@@ -3381,7 +3433,15 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3381
3433
if (Abs && !skipToken (AsmToken::LParen, " expected left paren after abs" ))
3382
3434
return ParseStatus::Failure;
3383
3435
3384
- Lit = trySkipId (" lit" );
3436
+ Lit64 = trySkipId (" lit64" );
3437
+ if (Lit64) {
3438
+ if (!skipToken (AsmToken::LParen, " expected left paren after lit64" ))
3439
+ return ParseStatus::Failure;
3440
+ if (!has64BitLiterals ())
3441
+ return Error (Loc, " lit64 is not supported on this GPU" );
3442
+ }
3443
+
3444
+ Lit = !Lit64 && trySkipId (" lit" );
3385
3445
if (Lit && !skipToken (AsmToken::LParen, " expected left paren after lit" ))
3386
3446
return ParseStatus::Failure;
3387
3447
@@ -3392,14 +3452,16 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3392
3452
3393
3453
ParseStatus Res;
3394
3454
if (AllowImm) {
3395
- Res = parseRegOrImm (Operands, SP3Abs, Lit);
3455
+ Res = parseRegOrImm (Operands, SP3Abs, Lit, Lit64 );
3396
3456
} else {
3397
3457
Res = parseReg (Operands);
3398
3458
}
3399
3459
if (!Res.isSuccess ())
3400
- return (SP3Neg || Neg || SP3Abs || Abs || Lit) ? ParseStatus::Failure : Res;
3460
+ return (SP3Neg || Neg || SP3Abs || Abs || Lit || Lit64)
3461
+ ? ParseStatus::Failure
3462
+ : Res;
3401
3463
3402
- if (Lit && !Operands.back ()->isImm ())
3464
+ if (( Lit || Lit64) && !Operands.back ()->isImm ())
3403
3465
Error (Loc, " expected immediate with lit modifier" );
3404
3466
3405
3467
if (SP3Abs && !skipToken (AsmToken::Pipe, " expected vertical bar" ))
@@ -3408,15 +3470,17 @@ AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands,
3408
3470
return ParseStatus::Failure;
3409
3471
if (Neg && !skipToken (AsmToken::RParen, " expected closing parentheses" ))
3410
3472
return ParseStatus::Failure;
3411
- if (Lit && !skipToken (AsmToken::RParen, " expected closing parentheses" ))
3473
+ if ((Lit || Lit64) &&
3474
+ !skipToken (AsmToken::RParen, " expected closing parentheses" ))
3412
3475
return ParseStatus::Failure;
3413
3476
3414
3477
AMDGPUOperand::Modifiers Mods;
3415
3478
Mods.Abs = Abs || SP3Abs;
3416
3479
Mods.Neg = Neg || SP3Neg;
3417
3480
Mods.Lit = Lit;
3481
+ Mods.Lit64 = Lit64;
3418
3482
3419
- if (Mods.hasFPModifiers () || Lit) {
3483
+ if (Mods.hasFPModifiers () || Lit || Lit64 ) {
3420
3484
AMDGPUOperand &Op = static_cast <AMDGPUOperand &>(*Operands.back ());
3421
3485
if (Op.isExpr ())
3422
3486
return Error (Op.getStartLoc (), " expected an absolute expression" );
@@ -4588,7 +4652,7 @@ bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const {
4588
4652
4589
4653
unsigned NumExprs = 0 ;
4590
4654
unsigned NumLiterals = 0 ;
4591
- uint32_t LiteralValue;
4655
+ uint64_t LiteralValue;
4592
4656
4593
4657
for (int OpIdx : OpIndices) {
4594
4658
if (OpIdx == -1 ) break ;
@@ -4597,7 +4661,7 @@ bool AMDGPUAsmParser::validateSOPLiteral(const MCInst &Inst) const {
4597
4661
// Exclude special imm operands (like that used by s_set_gpr_idx_on)
4598
4662
if (AMDGPU::isSISrcOperand (Desc, OpIdx)) {
4599
4663
if (MO.isImm () && !isInlineConstant (Inst, OpIdx)) {
4600
- uint32_t Value = static_cast <uint32_t >(MO.getImm ());
4664
+ uint64_t Value = static_cast <uint64_t >(MO.getImm ());
4601
4665
if (NumLiterals == 0 || LiteralValue != Value) {
4602
4666
LiteralValue = Value;
4603
4667
++NumLiterals;
0 commit comments