SMLoc &EndLoc) override;
bool parseAbsoluteExpression(int64_t &Res) override;
+ /// \brief Parse a floating point expression using the float \p Semantics
+ /// and set \p Res to the value.
+ bool parseRealValue(const fltSemantics &Semantics, APInt &Res);
+
/// \brief Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
bool parseIdentifier(StringRef &Res) override;
DK_RELOC,
DK_VALUE, DK_2BYTE, DK_LONG, DK_INT, DK_4BYTE, DK_QUAD, DK_8BYTE, DK_OCTA,
DK_DC, DK_DC_A, DK_DC_B, DK_DC_D, DK_DC_L, DK_DC_S, DK_DC_W, DK_DC_X,
+ DK_DCB, DK_DCB_B, DK_DCB_D, DK_DCB_L, DK_DCB_S, DK_DCB_W, DK_DCB_X,
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,
// ".space", ".skip"
bool parseDirectiveSpace(StringRef IDVal);
+ // ".dcb"
+ bool parseDirectiveDCB(StringRef IDVal, unsigned Size);
+ bool parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &);
+
// .sleb128 (Signed=true) and .uleb128 (Signed=false)
bool parseDirectiveLEB128(bool Signed);
return parseDirectiveRealValue(APFloat::IEEEsingle);
case DK_DC_W:
return parseDirectiveValue(2);
+ case DK_DCB:
+ case DK_DCB_W:
+ return parseDirectiveDCB(IDVal, 2);
+ case DK_DCB_B:
+ return parseDirectiveDCB(IDVal, 1);
+ case DK_DCB_D:
+ return parseDirectiveRealDCB(IDVal, APFloat::IEEEdouble);
+ case DK_DCB_L:
+ return parseDirectiveDCB(IDVal, 4);
+ case DK_DCB_S:
+ return parseDirectiveRealDCB(IDVal, APFloat::IEEEsingle);
case DK_DC_X:
+ case DK_DCB_X:
return TokError(Twine(IDVal) +
" not currently supported for this target");
}
return false;
}
+bool AsmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) {
+ // We don't truly support arithmetic on floating point expressions, so we
+ // have to manually parse unary prefixes.
+ bool IsNeg = false;
+ if (getLexer().is(AsmToken::Minus)) {
+ Lexer.Lex();
+ IsNeg = true;
+ } else if (getLexer().is(AsmToken::Plus))
+ Lexer.Lex();
+
+ if (Lexer.is(AsmToken::Error))
+ return TokError(Lexer.getErr());
+ if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
+ Lexer.isNot(AsmToken::Identifier))
+ return TokError("unexpected token in directive");
+
+ // Convert to an APFloat.
+ APFloat Value(Semantics);
+ StringRef IDVal = getTok().getString();
+ if (getLexer().is(AsmToken::Identifier)) {
+ if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
+ Value = APFloat::getInf(Semantics);
+ else if (!IDVal.compare_lower("nan"))
+ Value = APFloat::getNaN(Semantics, false, ~0);
+ else
+ return TokError("invalid floating point literal");
+ } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
+ APFloat::opInvalidOp)
+ return TokError("invalid floating point literal");
+ if (IsNeg)
+ Value.changeSign();
+
+ // Consume the numeric token.
+ Lex();
+
+ Res = Value.bitcastToAPInt();
+
+ return false;
+}
+
/// parseDirectiveRealValue
/// ::= (.single | .double) [ expression (, expression)* ]
bool AsmParser::parseDirectiveRealValue(const fltSemantics &Semantics) {
checkForValidSection();
while (true) {
- // We don't truly support arithmetic on floating point expressions, so we
- // have to manually parse unary prefixes.
- bool IsNeg = false;
- if (getLexer().is(AsmToken::Minus)) {
- Lexer.Lex();
- IsNeg = true;
- } else if (getLexer().is(AsmToken::Plus))
- Lexer.Lex();
-
- if (Lexer.is(AsmToken::Error))
- return TokError(Lexer.getErr());
- if (Lexer.isNot(AsmToken::Integer) && Lexer.isNot(AsmToken::Real) &&
- Lexer.isNot(AsmToken::Identifier))
- return TokError("unexpected token in directive");
-
- // Convert to an APFloat.
- APFloat Value(Semantics);
- StringRef IDVal = getTok().getString();
- if (getLexer().is(AsmToken::Identifier)) {
- if (!IDVal.compare_lower("infinity") || !IDVal.compare_lower("inf"))
- Value = APFloat::getInf(Semantics);
- else if (!IDVal.compare_lower("nan"))
- Value = APFloat::getNaN(Semantics, false, ~0);
- else
- return TokError("invalid floating point literal");
- } else if (Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) ==
- APFloat::opInvalidOp)
- return TokError("invalid floating point literal");
- if (IsNeg)
- Value.changeSign();
-
- // Consume the numeric token.
- Lex();
+ APInt AsInt;
+ if (parseRealValue(Semantics, AsInt))
+ return true;
- // Emit the value as an integer.
- APInt AsInt = Value.bitcastToAPInt();
getStreamer().EmitIntValue(AsInt.getLimitedValue(),
AsInt.getBitWidth() / 8);
return false;
}
+/// parseDirectiveDCB
+/// ::= .dcb.{b, l, w} expression, expression
+bool AsmParser::parseDirectiveDCB(StringRef IDVal, unsigned Size) {
+ checkForValidSection();
+
+ SMLoc NumValuesLoc = Lexer.getLoc();
+ int64_t NumValues;
+ if (parseAbsoluteExpression(NumValues))
+ return true;
+
+ if (NumValues < 0) {
+ Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
+ return false;
+ }
+
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
+
+ const MCExpr *Value;
+ SMLoc ExprLoc = getLexer().getLoc();
+ if (parseExpression(Value))
+ return true;
+
+ // Special case constant expressions to match code generator.
+ if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
+ assert(Size <= 8 && "Invalid size");
+ uint64_t IntValue = MCE->getValue();
+ if (!isUIntN(8 * Size, IntValue) && !isIntN(8 * Size, IntValue))
+ return Error(ExprLoc, "literal value out of range for directive");
+ for (uint64_t i = 0, e = NumValues; i != e; ++i)
+ getStreamer().EmitIntValue(IntValue, Size);
+ } else {
+ for (uint64_t i = 0, e = NumValues; i != e; ++i)
+ getStreamer().EmitValue(Value, Size, ExprLoc);
+ }
+
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
+
+ return false;
+}
+
+/// parseDirectiveRealDCB
+/// ::= .dcb.{d, s} expression, expression
+bool AsmParser::parseDirectiveRealDCB(StringRef IDVal, const fltSemantics &Semantics) {
+ checkForValidSection();
+
+ SMLoc NumValuesLoc = Lexer.getLoc();
+ int64_t NumValues;
+ if (parseAbsoluteExpression(NumValues))
+ return true;
+
+ if (NumValues < 0) {
+ Warning(NumValuesLoc, "'" + Twine(IDVal) + "' directive with negative repeat count has no effect");
+ return false;
+ }
+
+ if (parseToken(AsmToken::Comma,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
+
+ APInt AsInt;
+ if (parseRealValue(Semantics, AsInt))
+ return true;
+
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '" + Twine(IDVal) + "' directive"))
+ return true;
+
+ for (uint64_t i = 0, e = NumValues; i != e; ++i)
+ getStreamer().EmitIntValue(AsInt.getLimitedValue(),
+ AsInt.getBitWidth() / 8);
+
+ return false;
+}
+
/// parseDirectiveLEB128
/// ::= (.sleb128 | .uleb128) [ expression (, expression)* ]
bool AsmParser::parseDirectiveLEB128(bool Signed) {
DirectiveKindMap[".dc.s"] = DK_DC_S;
DirectiveKindMap[".dc.w"] = DK_DC_W;
DirectiveKindMap[".dc.x"] = DK_DC_X;
+ DirectiveKindMap[".dcb"] = DK_DCB;
+ DirectiveKindMap[".dcb.b"] = DK_DCB_B;
+ DirectiveKindMap[".dcb.d"] = DK_DCB_D;
+ DirectiveKindMap[".dcb.l"] = DK_DCB_L;
+ DirectiveKindMap[".dcb.s"] = DK_DCB_S;
+ DirectiveKindMap[".dcb.w"] = DK_DCB_W;
+ DirectiveKindMap[".dcb.x"] = DK_DCB_X;
}
MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) {