diff options
author | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-07 02:28:42 +0000 |
---|---|---|
committer | Saleem Abdulrasool <compnerd@compnerd.org> | 2014-01-07 02:28:42 +0000 |
commit | 8e129852fb27505fcc606601b256d1eb39676437 (patch) | |
tree | 34893e431a1c8af67172f411cceb97071511e40d /lib/Target/ARM/AsmParser/ARMAsmParser.cpp | |
parent | 307f17b9383dff92540e7fb8da28d36f966c2834 (diff) | |
download | llvm-8e129852fb27505fcc606601b256d1eb39676437.tar.gz llvm-8e129852fb27505fcc606601b256d1eb39676437.tar.bz2 llvm-8e129852fb27505fcc606601b256d1eb39676437.tar.xz |
ARM IAS: improve .eabi_attribute handling
Parse tag names as well as expressions. The former is part of the
specification, the latter is for improved compatibility with the GNU assembler.
Fix attribute value handling to be comformant to the specification.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198662 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser/ARMAsmParser.cpp')
-rw-r--r-- | lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 109 |
1 files changed, 94 insertions, 15 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index be148ca7d2..81cad168ae 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -7,11 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "ARMBuildAttrs.h" #include "ARMFPUName.h" #include "ARMFeatures.h" #include "llvm/MC/MCTargetAsmParser.h" #include "MCTargetDesc/ARMAddressingModes.h" +#include "MCTargetDesc/ARMBuildAttrs.h" #include "MCTargetDesc/ARMArchName.h" #include "MCTargetDesc/ARMBaseInfo.h" #include "MCTargetDesc/ARMMCExpr.h" @@ -8189,30 +8189,109 @@ bool ARMAsmParser::parseDirectiveArch(SMLoc L) { } /// parseDirectiveEabiAttr -/// ::= .eabi_attribute int, int +/// ::= .eabi_attribute int, int [, "str"] +/// ::= .eabi_attribute Tag_name, int [, "str"] bool ARMAsmParser::parseDirectiveEabiAttr(SMLoc L) { - if (Parser.getTok().isNot(AsmToken::Integer)) { - Error(L, "integer expected"); - return false; + int64_t Tag; + SMLoc TagLoc; + + TagLoc = Parser.getTok().getLoc(); + if (Parser.getTok().is(AsmToken::Identifier)) { + StringRef Name = Parser.getTok().getIdentifier(); + Tag = ARMBuildAttrs::AttrTypeFromString(Name); + if (Tag == -1) { + Error(TagLoc, "attribute name not recognised: " + Name); + Parser.eatToEndOfStatement(); + return false; + } + Parser.Lex(); + } else { + const MCExpr *AttrExpr; + + TagLoc = Parser.getTok().getLoc(); + if (Parser.parseExpression(AttrExpr)) { + Parser.eatToEndOfStatement(); + return false; + } + + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); + if (!CE) { + Error(TagLoc, "expected numeric constant"); + Parser.eatToEndOfStatement(); + return false; + } + + Tag = CE->getValue(); } - int64_t Tag = Parser.getTok().getIntVal(); - Parser.Lex(); // eat tag integer if (Parser.getTok().isNot(AsmToken::Comma)) { - Error(L, "comma expected"); + Error(Parser.getTok().getLoc(), "comma expected"); + Parser.eatToEndOfStatement(); return false; } Parser.Lex(); // skip comma - L = Parser.getTok().getLoc(); - if (Parser.getTok().isNot(AsmToken::Integer)) { - Error(L, "integer expected"); - return false; + StringRef StringValue = ""; + bool IsStringValue = false; + + int64_t IntegerValue = 0; + bool IsIntegerValue = false; + + if (Tag == ARMBuildAttrs::CPU_raw_name || Tag == ARMBuildAttrs::CPU_name) + IsStringValue = true; + else if (Tag == ARMBuildAttrs::compatibility) { + IsStringValue = true; + IsIntegerValue = true; + } else if (Tag == ARMBuildAttrs::nodefaults || Tag < 32 || Tag % 2 == 0) + IsIntegerValue = true; + else if (Tag % 2 == 1) + IsStringValue = true; + else + llvm_unreachable("invalid tag type"); + + if (IsIntegerValue) { + const MCExpr *ValueExpr; + SMLoc ValueExprLoc = Parser.getTok().getLoc(); + if (Parser.parseExpression(ValueExpr)) { + Parser.eatToEndOfStatement(); + return false; + } + + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); + if (!CE) { + Error(ValueExprLoc, "expected numeric constant"); + Parser.eatToEndOfStatement(); + return false; + } + + IntegerValue = CE->getValue(); + } + + if (Tag == ARMBuildAttrs::compatibility) { + if (Parser.getTok().isNot(AsmToken::Comma)) + IsStringValue = false; + else + Parser.Lex(); + } + + if (IsStringValue) { + if (Parser.getTok().isNot(AsmToken::String)) { + Error(Parser.getTok().getLoc(), "bad string constant"); + Parser.eatToEndOfStatement(); + return false; + } + + StringValue = Parser.getTok().getStringContents(); + Parser.Lex(); } - int64_t Value = Parser.getTok().getIntVal(); - Parser.Lex(); // eat value integer - getTargetStreamer().emitAttribute(Tag, Value); + if (IsIntegerValue && IsStringValue) { + assert(Tag == ARMBuildAttrs::compatibility); + getTargetStreamer().emitIntTextAttribute(Tag, IntegerValue, StringValue); + } else if (IsIntegerValue) + getTargetStreamer().emitAttribute(Tag, IntegerValue); + else if (IsStringValue) + getTargetStreamer().emitTextAttribute(Tag, StringValue); return false; } |