llvm.org GIT mirror llvm / 337439d
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 Tim Northover 7 years ago
3 changed file(s) with 90 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
6262 AsmToken LexSingleQuote();
6363 AsmToken LexQuote();
6464 AsmToken LexFloatLiteral();
65 AsmToken LexHexFloatLiteral(bool NoIntDigits);
6566 };
6667
6768 } // end namespace llvm
8888
8989 return AsmToken(AsmToken::Real,
9090 StringRef(TokStart, CurPtr - TokStart));
91 }
92
93 /// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+
94 /// while making sure there are enough actual digits around for the constant to
95 /// be valid.
96 ///
97 /// The leading "0x[0-9a-fA-F]*" (i.e. integer part) has already been consumed
98 /// before we get here.
99 AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) {
100 assert((*CurPtr == 'p' || *CurPtr == 'P' || *CurPtr == '.') &&
101 "unexpected parse state in floating hex");
102 bool NoFracDigits = true;
103
104 // Skip the fractional part if there is one
105 if (*CurPtr == '.') {
106 ++CurPtr;
107
108 const char *FracStart = CurPtr;
109 while (isxdigit(*CurPtr))
110 ++CurPtr;
111
112 NoFracDigits = CurPtr == FracStart;
113 }
114
115 if (NoIntDigits && NoFracDigits)
116 return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
117 "expected at least one significand digit");
118
119 // Make sure we do have some kind of proper exponent part
120 if (*CurPtr != 'p' && *CurPtr != 'P')
121 return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
122 "expected exponent part 'p'");
123 ++CurPtr;
124
125 if (*CurPtr == '+' || *CurPtr == '-')
126 ++CurPtr;
127
128 // N.b. exponent digits are *not* hex
129 const char *ExpStart = CurPtr;
130 while (isdigit(*CurPtr))
131 ++CurPtr;
132
133 if (CurPtr == ExpStart)
134 return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
135 "expected at least one exponent digit");
136
137 return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
91138 }
92139
93140 /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
264311 while (isxdigit(CurPtr[0]))
265312 ++CurPtr;
266313
267 // Requires at least one hex digit.
314 // "0x.0p0" is valid, and "0x0p0" (but not "0xp0" for example, which will be
315 // diagnosed by LexHexFloatLiteral).
316 if (CurPtr[0] == '.' || CurPtr[0] == 'p' || CurPtr[0] == 'P')
317 return LexHexFloatLiteral(NumStart == CurPtr);
318
319 // Otherwise requires at least one hex digit.
268320 if (CurPtr == NumStart)
269321 return ReturnError(CurPtr-2, "invalid hexadecimal number");
270322
None # RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s
0 # RUN: not llvm-mc -triple i386-unknown-unknown %s 2> /dev/null | FileCheck %s
1 # RUN: not llvm-mc -triple i386-unknown-unknown %s 2>&1 > /dev/null| FileCheck %s --check-prefix=CHECK-ERROR
12
23 # CHECK: .long 1067412619
34 # CHECK: .long 1075000115
4142 // APFloat should reject these with an error, not crash:
4243 //.double -1.2e+
4344 //.double -1.2e
45
46 # CHECK: .long 1310177520
47 .float 0x12f7.1ep+17
48 # CHECK: .long 1084227584
49 .float 0x.ap+3
50 # CHECK: .quad 4602678819172646912
51 .double 0x2.p-2
52 # CHECK: .long 1094713344
53 .float 0x3p2
54 # CHECK: .long 872284160
55 .float 0x7fp-30
56 # CHECK: .long 3212836864
57 .float -0x1.0p0
58
59 # CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
60 # CHECK-ERROR: unexpected token in directive
61 .float 0xa.apa
62
63 # CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
64 # CHECK-ERROR: unexpected token in directive
65 .double -0x1.2p+
66
67 # CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one exponent digit
68 # CHECK-ERROR: unexpected token in directive
69 .double -0x1.2p
70
71 # CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one significand digit
72 # CHECK-ERROR: unexpected token in directive
73 .float 0xp2
74
75 # CHECK-ERROR: invalid hexadecimal floating-point constant: expected at least one significand digit
76 # CHECK-ERROR: unexpected token in directive
77 .float 0x.p5
78