diff options
author | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-20 22:26:47 +0000 |
---|---|---|
committer | chaoyingfu <chaoyingfu@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-08-20 22:26:47 +0000 |
commit | 9421ebb9b381242a1fa9d4b435babe0910a58118 (patch) | |
tree | 64870172714a26b5105facd128201e6fef2f87b8 /gcc/c-decl.c | |
parent | a37e11205961890d4a52cca73615df79976171b2 (diff) | |
download | gcc-9421ebb9b381242a1fa9d4b435babe0910a58118.tar.gz |
* c-common.h (enum rid): Add new enumeration values of RID_SAT,
RID_FRACT, and RID_ACCUM. RID_SAT needs to be inserted before
RID_ONEWAY, so that it can be checked in declspecs_add_type.
(c_common_fixed_point_type_for_size): Declare.
* c-parser.c (reswords): Add _Fract, _Accum, and _Sat.
(c_token_starts_typename): Handle RID_FRACT, RID_ACCUM, and RID_SAT.
(c_token_starts_declspecs): Likewise.
(c_parser_declspecs): Likewise.
(c_parser_attributes): Likewise.
* c-tree.h (enum c_typespec_keyword): Add cts_fract and cts_accum.
(c_declspecs): Add saturating_p.
* c-decl.c (build_null_declspecs): Initialize saturating_p.
(declspecs_add_type): Avoid using complex with _Fract, _Accum, or _Sat.
Handle RID_SAT.
Avoid using void, bool, char, int, float, double, _Decimal32,
_Decimal64, _Decimal128, and complex with _Sat.
Handle RID_FRACT and RID_ACCUM.
Make sure _Sat is used with _Fract or _Accum.
(finish_declspecs): Handle cts_fract and cts_accum.
* c-common.c (fixed-value.h): New include.
(constant_expression_warning): Handle FIXED_CST.
(overflow_warning): Likewise.
(warnings_for_convert_and_check): Likewise.
(c_common_fixed_point_type_for_size): New.
(c_common_type_for_mode): Handle fixed-point modes to
return various saturating/non-saturating, signed/unsigned types.
(c_common_signed_or_unsigned_type): Support fixed-point types.
(shorten_compare): Check fixed-point zero.
Handle FIXED_POINT_TYPE.
(c_common_truthvalue_conversion): Handle FIXED_CST.
Handle FIXED_POINT_TYPE.
(c_common_nodes_and_builtins): Record builtin types for fixed-point
types.
(handle_mode_attribute): Handle fixed-point modes. Need to check
if the signness of base type and fixed-point modes are consistent.
(handle_vector_size_attribute): Handle fixed-point modes.
(same_scalar_type_ignoring_signedness): Handle FIXED_POINT_TYPE.
(warn_for_div_by_zero): Check fixed-point zero.
* c-typeck.c (c_common_type): Check FIXED_POINT_TYPE. Build
a common fixed-point type based on fbit, ibit, sign, and saturation.
(build_unary_op): Allow FIXED_POINT_TYPE for CONVERT_EXPR,
NEGATE_EXPR, TRUTH_NOT_EXPR, PREINCREMENT_EXPR, POSTINCREMENT_EXPR,
PREDECREMENT_EXPR, and POSTDECREMENT_EXPR.
(convert_for_assignment): Support FIXED_POINT_TYPE.
(digest_init): Handle FIXED_POINT_TYPE.
(build_binary_op): Support FIXED_POINT_TYPE in *_DIV_EXPR,
TRUTH_ANDIF_EXPR, TRUTH_ORIF_EXPR, TRUTH_AND_EXPR, TRUTH_OR_EXPR,
TRUTH_XOR_EXPR, RSHIFT_EXPR, LSHIFT_EXPR, EQ_EXPR, NE_EXPR, LE_EXPR,
GE_EXPR, LT_EXPR, GT_EXPR.
* target-def.h (TARGET_FIXED_POINT_SUPPORTED_P): New.
(TARGET_INITIALIZER): Add TARGET_FIXED_POINT_SUPPORTED_P.
* target.h (gcc_target): Add fixed_point_supported_p.
* targhooks.c (default_scalar_mode_supported_p): Handle MODE_FRACT,
MODE_UFRACT, MODE_ACCUM, and MODE_UACCUM.
(default_fixed_point_supported_p): Define.
* targhooks.h (default_fixed_point_supported_p): Declare.
* doc/tm.texi (TARGET_FIXED_POINT_SUPPORTED_P): Add.
* doc/install.texi (Configuration): Add --enable-fixed-point.
* configure.ac (--enable-fixed-point): New to enable fixed-point
arithmetic extension to C. For mips targets, we enable it by default.
* configure, config.in: Regenerate.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@127652 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 181 |
1 files changed, 178 insertions, 3 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ce93ac5799c..d6eb39aa45c 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -7134,6 +7134,7 @@ build_null_declspecs (void) ret->const_p = false; ret->volatile_p = false; ret->restrict_p = false; + ret->saturating_p = false; return ret; } @@ -7196,7 +7197,7 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) } if ((int) i <= (int) RID_LAST_MODIFIER) { - /* "long", "short", "signed", "unsigned" or "_Complex". */ + /* "long", "short", "signed", "unsigned", "_Complex" or "_Sat". */ bool dupe = false; switch (i) { @@ -7356,9 +7357,55 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->typespec_word == cts_dfloat128) error ("both %<complex%> and %<_Decimal128%> in " "declaration specifiers"); + else if (specs->typespec_word == cts_fract) + error ("both %<complex%> and %<_Fract%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_accum) + error ("both %<complex%> and %<_Accum%> in " + "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<complex%> and %<_Sat%> in " + "declaration specifiers"); else specs->complex_p = true; break; + case RID_SAT: + dupe = specs->saturating_p; + if (pedantic) + pedwarn ("ISO C does not support saturating types"); + if (specs->typespec_word == cts_void) + error ("both %<_Sat%> and %<void%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_bool) + error ("both %<_Sat%> and %<_Bool%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_char) + error ("both %<_Sat%> and %<char%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_int) + error ("both %<_Sat%> and %<int%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_float) + error ("both %<_Sat%> and %<float%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_double) + error ("both %<_Sat%> and %<double%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat32) + error ("both %<_Sat%> and %<_Decimal32%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat64) + error ("both %<_Sat%> and %<_Decimal64%> in " + "declaration specifiers"); + else if (specs->typespec_word == cts_dfloat128) + error ("both %<_Sat%> and %<_Decimal128%> in " + "declaration specifiers"); + else if (specs->complex_p) + error ("both %<_Sat%> and %<complex%> in " + "declaration specifiers"); + else + specs->saturating_p = true; + break; default: gcc_unreachable (); } @@ -7370,7 +7417,8 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) } else { - /* "void", "_Bool", "char", "int", "float" or "double". */ + /* "void", "_Bool", "char", "int", "float", "double", "_Decimal32", + "_Decimal64", "_Decimal128", "_Fract" or "_Accum". */ if (specs->typespec_word != cts_none) { error ("two or more data types in declaration specifiers"); @@ -7394,6 +7442,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->complex_p) error ("both %<complex%> and %<void%> in " "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<void%> in " + "declaration specifiers"); else specs->typespec_word = cts_void; return specs; @@ -7413,6 +7464,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->complex_p) error ("both %<complex%> and %<_Bool%> in " "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<_Bool%> in " + "declaration specifiers"); else specs->typespec_word = cts_bool; return specs; @@ -7423,11 +7477,18 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->short_p) error ("both %<short%> and %<char%> in " "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<char%> in " + "declaration specifiers"); else specs->typespec_word = cts_char; return specs; case RID_INT: - specs->typespec_word = cts_int; + if (specs->saturating_p) + error ("both %<_Sat%> and %<int%> in " + "declaration specifiers"); + else + specs->typespec_word = cts_int; return specs; case RID_FLOAT: if (specs->long_p) @@ -7442,6 +7503,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->unsigned_p) error ("both %<unsigned%> and %<float%> in " "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<float%> in " + "declaration specifiers"); else specs->typespec_word = cts_float; return specs; @@ -7458,6 +7522,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->unsigned_p) error ("both %<unsigned%> and %<double%> in " "declaration specifiers"); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<double%> in " + "declaration specifiers"); else specs->typespec_word = cts_double; return specs; @@ -7490,6 +7557,9 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) else if (specs->complex_p) error ("both %<complex%> and %<%s%> in " "declaration specifiers", str); + else if (specs->saturating_p) + error ("both %<_Sat%> and %<%s%> in " + "declaration specifiers", str); else if (i == RID_DFLOAT32) specs->typespec_word = cts_dfloat32; else if (i == RID_DFLOAT64) @@ -7502,6 +7572,27 @@ declspecs_add_type (struct c_declspecs *specs, struct c_typespec spec) if (pedantic) pedwarn ("ISO C does not support decimal floating point"); return specs; + case RID_FRACT: + case RID_ACCUM: + { + const char *str; + if (i == RID_FRACT) + str = "_Fract"; + else + str = "_Accum"; + if (specs->complex_p) + error ("both %<complex%> and %<%s%> in " + "declaration specifiers", str); + else if (i == RID_FRACT) + specs->typespec_word = cts_fract; + else + specs->typespec_word = cts_accum; + } + if (!targetm.fixed_point_supported_p ()) + error ("fixed-point types not supported for this target"); + if (pedantic) + pedwarn ("ISO C does not support fixed-point types"); + return specs; default: /* ObjC reserved word "id", handled below. */ break; @@ -7673,6 +7764,8 @@ finish_declspecs (struct c_declspecs *specs) "_Complex short" is equivalent to "_Complex short int". */ if (specs->typespec_word == cts_none) { + if (specs->saturating_p) + error ("%<_Sat%> is used without %<_Fract%> or %<_Accum%>"); if (specs->long_p || specs->short_p || specs->signed_p || specs->unsigned_p) { @@ -7792,6 +7885,88 @@ finish_declspecs (struct c_declspecs *specs) else specs->type = dfloat128_type_node; break; + case cts_fract: + gcc_assert (!specs->complex_p); + if (specs->saturating_p) + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_long_fract_type_node + : sat_long_long_fract_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_fract_type_node + : sat_long_fract_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? sat_unsigned_short_fract_type_node + : sat_short_fract_type_node; + else + specs->type = specs->unsigned_p + ? sat_unsigned_fract_type_node + : sat_fract_type_node; + } + else + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? unsigned_long_long_fract_type_node + : long_long_fract_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? unsigned_long_fract_type_node + : long_fract_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? unsigned_short_fract_type_node + : short_fract_type_node; + else + specs->type = specs->unsigned_p + ? unsigned_fract_type_node + : fract_type_node; + } + break; + case cts_accum: + gcc_assert (!specs->complex_p); + if (specs->saturating_p) + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_long_accum_type_node + : sat_long_long_accum_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? sat_unsigned_long_accum_type_node + : sat_long_accum_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? sat_unsigned_short_accum_type_node + : sat_short_accum_type_node; + else + specs->type = specs->unsigned_p + ? sat_unsigned_accum_type_node + : sat_accum_type_node; + } + else + { + if (specs->long_long_p) + specs->type = specs->unsigned_p + ? unsigned_long_long_accum_type_node + : long_long_accum_type_node; + else if (specs->long_p) + specs->type = specs->unsigned_p + ? unsigned_long_accum_type_node + : long_accum_type_node; + else if (specs->short_p) + specs->type = specs->unsigned_p + ? unsigned_short_accum_type_node + : short_accum_type_node; + else + specs->type = specs->unsigned_p + ? unsigned_accum_type_node + : accum_type_node; + } + break; default: gcc_unreachable (); } |