From 075a90a913e4f26ea074e720130ce8a0a892d235 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 1 Feb 2014 16:20:59 +0000 Subject: 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200614 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCParser/AsmParser.cpp | 57 ++++++++++++++++++++++++++++++++++-- test/MC/AsmParser/directive_values.s | 12 ++++++++ 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 + -- cgit v1.2.3