diff --git a/llvm/include/llvm/MC/MCParser/MCAsmLexer.h b/llvm/include/llvm/MC/MCParser/MCAsmLexer.h --- a/llvm/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/llvm/include/llvm/MC/MCParser/MCAsmLexer.h @@ -49,6 +49,7 @@ bool SkipSpace = true; bool AllowAtInIdentifier; bool IsAtStartOfStatement = true; + bool LexMasmHexFloats = false; bool LexMasmIntegers = false; bool UseMasmDefaultRadix = false; unsigned DefaultRadix = 10; @@ -159,6 +160,9 @@ 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/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp --- a/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -350,6 +350,11 @@ 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/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -3425,10 +3425,13 @@ // 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 @@ 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/llvm/test/tools/llvm-ml/builtin_types.test b/llvm/test/tools/llvm-ml/builtin_types.test --- a/llvm/test/tools/llvm-ml/builtin_types.test +++ b/llvm/test/tools/llvm-ml/builtin_types.test @@ -72,6 +72,14 @@ ; 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/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -169,6 +169,10 @@ "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 @@ Parser->setShowParsedOperands(ShowInstOperands); Parser->setTargetParser(*TAP); Parser->getLexer().setLexMasmIntegers(LexMasmIntegers); + Parser->getLexer().setLexMasmHexFloats(LexMasmHexFloats); int Res = Parser->Run(NoInitialTextSection); diff --git a/llvm/tools/llvm-ml/llvm-ml.cpp b/llvm/tools/llvm-ml/llvm-ml.cpp --- a/llvm/tools/llvm-ml/llvm-ml.cpp +++ b/llvm/tools/llvm-ml/llvm-ml.cpp @@ -177,6 +177,7 @@ 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 @@ Parser->setTargetParser(*TAP); Parser->getLexer().setLexMasmIntegers(true); Parser->getLexer().useMasmDefaultRadix(true); + Parser->getLexer().setLexMasmHexFloats(true); int Res = Parser->Run(/*NoInitialTextSection=*/true);