mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-27 14:45:50 +00:00
Support C99 hexadecimal floating-point literals in assembly
It's useful to be able to write down floating-point numbers without having to worry about what they'll be rounded to (as C99 discovered), this extends that ability to the MC assembly parsers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188370 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
79663c1910
commit
337439d12d
@ -63,6 +63,7 @@ private:
|
||||
AsmToken LexSingleQuote();
|
||||
AsmToken LexQuote();
|
||||
AsmToken LexFloatLiteral();
|
||||
AsmToken LexHexFloatLiteral(bool NoIntDigits);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -91,6 +91,53 @@ AsmToken AsmLexer::LexFloatLiteral() {
|
||||
StringRef(TokStart, CurPtr - TokStart));
|
||||
}
|
||||
|
||||
/// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+
|
||||
/// while making sure there are enough actual digits around for the constant to
|
||||
/// be valid.
|
||||
///
|
||||
/// The leading "0x[0-9a-fA-F]*" (i.e. integer part) has already been consumed
|
||||
/// before we get here.
|
||||
AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) {
|
||||
assert((*CurPtr == 'p' || *CurPtr == 'P' || *CurPtr == '.') &&
|
||||
"unexpected parse state in floating hex");
|
||||
bool NoFracDigits = true;
|
||||
|
||||
// Skip the fractional part if there is one
|
||||
if (*CurPtr == '.') {
|
||||
++CurPtr;
|
||||
|
||||
const char *FracStart = CurPtr;
|
||||
while (isxdigit(*CurPtr))
|
||||
++CurPtr;
|
||||
|
||||
NoFracDigits = CurPtr == FracStart;
|
||||
}
|
||||
|
||||
if (NoIntDigits && NoFracDigits)
|
||||
return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
|
||||
"expected at least one significand digit");
|
||||
|
||||
// Make sure we do have some kind of proper exponent part
|
||||
if (*CurPtr != 'p' && *CurPtr != 'P')
|
||||
return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
|
||||
"expected exponent part 'p'");
|
||||
++CurPtr;
|
||||
|
||||
if (*CurPtr == '+' || *CurPtr == '-')
|
||||
++CurPtr;
|
||||
|
||||
// N.b. exponent digits are *not* hex
|
||||
const char *ExpStart = CurPtr;
|
||||
while (isdigit(*CurPtr))
|
||||
++CurPtr;
|
||||
|
||||
if (CurPtr == ExpStart)
|
||||
return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
|
||||
"expected at least one exponent digit");
|
||||
|
||||
return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
|
||||
}
|
||||
|
||||
/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
|
||||
static bool IsIdentifierChar(char c) {
|
||||
return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@';
|
||||
@ -265,7 +312,12 @@ AsmToken AsmLexer::LexDigit() {
|
||||
while (isxdigit(CurPtr[0]))
|
||||
++CurPtr;
|
||||
|
||||
// Requires at least one hex digit.
|
||||
// "0x.0p0" is valid, and "0x0p0" (but not "0xp0" for example, which will be
|
||||
// diagnosed by LexHexFloatLiteral).
|
||||
if (CurPtr[0] == '.' || CurPtr[0] == 'p' || CurPtr[0] == 'P')
|
||||
return LexHexFloatLiteral(NumStart == CurPtr);
|
||||
|
||||
// Otherwise requires at least one hex digit.
|
||||
if (CurPtr == NumStart)
|
||||
return ReturnError(CurPtr-2, "invalid hexadecimal number");
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
|
||||
# RUN: not llvm-mc -triple i386-unknown-unknown %s 2> /dev/null | FileCheck %s
|
||||
# RUN: not llvm-mc -triple i386-unknown-unknown %s 2>&1 > /dev/null| FileCheck %s --check-prefix=CHECK-ERROR
|
||||
|
||||
# CHECK: .long 1067412619
|
||||
# CHECK: .long 1075000115
|
||||
@ -42,3 +43,37 @@
|
||||
// APFloat should reject these with an error, not crash:
|
||||
//.double -1.2e+
|
||||
//.double -1.2e
|
||||
|
||||
# CHECK: .long 1310177520
|
||||
.float 0x12f7.1ep+17
|
||||
# CHECK: .long 1084227584
|
||||
.float 0x.ap+3
|
||||
# CHECK: .quad 4602678819172646912
|
||||
.double 0x2.p-2
|
||||
# CHECK: .long 1094713344
|
||||
.float 0x3p2
|
||||
# CHECK: .long 872284160
|
||||
.float 0x7fp-30
|
||||
# CHECK: .long 3212836864
|
||||
.float -0x1.0p0
|
||||
|
||||
# CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
|
||||
# CHECK-ERROR: unexpected token in directive
|
||||
.float 0xa.apa
|
||||
|
||||
# CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
|
||||
# CHECK-ERROR: unexpected token in directive
|
||||
.double -0x1.2p+
|
||||
|
||||
# CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
|
||||
# CHECK-ERROR: unexpected token in directive
|
||||
.double -0x1.2p
|
||||
|
||||
# CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one significand digit
|
||||
# CHECK-ERROR: unexpected token in directive
|
||||
.float 0xp2
|
||||
|
||||
# CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one significand digit
|
||||
# CHECK-ERROR: unexpected token in directive
|
||||
.float 0x.p5
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user