[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-tech
Subject:    Re: binary integer constants in gcc
From:       Mark Kettenis <mark.kettenis () xs4all ! nl>
Date:       2013-06-26 15:20:34
Message-ID: 201306261520.r5QFKYwH015300 () glazunov ! sibelius ! xs4all ! nl
[Download RAW message or body]

> Date: Wed, 26 Jun 2013 13:32:31 +1000
> From: Jonathan Gray <jsg@jsg.id.au>
> 
> 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 <jsg@jsg.id.au>
> > > 
> > > 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
> 

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic