MC: Add support for .octa

This is a minimal implementation which accepts only constants rather than
full expressions, but that should be perfectly sufficient for all known
users for now.

Patch from PaX Team <pageexec@freemail.hu>

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200614 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Woodhouse 2014-02-01 16:20:59 +00:00
parent aac8e4e3f3
commit 075a90a913
2 changed files with 67 additions and 2 deletions

View File

@ -337,8 +337,8 @@ private:
enum DirectiveKind {
DK_NO_DIRECTIVE, // Placeholder
DK_SET, DK_EQU, DK_EQUIV, DK_ASCII, DK_ASCIZ, DK_STRING, DK_BYTE, DK_SHORT,
DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_SINGLE,
DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA,
DK_SINGLE, DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
@ -367,6 +367,7 @@ private:
// ".ascii", ".asciz", ".string"
bool parseDirectiveAscii(StringRef IDVal, bool ZeroTerminated);
bool parseDirectiveValue(unsigned Size); // ".byte", ".long", ...
bool parseDirectiveOctaValue(); // ".octa"
bool parseDirectiveRealValue(const fltSemantics &); // ".single", ...
bool parseDirectiveFill(); // ".fill"
bool parseDirectiveZero(); // ".zero"
@ -1376,6 +1377,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info) {
case DK_QUAD:
case DK_8BYTE:
return parseDirectiveValue(8);
case DK_OCTA:
return parseDirectiveOctaValue();
case DK_SINGLE:
case DK_FLOAT:
return parseDirectiveRealValue(APFloat::IEEEsingle);
@ -2310,6 +2313,55 @@ bool AsmParser::parseDirectiveValue(unsigned Size) {
return false;
}
/// ParseDirectiveOctaValue
/// ::= .octa [ hexconstant (, hexconstant)* ]
bool AsmParser::parseDirectiveOctaValue() {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
checkForValidSection();
for (;;) {
if (Lexer.getKind() == AsmToken::Error)
return true;
if (Lexer.getKind() != AsmToken::Integer &&
Lexer.getKind() != AsmToken::BigNum)
return TokError("unknown token in expression");
SMLoc ExprLoc = getLexer().getLoc();
APInt IntValue = getTok().getAPIntVal();
Lex();
uint64_t hi, lo;
if (IntValue.isIntN(64)) {
hi = 0;
lo = IntValue.getZExtValue();
} else if (IntValue.isIntN(128)) {
hi = IntValue.getHiBits(64).getZExtValue();
lo = IntValue.getLoBits(64).getZExtValue();
} else
return Error(ExprLoc, "literal value out of range for directive");
if (MAI.isLittleEndian()) {
getStreamer().EmitIntValue(lo, 8);
getStreamer().EmitIntValue(hi, 8);
} else {
getStreamer().EmitIntValue(hi, 8);
getStreamer().EmitIntValue(lo, 8);
}
if (getLexer().is(AsmToken::EndOfStatement))
break;
// FIXME: Improve diagnostic.
if (getLexer().isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
Lex();
}
}
Lex();
return false;
}
/// parseDirectiveRealValue
/// ::= (.single | .double) [ expression (, expression)* ]
bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
@ -3817,6 +3869,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".4byte"] = DK_4BYTE;
DirectiveKindMap[".quad"] = DK_QUAD;
DirectiveKindMap[".8byte"] = DK_8BYTE;
DirectiveKindMap[".octa"] = DK_OCTA;
DirectiveKindMap[".single"] = DK_SINGLE;
DirectiveKindMap[".float"] = DK_FLOAT;
DirectiveKindMap[".double"] = DK_DOUBLE;

View File

@ -69,3 +69,15 @@ TEST8:
.long 0x200000L+1
# CHECK: .long 2097153
# CHECK: .long 2097153
TEST9:
.octa 0x1234567812345678abcdef, 12345678901234567890123456789
.octa 0b00111010010110100101101001011010010110100101101001011010010110100101101001011010010110100101101001011010010110100101101001011010
# CHECK: TEST9
# CHECK: .quad 8652035380128501231
# CHECK: .quad 1193046
# CHECK: .quad 5097733592125636885
# CHECK: .quad 669260594
# CHECK: .quad 6510615555426900570
# CHECK: .quad 4204772546213206618