[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
This commit is contained in:
Eric Astor 2020-09-29 16:57:25 -04:00
parent ccf36de799
commit 95792b92ea
6 changed files with 41 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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())) {

View File

@ -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

View File

@ -169,6 +169,10 @@ static cl::opt<bool> LexMasmIntegers(
"masm-integers",
cl::desc("Enable binary and hex masm integers (0b110 and 0ABCh)"));
static cl::opt<bool> LexMasmHexFloats(
"masm-hexfloats",
cl::desc("Enable MASM-style hex float initializers (3F800000r)"));
static cl::opt<bool> 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);

View File

@ -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);