X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fgenmodes.c;h=3851aff11e442c25393ed16dada5af088675ae7f;hp=142dde4e7378a016906607896958e17f0ebcf9e0;hb=869bde6b9946186a3d4b71cb3d48090e16723f57;hpb=67ce556b47830dd825524e8370969b814c355216 diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 142dde4e737..3851aff11e4 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -1,12 +1,12 @@ /* Generate the machine mode enumeration and associated tables. - Copyright (C) 2003, 2004 + Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later +Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -15,9 +15,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to the Free -Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "bconfig.h" #include "system.h" @@ -60,7 +59,7 @@ struct mode_data unsigned int bytesize; /* storage size in addressable units */ unsigned int ncomponents; /* number of subunits */ unsigned int alignment; /* mode alignment */ - const char *format; /* floating point format - MODE_FLOAT only */ + const char *format; /* floating point format - float modes only */ struct mode_data *component; /* mode of components */ struct mode_data *wider; /* next wider mode */ @@ -72,6 +71,9 @@ struct mode_data const char *file; /* file and line of definition, */ unsigned int line; /* for error reporting */ + unsigned int counter; /* Rank ordering of modes */ + unsigned int ibit; /* the number of integral bits */ + unsigned int fbit; /* the number of fractional bits */ }; static struct mode_data *modes[MAX_MODE_CLASS]; @@ -82,7 +84,7 @@ static const struct mode_data blank_mode = { 0, "", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, 0, - "", 0 + "", 0, 0, 0, 0 }; static htab_t modes_by_name; @@ -103,6 +105,8 @@ struct mode_adjust static struct mode_adjust *adj_bytesize; static struct mode_adjust *adj_alignment; static struct mode_adjust *adj_format; +static struct mode_adjust *adj_ibit; +static struct mode_adjust *adj_fbit; /* Mode class operations. */ static enum mode_class @@ -125,6 +129,10 @@ vector_class (enum mode_class cl) { case MODE_INT: return MODE_VECTOR_INT; case MODE_FLOAT: return MODE_VECTOR_FLOAT; + case MODE_FRACT: return MODE_VECTOR_FRACT; + case MODE_UFRACT: return MODE_VECTOR_UFRACT; + case MODE_ACCUM: return MODE_VECTOR_ACCUM; + case MODE_UACCUM: return MODE_VECTOR_UACCUM; default: error ("no vector class for class %s", mode_class_names[cl]); return MODE_RANDOM; @@ -146,6 +154,7 @@ new_mode (enum mode_class cl, const char *name, const char *file, unsigned int line) { struct mode_data *m; + static unsigned int count = 0; m = find_mode (name); if (m) @@ -163,6 +172,7 @@ new_mode (enum mode_class cl, const char *name, if (file) m->file = trim_filename (file); m->line = line; + m->counter = count++; m->next = modes[cl]; modes[cl] = m; @@ -197,7 +207,8 @@ static void ATTRIBUTE_UNUSED new_adjust (const char *name, struct mode_adjust **category, const char *catname, const char *adjustment, - enum mode_class required_class, + enum mode_class required_class_from, + enum mode_class required_class_to, const char *file, unsigned int line) { struct mode_data *mode = find_mode (name); @@ -211,10 +222,12 @@ new_adjust (const char *name, return; } - if (required_class != MODE_RANDOM && mode->cl != required_class) + if (required_class_from != MODE_RANDOM + && (mode->cl < required_class_from || mode->cl > required_class_to)) { - error ("%s:%d: mode \"%s\" is not class %s", - file, line, name, mode_class_names[required_class] + 5); + error ("%s:%d: mode \"%s\" is not among class {%s, %s}", + file, line, name, mode_class_names[required_class_from] + 5, + mode_class_names[required_class_to] + 5); return; } @@ -323,11 +336,17 @@ complete_mode (struct mode_data *m) case MODE_INT: case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: /* A scalar mode must have a byte size, may have a bit size, and must not have components. A float mode must have a format. */ validate_mode (m, OPTIONAL, SET, UNSET, UNSET, - m->cl == MODE_FLOAT ? SET : UNSET); + (m->cl == MODE_FLOAT || m->cl == MODE_DECIMAL_FLOAT) + ? SET : UNSET); m->ncomponents = 1; m->component = 0; @@ -357,6 +376,10 @@ complete_mode (struct mode_data *m) case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: /* Vector modes should have a component and a number of components. */ validate_mode (m, UNSET, UNSET, SET, SET, UNSET); if (m->component->precision != (unsigned int)-1) @@ -429,17 +452,22 @@ make_complex_modes (enum mode_class cl, This inconsistency should be eliminated. */ if (cl == MODE_FLOAT) { - char *p; + char *p, *q = 0; strncpy (buf, m->name, sizeof buf); p = strchr (buf, 'F'); if (p == 0) + q = strchr (buf, 'D'); + if (p == 0 && q == 0) { - error ("%s:%d: float mode \"%s\" has no 'F'", + error ("%s:%d: float mode \"%s\" has no 'F' or 'D'", m->file, m->line, m->name); continue; } - *p = 'C'; + if (p != 0) + *p = 'C'; + else + snprintf (buf, sizeof buf, "C%s", m->name); } else snprintf (buf, sizeof buf, "C%s", m->name); @@ -524,6 +552,35 @@ make_int_mode (const char *name, m->precision = precision; } +#define FRACT_MODE(N, Y, F) \ + make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__) + +#define UFRACT_MODE(N, Y, F) \ + make_fixed_point_mode (MODE_UFRACT, #N, Y, 0, F, __FILE__, __LINE__) + +#define ACCUM_MODE(N, Y, I, F) \ + make_fixed_point_mode (MODE_ACCUM, #N, Y, I, F, __FILE__, __LINE__) + +#define UACCUM_MODE(N, Y, I, F) \ + make_fixed_point_mode (MODE_UACCUM, #N, Y, I, F, __FILE__, __LINE__) + +/* Create a fixed-point mode by setting CL, NAME, BYTESIZE, IBIT, FBIT, + FILE, and LINE. */ + +static void +make_fixed_point_mode (enum mode_class cl, + const char *name, + unsigned int bytesize, + unsigned int ibit, + unsigned int fbit, + const char *file, unsigned int line) +{ + struct mode_data *m = new_mode (cl, name, file, line); + m->bytesize = bytesize; + m->ibit = ibit; + m->fbit = fbit; +} + #define FLOAT_MODE(N, Y, F) FRACTIONAL_FLOAT_MODE (N, -1U, Y, F) #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \ make_float_mode (#N, B, Y, #F, __FILE__, __LINE__) @@ -540,6 +597,23 @@ make_float_mode (const char *name, m->format = format; } +#define DECIMAL_FLOAT_MODE(N, Y, F) \ + FRACTIONAL_DECIMAL_FLOAT_MODE (N, -1U, Y, F) +#define FRACTIONAL_DECIMAL_FLOAT_MODE(N, B, Y, F) \ + make_decimal_float_mode (#N, B, Y, #F, __FILE__, __LINE__) + +static void +make_decimal_float_mode (const char *name, + unsigned int precision, unsigned int bytesize, + const char *format, + const char *file, unsigned int line) +{ + struct mode_data *m = new_mode (MODE_DECIMAL_FLOAT, name, file, line); + m->bytesize = bytesize; + m->precision = precision; + m->format = format; +} + #define RESET_FLOAT_FORMAT(N, F) \ reset_float_format (#N, #F, __FILE__, __LINE__) static void ATTRIBUTE_UNUSED @@ -552,9 +626,9 @@ reset_float_format (const char *name, const char *format, error ("%s:%d: no mode \"%s\"", file, line, name); return; } - if (m->cl != MODE_FLOAT) + if (m->cl != MODE_FLOAT && m->cl != MODE_DECIMAL_FLOAT) { - error ("%s:%d: mode \"%s\" is not class FLOAT", file, line, name); + error ("%s:%d: mode \"%s\" is not a FLOAT class", file, line, name); return; } m->format = format; @@ -609,7 +683,9 @@ make_vector_mode (enum mode_class bclass, error ("%s:%d: no mode \"%s\"", file, line, base); return; } - if (component->cl != bclass) + if (component->cl != bclass + && (component->cl != MODE_PARTIAL_INT + || bclass != MODE_INT)) { error ("%s:%d: mode \"%s\" is not class %s", file, line, base, mode_class_names[bclass] + 5); @@ -630,12 +706,14 @@ make_vector_mode (enum mode_class bclass, } /* Adjustability. */ -#define _ADD_ADJUST(A, M, X, C) \ - new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __FILE__, __LINE__) +#define _ADD_ADJUST(A, M, X, C1, C2) \ + new_adjust (#M, &adj_##A, #A, #X, MODE_##C1, MODE_##C2, __FILE__, __LINE__) -#define ADJUST_BYTESIZE(M, X) _ADD_ADJUST(bytesize, M, X, RANDOM) -#define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM) -#define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST(format, M, X, FLOAT) +#define ADJUST_BYTESIZE(M, X) _ADD_ADJUST(bytesize, M, X, RANDOM, RANDOM) +#define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM, RANDOM) +#define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST(format, M, X, FLOAT, FLOAT) +#define ADJUST_IBIT(M, X) _ADD_ADJUST(ibit, M, X, ACCUM, UACCUM) +#define ADJUST_FBIT(M, X) _ADD_ADJUST(fbit, M, X, FRACT, UACCUM) static void create_modes (void) @@ -661,8 +739,8 @@ create_modes (void) static int cmp_modes (const void *a, const void *b) { - struct mode_data *m = *(struct mode_data **)a; - struct mode_data *n = *(struct mode_data **)b; + const struct mode_data *const m = *(const struct mode_data *const*)a; + const struct mode_data *const n = *(const struct mode_data *const*)b; if (m->bytesize > n->bytesize) return 1; @@ -675,7 +753,12 @@ cmp_modes (const void *a, const void *b) return -1; if (!m->component && !n->component) - return 0; + { + if (m->counter < n->counter) + return -1; + else + return 1; + } if (m->component->bytesize > n->component->bytesize) return 1; @@ -687,7 +770,10 @@ cmp_modes (const void *a, const void *b) else if (m->component->precision < n->component->precision) return -1; - return 0; + if (m->counter < n->counter) + return -1; + else + return 1; } static void @@ -750,8 +836,7 @@ calc_wider_mode (void) /* Output routines. */ #define tagged_printf(FMT, ARG, TAG) do { \ - int count_; \ - printf (" " FMT ",%n", ARG, &count_); \ + int count_ = printf (" " FMT ",", ARG); \ printf ("%*s/* %s */\n", 27 - count_, "", TAG); \ } while (0) @@ -785,8 +870,7 @@ enum machine_mode\n{"); for (c = 0; c < MAX_MODE_CLASS; c++) for (m = modes[c]; m; m = m->next) { - int count_; - printf (" %smode,%n", m->name, &count_); + int count_ = printf (" %smode,", m->name); printf ("%*s/* %s:%d */\n", 27 - count_, "", trim_filename (m->file), m->line); } @@ -827,6 +911,8 @@ enum machine_mode\n{"); #if 0 /* disabled for backward compatibility, temporary */ printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const"); #endif + printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const"); + printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const"); puts ("\ \n\ #endif /* insn-modes.h */"); @@ -1083,15 +1169,24 @@ emit_real_format_for_mode (void) format); #else print_decl ("struct real_format *\n", "real_format_for_mode", - "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1"); + "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1 " + "+ MAX_MODE_DECIMAL_FLOAT - MIN_MODE_DECIMAL_FLOAT + 1"); #endif + /* The beginning of the table is entries for float modes. */ for (m = modes[MODE_FLOAT]; m; m = m->next) if (!strcmp (m->format, "0")) tagged_printf ("%s", m->format, m->name); else tagged_printf ("&%s", m->format, m->name); + /* The end of the table is entries for decimal float modes. */ + for (m = modes[MODE_DECIMAL_FLOAT]; m; m = m->next) + if (!strcmp (m->format, "0")) + tagged_printf ("%s", m->format, m->name); + else + tagged_printf ("&%s", m->format, m->name); + print_closer (); } @@ -1130,6 +1225,10 @@ emit_mode_adjustments (void) case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: printf (" mode_size[%smode] = %d*s;\n", m->name, m->ncomponents); printf (" mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n", @@ -1164,6 +1263,10 @@ emit_mode_adjustments (void) case MODE_VECTOR_INT: case MODE_VECTOR_FLOAT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: printf (" mode_base_align[%smode] = %d*s;\n", m->name, m->ncomponents); break; @@ -1176,6 +1279,22 @@ emit_mode_adjustments (void) } } } + + /* Ibit adjustments don't have to propagate. */ + for (a = adj_ibit; a; a = a->next) + { + printf ("\n /* %s:%d */\n s = %s;\n", + a->file, a->line, a->adjustment); + printf (" mode_ibit[%smode] = s;\n", a->mode->name); + } + + /* Fbit adjustments don't have to propagate. */ + for (a = adj_fbit; a; a = a->next) + { + printf ("\n /* %s:%d */\n s = %s;\n", + a->file, a->line, a->adjustment); + printf (" mode_fbit[%smode] = s;\n", a->mode->name); + } /* Real mode formats don't have to propagate anywhere. */ for (a = adj_format; a; a = a->next) @@ -1185,6 +1304,43 @@ emit_mode_adjustments (void) puts ("}"); } +/* Emit ibit for all modes. */ + +static void +emit_mode_ibit (void) +{ + int c; + struct mode_data *m; + + print_maybe_const_decl ("%sunsigned char", + "mode_ibit", "NUM_MACHINE_MODES", + ibit); + + for_all_modes (c, m) + tagged_printf ("%u", m->ibit, m->name); + + print_closer (); +} + +/* Emit fbit for all modes. */ + +static void +emit_mode_fbit (void) +{ + int c; + struct mode_data *m; + + print_maybe_const_decl ("%sunsigned char", + "mode_fbit", "NUM_MACHINE_MODES", + fbit); + + for_all_modes (c, m) + tagged_printf ("%u", m->fbit, m->name); + + print_closer (); +} + + static void emit_insn_modes_c (void) { @@ -1201,6 +1357,8 @@ emit_insn_modes_c (void) emit_class_narrowest_mode (); emit_real_format_for_mode (); emit_mode_adjustments (); + emit_mode_ibit (); + emit_mode_fbit (); } static void @@ -1215,7 +1373,7 @@ emit_min_insn_modes_c (void) /* Master control. */ int -main(int argc, char **argv) +main (int argc, char **argv) { bool gen_header = false, gen_min = false; progname = argv[0];