diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index b7f043860115..ba79affe683d 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -1342,10 +1342,8 @@ private: unsigned ParseRegList(RegisterKind &RegKind, unsigned &RegNum, unsigned &RegWidth, SmallVectorImpl<AsmToken> &Tokens); bool ParseRegRange(unsigned& Num, unsigned& Width); - unsigned getRegularReg(RegisterKind RegKind, - unsigned RegNum, - unsigned RegWidth, - SMLoc Loc); + unsigned getRegularReg(RegisterKind RegKind, unsigned RegNum, unsigned SubReg, + unsigned RegWidth, SMLoc Loc); bool isRegister(); bool isRegister(const AsmToken &Token, const AsmToken &NextToken) const; @@ -2616,6 +2614,8 @@ AMDGPUAsmParser::isRegister(const AsmToken &Token, StringRef RegName = Reg->Name; StringRef RegSuffix = Str.substr(RegName.size()); if (!RegSuffix.empty()) { + RegSuffix.consume_back(".l"); + RegSuffix.consume_back(".h"); unsigned Num; // A single register with an index: rXX if (getRegNum(RegSuffix, Num)) @@ -2636,12 +2636,9 @@ AMDGPUAsmParser::isRegister() return isRegister(getToken(), peekToken()); } -unsigned -AMDGPUAsmParser::getRegularReg(RegisterKind RegKind, - unsigned RegNum, - unsigned RegWidth, - SMLoc Loc) { - +unsigned AMDGPUAsmParser::getRegularReg(RegisterKind RegKind, unsigned RegNum, + unsigned SubReg, unsigned RegWidth, + SMLoc Loc) { assert(isRegularReg(RegKind)); unsigned AlignSize = 1; @@ -2670,7 +2667,17 @@ AMDGPUAsmParser::getRegularReg(RegisterKind RegKind, return AMDGPU::NoRegister; } - return RC.getRegister(RegIdx); + unsigned Reg = RC.getRegister(RegIdx); + + if (SubReg) { + Reg = TRI->getSubReg(Reg, SubReg); + + // Currently all regular registers have their .l and .h subregisters, so + // we should never need to generate an error here. + assert(Reg && "Invalid subregister!"); + } + + return Reg; } bool AMDGPUAsmParser::ParseRegRange(unsigned &Num, unsigned &RegWidth) { @@ -2748,7 +2755,17 @@ unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind, RegKind = RI->Kind; StringRef RegSuffix = RegName.substr(RI->Name.size()); + unsigned SubReg = NoSubRegister; if (!RegSuffix.empty()) { + // We don't know the opcode till we are done parsing, so we don't know if + // registers should be 16 or 32 bit. It is therefore mandatory to put .l or + // .h to correctly specify 16 bit registers. We also can't determine class + // VGPR_16_Lo128 or VGPR_16, so always parse them as VGPR_16. + if (RegSuffix.consume_back(".l")) + SubReg = AMDGPU::lo16; + else if (RegSuffix.consume_back(".h")) + SubReg = AMDGPU::hi16; + // Single 32-bit register: vXX. if (!getRegNum(RegSuffix, RegNum)) { Error(Loc, "invalid register index"); @@ -2761,7 +2778,7 @@ unsigned AMDGPUAsmParser::ParseRegularReg(RegisterKind &RegKind, return AMDGPU::NoRegister; } - return getRegularReg(RegKind, RegNum, RegWidth, Loc); + return getRegularReg(RegKind, RegNum, SubReg, RegWidth, Loc); } unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind, unsigned &RegNum, @@ -2813,7 +2830,7 @@ unsigned AMDGPUAsmParser::ParseRegList(RegisterKind &RegKind, unsigned &RegNum, } if (isRegularReg(RegKind)) - Reg = getRegularReg(RegKind, RegNum, RegWidth, ListLoc); + Reg = getRegularReg(RegKind, RegNum, NoSubRegister, RegWidth, ListLoc); return Reg; } |
