diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 499acfe8317..35f68c1d945 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2007-07-03 Uros Bizjak + + * targhooks.h (default_mode_for_suffix): New function declaration. + * targhooks.c (default_mode_for_suffix): New default target hook. + * target.h (struct c): New structure in the targetm struct. + (mode_for_suffix): New target hook as part of struct c. + target-def.h (TARGET_C_MODE_FOR_SUFFIX): Define as + default_mode_for_suffix. + (TARGET_C): New define. + * c-lex.c: Include "target.h". + (interpret_float): Use targetm.c.mode_for_suffix to determine + the mode for a given non-standard suffix. + Makefile.in (c-lex.o): Depend on $(TARGET_H). + + * config/i386/i386.c (ix86_c_mode_for_suffix): New static function. + (TARGET_C_MODE_FOR_SUFFIX): Define to ix86_c_mode_for_suffix. + + * doc/extend.texi (Floating Types): New node. Document __float80 and + __float128 types. Document 'w', 'W', 'q' and 'Q' suffixes. + 2007-07-03 Kaz Kojima PR target/32506 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 61c51856b12..c084f0a838b 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1718,7 +1718,7 @@ stub-objc.o : stub-objc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ c-lex.o : c-lex.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(RTL_H) debug.h $(C_TREE_H) $(C_COMMON_H) $(REAL_H) $(SPLAY_TREE_H) \ $(C_PRAGMA_H) input.h intl.h $(FLAGS_H) toplev.h output.h \ - $(CPPLIB_H) $(TIMEVAR_H) $(TM_P_H) + $(CPPLIB_H) $(TARGET_H) $(TIMEVAR_H) $(TM_P_H) c-ppoutput.o : c-ppoutput.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(C_COMMON_H) $(TREE_H) $(CPPLIB_H) $(srcdir)/../libcpp/internal.h \ $(C_PRAGMA_H) diff --git a/gcc/c-lex.c b/gcc/c-lex.c index a89643c6046..ff8eee6baec 100644 --- a/gcc/c-lex.c +++ b/gcc/c-lex.c @@ -41,6 +41,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "tm_p.h" #include "splay-tree.h" #include "debug.h" +#include "target.h" /* We may keep statistics about how long which files took to compile. */ static int header_time, body_time; @@ -649,7 +650,31 @@ interpret_float (const cpp_token *token, unsigned int flags) else type = dfloat64_type_node; else - if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) + if (flags & CPP_N_WIDTH_MD) + { + char suffix; + enum machine_mode mode; + + if ((flags & CPP_N_WIDTH_MD) == CPP_N_MD_W) + suffix = 'w'; + else + suffix = 'q'; + + mode = targetm.c.mode_for_suffix (suffix); + if (mode == VOIDmode) + { + error ("unsupported non-standard suffix on floating constant"); + errorcount++; + + return error_mark_node; + } + else if (pedantic) + pedwarn ("non-standard suffix on floating constant"); + + type = c_common_type_for_mode (mode, 0); + gcc_assert (type); + } + else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE) type = long_double_type_node; else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL || flag_single_precision_constant) @@ -666,7 +691,7 @@ interpret_float (const cpp_token *token, unsigned int flags) else { if ((flags & CPP_N_WIDTH) != CPP_N_MEDIUM) - /* Must be an F or L suffix. */ + /* Must be an F or L or machine defined suffix. */ copylen--; if (flags & CPP_N_IMAGINARY) /* I or J suffix. */ diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 96c948f6dea..341bf90bf9e 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -22423,6 +22423,18 @@ ix86_vector_mode_supported_p (enum machine_mode mode) return false; } +/* Target hook for c_mode_for_suffix. */ +static enum machine_mode +ix86_c_mode_for_suffix (char suffix) +{ + if (TARGET_64BIT && suffix == 'q') + return TFmode; + if (TARGET_MMX && suffix == 'w') + return XFmode; + + return VOIDmode; +} + /* Worker function for TARGET_MD_ASM_CLOBBERS. We do this in the new i386 backend to maintain source compatibility @@ -23520,6 +23532,9 @@ static const struct attribute_spec ix86_attribute_table[] = #undef TARGET_VECTOR_MODE_SUPPORTED_P #define TARGET_VECTOR_MODE_SUPPORTED_P ix86_vector_mode_supported_p +#undef TARGET_C_MODE_FOR_SUFFIX +#define TARGET_C_MODE_FOR_SUFFIX ix86_c_mode_for_suffix + #ifdef HAVE_AS_TLS #undef TARGET_ASM_OUTPUT_DWARF_DTPREL #define TARGET_ASM_OUTPUT_DWARF_DTPREL i386_output_dwarf_dtprel diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 76cc546fac6..0a1cdeb2abf 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -33,6 +33,7 @@ extensions, accepted by GCC in C89 mode and in C++. * Conditionals:: Omitting the middle operand of a @samp{?:} expression. * Long Long:: Double-word integers---@code{long long int}. * Complex:: Data types for complex numbers. +* Floating Types:: Additional Floating Types. * Decimal Float:: Decimal Floating Types. * Hex Floats:: Hexadecimal floating-point constants. * Zero Length:: Zero-length arrays. @@ -816,6 +817,37 @@ If the variable's actual name is @code{foo}, the two fictitious variables are named @code{foo$real} and @code{foo$imag}. You can examine and set these two fictitious variables with your debugger. +@node Floating Types +@section Additional Floating Types +@cindex additional floating types +@cindex @code{__float80} data type +@cindex @code{__float128} data type +@cindex @code{w} floating point suffix +@cindex @code{q} floating point suffix +@cindex @code{W} floating point suffix +@cindex @code{Q} floating point suffix + +As an extension, the GNU C compiler supports additional floating +types, @code{__float80} and @code{__float128} to support 80bit +(@code{XFmode}) and 128 bit (@code{TFmode}) floating types. +Support for additional types includes the arithmetic operators: +add, subtract, multiply, divide; unary arithmetic operators; +relational operators; equality operators; and conversions to and from +integer and other floating types. Use a suffix @samp{w} or @samp{W} +in a literal constant of type @code{__float80} and @samp{q} or @samp{Q} +for @code{_float128}. You can declare complex types using the +corresponding internal complex type, @code{XCmode} for @code{__float80} +type and @code{TCmode} for @code{__float128} type: + +@smallexample +typedef _Complex float __attribute__((mode(TC))) _Complex128; +typedef _Complex float __attribute__((mode(XC))) _Complex80; +@end smallexample + +Not all targets support additional floating point types. @code{__float80} +is supported on i386, x86_64 and ia64 targets and target @code{__float128} +is supported on x86_64 and ia64 targets. + @node Decimal Float @section Decimal Floating Types @cindex decimal floating types diff --git a/gcc/target-def.h b/gcc/target-def.h index bc07f628778..c106577c7fb 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -578,6 +578,15 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define TARGET_SECONDARY_RELOAD default_secondary_reload #endif +/* C specific. */ +#ifndef TARGET_C_MODE_FOR_SUFFIX +#define TARGET_C_MODE_FOR_SUFFIX default_mode_for_suffix +#endif + +#define TARGET_C \ + { \ + TARGET_C_MODE_FOR_SUFFIX \ + } /* C++ specific. */ #ifndef TARGET_CXX_GUARD_TYPE @@ -729,8 +738,9 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. TARGET_INVALID_UNARY_OP, \ TARGET_INVALID_BINARY_OP, \ TARGET_SECONDARY_RELOAD, \ + TARGET_C, \ TARGET_CXX, \ - TARGET_EXTRA_LIVE_ON_ENTRY, \ + TARGET_EXTRA_LIVE_ON_ENTRY, \ TARGET_UNWIND_TABLES_DEFAULT, \ TARGET_HAVE_NAMED_SECTIONS, \ TARGET_HAVE_SWITCHABLE_BSS_SECTIONS, \ diff --git a/gcc/target.h b/gcc/target.h index 7e144dec19a..effd93345dd 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -798,6 +798,13 @@ struct gcc_target enum machine_mode, struct secondary_reload_info *); + /* Functions specific to the C family of frontends. */ + struct c { + /* Return machine mode for non-standard suffix + or VOIDmode if non-standard suffixes are unsupported. */ + enum machine_mode (*mode_for_suffix) (char); + } c; + /* Functions specific to the C++ frontend. */ struct cxx { /* Return the integer type used for guard variables. */ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 862cd6f31b8..cc375890fc5 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -173,6 +173,13 @@ hook_bool_CUMULATIVE_ARGS_true (CUMULATIVE_ARGS * a ATTRIBUTE_UNUSED) return true; } +/* Return machine mode for non-standard suffix + or VOIDmode if non-standard suffixes are unsupported. */ +enum machine_mode +default_mode_for_suffix (char suffix ATTRIBUTE_UNUSED) +{ + return VOIDmode; +} /* The generic C++ ABI specifies this is a 64-bit value. */ tree diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 412bf5de804..c69be80f3d2 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -40,6 +40,8 @@ extern tree default_stack_protect_guard (void); extern tree default_external_stack_protect_fail (void); extern tree default_hidden_stack_protect_fail (void); +extern enum machine_mode default_mode_for_suffix (char); + extern tree default_cxx_guard_type (void); extern tree default_cxx_get_cookie_size (tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b536803481..9b068650cfa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2007-07-03 Uros Bizjak + + * gcc.dg/const-float80.c : New test. + * gcc.dg/const-float128.c : New test. + * gcc.dg/const-float80-ped.c : New test. + * gcc.dg/const-float128-ped.c : New test. + 2007-07-02 Kaveh R. Ghazi * gcc.dg/c99-math.h: Fix typo. diff --git a/gcc/testsuite/gcc.dg/const-float128-ped.c b/gcc/testsuite/gcc.dg/const-float128-ped.c new file mode 100644 index 00000000000..52f0525dcd3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/const-float128-ped.c @@ -0,0 +1,5 @@ +/* Test 'q' suffix with -pedantic on __float128 type constants. */ +/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */ +/* { dg-options "-pedantic" } */ + +__float128 a = 123.456789q; /* { dg-warning "non-standard suffix on floating constant" } */ diff --git a/gcc/testsuite/gcc.dg/const-float128.c b/gcc/testsuite/gcc.dg/const-float128.c new file mode 100644 index 00000000000..1797e08bc30 --- /dev/null +++ b/gcc/testsuite/gcc.dg/const-float128.c @@ -0,0 +1,6 @@ +/* Test 'q' and 'Q' suffixes on __float128 type constants. */ +/* { dg-do compile { target { ia64-*-* || { { i?86-*-* x86_64-*-*} && lp64 } } } } */ +/* { dg-options "" } */ + +__float128 a = 123.456789q; +__float128 b = 123.456789Q; diff --git a/gcc/testsuite/gcc.dg/const-float80-ped.c b/gcc/testsuite/gcc.dg/const-float80-ped.c new file mode 100644 index 00000000000..9cf047804a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/const-float80-ped.c @@ -0,0 +1,6 @@ +/* Test 'w' suffix with -pedantic on __float80 type constants. */ +/* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-options "-pedantic" } */ +/* { dg-options "-mmmx -pedantic" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +__float80 a = 123.456789w; /* { dg-warning "non-standard suffix on floating constant" } */ diff --git a/gcc/testsuite/gcc.dg/const-float80.c b/gcc/testsuite/gcc.dg/const-float80.c new file mode 100644 index 00000000000..f2a836d3e64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/const-float80.c @@ -0,0 +1,7 @@ +/* Test 'w' and 'W' suffixes on __float80 type constants. */ +/* { dg-do compile { target i?86-*-* x86_64-*-* ia64-*-* } } */ +/* { dg-options "" } */ +/* { dg-options "-mmmx" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ + +__float80 a = 123.456789W; +__float80 b = 123.456789w; diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 70a9f608a10..0c11a0fb581 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,11 @@ +2007-07-03 Uros Bizjak + + * include/cpplib.h (CPP_N_WIDTH_MD, CPP_N_MD_W, CPP_N_MD_Q): + Add new constants. + * expr.c (interpret_float_suffix): Process 'w', 'W', 'q' and 'Q' + suffixes. Return CPP_N_MD_W for 'w' or 'W' suffixes and CPP_N_MD_Q + for 'q' or 'Q' suffixes. + 2007-06-17 Danny Smith 0) + return 0; + w++; + break; + case 'q': case 'Q': + if (d > 0) + return 0; + q++; + break; case 'i': case 'I': case 'j': case 'J': i++; break; case 'd': case 'D': d++; break; @@ -104,7 +116,7 @@ interpret_float_suffix (const uchar *s, size_t len) return 0; } - if (f + l > 1 || i > 1) + if (f + l + w + q > 1 || i > 1) return 0; /* Allow dd, df, dl suffixes for decimal float constants. */ @@ -113,7 +125,9 @@ interpret_float_suffix (const uchar *s, size_t len) return ((i ? CPP_N_IMAGINARY : 0) | (f ? CPP_N_SMALL : - l ? CPP_N_LARGE : CPP_N_MEDIUM) + l ? CPP_N_LARGE : + w ? CPP_N_MD_W : + q ? CPP_N_MD_Q : CPP_N_MEDIUM) | (d ? CPP_N_DFLOAT : 0)); } diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 0edcf655c92..ee46c4f169f 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -744,6 +744,10 @@ struct cpp_num #define CPP_N_MEDIUM 0x0020 /* long, double. */ #define CPP_N_LARGE 0x0040 /* long long, long double. */ +#define CPP_N_WIDTH_MD 0xF0000 /* machine defined. */ +#define CPP_N_MD_W 0x10000 +#define CPP_N_MD_Q 0x20000 + #define CPP_N_RADIX 0x0F00 #define CPP_N_DECIMAL 0x0100 #define CPP_N_HEX 0x0200