summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2013-07-04 02:19:47 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2013-07-04 02:19:47 +0000
commit11bc421ce0aa7c6754ffd7c7586196dde69c15c1 (patch)
tree109b3a1a78cca87c6c1ae834def3f791dce6d330
parente181c2b6b4264069c35db79717a54785e71b85f8 (diff)
Add support for the GCC binary integer constants extension.
From Joerg Wunsch in GCC PR 23479, under the GPLv2. This is required to build the i965 backend with newer versions of mesa. ok kettenis@ espie@ miod@
-rw-r--r--gnu/gcc/libcpp/expr.c46
-rw-r--r--gnu/gcc/libcpp/include/cpplib.h1
-rw-r--r--gnu/usr.bin/gcc/gcc/cppexp.c45
-rw-r--r--gnu/usr.bin/gcc/gcc/cpplib.h5
4 files changed, 91 insertions, 6 deletions
diff --git a/gnu/gcc/libcpp/expr.c b/gnu/gcc/libcpp/expr.c
index bf8baaff265..24fcb1b863e 100644
--- a/gnu/gcc/libcpp/expr.c
+++ b/gnu/gcc/libcpp/expr.c
@@ -188,6 +188,11 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *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. */
@@ -226,10 +231,22 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *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, 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, const cpp_token *token)
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, const cpp_token *token,
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;
diff --git a/gnu/gcc/libcpp/include/cpplib.h b/gnu/gcc/libcpp/include/cpplib.h
index bb0bfff7b62..38599109e14 100644
--- a/gnu/gcc/libcpp/include/cpplib.h
+++ b/gnu/gcc/libcpp/include/cpplib.h
@@ -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
diff --git a/gnu/usr.bin/gcc/gcc/cppexp.c b/gnu/usr.bin/gcc/gcc/cppexp.c
index 12919f6f88f..30fe04e43bf 100644
--- a/gnu/usr.bin/gcc/gcc/cppexp.c
+++ b/gnu/usr.bin/gcc/gcc/cppexp.c
@@ -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, type)
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, precision)
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;
diff --git a/gnu/usr.bin/gcc/gcc/cpplib.h b/gnu/usr.bin/gcc/gcc/cpplib.h
index 7b3a54a3576..0f8f5be3677 100644
--- a/gnu/usr.bin/gcc/gcc/cpplib.h
+++ b/gnu/usr.bin/gcc/gcc/cpplib.h
@@ -240,6 +240,10 @@ struct cpp_options
const char *include_prefix;
unsigned int include_prefix_len;
+ /* Directory prefix for system include directories in the standard search
+ path. */
+ const char *sysroot;
+
/* The language we're preprocessing. */
enum c_lang lang;
@@ -626,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