> Date: Fri, 21 Jun 2013 17:31:39 +1000
> From: Jonathan Gray <[email protected]>
> 
> Both gcc and clang have an extension for binary integer constants.
> In gcc's case this has been around since 4.3.
> 
> The mesa backend for newer intel parts (i965) assumes this extension
> is present in recent versions.

Sigh...  Can't these people just write portable C?

> Below is a diff to add support for this to our in tree gcc4.  While the
> i965 backend is only built on gcc4 archs the concern is that abuse
> of this extension in ports or other places may make gcc3/gcc2 archs
> worse off unless similiar patches can be done...

Well, lots of ports stuff is compiled with newer gcc versions anyway.

Looks like it is trivial to bring this extension to gcc3, since the
code seems to be almost unchanged in gcc4.  It just moved to a
different location.

Diff looks ok to me.

> >From 
> http://gcc.gnu.org/git/?p=gcc.git;a=patch;h=d7282a2b2cacdf62e80c1f29f06933f38a70d743
> still under the GPLv2.
> 
> Index: libcpp/expr.c
> ===================================================================
> RCS file: /cvs/src/gnu/gcc/libcpp/expr.c,v
> retrieving revision 1.2
> diff -u -p -r1.2 expr.c
> --- libcpp/expr.c     4 Apr 2013 22:01:32 -0000       1.2
> +++ libcpp/expr.c     21 Jun 2013 06:34:53 -0000
> @@ -188,6 +188,11 @@ cpp_classify_number (cpp_reader *pfile, 
>         radix = 16;
>         str++;
>       }
> +      else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == 
> '1'))
> +     {
> +       radix = 2;
> +       str++;
> +     }
>      }
>  
>    /* Now scan for a well-formed integer or float.  */
> @@ -226,10 +231,22 @@ cpp_classify_number (cpp_reader *pfile, 
>      radix = 10;
>  
>    if (max_digit >= radix)
> -    SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + 
> max_digit);
> +    {
> +      if (radix == 2)
> +     SYNTAX_ERROR2 ("invalid digit \"%c\" in binary constant", '0' + 
> max_digit);
> +      else
> +     SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + 
> max_digit);
> +    }
>  
>    if (float_flag != NOT_FLOAT)
>      {
> +      if (radix == 2)
> +     {
> +       cpp_error (pfile, CPP_DL_ERROR,
> +                  "invalid prefix \"0b\" for floating constant");
> +       return CPP_N_INVALID;
> +     }
> +
>        if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
>       cpp_error (pfile, CPP_DL_PEDWARN,
>                  "use of C99 hexadecimal floating constant");
> @@ -321,11 +338,16 @@ cpp_classify_number (cpp_reader *pfile, 
>    if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
>      cpp_error (pfile, CPP_DL_PEDWARN,
>              "imaginary constants are a GCC extension");
> +  if (radix == 2 && CPP_PEDANTIC (pfile))
> +    cpp_error (pfile, CPP_DL_PEDWARN,
> +            "binary constants are a GCC extension");
>  
>    if (radix == 10)
>      result |= CPP_N_DECIMAL;
>    else if (radix == 16)
>      result |= CPP_N_HEX;
> +  else if (radix == 2)
> +    result |= CPP_N_BINARY;
>    else
>      result |= CPP_N_OCTAL;
>  
> @@ -376,6 +398,11 @@ cpp_interpret_integer (cpp_reader *pfile
>         base = 16;
>         p += 2;
>       }
> +      else if ((type & CPP_N_RADIX) == CPP_N_BINARY)
> +     {
> +       base = 2;
> +       p += 2;
> +     }
>  
>        /* We can add a digit to numbers strictly less than this without
>        needing the precision and slowness of double integers.  */
> @@ -431,12 +458,25 @@ static cpp_num
>  append_digit (cpp_num num, int digit, int base, size_t precision)
>  {
>    cpp_num result;
> -  unsigned int shift = 3 + (base == 16);
> +  unsigned int shift;
>    bool overflow;
>    cpp_num_part add_high, add_low;
>  
> -  /* Multiply by 8 or 16.  Catching this overflow here means we don't
> +  /* Multiply by 2, 8 or 16.  Catching this overflow here means we don't
>       need to worry about add_high overflowing.  */
> +  switch (base)
> +    {
> +    case 2:
> +      shift = 1;
> +      break;
> +
> +    case 16:
> +      shift = 4;
> +      break;
> +
> +    default:
> +      shift = 3;
> +    }
>    overflow = !!(num.high >> (PART_PRECISION - shift));
>    result.high = num.high << shift;
>    result.low = num.low << shift;
> Index: libcpp/include/cpplib.h
> ===================================================================
> RCS file: /cvs/src/gnu/gcc/libcpp/include/cpplib.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 cpplib.h
> --- libcpp/include/cpplib.h   4 Apr 2013 22:01:32 -0000       1.2
> +++ libcpp/include/cpplib.h   21 Jun 2013 06:34:53 -0000
> @@ -744,6 +744,7 @@ struct cpp_num
>  #define CPP_N_DECIMAL        0x0100
>  #define CPP_N_HEX    0x0200
>  #define CPP_N_OCTAL  0x0400
> +#define CPP_N_BINARY 0x0800
>  
>  #define CPP_N_UNSIGNED       0x1000  /* Properties.  */
>  #define CPP_N_IMAGINARY      0x2000
> 
> 

Reply via email to