> Date: Wed, 26 Jun 2013 13:32:31 +1000
> From: Jonathan Gray <[email protected]>
> 
> On Fri, Jun 21, 2013 at 10:20:01AM +0200, Mark Kettenis wrote:
> > > 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.
> 
> Here is the gcc3 diff:

Looks fine to me.  Would be good if you can get an ok from miod@

> Index: gcc/cppexp.c
> ===================================================================
> RCS file: /cvs/src/gnu/usr.bin/gcc/gcc/cppexp.c,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 cppexp.c
> --- gcc/cppexp.c      29 Nov 2003 12:21:45 -0000      1.1.1.1
> +++ gcc/cppexp.c      26 Jun 2013 03:17:21 -0000
> @@ -178,6 +178,11 @@ cpp_classify_number (pfile, token)
>         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.  */
> @@ -216,10 +221,22 @@ cpp_classify_number (pfile, token)
>      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, 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, DL_PEDWARN,
>                  "use of C99 hexadecimal floating constant");
> @@ -293,11 +310,15 @@ cpp_classify_number (pfile, token)
>  
>    if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
>      cpp_error (pfile, DL_PEDWARN, "imaginary constants are a GCC extension");
> +  if (radix == 2 && CPP_PEDANTIC (pfile))
> +    cpp_error (pfile, 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;
>  
> @@ -350,6 +371,11 @@ cpp_interpret_integer (pfile, token, typ
>         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.  */
> @@ -409,12 +435,25 @@ append_digit (num, digit, base, precisio
>       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: gcc/cpplib.h
> ===================================================================
> RCS file: /cvs/src/gnu/usr.bin/gcc/gcc/cpplib.h,v
> retrieving revision 1.1.1.2
> diff -u -p -r1.1.1.2 cpplib.h
> --- gcc/cpplib.h      24 Dec 2004 23:51:31 -0000      1.1.1.2
> +++ gcc/cpplib.h      26 Jun 2013 03:10:33 -0000
> @@ -630,6 +630,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