Skip to content

[llvm][SystemZ] Fix parsing of .cfi_undefined with percent-less registers. #107032

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,8 @@ class SystemZAsmParser : public MCTargetAsmParser {
return static_cast<SystemZTargetStreamer &>(TS);
}

bool parseRegister(Register &Reg, bool RestoreOnFailure = false);
bool parseRegister(Register &Reg, bool RequirePercent,
bool RestoreOnFailure = false);

bool parseIntegerRegister(Register &Reg, RegisterGroup Group);

Expand Down Expand Up @@ -495,7 +496,7 @@ class SystemZAsmParser : public MCTargetAsmParser {
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,
Expand Down Expand Up @@ -756,34 +757,40 @@ void SystemZOperand::print(raw_ostream &OS) const {
}

// Parse one register of the form %<prefix><number>.
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");
}
char Prefix = Name[0];

// 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");
}
Expand All @@ -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");
}
Expand Down Expand Up @@ -842,7 +849,7 @@ ParseStatus SystemZAsmParser::parseRegister(OperandVector &Operands,

// Handle register names of the form %<prefix><number>
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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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];
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 0 additions & 3 deletions llvm/test/MC/SystemZ/regs-bad.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
128 changes: 128 additions & 0 deletions llvm/test/MC/SystemZ/regs-good.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Loading