diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index f2c04215d12d..7c3898ac6731 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -416,7 +416,8 @@ private: return static_cast(TS); } - bool parseRegister(Register &Reg, bool RestoreOnFailure = false); + bool parseRegister(Register &Reg, bool RequirePercent, + bool RestoreOnFailure = false); bool parseIntegerRegister(Register &Reg, RegisterGroup Group); @@ -495,7 +496,7 @@ public: ParseStatus parseDirective(AsmToken DirectiveID) override; bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; bool ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, SMLoc &EndLoc, - bool RestoreOnFailure); + bool RequirePercent, bool RestoreOnFailure); ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override; bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, @@ -756,26 +757,32 @@ void SystemZOperand::print(raw_ostream &OS) const { } // Parse one register of the form %. -bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) { - Reg.StartLoc = Parser.getTok().getLoc(); - - // Eat the % prefix. - if (Parser.getTok().isNot(AsmToken::Percent)) - return Error(Parser.getTok().getLoc(), "register expected"); +bool SystemZAsmParser::parseRegister(Register &Reg, bool RequirePercent, + bool RestoreOnFailure) { const AsmToken &PercentTok = Parser.getTok(); - Parser.Lex(); + bool HasPercent = PercentTok.is(AsmToken::Percent); + + Reg.StartLoc = PercentTok.getLoc(); + + if (RequirePercent && PercentTok.isNot(AsmToken::Percent)) + return Error(PercentTok.getLoc(), "register expected"); + + if (HasPercent) { + Parser.Lex(); // Eat percent token. + } // Expect a register name. if (Parser.getTok().isNot(AsmToken::Identifier)) { - if (RestoreOnFailure) + if (RestoreOnFailure && HasPercent) getLexer().UnLex(PercentTok); - return Error(Reg.StartLoc, "invalid register"); + return Error(Reg.StartLoc, + HasPercent ? "invalid register" : "register expected"); } // Check that there's a prefix. StringRef Name = Parser.getTok().getString(); if (Name.size() < 2) { - if (RestoreOnFailure) + if (RestoreOnFailure && HasPercent) getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); } @@ -783,7 +790,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) { // Treat the rest of the register name as a register number. if (Name.substr(1).getAsInteger(10, Reg.Num)) { - if (RestoreOnFailure) + if (RestoreOnFailure && HasPercent) getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); } @@ -800,7 +807,7 @@ bool SystemZAsmParser::parseRegister(Register &Reg, bool RestoreOnFailure) { else if (Prefix == 'c' && Reg.Num < 16) Reg.Group = RegCR; else { - if (RestoreOnFailure) + if (RestoreOnFailure && HasPercent) getLexer().UnLex(PercentTok); return Error(Reg.StartLoc, "invalid register"); } @@ -842,7 +849,7 @@ ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands, // Handle register names of the form % if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) { - if (parseRegister(Reg)) + if (parseRegister(Reg, /*RequirePercent=*/true)) return ParseStatus::Failure; // Check the parsed register group "Reg.Group" with the expected "Group" @@ -918,7 +925,7 @@ ParseStatus SystemZAsmParser::parseAnyRegister(OperandVector &Operands) { return ParseStatus::NoMatch; Register Reg; - if (parseRegister(Reg)) + if (parseRegister(Reg, /*RequirePercent=*/true)) return ParseStatus::Failure; if (Reg.Num > 15) @@ -1025,7 +1032,7 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1, if (isParsingATT() && getLexer().is(AsmToken::Percent)) { // Parse the first register. HaveReg1 = true; - if (parseRegister(Reg1)) + if (parseRegister(Reg1, /*RequirePercent=*/true)) return true; } // So if we have an integer as the first token in ([tok1], ..), it could: @@ -1065,7 +1072,7 @@ bool SystemZAsmParser::parseAddress(bool &HaveReg1, Register &Reg1, if (parseIntegerRegister(Reg2, RegGR)) return true; } else { - if (isParsingATT() && parseRegister(Reg2)) + if (isParsingATT() && parseRegister(Reg2, /*RequirePercent=*/true)) return true; } } @@ -1355,9 +1362,10 @@ bool SystemZAsmParser::ParseGNUAttribute(SMLoc L) { } bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, - SMLoc &EndLoc, bool RestoreOnFailure) { + SMLoc &EndLoc, bool RequirePercent, + bool RestoreOnFailure) { Register Reg; - if (parseRegister(Reg, RestoreOnFailure)) + if (parseRegister(Reg, RequirePercent, RestoreOnFailure)) return true; if (Reg.Group == RegGR) RegNo = SystemZMC::GR64Regs[Reg.Num]; @@ -1376,12 +1384,14 @@ bool SystemZAsmParser::ParseRegister(MCRegister &RegNo, SMLoc &StartLoc, bool SystemZAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) { - return ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/false); + return ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false, + /*RestoreOnFailure=*/false); } ParseStatus SystemZAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) { - bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RestoreOnFailure=*/true); + bool Result = ParseRegister(Reg, StartLoc, EndLoc, /*RequirePercent=*/false, + /*RestoreOnFailure=*/true); bool PendingErrors = getParser().hasPendingError(); getParser().clearPendingErrors(); if (PendingErrors) @@ -1482,7 +1492,7 @@ bool SystemZAsmParser::parseOperand(OperandVector &Operands, // the instruction isn't recognized. if (isParsingATT() && Parser.getTok().is(AsmToken::Percent)) { Register Reg; - if (parseRegister(Reg)) + if (parseRegister(Reg, /*RequirePercent=*/true)) return true; Operands.push_back(SystemZOperand::createInvalid(Reg.StartLoc, Reg.EndLoc)); return false; diff --git a/llvm/test/MC/SystemZ/regs-bad.s b/llvm/test/MC/SystemZ/regs-bad.s index 320cba0fc856..6392ff286300 100644 --- a/llvm/test/MC/SystemZ/regs-bad.s +++ b/llvm/test/MC/SystemZ/regs-bad.s @@ -262,8 +262,6 @@ # Test general register parsing, with no predetermined class in mind. # -#CHECK: error: register expected -#CHECK: .cfi_offset r0,0 #CHECK: error: invalid register #CHECK: .cfi_offset %,0 #CHECK: error: invalid register @@ -289,7 +287,6 @@ #CHECK: error: invalid register #CHECK: .cfi_offset %arid,0 - .cfi_offset r0,0 .cfi_offset %,0 .cfi_offset %r,0 .cfi_offset %f,0 diff --git a/llvm/test/MC/SystemZ/regs-good.s b/llvm/test/MC/SystemZ/regs-good.s index b4c1edd1b591..49bf8a48ca4c 100644 --- a/llvm/test/MC/SystemZ/regs-good.s +++ b/llvm/test/MC/SystemZ/regs-good.s @@ -176,6 +176,70 @@ st 0, 4095(1,15) st 0, 4095(15,1) +#CHECK: .cfi_offset %r0, 0 +#CHECK: .cfi_offset %r1, 8 +#CHECK: .cfi_offset %r2, 16 +#CHECK: .cfi_offset %r3, 24 +#CHECK: .cfi_offset %r4, 32 +#CHECK: .cfi_offset %r5, 40 +#CHECK: .cfi_offset %r6, 48 +#CHECK: .cfi_offset %r7, 56 +#CHECK: .cfi_offset %r8, 64 +#CHECK: .cfi_offset %r9, 72 +#CHECK: .cfi_offset %r10, 80 +#CHECK: .cfi_offset %r11, 88 +#CHECK: .cfi_offset %r12, 96 +#CHECK: .cfi_offset %r13, 104 +#CHECK: .cfi_offset %r14, 112 +#CHECK: .cfi_offset %r15, 120 +#CHECK: .cfi_offset %f0, 128 +#CHECK: .cfi_offset %f1, 136 +#CHECK: .cfi_offset %f2, 144 +#CHECK: .cfi_offset %f3, 152 +#CHECK: .cfi_offset %f4, 160 +#CHECK: .cfi_offset %f5, 168 +#CHECK: .cfi_offset %f6, 176 +#CHECK: .cfi_offset %f7, 184 +#CHECK: .cfi_offset %f8, 192 +#CHECK: .cfi_offset %f9, 200 +#CHECK: .cfi_offset %f10, 208 +#CHECK: .cfi_offset %f11, 216 +#CHECK: .cfi_offset %f12, 224 +#CHECK: .cfi_offset %f13, 232 +#CHECK: .cfi_offset %f14, 240 +#CHECK: .cfi_offset %f15, 248 +#CHECK: .cfi_offset %a0, 256 +#CHECK: .cfi_offset %a1, 260 +#CHECK: .cfi_offset %a2, 264 +#CHECK: .cfi_offset %a3, 268 +#CHECK: .cfi_offset %a4, 272 +#CHECK: .cfi_offset %a5, 276 +#CHECK: .cfi_offset %a6, 280 +#CHECK: .cfi_offset %a7, 284 +#CHECK: .cfi_offset %a8, 288 +#CHECK: .cfi_offset %r9, 292 +#CHECK: .cfi_offset %a10, 296 +#CHECK: .cfi_offset %a11, 300 +#CHECK: .cfi_offset %a12, 304 +#CHECK: .cfi_offset %a13, 308 +#CHECK: .cfi_offset %a14, 312 +#CHECK: .cfi_offset %a15, 316 +#CHECK: .cfi_offset %c0, 318 +#CHECK: .cfi_offset %c1, 326 +#CHECK: .cfi_offset %c2, 334 +#CHECK: .cfi_offset %c3, 342 +#CHECK: .cfi_offset %c4, 350 +#CHECK: .cfi_offset %c5, 358 +#CHECK: .cfi_offset %c6, 366 +#CHECK: .cfi_offset %c7, 374 +#CHECK: .cfi_offset %c8, 382 +#CHECK: .cfi_offset %c9, 390 +#CHECK: .cfi_offset %c10, 398 +#CHECK: .cfi_offset %c11, 406 +#CHECK: .cfi_offset %c12, 414 +#CHECK: .cfi_offset %c13, 422 +#CHECK: .cfi_offset %c14, 430 +#CHECK: .cfi_offset %c15, 438 #CHECK: .cfi_offset %r0, 0 #CHECK: .cfi_offset %r1, 8 #CHECK: .cfi_offset %r2, 16 @@ -306,4 +370,68 @@ .cfi_offset %c13,422 .cfi_offset %c14,430 .cfi_offset %c15,438 + .cfi_offset r0,0 + .cfi_offset r1,8 + .cfi_offset r2,16 + .cfi_offset r3,24 + .cfi_offset r4,32 + .cfi_offset r5,40 + .cfi_offset r6,48 + .cfi_offset r7,56 + .cfi_offset r8,64 + .cfi_offset r9,72 + .cfi_offset r10,80 + .cfi_offset r11,88 + .cfi_offset r12,96 + .cfi_offset r13,104 + .cfi_offset r14,112 + .cfi_offset r15,120 + .cfi_offset f0,128 + .cfi_offset f1,136 + .cfi_offset f2,144 + .cfi_offset f3,152 + .cfi_offset f4,160 + .cfi_offset f5,168 + .cfi_offset f6,176 + .cfi_offset f7,184 + .cfi_offset f8,192 + .cfi_offset f9,200 + .cfi_offset f10,208 + .cfi_offset f11,216 + .cfi_offset f12,224 + .cfi_offset f13,232 + .cfi_offset f14,240 + .cfi_offset f15,248 + .cfi_offset a0,256 + .cfi_offset a1,260 + .cfi_offset a2,264 + .cfi_offset a3,268 + .cfi_offset a4,272 + .cfi_offset a5,276 + .cfi_offset a6,280 + .cfi_offset a7,284 + .cfi_offset a8,288 + .cfi_offset r9,292 + .cfi_offset a10,296 + .cfi_offset a11,300 + .cfi_offset a12,304 + .cfi_offset a13,308 + .cfi_offset a14,312 + .cfi_offset a15,316 + .cfi_offset c0,318 + .cfi_offset c1,326 + .cfi_offset c2,334 + .cfi_offset c3,342 + .cfi_offset c4,350 + .cfi_offset c5,358 + .cfi_offset c6,366 + .cfi_offset c7,374 + .cfi_offset c8,382 + .cfi_offset c9,390 + .cfi_offset c10,398 + .cfi_offset c11,406 + .cfi_offset c12,414 + .cfi_offset c13,422 + .cfi_offset c14,430 + .cfi_offset c15,438 .cfi_endproc