mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-07-08 18:30:04 +00:00
[MC] [IAS] Add support for the \@ .macro pseudo-variable.
Summary: When used, it is substituted with the number of .macro instantiations we've done up to that point in time. So if this is the 1st time we've instantiated a .macro (any .macro, regardless of name), \@ will instantiate to 0, if it's the 2nd .macro instantiation, it will instantiate to 1 etc. It can only be used inside a .macro definition, an .irp definition or an .irpc definition (those last 2 uses are undocumented). Reviewers: echristo, rafael Reviewed By: rafael Subscribers: dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D9197 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235862 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
59764b94a7
commit
0b5a15b779
@ -147,6 +147,9 @@ private:
|
|||||||
/// Boolean tracking whether macro substitution is enabled.
|
/// Boolean tracking whether macro substitution is enabled.
|
||||||
unsigned MacrosEnabledFlag : 1;
|
unsigned MacrosEnabledFlag : 1;
|
||||||
|
|
||||||
|
/// \brief Keeps track of how many .macro's have been instantiated.
|
||||||
|
unsigned NumOfMacroInstantiations;
|
||||||
|
|
||||||
/// Flag tracking whether any errors have been encountered.
|
/// Flag tracking whether any errors have been encountered.
|
||||||
unsigned HadError : 1;
|
unsigned HadError : 1;
|
||||||
|
|
||||||
@ -251,7 +254,7 @@ private:
|
|||||||
ArrayRef<MCAsmMacroParameter> Parameters);
|
ArrayRef<MCAsmMacroParameter> Parameters);
|
||||||
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
|
bool expandMacro(raw_svector_ostream &OS, StringRef Body,
|
||||||
ArrayRef<MCAsmMacroParameter> Parameters,
|
ArrayRef<MCAsmMacroParameter> Parameters,
|
||||||
ArrayRef<MCAsmMacroArgument> A,
|
ArrayRef<MCAsmMacroArgument> A, bool EnableAtPseudoVariable,
|
||||||
const SMLoc &L);
|
const SMLoc &L);
|
||||||
|
|
||||||
/// \brief Are macros enabled in the parser?
|
/// \brief Are macros enabled in the parser?
|
||||||
@ -519,6 +522,8 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
|
|||||||
|
|
||||||
PlatformParser->Initialize(*this);
|
PlatformParser->Initialize(*this);
|
||||||
initializeDirectiveKindMap();
|
initializeDirectiveKindMap();
|
||||||
|
|
||||||
|
NumOfMacroInstantiations = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AsmParser::~AsmParser() {
|
AsmParser::~AsmParser() {
|
||||||
@ -1764,7 +1769,8 @@ static bool isIdentifierChar(char c) {
|
|||||||
|
|
||||||
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
|
bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
|
||||||
ArrayRef<MCAsmMacroParameter> Parameters,
|
ArrayRef<MCAsmMacroParameter> Parameters,
|
||||||
ArrayRef<MCAsmMacroArgument> A, const SMLoc &L) {
|
ArrayRef<MCAsmMacroArgument> A,
|
||||||
|
bool EnableAtPseudoVariable, const SMLoc &L) {
|
||||||
unsigned NParameters = Parameters.size();
|
unsigned NParameters = Parameters.size();
|
||||||
bool HasVararg = NParameters ? Parameters.back().Vararg : false;
|
bool HasVararg = NParameters ? Parameters.back().Vararg : false;
|
||||||
if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
|
if ((!IsDarwin || NParameters != 0) && NParameters != A.size())
|
||||||
@ -1830,12 +1836,22 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
|
|||||||
Pos += 2;
|
Pos += 2;
|
||||||
} else {
|
} else {
|
||||||
unsigned I = Pos + 1;
|
unsigned I = Pos + 1;
|
||||||
|
|
||||||
|
// Check for the \@ pseudo-variable.
|
||||||
|
if (EnableAtPseudoVariable && Body[I] == '@' && I + 1 != End)
|
||||||
|
++I;
|
||||||
|
else
|
||||||
while (isIdentifierChar(Body[I]) && I + 1 != End)
|
while (isIdentifierChar(Body[I]) && I + 1 != End)
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
const char *Begin = Body.data() + Pos + 1;
|
const char *Begin = Body.data() + Pos + 1;
|
||||||
StringRef Argument(Begin, I - (Pos + 1));
|
StringRef Argument(Begin, I - (Pos + 1));
|
||||||
unsigned Index = 0;
|
unsigned Index = 0;
|
||||||
|
|
||||||
|
if (Argument == "@") {
|
||||||
|
OS << NumOfMacroInstantiations;
|
||||||
|
Pos += 2;
|
||||||
|
} else {
|
||||||
for (; Index < NParameters; ++Index)
|
for (; Index < NParameters; ++Index)
|
||||||
if (Parameters[Index].Name == Argument)
|
if (Parameters[Index].Name == Argument)
|
||||||
break;
|
break;
|
||||||
@ -1862,6 +1878,7 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
|
|||||||
Pos += 1 + Argument.size();
|
Pos += 1 + Argument.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Update the scan point.
|
// Update the scan point.
|
||||||
Body = Body.substr(Pos);
|
Body = Body.substr(Pos);
|
||||||
}
|
}
|
||||||
@ -2117,7 +2134,7 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
|||||||
StringRef Body = M->Body;
|
StringRef Body = M->Body;
|
||||||
raw_svector_ostream OS(Buf);
|
raw_svector_ostream OS(Buf);
|
||||||
|
|
||||||
if (expandMacro(OS, Body, M->Parameters, A, getTok().getLoc()))
|
if (expandMacro(OS, Body, M->Parameters, A, true, getTok().getLoc()))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// We include the .endmacro in the buffer as our cue to exit the macro
|
// We include the .endmacro in the buffer as our cue to exit the macro
|
||||||
@ -2133,6 +2150,8 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
|||||||
NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
|
NameLoc, CurBuffer, getTok().getLoc(), TheCondStack.size());
|
||||||
ActiveMacros.push_back(MI);
|
ActiveMacros.push_back(MI);
|
||||||
|
|
||||||
|
++NumOfMacroInstantiations;
|
||||||
|
|
||||||
// Jump to the macro instantiation and prime the lexer.
|
// Jump to the macro instantiation and prime the lexer.
|
||||||
CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
|
CurBuffer = SrcMgr.AddNewSourceBuffer(std::move(Instantiation), SMLoc());
|
||||||
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
|
Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer());
|
||||||
@ -4378,7 +4397,8 @@ bool AsmParser::parseDirectiveRept(SMLoc DirectiveLoc, StringRef Dir) {
|
|||||||
SmallString<256> Buf;
|
SmallString<256> Buf;
|
||||||
raw_svector_ostream OS(Buf);
|
raw_svector_ostream OS(Buf);
|
||||||
while (Count--) {
|
while (Count--) {
|
||||||
if (expandMacro(OS, M->Body, None, None, getTok().getLoc()))
|
// Note that the AtPseudoVariable is disabled for instantiations of .rep(t).
|
||||||
|
if (expandMacro(OS, M->Body, None, None, false, getTok().getLoc()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
instantiateMacroLikeBody(M, DirectiveLoc, OS);
|
instantiateMacroLikeBody(M, DirectiveLoc, OS);
|
||||||
@ -4417,7 +4437,9 @@ bool AsmParser::parseDirectiveIrp(SMLoc DirectiveLoc) {
|
|||||||
raw_svector_ostream OS(Buf);
|
raw_svector_ostream OS(Buf);
|
||||||
|
|
||||||
for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
|
for (MCAsmMacroArguments::iterator i = A.begin(), e = A.end(); i != e; ++i) {
|
||||||
if (expandMacro(OS, M->Body, Parameter, *i, getTok().getLoc()))
|
// Note that the AtPseudoVariable is enabled for instantiations of .irp.
|
||||||
|
// This is undocumented, but GAS seems to support it.
|
||||||
|
if (expandMacro(OS, M->Body, Parameter, *i, true, getTok().getLoc()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4464,7 +4486,9 @@ bool AsmParser::parseDirectiveIrpc(SMLoc DirectiveLoc) {
|
|||||||
MCAsmMacroArgument Arg;
|
MCAsmMacroArgument Arg;
|
||||||
Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1)));
|
Arg.push_back(AsmToken(AsmToken::Identifier, Values.slice(I, I + 1)));
|
||||||
|
|
||||||
if (expandMacro(OS, M->Body, Parameter, Arg, getTok().getLoc()))
|
// Note that the AtPseudoVariable is enabled for instantiations of .irpc.
|
||||||
|
// This is undocumented, but GAS seems to support it.
|
||||||
|
if (expandMacro(OS, M->Body, Parameter, Arg, true, getTok().getLoc()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
test/MC/AsmParser/at-pseudo-variable-bad.s
Normal file
23
test/MC/AsmParser/at-pseudo-variable-bad.s
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# RUN: not llvm-mc -triple i386-unknown-unknown < %s 2>&1 | FileCheck %s
|
||||||
|
|
||||||
|
add $1\@, %eax
|
||||||
|
# CHECK: :[[@LINE-1]]:8: error: unexpected token in argument list
|
||||||
|
|
||||||
|
.macro A @
|
||||||
|
mov %eax, %eax
|
||||||
|
.endm
|
||||||
|
# CHECK: :[[@LINE-3]]:11: error: expected identifier in '.macro' directive
|
||||||
|
|
||||||
|
.rept 2
|
||||||
|
addi $8, $8, \@
|
||||||
|
.endr
|
||||||
|
# CHECK: error: unknown token in expression
|
||||||
|
# CHECK: :[[@LINE-4]]:1: note: while in macro instantiation
|
||||||
|
# CHECK-NEXT: .rept 2
|
||||||
|
|
||||||
|
.rep 3
|
||||||
|
addi $9, $9, \@
|
||||||
|
.endr
|
||||||
|
# CHECK: error: unknown token in expression
|
||||||
|
# CHECK: :[[@LINE-4]]:1: note: while in macro instantiation
|
||||||
|
# CHECK-NEXT: .rep 3
|
64
test/MC/AsmParser/at-pseudo-variable.s
Normal file
64
test/MC/AsmParser/at-pseudo-variable.s
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
|
||||||
|
|
||||||
|
.macro A
|
||||||
|
add $1\@, %eax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro B
|
||||||
|
sub $1\@, %eax
|
||||||
|
.endm
|
||||||
|
|
||||||
|
A
|
||||||
|
# CHECK: addl $10, %eax
|
||||||
|
A
|
||||||
|
# CHECK: addl $11, %eax
|
||||||
|
B
|
||||||
|
# CHECK: subl $12, %eax
|
||||||
|
B
|
||||||
|
# CHECK: subl $13, %eax
|
||||||
|
|
||||||
|
# The following uses of \@ are undocumented, but valid:
|
||||||
|
.irpc foo,234
|
||||||
|
add $\foo\@, %eax
|
||||||
|
.endr
|
||||||
|
# CHECK: addl $24, %eax
|
||||||
|
# CHECK: addl $34, %eax
|
||||||
|
# CHECK: addl $44, %eax
|
||||||
|
|
||||||
|
.irp reg,%eax,%ebx
|
||||||
|
sub $2\@, \reg
|
||||||
|
.endr
|
||||||
|
# CHECK: subl $24, %eax
|
||||||
|
# CHECK: subl $24, %ebx
|
||||||
|
|
||||||
|
# Test that .irp(c) and .rep(t) do not increase \@.
|
||||||
|
# Only the use of A should increase \@, so we can test that it increases by 1
|
||||||
|
# each time.
|
||||||
|
|
||||||
|
.irpc foo,123
|
||||||
|
sub $\foo, %eax
|
||||||
|
.endr
|
||||||
|
|
||||||
|
A
|
||||||
|
# CHECK: addl $14, %eax
|
||||||
|
|
||||||
|
.irp reg,%eax,%ebx
|
||||||
|
sub $4, \reg
|
||||||
|
.endr
|
||||||
|
|
||||||
|
A
|
||||||
|
# CHECK: addl $15, %eax
|
||||||
|
|
||||||
|
.rept 2
|
||||||
|
sub $5, %eax
|
||||||
|
.endr
|
||||||
|
|
||||||
|
A
|
||||||
|
# CHECK: addl $16, %eax
|
||||||
|
|
||||||
|
.rep 3
|
||||||
|
sub $6, %eax
|
||||||
|
.endr
|
||||||
|
|
||||||
|
A
|
||||||
|
# CHECK: addl $17, %eax
|
Loading…
Reference in New Issue
Block a user