[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