forked from OSchip/llvm-project
llvm-mc: Parse .{,b,p2}align{,w,l} directives.
llvm-svn: 74478
This commit is contained in:
parent
0a9f9759a3
commit
cc566a714b
|
@ -135,7 +135,7 @@ namespace llvm {
|
|||
/// This used to implement the .align assembler directive.
|
||||
///
|
||||
/// @param ByteAlignment - The alignment to reach. This must be a power of
|
||||
/// two.
|
||||
/// two on some targets.
|
||||
/// @param Value - The value to use when filling bytes.
|
||||
/// @param Size - The size of the integer (in bytes) to emit for @param
|
||||
/// Value. This must match a native machine width.
|
||||
|
|
|
@ -105,6 +105,7 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
|
|||
|
||||
OS << Symbol->getName() << ":\n";
|
||||
Symbol->setSection(CurSection);
|
||||
Symbol->setExternal(false);
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCValue &Value,
|
||||
|
@ -164,20 +165,23 @@ void MCAsmStreamer::EmitValue(const MCValue &Value, unsigned Size) {
|
|||
void MCAsmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
|
||||
unsigned ValueSize,
|
||||
unsigned MaxBytesToEmit) {
|
||||
// Some assemblers don't support .balign, so we always emit as .p2align if
|
||||
// this is a power of two. Otherwise we assume the client knows the target
|
||||
// supports .balign and use that.
|
||||
unsigned Pow2 = Log2_32(ByteAlignment);
|
||||
assert((1U << Pow2) == ByteAlignment && "Invalid alignment!");
|
||||
bool IsPow2 = (1U << Pow2) == ByteAlignment;
|
||||
|
||||
switch (ValueSize) {
|
||||
default:
|
||||
assert(0 && "Invalid size for machine code value!");
|
||||
case 8:
|
||||
assert(0 && "Unsupported alignment size!");
|
||||
case 1: OS << ".p2align"; break;
|
||||
case 2: OS << ".p2alignw"; break;
|
||||
case 4: OS << ".p2alignl"; break;
|
||||
case 1: OS << (IsPow2 ? ".p2align" : ".balign"); break;
|
||||
case 2: OS << (IsPow2 ? ".p2alignw" : ".balignw"); break;
|
||||
case 4: OS << (IsPow2 ? ".p2alignl" : ".balignl"); break;
|
||||
}
|
||||
|
||||
OS << ' ' << Pow2;
|
||||
OS << ' ' << (IsPow2 ? Pow2 : ByteAlignment);
|
||||
|
||||
OS << ", " << truncateToSize(Value, ValueSize);
|
||||
if (MaxBytesToEmit)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# RUN: llvm-mc %s > %t
|
||||
|
||||
# RUN: grep -A 2 TEST0 %t > %t2
|
||||
# RUN: grep ".p2align 1, 0" %t2 | count 1
|
||||
TEST0:
|
||||
.align 1
|
||||
|
||||
# RUN: grep -A 2 TEST1 %t > %t2
|
||||
# RUN: grep ".p2alignl 3, 0, 2" %t2 | count 1
|
||||
TEST1:
|
||||
.align32 3,,2
|
||||
|
||||
# RUN: grep -A 2 TEST2 %t > %t2
|
||||
# RUN: grep ".balign 3, 10" %t2 | count 1
|
||||
TEST2:
|
||||
.balign 3,10
|
|
@ -429,10 +429,30 @@ bool AsmParser::ParseStatement() {
|
|||
return ParseDirectiveValue(4);
|
||||
if (!strcmp(IDVal, ".quad"))
|
||||
return ParseDirectiveValue(8);
|
||||
if (!strcmp(IDVal, ".fill"))
|
||||
return ParseDirectiveFill();
|
||||
|
||||
// FIXME: Target hooks for IsPow2.
|
||||
if (!strcmp(IDVal, ".align"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
|
||||
if (!strcmp(IDVal, ".align32"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
|
||||
if (!strcmp(IDVal, ".balign"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/1);
|
||||
if (!strcmp(IDVal, ".balignw"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/2);
|
||||
if (!strcmp(IDVal, ".balignl"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/false, /*ExprSize=*/4);
|
||||
if (!strcmp(IDVal, ".p2align"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/1);
|
||||
if (!strcmp(IDVal, ".p2alignw"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/2);
|
||||
if (!strcmp(IDVal, ".p2alignl"))
|
||||
return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
|
||||
|
||||
if (!strcmp(IDVal, ".org"))
|
||||
return ParseDirectiveOrg();
|
||||
|
||||
if (!strcmp(IDVal, ".fill"))
|
||||
return ParseDirectiveFill();
|
||||
if (!strcmp(IDVal, ".space"))
|
||||
return ParseDirectiveSpace();
|
||||
|
||||
|
@ -708,3 +728,77 @@ bool AsmParser::ParseDirectiveOrg() {
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseDirectiveAlign
|
||||
/// ::= {.align, ...} expression [ , expression [ , expression ]]
|
||||
bool AsmParser::ParseDirectiveAlign(bool IsPow2, unsigned ValueSize) {
|
||||
int64_t Alignment;
|
||||
if (ParseAbsoluteExpression(Alignment))
|
||||
return true;
|
||||
|
||||
SMLoc MaxBytesLoc;
|
||||
bool HasFillExpr = false;
|
||||
int64_t FillExpr = 0;
|
||||
int64_t MaxBytesToFill = 0;
|
||||
if (Lexer.isNot(asmtok::EndOfStatement)) {
|
||||
if (Lexer.isNot(asmtok::Comma))
|
||||
return TokError("unexpected token in directive");
|
||||
Lexer.Lex();
|
||||
|
||||
// The fill expression can be omitted while specifying a maximum number of
|
||||
// alignment bytes, e.g:
|
||||
// .align 3,,4
|
||||
if (Lexer.isNot(asmtok::Comma)) {
|
||||
HasFillExpr = true;
|
||||
if (ParseAbsoluteExpression(FillExpr))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Lexer.isNot(asmtok::EndOfStatement)) {
|
||||
if (Lexer.isNot(asmtok::Comma))
|
||||
return TokError("unexpected token in directive");
|
||||
Lexer.Lex();
|
||||
|
||||
MaxBytesLoc = Lexer.getLoc();
|
||||
if (ParseAbsoluteExpression(MaxBytesToFill))
|
||||
return true;
|
||||
|
||||
if (Lexer.isNot(asmtok::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
}
|
||||
}
|
||||
|
||||
Lexer.Lex();
|
||||
|
||||
if (!HasFillExpr) {
|
||||
// FIXME: Sometimes fill with nop.
|
||||
FillExpr = 0;
|
||||
}
|
||||
|
||||
// Compute alignment in bytes.
|
||||
if (IsPow2) {
|
||||
// FIXME: Diagnose overflow.
|
||||
Alignment = 1 << Alignment;
|
||||
}
|
||||
|
||||
// Diagnose non-sensical max bytes to fill.
|
||||
if (MaxBytesLoc.isValid()) {
|
||||
if (MaxBytesToFill < 1) {
|
||||
Lexer.PrintMessage(MaxBytesLoc, "warning: alignment directive can never "
|
||||
"be satisfied in this many bytes, ignoring");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MaxBytesToFill >= Alignment) {
|
||||
Lexer.PrintMessage(MaxBytesLoc, "warning: maximum bytes expression "
|
||||
"exceeds alignment and has no effect");
|
||||
MaxBytesToFill = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Target specific behavior about how the "extra" bytes are filled.
|
||||
Out.EmitValueToAlignment(Alignment, FillExpr, ValueSize, MaxBytesToFill);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@ private:
|
|||
bool ParseDirectiveSpace(); // ".space"
|
||||
bool ParseDirectiveSet(); // ".set"
|
||||
bool ParseDirectiveOrg(); // ".org"
|
||||
// ".align{,32}", ".p2align{,w,l}"
|
||||
bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue