mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
Let the integrated assembler understand .exitm, PR20426.
llvm-svn: 213876
This commit is contained in:
parent
792c734c18
commit
15e38a4b92
@ -92,8 +92,12 @@ struct MacroInstantiation {
|
||||
/// The location where parsing should resume upon instantiation completion.
|
||||
SMLoc ExitLoc;
|
||||
|
||||
/// The depth of TheCondStack at the start of the instantiation.
|
||||
size_t CondStackDepth;
|
||||
|
||||
public:
|
||||
MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I);
|
||||
MacroInstantiation(SMLoc IL, int EB, SMLoc EL, MemoryBuffer *I,
|
||||
size_t CondStackDepth);
|
||||
};
|
||||
|
||||
struct ParseStatementInfo {
|
||||
@ -351,7 +355,8 @@ private:
|
||||
DK_CFI_REMEMBER_STATE, DK_CFI_RESTORE_STATE, DK_CFI_SAME_VALUE,
|
||||
DK_CFI_RESTORE, DK_CFI_ESCAPE, DK_CFI_SIGNAL_FRAME, DK_CFI_UNDEFINED,
|
||||
DK_CFI_REGISTER, DK_CFI_WINDOW_SAVE,
|
||||
DK_MACROS_ON, DK_MACROS_OFF, DK_MACRO, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
|
||||
DK_MACROS_ON, DK_MACROS_OFF,
|
||||
DK_MACRO, DK_EXITM, DK_ENDM, DK_ENDMACRO, DK_PURGEM,
|
||||
DK_SLEB128, DK_ULEB128,
|
||||
DK_ERR, DK_ERROR, DK_WARNING,
|
||||
DK_END
|
||||
@ -403,6 +408,7 @@ private:
|
||||
|
||||
// macro directives
|
||||
bool parseDirectivePurgeMacro(SMLoc DirectiveLoc);
|
||||
bool parseDirectiveExitMacro(StringRef Directive);
|
||||
bool parseDirectiveEndMacro(StringRef Directive);
|
||||
bool parseDirectiveMacro(SMLoc DirectiveLoc);
|
||||
bool parseDirectiveMacrosOnOff(StringRef Directive);
|
||||
@ -1541,6 +1547,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
|
||||
return parseDirectiveMacrosOnOff(IDVal);
|
||||
case DK_MACRO:
|
||||
return parseDirectiveMacro(IDLoc);
|
||||
case DK_EXITM:
|
||||
return parseDirectiveExitMacro(IDVal);
|
||||
case DK_ENDM:
|
||||
case DK_ENDMACRO:
|
||||
return parseDirectiveEndMacro(IDVal);
|
||||
@ -1858,8 +1866,9 @@ bool AsmParser::expandMacro(raw_svector_ostream &OS, StringRef Body,
|
||||
}
|
||||
|
||||
MacroInstantiation::MacroInstantiation(SMLoc IL, int EB, SMLoc EL,
|
||||
MemoryBuffer *I)
|
||||
: Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL) {}
|
||||
MemoryBuffer *I, size_t CondStackDepth)
|
||||
: Instantiation(I), InstantiationLoc(IL), ExitBuffer(EB), ExitLoc(EL),
|
||||
CondStackDepth(CondStackDepth) {}
|
||||
|
||||
static bool isOperator(AsmToken::TokenKind kind) {
|
||||
switch (kind) {
|
||||
@ -2122,8 +2131,9 @@ bool AsmParser::handleMacroEntry(const MCAsmMacro *M, SMLoc NameLoc) {
|
||||
|
||||
// Create the macro instantiation object and add to the current macro
|
||||
// instantiation stack.
|
||||
MacroInstantiation *MI = new MacroInstantiation(
|
||||
NameLoc, CurBuffer, getTok().getLoc(), Instantiation);
|
||||
MacroInstantiation *MI =
|
||||
new MacroInstantiation(NameLoc, CurBuffer, getTok().getLoc(),
|
||||
Instantiation, TheCondStack.size());
|
||||
ActiveMacros.push_back(MI);
|
||||
|
||||
// Jump to the macro instantiation and prime the lexer.
|
||||
@ -3471,6 +3481,26 @@ void AsmParser::checkForBadMacro(SMLoc DirectiveLoc, StringRef Name,
|
||||
"found in body which will have no effect");
|
||||
}
|
||||
|
||||
/// parseDirectiveExitMacro
|
||||
/// ::= .exitm
|
||||
bool AsmParser::parseDirectiveExitMacro(StringRef Directive) {
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in '" + Directive + "' directive");
|
||||
|
||||
if (!isInsideMacroInstantiation())
|
||||
return TokError("unexpected '" + Directive + "' in file, "
|
||||
"no current macro definition");
|
||||
|
||||
// Exit all conditionals that are active in the current macro.
|
||||
while (TheCondStack.size() != ActiveMacros.back()->CondStackDepth) {
|
||||
TheCondState = TheCondStack.back();
|
||||
TheCondStack.pop_back();
|
||||
}
|
||||
|
||||
handleMacroExit();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// parseDirectiveEndMacro
|
||||
/// ::= .endm
|
||||
/// ::= .endmacro
|
||||
@ -4226,6 +4256,7 @@ void AsmParser::initializeDirectiveKindMap() {
|
||||
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
|
||||
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
|
||||
DirectiveKindMap[".macro"] = DK_MACRO;
|
||||
DirectiveKindMap[".exitm"] = DK_EXITM;
|
||||
DirectiveKindMap[".endm"] = DK_ENDM;
|
||||
DirectiveKindMap[".endmacro"] = DK_ENDMACRO;
|
||||
DirectiveKindMap[".purgem"] = DK_PURGEM;
|
||||
@ -4286,8 +4317,9 @@ void AsmParser::instantiateMacroLikeBody(MCAsmMacro *M, SMLoc DirectiveLoc,
|
||||
|
||||
// Create the macro instantiation object and add to the current macro
|
||||
// instantiation stack.
|
||||
MacroInstantiation *MI = new MacroInstantiation(
|
||||
DirectiveLoc, CurBuffer, getTok().getLoc(), Instantiation);
|
||||
MacroInstantiation *MI =
|
||||
new MacroInstantiation(DirectiveLoc, CurBuffer, getTok().getLoc(),
|
||||
Instantiation, TheCondStack.size());
|
||||
ActiveMacros.push_back(MI);
|
||||
|
||||
// Jump to the macro instantiation and prime the lexer.
|
||||
|
64
test/MC/AsmParser/macro-exitm.s
Normal file
64
test/MC/AsmParser/macro-exitm.s
Normal file
@ -0,0 +1,64 @@
|
||||
// RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
|
||||
|
||||
// .exitm is encountered in a normal macro expansion
|
||||
.macro REP
|
||||
.rept 3
|
||||
.long 0
|
||||
.exitm
|
||||
.endr
|
||||
.endm
|
||||
REP
|
||||
// Only the output from the first rept expansion should make it through:
|
||||
// CHECK: .long 0
|
||||
// CHECK-NOT: .long 0
|
||||
|
||||
// .exitm is in a true branch
|
||||
.macro A
|
||||
.if 1
|
||||
.long 1
|
||||
.exitm
|
||||
.endif
|
||||
.long 1
|
||||
.endm
|
||||
A
|
||||
// CHECK: .long 1
|
||||
// CHECK-NOT: .long 1
|
||||
|
||||
// .exitm is in a false branch
|
||||
.macro B
|
||||
.if 1
|
||||
.long 2
|
||||
.else
|
||||
.exitm
|
||||
.endif
|
||||
.long 2
|
||||
.endm
|
||||
B
|
||||
// CHECK: .long 2
|
||||
// CHECK: .long 2
|
||||
|
||||
|
||||
// .exitm is in a false branch that is encountered prior to the true branch
|
||||
.macro C
|
||||
.if 0
|
||||
.exitm
|
||||
.else
|
||||
.long 3
|
||||
.endif
|
||||
.long 3
|
||||
.endm
|
||||
C
|
||||
// CHECK: .long 3
|
||||
// CHECK: .long 3
|
||||
|
||||
// .exitm is in a macro that's expanded in a conditional block.
|
||||
.macro D
|
||||
.long 4
|
||||
.exitm
|
||||
.long 4
|
||||
.endm
|
||||
.if 1
|
||||
D
|
||||
.endif
|
||||
// CHECK: .long 4
|
||||
// CHECK-NOT: .long 4
|
Loading…
Reference in New Issue
Block a user