mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-28 15:38:57 +00:00
[ms-inline-asm] Implement align directive (which is roughly equivalent to .align).
Also, allow _EMIT and __EMIT for the emit directive. We already do the same for TYPE, SIZE, and LENGTH. rdar://13200215 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175008 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
dc08bfbd56
commit
469b144f1c
@ -22,6 +22,7 @@ class MCInst;
|
|||||||
template <typename T> class SmallVectorImpl;
|
template <typename T> class SmallVectorImpl;
|
||||||
|
|
||||||
enum AsmRewriteKind {
|
enum AsmRewriteKind {
|
||||||
|
AOK_Align, // Rewrite align as .align.
|
||||||
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
|
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
|
||||||
// E.g., [eax].foo.bar -> [eax].8
|
// E.g., [eax].foo.bar -> [eax].8
|
||||||
AOK_Emit, // Rewrite _emit as .byte.
|
AOK_Emit, // Rewrite _emit as .byte.
|
||||||
|
@ -443,9 +443,12 @@ private:
|
|||||||
bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
|
bool ParseDirectiveIrpc(SMLoc DirectiveLoc); // ".irpc"
|
||||||
bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
|
bool ParseDirectiveEndr(SMLoc DirectiveLoc); // ".endr"
|
||||||
|
|
||||||
// "_emit"
|
// "_emit" or "__emit"
|
||||||
bool ParseDirectiveEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
|
bool ParseDirectiveMSEmit(SMLoc DirectiveLoc, ParseStatementInfo &Info,
|
||||||
size_t len);
|
size_t Len);
|
||||||
|
|
||||||
|
// "align"
|
||||||
|
bool ParseDirectiveMSAlign(SMLoc DirectiveLoc, ParseStatementInfo &Info);
|
||||||
|
|
||||||
void initializeDirectiveKindMap();
|
void initializeDirectiveKindMap();
|
||||||
};
|
};
|
||||||
@ -1447,9 +1450,14 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
|
|||||||
return Error(IDLoc, "unknown directive");
|
return Error(IDLoc, "unknown directive");
|
||||||
}
|
}
|
||||||
|
|
||||||
// _emit or __emit
|
// __asm _emit or __asm __emit
|
||||||
if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit"))
|
if (ParsingInlineAsm && (IDVal == "_emit" || IDVal == "__emit" ||
|
||||||
return ParseDirectiveEmit(IDLoc, Info, IDVal.size());
|
IDVal == "_EMIT" || IDVal == "__EMIT"))
|
||||||
|
return ParseDirectiveMSEmit(IDLoc, Info, IDVal.size());
|
||||||
|
|
||||||
|
// __asm align
|
||||||
|
if (ParsingInlineAsm && (IDVal == "align" || IDVal == "ALIGN"))
|
||||||
|
return ParseDirectiveMSAlign(IDLoc, Info);
|
||||||
|
|
||||||
CheckForValidSection();
|
CheckForValidSection();
|
||||||
|
|
||||||
@ -3989,7 +3997,7 @@ bool AsmParser::ParseDirectiveEndr(SMLoc DirectiveLoc) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t len) {
|
bool AsmParser::ParseDirectiveMSEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t Len) {
|
||||||
const MCExpr *Value;
|
const MCExpr *Value;
|
||||||
SMLoc ExprLoc = getLexer().getLoc();
|
SMLoc ExprLoc = getLexer().getLoc();
|
||||||
if (ParseExpression(Value))
|
if (ParseExpression(Value))
|
||||||
@ -4001,7 +4009,23 @@ bool AsmParser::ParseDirectiveEmit(SMLoc IDLoc, ParseStatementInfo &Info, size_t
|
|||||||
if (!isUIntN(8, IntValue) && !isIntN(8, IntValue))
|
if (!isUIntN(8, IntValue) && !isIntN(8, IntValue))
|
||||||
return Error(ExprLoc, "literal value out of range for directive");
|
return Error(ExprLoc, "literal value out of range for directive");
|
||||||
|
|
||||||
Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, len));
|
Info.AsmRewrites->push_back(AsmRewrite(AOK_Emit, IDLoc, Len));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AsmParser::ParseDirectiveMSAlign(SMLoc IDLoc, ParseStatementInfo &Info) {
|
||||||
|
const MCExpr *Value;
|
||||||
|
SMLoc ExprLoc = getLexer().getLoc();
|
||||||
|
if (ParseExpression(Value))
|
||||||
|
return true;
|
||||||
|
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
|
||||||
|
if (!MCE)
|
||||||
|
return Error(ExprLoc, "unexpected expression in align");
|
||||||
|
uint64_t IntValue = MCE->getValue();
|
||||||
|
if (!isPowerOf2_64(IntValue))
|
||||||
|
return Error(ExprLoc, "literal value not a power of two greater then zero");
|
||||||
|
|
||||||
|
Info.AsmRewrites->push_back(AsmRewrite(AOK_Align, IDLoc, 5, Log2_64(IntValue)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4133,6 +4157,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
|
|||||||
I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {
|
I = AsmStrRewrites.begin(), E = AsmStrRewrites.end(); I != E; ++I) {
|
||||||
const char *Loc = (*I).Loc.getPointer();
|
const char *Loc = (*I).Loc.getPointer();
|
||||||
|
|
||||||
|
unsigned AdditionalSkip = 0;
|
||||||
AsmRewriteKind Kind = (*I).Kind;
|
AsmRewriteKind Kind = (*I).Kind;
|
||||||
|
|
||||||
// Emit everything up to the immediate/expression. If the previous rewrite
|
// Emit everything up to the immediate/expression. If the previous rewrite
|
||||||
@ -4180,6 +4205,15 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
|
|||||||
case AOK_Emit:
|
case AOK_Emit:
|
||||||
OS << ".byte";
|
OS << ".byte";
|
||||||
break;
|
break;
|
||||||
|
case AOK_Align: {
|
||||||
|
unsigned Val = (*I).Val;
|
||||||
|
OS << ".align " << Val;
|
||||||
|
|
||||||
|
// Skip the original immediate.
|
||||||
|
assert (Val < 10 && "Expected alignment less then 2^10.");
|
||||||
|
AdditionalSkip = (Val < 4) ? 2 : Val < 7 ? 3 : 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AOK_DotOperator:
|
case AOK_DotOperator:
|
||||||
OS << (*I).Val;
|
OS << (*I).Val;
|
||||||
break;
|
break;
|
||||||
@ -4187,7 +4221,7 @@ bool AsmParser::ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
|
|||||||
|
|
||||||
// Skip the original expression.
|
// Skip the original expression.
|
||||||
if (Kind != AOK_SizeDirective)
|
if (Kind != AOK_SizeDirective)
|
||||||
Start = Loc + (*I).Len;
|
Start = Loc + (*I).Len + AdditionalSkip;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emit the remainder of the asm string.
|
// Emit the remainder of the asm string.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user