summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2014-02-01 16:20:59 +0000
committerDavid Woodhouse <dwmw2@infradead.org>2014-02-01 16:20:59 +0000
commit075a90a913e4f26ea074e720130ce8a0a892d235 (patch)
tree5bf6385bcfd838a00f14a29c5f77ea834749c08d
parentaac8e4e3f332c8be2b1049f892549a367d902919 (diff)
downloadllvm-075a90a913e4f26ea074e720130ce8a0a892d235.tar.gz
llvm-075a90a913e4f26ea074e720130ce8a0a892d235.tar.bz2
llvm-075a90a913e4f26ea074e720130ce8a0a892d235.tar.xz
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
-rw-r--r--lib/MC/MCParser/AsmParser.cpp57
-rw-r--r--test/MC/AsmParser/directive_values.s12
2 files changed, 67 insertions, 2 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index e236c170b7..37b759e64f 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -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;
diff --git a/test/MC/AsmParser/directive_values.s b/test/MC/AsmParser/directive_values.s
index ed932b2974..c4aea51ca5 100644
--- a/test/MC/AsmParser/directive_values.s
+++ b/test/MC/AsmParser/directive_values.s
@@ -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
+