Skip to content

Commit 7c95629

Browse files
committed
MCAsmParser: Support \+
In .macro, \+ expands to the per-macro invocation count. https://sourceware.org/pipermail/binutils/2024-May/134009.html \+ counts from 0 for .irp/.irpc/.rept . Note: We currently prints \q for `.print "\q"` while gas doesn't. This patch does not change this behavior.
1 parent e27f9bb commit 7c95629

File tree

4 files changed

+61
-23
lines changed

4 files changed

+61
-23
lines changed

llvm/include/llvm/MC/MCAsmMacro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct MCAsmMacro {
145145
MCAsmMacroParameters Parameters;
146146
std::vector<std::string> Locals;
147147
bool IsFunction = false;
148+
unsigned Count = 0;
148149

149150
public:
150151
MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)

llvm/include/llvm/MC/MCContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ class MCContext {
856856
void reportError(SMLoc L, const Twine &Msg);
857857
void reportWarning(SMLoc L, const Twine &Msg);
858858

859-
const MCAsmMacro *lookupMacro(StringRef Name) {
859+
MCAsmMacro *lookupMacro(StringRef Name) {
860860
StringMap<MCAsmMacro>::iterator I = MacroMap.find(Name);
861861
return (I == MacroMap.end()) ? nullptr : &I->getValue();
862862
}

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ class AsmParser : public MCAsmParser {
295295

296296
void checkForBadMacro(SMLoc DirectiveLoc, StringRef Name, StringRef Body,
297297
ArrayRef<MCAsmMacroParameter> Parameters);
298-
bool expandMacro(raw_svector_ostream &OS, const MCAsmMacro &Macro,
298+
bool expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
299299
ArrayRef<MCAsmMacroParameter> Parameters,
300300
ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable);
301301

@@ -312,7 +312,7 @@ class AsmParser : public MCAsmParser {
312312
///
313313
/// \param M The macro.
314314
/// \param NameLoc Instantiation location.
315-
bool handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc);
315+
bool handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc);
316316

317317
/// Handle exit from macro instantiation.
318318
void handleMacroExit();
@@ -1980,9 +1980,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
19801980

19811981
// If macros are enabled, check to see if this is a macro instantiation.
19821982
if (areMacrosEnabled())
1983-
if (const MCAsmMacro *M = getContext().lookupMacro(IDVal)) {
1983+
if (MCAsmMacro *M = getContext().lookupMacro(IDVal))
19841984
return handleMacroEntry(M, IDLoc);
1985-
}
19861985

19871986
// Otherwise, we have a normal instruction or directive.
19881987

@@ -2495,7 +2494,7 @@ static bool isIdentifierChar(char c) {
24952494
c == '.';
24962495
}
24972496

2498-
bool AsmParser::expandMacro(raw_svector_ostream &OS, const MCAsmMacro &Macro,
2497+
bool AsmParser::expandMacro(raw_svector_ostream &OS, MCAsmMacro &Macro,
24992498
ArrayRef<MCAsmMacroParameter> Parameters,
25002499
ArrayRef<MCAsmMacroArgument> A,
25012500
bool EnableAtPseudoVariable) {
@@ -2560,14 +2559,18 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, const MCAsmMacro &Macro,
25602559
}
25612560
Pos += 2;
25622561
} else {
2562+
// Check for \@ and \+ pseudo variables.
25632563
unsigned I = Pos + 1;
2564-
2565-
// Check for the \@ pseudo-variable.
2566-
if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
2567-
++I;
2568-
else
2569-
while (isIdentifierChar(Body[I]) && I + 1 != End)
2564+
if (I + 1 != End) {
2565+
if (EnableAtPseudoVariable && Body[I] == '@') {
2566+
++I;
2567+
} else if (Body[I] == '+') {
25702568
++I;
2569+
} else {
2570+
while (isIdentifierChar(Body[I]) && I + 1 != End)
2571+
++I;
2572+
}
2573+
}
25712574

25722575
const char *Begin = Body.data() + Pos + 1;
25732576
StringRef Argument(Begin, I - (Pos + 1));
@@ -2576,6 +2579,9 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, const MCAsmMacro &Macro,
25762579
if (Argument == "@") {
25772580
OS << NumOfMacroInstantiations;
25782581
Pos += 2;
2582+
} else if (Argument == "+") {
2583+
OS << Macro.Count++;
2584+
Pos += 2;
25792585
} else {
25802586
for (; Index < NParameters; ++Index)
25812587
if (Parameters[Index].Name == Argument)
@@ -2860,7 +2866,7 @@ bool AsmParser::parseMacroArguments(const MCAsmMacro *M,
28602866
return TokError("too many positional arguments");
28612867
}
28622868

2863-
bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
2869+
bool AsmParser::handleMacroEntry(MCAsmMacro *M, SMLoc NameLoc) {
28642870
// Arbitrarily limit macro nesting depth (default matches 'as'). We can
28652871
// eliminate this, although we should protect against infinite loops.
28662872
unsigned MaxNestingDepth = AsmMacroMaxNestingDepth;

llvm/test/MC/AsmParser/macro-at-pseudo-variable.s

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,44 @@
1-
# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
1+
# RUN: rm -rf %t && split-file %s %t && cd %t
2+
# RUN: llvm-mc -triple i386 a.s | FileCheck %s
3+
# RUN: llvm-mc -triple i386 b.s | FileCheck %s --check-prefix=CHECK2
24

5+
#--- a.s
36
.macro A
47
add $1\@, %eax
8+
add $2\+, %eax
59
.endm
610

711
.macro B
812
sub $1\@, %eax
13+
sub $2\+, %eax
914
.endm
1015

1116
A
12-
# CHECK: addl $10, %eax
17+
# CHECK: addl $10, %eax
18+
# CHECK-NEXT: addl $20, %eax
1319
A
14-
# CHECK: addl $11, %eax
20+
# CHECK: addl $11, %eax
21+
# CHECK-NEXT: addl $21, %eax
1522
B
16-
# CHECK: subl $12, %eax
23+
# CHECK: subl $12, %eax
24+
# CHECK-NEXT: subl $20, %eax
1725
B
18-
# CHECK: subl $13, %eax
26+
# CHECK: subl $13, %eax
27+
# CHECK-NEXT: subl $21, %eax
1928

2029
# The following uses of \@ are undocumented, but valid:
2130
.irpc foo,234
2231
add $\foo\@, %eax
2332
.endr
24-
# CHECK: addl $24, %eax
25-
# CHECK: addl $34, %eax
26-
# CHECK: addl $44, %eax
33+
# CHECK: addl $24, %eax
34+
# CHECK-NEXT: addl $34, %eax
35+
# CHECK-NEXT: addl $44, %eax
2736

2837
.irp reg,%eax,%ebx
2938
sub $2\@, \reg
3039
.endr
31-
# CHECK: subl $24, %eax
32-
# CHECK: subl $24, %ebx
40+
# CHECK: subl $24, %eax
41+
# CHECK-NEXT: subl $24, %ebx
3342

3443
# Test that .irp(c) and .rep(t) do not increase \@.
3544
# Only the use of A should increase \@, so we can test that it increases by 1
@@ -62,3 +71,25 @@
6271

6372
A
6473
# CHECK: addl $17, %eax
74+
75+
#--- b.s
76+
.rept 2
77+
.print "r\+"
78+
.endr
79+
.irpc foo,12
80+
.print "\+i"
81+
.endr
82+
# CHECK2: r0
83+
# CHECK2-NEXT: r1
84+
# CHECK2-NEXT: 0i
85+
# CHECK2-NEXT: 1i
86+
87+
.rept 2
88+
.rept 2
89+
.print "n\+"
90+
.endr
91+
.endr
92+
# CHECK2: n0
93+
# CHECK2-NEXT: n0
94+
# CHECK2-NEXT: n1
95+
# CHECK2-NEXT: n1

0 commit comments

Comments
 (0)