From 95792b92eaa5093e7f214ee74973ff1066b1089d Mon Sep 17 00:00:00 2001 From: Eric Astor Date: Tue, 29 Sep 2020 16:57:25 -0400 Subject: [PATCH] [ms] [llvm-ml] Add MASM hex float support Implement MASM's syntax for specifying floats in raw hexadecimal bytes. Reviewed By: thakis Differential Revision: https://reviews.llvm.org/D87401 --- include/llvm/MC/MCParser/MCAsmLexer.h | 4 ++++ lib/MC/MCParser/AsmLexer.cpp | 5 +++++ lib/MC/MCParser/MasmParser.cpp | 17 +++++++++++++++++ test/tools/llvm-ml/builtin_types.test | 8 ++++++++ tools/llvm-mc/llvm-mc.cpp | 5 +++++ tools/llvm-ml/llvm-ml.cpp | 2 ++ 6 files changed, 41 insertions(+) diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 1e449a7f59d..e2f3301d2f2 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -49,6 +49,7 @@ protected: // Can only create subclasses. bool SkipSpace = true; bool AllowAtInIdentifier; bool IsAtStartOfStatement = true; + bool LexMasmHexFloats = false; bool LexMasmIntegers = false; bool UseMasmDefaultRadix = false; unsigned DefaultRadix = 10; @@ -159,6 +160,9 @@ public: unsigned getMasmDefaultRadix() const { return DefaultRadix; } void setMasmDefaultRadix(unsigned Radix) { DefaultRadix = Radix; } + + /// Set whether to lex masm-style hex float literals, such as 3f800000r. + void setLexMasmHexFloats(bool V) { LexMasmHexFloats = V; } }; } // end namespace llvm diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index 12a71d69ed7..d8a20341bfb 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -350,6 +350,11 @@ AsmToken AsmLexer::LexDigit() { return LexFloatLiteral(); } + if (LexMasmHexFloats && (*CurPtr == 'r' || *CurPtr == 'R')) { + ++CurPtr; + return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart)); + } + unsigned Radix = 0; if (*CurPtr == 'h' || *CurPtr == 'H') { // hexadecimal number diff --git a/lib/MC/MCParser/MasmParser.cpp b/lib/MC/MCParser/MasmParser.cpp index 352d9473a23..d0a52657d66 100644 --- a/lib/MC/MCParser/MasmParser.cpp +++ b/lib/MC/MCParser/MasmParser.cpp @@ -3425,10 +3425,13 @@ bool MasmParser::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; + SMLoc SignLoc; if (getLexer().is(AsmToken::Minus)) { + SignLoc = getLexer().getLoc(); Lexer.Lex(); IsNeg = true; } else if (getLexer().is(AsmToken::Plus)) { + SignLoc = getLexer().getLoc(); Lexer.Lex(); } @@ -3450,6 +3453,20 @@ bool MasmParser::parseRealValue(const fltSemantics &Semantics, APInt &Res) { Value = APFloat::getZero(Semantics); else return TokError("invalid floating point literal"); + } else if (IDVal.consume_back("r") || IDVal.consume_back("R")) { + // MASM hexadecimal floating-point literal; no APFloat conversion needed. + // To match ML64.exe, ignore the initial sign. + unsigned Size = Value.getSizeInBits(Semantics); + if (Size != (IDVal.size() << 2)) + return TokError("invalid floating point literal"); + + // Consume the numeric token. + Lex(); + + Res = APInt(Size, IDVal, 16); + if (SignLoc.isValid()) + return Warning(SignLoc, "MASM-style hex floats ignore explicit sign"); + return false; } else if (errorToBool( Value.convertFromString(IDVal, APFloat::rmNearestTiesToEven) .takeError())) { diff --git a/test/tools/llvm-ml/builtin_types.test b/test/tools/llvm-ml/builtin_types.test index b99c491cb8d..f04e318b1b0 100644 --- a/test/tools/llvm-ml/builtin_types.test +++ b/test/tools/llvm-ml/builtin_types.test @@ -72,6 +72,14 @@ t6_double REAL8 1.3 ; CHECK-LABEL: t6_double: ; CHECK-NEXT: .quad 4608533498688228557 +t7_single_hex REAL4 3f800000r +t7_double_hex REAL8 3FF0000000000000R + +; CHECK-LABEL: t7_single_hex: +; CHECK-NEXT: .long 1065353216 +; CHECK-LABEL: t7_double_hex: +; CHECK-NEXT: .quad 4607182418800017408 + .code END diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 66b55abc489..f8352f36ad7 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -169,6 +169,10 @@ static cl::opt LexMasmIntegers( "masm-integers", cl::desc("Enable binary and hex masm integers (0b110 and 0ABCh)")); +static cl::opt LexMasmHexFloats( + "masm-hexfloats", + cl::desc("Enable MASM-style hex float initializers (3F800000r)")); + static cl::opt NoExecStack("no-exec-stack", cl::desc("File doesn't need an exec stack")); @@ -300,6 +304,7 @@ static int AssembleInput(const char *ProgName, const Target *TheTarget, Parser->setShowParsedOperands(ShowInstOperands); Parser->setTargetParser(*TAP); Parser->getLexer().setLexMasmIntegers(LexMasmIntegers); + Parser->getLexer().setLexMasmHexFloats(LexMasmHexFloats); int Res = Parser->Run(NoInitialTextSection); diff --git a/tools/llvm-ml/llvm-ml.cpp b/tools/llvm-ml/llvm-ml.cpp index 460a566f321..3a3984286e4 100644 --- a/tools/llvm-ml/llvm-ml.cpp +++ b/tools/llvm-ml/llvm-ml.cpp @@ -177,6 +177,7 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, raw_ostream &OS) { Lexer.setBuffer(SrcMgr.getMemoryBuffer(SrcMgr.getMainFileID())->getBuffer()); Lexer.setLexMasmIntegers(true); Lexer.useMasmDefaultRadix(true); + Lexer.setLexMasmHexFloats(true); bool Error = false; while (Lexer.Lex().isNot(AsmToken::Eof)) { @@ -208,6 +209,7 @@ static int AssembleInput(const char *ProgName, const Target *TheTarget, Parser->setTargetParser(*TAP); Parser->getLexer().setLexMasmIntegers(true); Parser->getLexer().useMasmDefaultRadix(true); + Parser->getLexer().setLexMasmHexFloats(true); int Res = Parser->Run(/*NoInitialTextSection=*/true);