[llvm] r188370 - Support C99 hexadecimal floating-point literals in assembly

Stephen Canon scanon at apple.com
Wed Aug 14 07:37:26 PDT 2013


Probably should have a test case of the form 0x1.2.  The binary-exponent-part isn’t optional for hex-float literals.

Thanks much for working on this!

On Aug 14, 2013, at 10:23 AM, Tim Northover <tnorthover at apple.com> wrote:

> Author: tnorthover
> Date: Wed Aug 14 09:23:31 2013
> New Revision: 188370
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=188370&view=rev
> Log:
> 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.
> 
> Modified:
>    llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h
>    llvm/trunk/lib/MC/MCParser/AsmLexer.cpp
>    llvm/trunk/test/MC/AsmParser/floating-literals.s
> 
> Modified: llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h?rev=188370&r1=188369&r2=188370&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h (original)
> +++ llvm/trunk/include/llvm/MC/MCParser/AsmLexer.h Wed Aug 14 09:23:31 2013
> @@ -63,6 +63,7 @@ private:
>   AsmToken LexSingleQuote();
>   AsmToken LexQuote();
>   AsmToken LexFloatLiteral();
> +  AsmToken LexHexFloatLiteral(bool NoIntDigits);
> };
> 
> } // end namespace llvm
> 
> Modified: llvm/trunk/lib/MC/MCParser/AsmLexer.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmLexer.cpp?rev=188370&r1=188369&r2=188370&view=diff
> ==============================================================================
> --- llvm/trunk/lib/MC/MCParser/AsmLexer.cpp (original)
> +++ llvm/trunk/lib/MC/MCParser/AsmLexer.cpp Wed Aug 14 09:23:31 2013
> @@ -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");
> 
> 
> Modified: llvm/trunk/test/MC/AsmParser/floating-literals.s
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/AsmParser/floating-literals.s?rev=188370&r1=188369&r2=188370&view=diff
> ==============================================================================
> --- llvm/trunk/test/MC/AsmParser/floating-literals.s (original)
> +++ llvm/trunk/test/MC/AsmParser/floating-literals.s Wed Aug 14 09:23:31 2013
> @@ -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
> +
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits





More information about the llvm-commits mailing list