+/* Define __DECx__ constants for TYPE using NAME_PREFIX and SUFFIX. */
+static void
+builtin_define_decimal_float_constants (const char *name_prefix,
+ const char *suffix,
+ tree type)
+{
+ const struct real_format *fmt;
+ char name[64], buf[128], *p;
+ int digits;
+
+ fmt = REAL_MODE_FORMAT (TYPE_MODE (type));
+
+ /* The number of radix digits, p, in the significand. */
+ sprintf (name, "__%s_MANT_DIG__", name_prefix);
+ builtin_define_with_int_value (name, fmt->p);
+
+ /* The minimum negative int x such that b**(x-1) is a normalized float. */
+ sprintf (name, "__%s_MIN_EXP__", name_prefix);
+ sprintf (buf, "(%d)", fmt->emin);
+ builtin_define_with_value (name, buf, 0);
+
+ /* The maximum int x such that b**(x-1) is a representable float. */
+ sprintf (name, "__%s_MAX_EXP__", name_prefix);
+ builtin_define_with_int_value (name, fmt->emax);
+
+ /* Compute the minimum representable value. */
+ sprintf (name, "__%s_MIN__", name_prefix);
+ sprintf (buf, "1E%d%s", fmt->emin - 1, suffix);
+ builtin_define_with_value (name, buf, 0);
+
+ /* Compute the maximum representable value. */
+ sprintf (name, "__%s_MAX__", name_prefix);
+ p = buf;
+ for (digits = fmt->p; digits; digits--)
+ {
+ *p++ = '9';
+ if (digits == fmt->p)
+ *p++ = '.';
+ }
+ *p = 0;
+ /* fmt->p plus 1, to account for the decimal point and fmt->emax
+ minus 1 because the digits are nines, not 1.0. */
+ sprintf (&buf[fmt->p + 1], "E%d%s", fmt->emax - 1, suffix);
+ builtin_define_with_value (name, buf, 0);
+
+ /* Compute epsilon (the difference between 1 and least value greater
+ than 1 representable). */
+ sprintf (name, "__%s_EPSILON__", name_prefix);
+ sprintf (buf, "1E-%d%s", fmt->p - 1, suffix);
+ builtin_define_with_value (name, buf, 0);
+
+ /* Minimum subnormal positive decimal value. */
+ sprintf (name, "__%s_SUBNORMAL_MIN__", name_prefix);
+ p = buf;
+ for (digits = fmt->p; digits > 1; digits--)
+ {
+ *p++ = '0';
+ if (digits == fmt->p)
+ *p++ = '.';
+ }
+ *p = 0;
+ sprintf (&buf[fmt->p], "1E%d%s", fmt->emin - 1, suffix);
+ 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);
+}
+