diff options
author | Chao-ying Fu <fu@mips.com> | 2007-09-07 01:24:09 +0000 |
---|---|---|
committer | Chao-ying Fu <chaoyingfu@gcc.gnu.org> | 2007-09-07 01:24:09 +0000 |
commit | 0f996086cbf16283b2494ca36c7573abb5f06df7 (patch) | |
tree | efee8ca8b1b0b17d1b3afab3a5bc101a5bfb2b1d /gcc/c-cppbuiltin.c | |
parent | 58cfe6985ba4e4050a48ebc29dd7835260d5c58e (diff) | |
download | gcc-0f996086cbf16283b2494ca36c7573abb5f06df7.tar.gz |
stdfix.h: New file.
* ginclude/stdfix.h: New file.
* Makefile.in (USER_H): Add $(srcdir)/ginclude/stdfix.h.
(convert.o): Add dependence on fixed-value.h.
* c-convert.c (convert): Support FIXED_POINT_TYPE.
* c-cppbuiltin.c (builtin_define_fixed_point_constants): New function
to define fixed-point constants.
(c_cpp_builtins): Define fixed-point constants.
* convert.c (fixed-value.h): New include.
(convert_to_real): Update comment to include fixed-point.
Support FIXED_POINT_TYPE.
(convert_to_integer): Update comment to include fixed-point.
Support FIXED_POINT_TYPE.
(convert_to_complex): Support FIXED_POINT_TYPE.
(convert_to_fixed): New function.
* convert.h (convert_to_fixed): Declare.
* genopinit.c: Add comment about $Q for only fixed-point modes.
(optabs): Add fract_optab, fractuns_optab, satfract_optab,
satfractuns_optab, add_optab, ssadd_optab, usadd_optab, sub_optab,
sssub_optab, ussub_optab, smul_optab, ssmul_optab, usmul_optab,
ssmadd_widen_optab, usmadd_widen_optab, ssdiv_optab, udiv_optab,
usdiv_optab, ssashl_optab, usashl_optab, neg_optab, ssneg_optab,
usneg_optab for fixed-point modes.
(gen_insn): Add force_fixed to track the $Q format for all fixed-point
modes.
* optabs.c (optab_for_tree_code): For *DIV_EXPR, LSHIFT_EXPR,
PLUS_EXPR, MINUS_EXPR, MULT_EXPR, NEGATE_EXPR, return signed or
unsigned saturation optabs, when type is saturating.
(shift_optab_p): Return true for SS_ASHIFT or US_ASHIFT.
(expand_fixed_convert): New function.
(gen_fixed_libfunc, gen_signed_fixed_libfunc,
gen_unsigned_fixed_libfunc, gen_int_fp_fixed_libfunc,
gen_int_fp_signed_fixed_libfunc, gen_int_fixed_libfunc,
gen_int_signed_fixed_libfunc, gen_int_unsigned_fixed_libfunc,
gen_fract_conv_libfunc, gen_fractuns_conv_libfunc,
gen_satfract_conv_libfunc, gen_satfractuns_conv_libfunc): New
functions.
(init_optabs): Initialize ssadd_optab, usadd_optab, sssub_optab,
ussub_optab, ssmul_optab, usmul_optab, ssmadd_widen_optab,
usmadd_widen_optab, ssmsub_widen_optab, usmsub_widen_optab,
ssdiv_optab, usdiv_optab, ssashl_optab, usashl_optab, ssneg_optab,
usneg_optab, fract_optab, fractuns_optab, satfract_optab,
satfractuns_optab.
Initialize fixed-point libraries, including add, ssadd, usadd, sub,
sssub, ussub, mul, ssmul, usmul, div, ssdiv, udiv, usdiv, ashl,
ssashl, usashl, ashr, lshr, neg, ssneg, usneg, cmp, fract, satfract,
fractuns, satfractuns.
* optabs.h (enum optab_index): Add OTI_ssadd, OTI_usadd, OTI_sssub,
OTI_ussub, OTI_ssmul, OTI_usmul, OTI_ssdiv, OTI_usdiv, OTI_ssneg,
OTI_usneg, OTI_ssashl, OTI_usashl, OTI_ssmadd_widen, OTI_usmadd_widen,
OTI_ssmsub_widen, OTI_usmsub_widen.
(ssadd_optab, usadd_optab, sssub_optab, ussub_optab, ssmul_optab,
usmul_optab, ssdiv_optab, usdiv_optab, ssneg_optab, usneg_optab,
ssashl_optab, usashl_optab, ssmadd_widen_optab, usmadd_widen_optab,
umsub_widen_optab, usmsub_widen_optab): Define.
(enum convert_optab_index): Add COI_fract, COI_fractuns, COI_satfract,
COI_satfractuns.
(fract_optab, fractuns_optab, satfract_optab, satfractuns_optab):
Define.
(expand_fixed_convert): Declare.
* expr.c (convert_move): Support the move of fixed-point modes.
(emit_move_insn_1): Handle fixed-point mode to move via integer.
(categorize_ctor_elements_1): Handle FIXED_CST.
(count_type_elements): Handle FIXED_POINT_TYPE.
(expand_expr_real_1): For VECTOR_CST, check MODE_VECTOR_FRACT,
MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
Support FIXED_CST.
For PLUS_EXPR and MINUS_EXPR, support saturating and non-saturating
multiply and add/subtract for fixed-point types.
For MULT_EXPR, *DIV_EXPR, *SHIFT_EXPR, if the mode if a fixed-point
mode, we jump to binop directly.
Support FIXED_CONVERT_EXPR.
(do_store_flag): Check FIXED_CST to put a constant second.
(vector_mode_valid_p): Handle MODE_VECTOR_FRACT,
MODE_VECTOR_UFRACT, MODE_VECTOR_ACCUM, MODE_VECTOR_UACCUM.
(const_vector_from_tree): Support FIXED_CST.
* doc/extend.texi (Fixed-Point): New node.
* doc/md.texi (ssadd, usadd, sssub, ussub, ssmul, usmul, ssdiv, usdiv,
ssmadd, usmadd, ssmsub, usmsub, ssashl, usashl, ssneg, usneg, fract,
satfract, fractuns, satfractuns): Document them.
From-SVN: r128218
Diffstat (limited to 'gcc/c-cppbuiltin.c')
-rw-r--r-- | gcc/c-cppbuiltin.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/gcc/c-cppbuiltin.c b/gcc/c-cppbuiltin.c index efb40c31584..e201b058f5f 100644 --- a/gcc/c-cppbuiltin.c +++ b/gcc/c-cppbuiltin.c @@ -317,6 +317,60 @@ builtin_define_decimal_float_constants (const char *name_prefix, builtin_define_with_value (name, buf, 0); } +/* Define fixed-point constants for TYPE using NAME_PREFIX and SUFFIX. */ + +static void +builtin_define_fixed_point_constants (const char *name_prefix, + const char *suffix, + tree type) +{ + char name[64], buf[256], *new_buf; + int i, mod; + + sprintf (name, "__%s_FBIT__", name_prefix); + builtin_define_with_int_value (name, TYPE_FBIT (type)); + + sprintf (name, "__%s_IBIT__", name_prefix); + builtin_define_with_int_value (name, TYPE_IBIT (type)); + + /* If there is no suffix, defines are for fixed-point modes. + We just return. */ + if (strcmp (suffix, "") == 0) + return; + + if (TYPE_UNSIGNED (type)) + { + sprintf (name, "__%s_MIN__", name_prefix); + sprintf (buf, "0.0%s", suffix); + builtin_define_with_value (name, buf, 0); + } + else + { + sprintf (name, "__%s_MIN__", name_prefix); + if (ALL_ACCUM_MODE_P (TYPE_MODE (type))) + sprintf (buf, "(-0X1P%d%s-0X1P%d%s)", TYPE_IBIT (type) - 1, suffix, + TYPE_IBIT (type) - 1, suffix); + else + sprintf (buf, "(-0.5%s-0.5%s)", suffix, suffix); + builtin_define_with_value (name, buf, 0); + } + + sprintf (name, "__%s_MAX__", name_prefix); + sprintf (buf, "0X"); + new_buf = buf + 2; + mod = (TYPE_FBIT (type) + TYPE_IBIT (type)) % 4; + if (mod) + sprintf (new_buf++, "%x", (1 << mod) - 1); + for (i = 0; i < (TYPE_FBIT (type) + TYPE_IBIT (type)) / 4; i++) + sprintf (new_buf++, "F"); + sprintf (new_buf, "P-%d%s", TYPE_FBIT (type), suffix); + builtin_define_with_value (name, buf, 0); + + sprintf (name, "__%s_EPSILON__", name_prefix); + sprintf (buf, "0x1P-%d%s", TYPE_FBIT (type), suffix); + builtin_define_with_value (name, buf, 0); +} + /* Define __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__. */ static void define__GNUC__ (void) @@ -465,6 +519,62 @@ c_cpp_builtins (cpp_reader *pfile) builtin_define_decimal_float_constants ("DEC64", "DD", dfloat64_type_node); builtin_define_decimal_float_constants ("DEC128", "DL", dfloat128_type_node); + /* For fixed-point fibt, ibit, max, min, and epsilon. */ + if (targetm.fixed_point_supported_p ()) + { + builtin_define_fixed_point_constants ("SFRACT", "HR", + short_fract_type_node); + builtin_define_fixed_point_constants ("USFRACT", "UHR", + unsigned_short_fract_type_node); + builtin_define_fixed_point_constants ("FRACT", "R", + fract_type_node); + builtin_define_fixed_point_constants ("UFRACT", "UR", + unsigned_fract_type_node); + builtin_define_fixed_point_constants ("LFRACT", "LR", + long_fract_type_node); + builtin_define_fixed_point_constants ("ULFRACT", "ULR", + unsigned_long_fract_type_node); + builtin_define_fixed_point_constants ("LLFRACT", "LLR", + long_long_fract_type_node); + builtin_define_fixed_point_constants ("ULLFRACT", "ULLR", + unsigned_long_long_fract_type_node); + builtin_define_fixed_point_constants ("SACCUM", "HK", + short_accum_type_node); + builtin_define_fixed_point_constants ("USACCUM", "UHK", + unsigned_short_accum_type_node); + builtin_define_fixed_point_constants ("ACCUM", "K", + accum_type_node); + builtin_define_fixed_point_constants ("UACCUM", "UK", + unsigned_accum_type_node); + builtin_define_fixed_point_constants ("LACCUM", "LK", + long_accum_type_node); + builtin_define_fixed_point_constants ("ULACCUM", "ULK", + unsigned_long_accum_type_node); + builtin_define_fixed_point_constants ("LLACCUM", "LLK", + long_long_accum_type_node); + builtin_define_fixed_point_constants ("ULLACCUM", "ULLK", + unsigned_long_long_accum_type_node); + + builtin_define_fixed_point_constants ("QQ", "", qq_type_node); + builtin_define_fixed_point_constants ("HQ", "", hq_type_node); + builtin_define_fixed_point_constants ("SQ", "", sq_type_node); + builtin_define_fixed_point_constants ("DQ", "", dq_type_node); + builtin_define_fixed_point_constants ("TQ", "", tq_type_node); + builtin_define_fixed_point_constants ("UQQ", "", uqq_type_node); + builtin_define_fixed_point_constants ("UHQ", "", uhq_type_node); + builtin_define_fixed_point_constants ("USQ", "", usq_type_node); + builtin_define_fixed_point_constants ("UDQ", "", udq_type_node); + builtin_define_fixed_point_constants ("UTQ", "", utq_type_node); + builtin_define_fixed_point_constants ("HA", "", ha_type_node); + builtin_define_fixed_point_constants ("SA", "", sa_type_node); + builtin_define_fixed_point_constants ("DA", "", da_type_node); + builtin_define_fixed_point_constants ("TA", "", ta_type_node); + builtin_define_fixed_point_constants ("UHA", "", uha_type_node); + builtin_define_fixed_point_constants ("USA", "", usa_type_node); + builtin_define_fixed_point_constants ("UDA", "", uda_type_node); + builtin_define_fixed_point_constants ("UTA", "", uta_type_node); + } + /* For use in assembly language. */ builtin_define_with_value ("__REGISTER_PREFIX__", REGISTER_PREFIX, 0); builtin_define_with_value ("__USER_LABEL_PREFIX__", user_label_prefix, 0); |