diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index b43876582daa8..0dc1d13773229 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1395,7 +1395,7 @@ class AMDGPUAsmParser : public MCTargetAsmParser { MCRegister ParseRegList(RegisterKind &RegKind, unsigned &RegNum, unsigned &RegWidth, SmallVectorImpl &Tokens); - bool ParseRegRange(unsigned& Num, unsigned& Width); + bool ParseRegRange(unsigned &Num, unsigned &Width, unsigned &SubReg); MCRegister getRegularReg(RegisterKind RegKind, unsigned RegNum, unsigned SubReg, unsigned RegWidth, SMLoc Loc); @@ -2857,7 +2857,8 @@ MCRegister AMDGPUAsmParser::getRegularReg(RegisterKind RegKind, unsigned RegNum, return Reg; } -bool AMDGPUAsmParser::ParseRegRange(unsigned &Num, unsigned &RegWidth) { +bool AMDGPUAsmParser::ParseRegRange(unsigned &Num, unsigned &RegWidth, + unsigned &SubReg) { int64_t RegLo, RegHi; if (!skipToken(AsmToken::LBrac, "missing register index")) return false; @@ -2894,8 +2895,20 @@ bool AMDGPUAsmParser::ParseRegRange(unsigned &Num, unsigned &RegWidth) { return false; } + if (RegHi == RegLo) { + StringRef RegSuffix = getTokenStr(); + if (RegSuffix == ".l") { + SubReg = AMDGPU::lo16; + lex(); + } else if (RegSuffix == ".h") { + SubReg = AMDGPU::hi16; + lex(); + } + } + Num = static_cast(RegLo); RegWidth = 32 * ((RegHi - RegLo) + 1); + return true; } @@ -2949,7 +2962,7 @@ MCRegister AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind, RegWidth = 32; } else { // Range of registers: v[XX:YY]. ":YY" is optional. - if (!ParseRegRange(RegNum, RegWidth)) + if (!ParseRegRange(RegNum, RegWidth, SubReg)) return MCRegister(); } diff --git a/llvm/test/MC/AMDGPU/gfx11_asm_vop1.s b/llvm/test/MC/AMDGPU/gfx11_asm_vop1.s index 93e01954bea55..f1438532d7c5e 100644 --- a/llvm/test/MC/AMDGPU/gfx11_asm_vop1.s +++ b/llvm/test/MC/AMDGPU/gfx11_asm_vop1.s @@ -3808,3 +3808,9 @@ v_trunc_f64 v[5:6], src_scc v_trunc_f64 v[254:255], 0xaf123456 // GFX11: v_trunc_f64_e32 v[254:255], 0xaf123456 ; encoding: [0xff,0x2e,0xfc,0x7f,0x56,0x34,0x12,0xaf] + +v_trunc_f16 v[5].l, v[1].h +// GFX11: v_trunc_f16_e32 v5.l, v1.h ; encoding: [0x81,0xbb,0x0a,0x7e] + +v_trunc_f16 v[5:5].l, v[1:1].h +// GFX11: v_trunc_f16_e32 v5.l, v1.h ; encoding: [0x81,0xbb,0x0a,0x7e] diff --git a/llvm/test/MC/AMDGPU/gfx11_asm_vop1_t16_err.s b/llvm/test/MC/AMDGPU/gfx11_asm_vop1_t16_err.s index 55a25ad3ec81b..d19220867f29f 100644 --- a/llvm/test/MC/AMDGPU/gfx11_asm_vop1_t16_err.s +++ b/llvm/test/MC/AMDGPU/gfx11_asm_vop1_t16_err.s @@ -1231,3 +1231,9 @@ v_trunc_f16_e32 v5.l, v199.l dpp8:[7,6,5,4,3,2,1,0] v_trunc_f16_e32 v5.l, v199.l quad_perm:[3,2,1,0] // GFX11: :[[@LINE-1]]:23: error: invalid operand for instruction + +v_ceil_f16_e32 v[5:5].s, 0xfe0b +// GFX11: :[[@LINE-1]]:22: error: invalid operand for instruction + +v_ceil_f16_e32 v[6:7].l, 0xfe0b +// GFX11: :[[@LINE-1]]:16: error: invalid operand for instruction