00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "bconfig.h"
00023 #include "system.h"
00024 #include "errors.h"
00025 #include "hashtab.h"
00026
00027
00028
00029 #include "mode-classes.def"
00030
00031 #define DEF_MODE_CLASS(M) M
00032 enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
00033 #undef DEF_MODE_CLASS
00034
00035
00036 #define DEF_MODE_CLASS(M) #M
00037 static const char *const mode_class_names[MAX_MODE_CLASS] =
00038 {
00039 MODE_CLASSES
00040 };
00041 #undef DEF_MODE_CLASS
00042 #undef MODE_CLASSES
00043
00044 #ifdef EXTRA_MODES_FILE
00045 # define HAVE_EXTRA_MODES 1
00046 #else
00047 # define HAVE_EXTRA_MODES 0
00048 # define EXTRA_MODES_FILE ""
00049 #endif
00050
00051
00052
00053 struct mode_data
00054 {
00055 struct mode_data *next;
00056
00057 const char *name;
00058 enum mode_class cl;
00059 unsigned int precision;
00060 unsigned int bytesize;
00061 unsigned int ncomponents;
00062 unsigned int alignment;
00063 const char *format;
00064
00065 struct mode_data *component;
00066 struct mode_data *wider;
00067
00068 struct mode_data *contained;
00069
00070 struct mode_data *next_cont;
00071
00072 const char *file;
00073 unsigned int line;
00074 };
00075
00076 static struct mode_data *modes[MAX_MODE_CLASS];
00077 static unsigned int n_modes[MAX_MODE_CLASS];
00078 static struct mode_data *void_mode;
00079
00080 static const struct mode_data blank_mode = {
00081 0, "<unknown>", MAX_MODE_CLASS,
00082 -1U, -1U, -1U, -1U,
00083 0, 0, 0, 0, 0,
00084 "<unknown>", 0
00085 };
00086
00087 static htab_t modes_by_name;
00088
00089
00090
00091
00092 struct mode_adjust
00093 {
00094 struct mode_adjust *next;
00095 struct mode_data *mode;
00096 const char *adjustment;
00097
00098 const char *file;
00099 unsigned int line;
00100 };
00101
00102 static struct mode_adjust *adj_bytesize;
00103 static struct mode_adjust *adj_alignment;
00104 static struct mode_adjust *adj_format;
00105
00106
00107 static enum mode_class
00108 complex_class (enum mode_class c)
00109 {
00110 switch (c)
00111 {
00112 case MODE_INT: return MODE_COMPLEX_INT;
00113 case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
00114 default:
00115 error ("no complex class for class %s", mode_class_names[c]);
00116 return MODE_RANDOM;
00117 }
00118 }
00119
00120 static enum mode_class
00121 vector_class (enum mode_class cl)
00122 {
00123 switch (cl)
00124 {
00125 case MODE_INT: return MODE_VECTOR_INT;
00126 case MODE_FLOAT: return MODE_VECTOR_FLOAT;
00127 default:
00128 error ("no vector class for class %s", mode_class_names[cl]);
00129 return MODE_RANDOM;
00130 }
00131 }
00132
00133
00134 static inline struct mode_data *
00135 find_mode (const char *name)
00136 {
00137 struct mode_data key;
00138
00139 key.name = name;
00140 return (struct mode_data *) htab_find (modes_by_name, &key);
00141 }
00142
00143 static struct mode_data *
00144 new_mode (enum mode_class cl, const char *name,
00145 const char *file, unsigned int line)
00146 {
00147 struct mode_data *m;
00148
00149 m = find_mode (name);
00150 if (m)
00151 {
00152 error ("%s:%d: duplicate definition of mode \"%s\"",
00153 trim_filename (file), line, name);
00154 error ("%s:%d: previous definition here", m->file, m->line);
00155 return m;
00156 }
00157
00158 m = XNEW (struct mode_data);
00159 memcpy (m, &blank_mode, sizeof (struct mode_data));
00160 m->cl = cl;
00161 m->name = name;
00162 if (file)
00163 m->file = trim_filename (file);
00164 m->line = line;
00165
00166 m->next = modes[cl];
00167 modes[cl] = m;
00168 n_modes[cl]++;
00169
00170 *htab_find_slot (modes_by_name, m, INSERT) = m;
00171
00172 return m;
00173 }
00174
00175 static hashval_t
00176 hash_mode (const void *p)
00177 {
00178 const struct mode_data *m = (const struct mode_data *)p;
00179 return htab_hash_string (m->name);
00180 }
00181
00182 static int
00183 eq_mode (const void *p, const void *q)
00184 {
00185 const struct mode_data *a = (const struct mode_data *)p;
00186 const struct mode_data *b = (const struct mode_data *)q;
00187
00188 return !strcmp (a->name, b->name);
00189 }
00190
00191 #define for_all_modes(C, M) \
00192 for (C = 0; C < MAX_MODE_CLASS; C++) \
00193 for (M = modes[C]; M; M = M->next)
00194
00195 static void ATTRIBUTE_UNUSED
00196 new_adjust (const char *name,
00197 struct mode_adjust **category, const char *catname,
00198 const char *adjustment,
00199 enum mode_class required_class,
00200 const char *file, unsigned int line)
00201 {
00202 struct mode_data *mode = find_mode (name);
00203 struct mode_adjust *a;
00204
00205 file = trim_filename (file);
00206
00207 if (!mode)
00208 {
00209 error ("%s:%d: no mode \"%s\"", file, line, name);
00210 return;
00211 }
00212
00213 if (required_class != MODE_RANDOM && mode->cl != required_class)
00214 {
00215 error ("%s:%d: mode \"%s\" is not class %s",
00216 file, line, name, mode_class_names[required_class] + 5);
00217 return;
00218 }
00219
00220 for (a = *category; a; a = a->next)
00221 if (a->mode == mode)
00222 {
00223 error ("%s:%d: mode \"%s\" already has a %s adjustment",
00224 file, line, name, catname);
00225 error ("%s:%d: previous adjustment here", a->file, a->line);
00226 return;
00227 }
00228
00229 a = XNEW (struct mode_adjust);
00230 a->mode = mode;
00231 a->adjustment = adjustment;
00232 a->file = file;
00233 a->line = line;
00234
00235 a->next = *category;
00236 *category = a;
00237 }
00238
00239
00240
00241 enum requirement { SET, UNSET, OPTIONAL };
00242
00243 #define validate_field_(mname, fname, req, val, unset, file, line) do { \
00244 switch (req) \
00245 { \
00246 case SET: \
00247 if (val == unset) \
00248 error ("%s:%d: (%s) field %s must be set", \
00249 file, line, mname, fname); \
00250 break; \
00251 case UNSET: \
00252 if (val != unset) \
00253 error ("%s:%d: (%s) field %s must not be set", \
00254 file, line, mname, fname); \
00255 case OPTIONAL: \
00256 break; \
00257 } \
00258 } while (0)
00259
00260 #define validate_field(M, F) \
00261 validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
00262
00263 static void
00264 validate_mode (struct mode_data *m,
00265 enum requirement r_precision,
00266 enum requirement r_bytesize,
00267 enum requirement r_component,
00268 enum requirement r_ncomponents,
00269 enum requirement r_format)
00270 {
00271 validate_field (m, precision);
00272 validate_field (m, bytesize);
00273 validate_field (m, component);
00274 validate_field (m, ncomponents);
00275 validate_field (m, format);
00276 }
00277 #undef validate_field
00278 #undef validate_field_
00279
00280
00281
00282 static void
00283 complete_mode (struct mode_data *m)
00284 {
00285 unsigned int alignment;
00286
00287 if (!m->name)
00288 {
00289 error ("%s:%d: mode with no name", m->file, m->line);
00290 return;
00291 }
00292 if (m->cl == MAX_MODE_CLASS)
00293 {
00294 error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
00295 return;
00296 }
00297
00298 switch (m->cl)
00299 {
00300 case MODE_RANDOM:
00301
00302 if (!strcmp (m->name, "VOID"))
00303 void_mode = m;
00304
00305 validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
00306
00307 m->precision = 0;
00308 m->bytesize = 0;
00309 m->ncomponents = 0;
00310 m->component = 0;
00311 break;
00312
00313 case MODE_CC:
00314
00315
00316 validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
00317
00318 m->bytesize = 4;
00319 m->ncomponents = 1;
00320 m->component = 0;
00321 break;
00322
00323 case MODE_INT:
00324 case MODE_FLOAT:
00325
00326
00327
00328 validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
00329 m->cl == MODE_FLOAT ? SET : UNSET);
00330
00331 m->ncomponents = 1;
00332 m->component = 0;
00333 break;
00334
00335 case MODE_PARTIAL_INT:
00336
00337
00338
00339 validate_mode (m, OPTIONAL, UNSET, SET, UNSET, UNSET);
00340
00341 m->bytesize = m->component->bytesize;
00342
00343 m->ncomponents = 1;
00344 m->component = 0;
00345 break;
00346
00347 case MODE_COMPLEX_INT:
00348 case MODE_COMPLEX_FLOAT:
00349
00350 validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET);
00351 m->ncomponents = 2;
00352 if (m->component->precision != (unsigned int)-1)
00353 m->precision = 2 * m->component->precision;
00354 m->bytesize = 2 * m->component->bytesize;
00355 break;
00356
00357 case MODE_VECTOR_INT:
00358 case MODE_VECTOR_FLOAT:
00359
00360 validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
00361 if (m->component->precision != (unsigned int)-1)
00362 m->precision = m->ncomponents * m->component->precision;
00363 m->bytesize = m->ncomponents * m->component->bytesize;
00364 break;
00365
00366 default:
00367 gcc_unreachable ();
00368 }
00369
00370
00371
00372
00373 if (m->cl == MODE_COMPLEX_INT || m->cl == MODE_COMPLEX_FLOAT)
00374 alignment = m->component->bytesize;
00375 else
00376 alignment = m->bytesize;
00377
00378 m->alignment = alignment & (~alignment + 1);
00379
00380
00381
00382 if (m->component)
00383 {
00384 m->next_cont = m->component->contained;
00385 m->component->contained = m;
00386 }
00387 }
00388
00389 static void
00390 complete_all_modes (void)
00391 {
00392 struct mode_data *m;
00393 int cl;
00394
00395 for_all_modes (cl, m)
00396 complete_mode (m);
00397 }
00398
00399
00400 #define COMPLEX_MODES(C) make_complex_modes(MODE_##C, __FILE__, __LINE__)
00401 static void
00402 make_complex_modes (enum mode_class cl,
00403 const char *file, unsigned int line)
00404 {
00405 struct mode_data *m;
00406 struct mode_data *c;
00407 char buf[8];
00408 enum mode_class cclass = complex_class (cl);
00409
00410 if (cclass == MODE_RANDOM)
00411 return;
00412
00413 for (m = modes[cl]; m; m = m->next)
00414 {
00415
00416 if (m->precision == 1)
00417 continue;
00418
00419 if (strlen (m->name) >= sizeof buf)
00420 {
00421 error ("%s:%d:mode name \"%s\" is too long",
00422 m->file, m->line, m->name);
00423 continue;
00424 }
00425
00426
00427
00428
00429 if (cl == MODE_FLOAT)
00430 {
00431 char *p;
00432 strncpy (buf, m->name, sizeof buf);
00433 p = strchr (buf, 'F');
00434 if (p == 0)
00435 {
00436 error ("%s:%d: float mode \"%s\" has no 'F'",
00437 m->file, m->line, m->name);
00438 continue;
00439 }
00440
00441 *p = 'C';
00442 }
00443 else
00444 snprintf (buf, sizeof buf, "C%s", m->name);
00445
00446 c = new_mode (cclass, xstrdup (buf), file, line);
00447 c->component = m;
00448 }
00449 }
00450
00451
00452
00453 #define VECTOR_MODES(C, W) make_vector_modes(MODE_##C, W, __FILE__, __LINE__)
00454 static void ATTRIBUTE_UNUSED
00455 make_vector_modes (enum mode_class cl, unsigned int width,
00456 const char *file, unsigned int line)
00457 {
00458 struct mode_data *m;
00459 struct mode_data *v;
00460 char buf[8];
00461 unsigned int ncomponents;
00462 enum mode_class vclass = vector_class (cl);
00463
00464 if (vclass == MODE_RANDOM)
00465 return;
00466
00467 for (m = modes[cl]; m; m = m->next)
00468 {
00469
00470
00471
00472 ncomponents = width / m->bytesize;
00473 if (ncomponents < 2)
00474 continue;
00475 if (width % m->bytesize)
00476 continue;
00477
00478
00479
00480 if (cl == MODE_FLOAT && m->bytesize == 1)
00481 continue;
00482 if (cl == MODE_INT && m->precision == 1)
00483 continue;
00484
00485 if ((size_t)snprintf (buf, sizeof buf, "V%u%s", ncomponents, m->name)
00486 >= sizeof buf)
00487 {
00488 error ("%s:%d: mode name \"%s\" is too long",
00489 m->file, m->line, m->name);
00490 continue;
00491 }
00492
00493 v = new_mode (vclass, xstrdup (buf), file, line);
00494 v->component = m;
00495 v->ncomponents = ncomponents;
00496 }
00497 }
00498
00499
00500
00501 #define _SPECIAL_MODE(C, N) make_special_mode(MODE_##C, #N, __FILE__, __LINE__)
00502 #define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
00503 #define CC_MODE(N) _SPECIAL_MODE (CC, N)
00504
00505 static void
00506 make_special_mode (enum mode_class cl, const char *name,
00507 const char *file, unsigned int line)
00508 {
00509 new_mode (cl, name, file, line);
00510 }
00511
00512 #define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
00513 #define FRACTIONAL_INT_MODE(N, B, Y) \
00514 make_int_mode (#N, B, Y, __FILE__, __LINE__)
00515
00516 static void
00517 make_int_mode (const char *name,
00518 unsigned int precision, unsigned int bytesize,
00519 const char *file, unsigned int line)
00520 {
00521 struct mode_data *m = new_mode (MODE_INT, name, file, line);
00522 m->bytesize = bytesize;
00523 m->precision = precision;
00524 }
00525
00526 #define FLOAT_MODE(N, Y, F) FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
00527 #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
00528 make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
00529
00530 static void
00531 make_float_mode (const char *name,
00532 unsigned int precision, unsigned int bytesize,
00533 const char *format,
00534 const char *file, unsigned int line)
00535 {
00536 struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
00537 m->bytesize = bytesize;
00538 m->precision = precision;
00539 m->format = format;
00540 }
00541
00542 #define RESET_FLOAT_FORMAT(N, F) \
00543 reset_float_format (#N, #F, __FILE__, __LINE__)
00544 static void ATTRIBUTE_UNUSED
00545 reset_float_format (const char *name, const char *format,
00546 const char *file, unsigned int line)
00547 {
00548 struct mode_data *m = find_mode (name);
00549 if (!m)
00550 {
00551 error ("%s:%d: no mode \"%s\"", file, line, name);
00552 return;
00553 }
00554 if (m->cl != MODE_FLOAT)
00555 {
00556 error ("%s:%d: mode \"%s\" is not class FLOAT", file, line, name);
00557 return;
00558 }
00559 m->format = format;
00560 }
00561
00562
00563
00564 #define PARTIAL_INT_MODE(M) \
00565 make_partial_integer_mode (#M, "P" #M, -1U, __FILE__, __LINE__)
00566 static void ATTRIBUTE_UNUSED
00567 make_partial_integer_mode (const char *base, const char *name,
00568 unsigned int precision,
00569 const char *file, unsigned int line)
00570 {
00571 struct mode_data *m;
00572 struct mode_data *component = find_mode (base);
00573 if (!component)
00574 {
00575 error ("%s:%d: no mode \"%s\"", file, line, name);
00576 return;
00577 }
00578 if (component->cl != MODE_INT)
00579 {
00580 error ("%s:%d: mode \"%s\" is not class INT", file, line, name);
00581 return;
00582 }
00583
00584 m = new_mode (MODE_PARTIAL_INT, name, file, line);
00585 m->precision = precision;
00586 m->component = component;
00587 }
00588
00589
00590
00591 #define VECTOR_MODE(C, M, N) \
00592 make_vector_mode (MODE_##C, #M, N, __FILE__, __LINE__);
00593 static void ATTRIBUTE_UNUSED
00594 make_vector_mode (enum mode_class bclass,
00595 const char *base,
00596 unsigned int ncomponents,
00597 const char *file, unsigned int line)
00598 {
00599 struct mode_data *v;
00600 enum mode_class vclass = vector_class (bclass);
00601 struct mode_data *component = find_mode (base);
00602 char namebuf[8];
00603
00604 if (vclass == MODE_RANDOM)
00605 return;
00606 if (component == 0)
00607 {
00608 error ("%s:%d: no mode \"%s\"", file, line, base);
00609 return;
00610 }
00611 if (component->cl != bclass)
00612 {
00613 error ("%s:%d: mode \"%s\" is not class %s",
00614 file, line, base, mode_class_names[bclass] + 5);
00615 return;
00616 }
00617
00618 if ((size_t)snprintf (namebuf, sizeof namebuf, "V%u%s",
00619 ncomponents, base) >= sizeof namebuf)
00620 {
00621 error ("%s:%d: mode name \"%s\" is too long",
00622 base, file, line);
00623 return;
00624 }
00625
00626 v = new_mode (vclass, xstrdup (namebuf), file, line);
00627 v->ncomponents = ncomponents;
00628 v->component = component;
00629 }
00630
00631
00632 #define _ADD_ADJUST(A, M, X, C) \
00633 new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __FILE__, __LINE__)
00634
00635 #define ADJUST_BYTESIZE(M, X) _ADD_ADJUST(bytesize, M, X, RANDOM)
00636 #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM)
00637 #define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST(format, M, X, FLOAT)
00638
00639 static void
00640 create_modes (void)
00641 {
00642 #include "machmode.def"
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 static int
00661 cmp_modes (const void *a, const void *b)
00662 {
00663 struct mode_data *m = *(struct mode_data **)a;
00664 struct mode_data *n = *(struct mode_data **)b;
00665
00666 if (m->bytesize > n->bytesize)
00667 return 1;
00668 else if (m->bytesize < n->bytesize)
00669 return -1;
00670
00671 if (m->precision > n->precision)
00672 return 1;
00673 else if (m->precision < n->precision)
00674 return -1;
00675
00676 if (!m->component && !n->component)
00677 return 0;
00678
00679 if (m->component->bytesize > n->component->bytesize)
00680 return 1;
00681 else if (m->component->bytesize < n->component->bytesize)
00682 return -1;
00683
00684 if (m->component->precision > n->component->precision)
00685 return 1;
00686 else if (m->component->precision < n->component->precision)
00687 return -1;
00688
00689 return 0;
00690 }
00691
00692 static void
00693 calc_wider_mode (void)
00694 {
00695 int c;
00696 struct mode_data *m;
00697 struct mode_data **sortbuf;
00698 unsigned int max_n_modes = 0;
00699 unsigned int i, j;
00700
00701 for (c = 0; c < MAX_MODE_CLASS; c++)
00702 max_n_modes = MAX (max_n_modes, n_modes[c]);
00703
00704
00705
00706 sortbuf = (struct mode_data **) alloca ((max_n_modes + 1) * sizeof (struct mode_data *));
00707
00708 for (c = 0; c < MAX_MODE_CLASS; c++)
00709 {
00710
00711
00712
00713 if (c == MODE_RANDOM || c == MODE_CC)
00714 {
00715 struct mode_data *prev, *next;
00716
00717 for (prev = 0, m = modes[c]; m; m = next)
00718 {
00719 m->wider = void_mode;
00720
00721
00722 next = m->next;
00723 m->next = prev;
00724 prev = m;
00725 }
00726 modes[c] = prev;
00727 }
00728 else
00729 {
00730 if (!modes[c])
00731 continue;
00732
00733 for (i = 0, m = modes[c]; m; i++, m = m->next)
00734 sortbuf[i] = m;
00735
00736 qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
00737
00738 sortbuf[i] = 0;
00739 for (j = 0; j < i; j++)
00740 sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
00741
00742
00743 modes[c] = sortbuf[0];
00744 }
00745 }
00746 }
00747
00748
00749
00750 #define tagged_printf(FMT, ARG, TAG) do { \
00751 int count_; \
00752 printf (" " FMT ",%n", ARG, &count_); \
00753 printf ("%*s\n", 27 - count_, "", TAG); \
00754 } while (0)
00755
00756 #define print_decl(TYPE, NAME, ASIZE) \
00757 puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{");
00758
00759 #define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY) \
00760 printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n", \
00761 adj_##CATEGORY ? "" : "const ")
00762
00763 #define print_closer() puts ("};")
00764
00765 static void
00766 emit_insn_modes_h (void)
00767 {
00768 int c;
00769 struct mode_data *m, *first, *last;
00770
00771 printf ("/* Generated automatically from machmode.def%s%s\n",
00772 HAVE_EXTRA_MODES ? " and " : "",
00773 EXTRA_MODES_FILE);
00774
00775 puts ("\
00776 by genmodes. */\n\
00777 \n\
00778 #ifndef GCC_INSN_MODES_H\n\
00779 #define GCC_INSN_MODES_H\n\
00780 \n\
00781 enum machine_mode\n{");
00782
00783 for (c = 0; c < MAX_MODE_CLASS; c++)
00784 for (m = modes[c]; m; m = m->next)
00785 {
00786 int count_;
00787 printf (" %smode,%n", m->name, &count_);
00788 printf ("%*s/* %s:%d */\n", 27 - count_, "",
00789 trim_filename (m->file), m->line);
00790 }
00791
00792 puts (" MAX_MACHINE_MODE,\n");
00793
00794 for (c = 0; c < MAX_MODE_CLASS; c++)
00795 {
00796 first = modes[c];
00797 last = 0;
00798 for (m = first; m; last = m, m = m->next)
00799 ;
00800
00801
00802
00803
00804
00805 if (first && first->precision == 1)
00806 first = first->next;
00807
00808 if (first && last)
00809 printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
00810 mode_class_names[c], first->name,
00811 mode_class_names[c], last->name);
00812 else
00813 printf (" MIN_%s = %smode,\n MAX_%s = %smode,\n\n",
00814 mode_class_names[c], void_mode->name,
00815 mode_class_names[c], void_mode->name);
00816 }
00817
00818 puts ("\
00819 NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
00820 };\n");
00821
00822
00823 printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" : " const");
00824 printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const");
00825 #if 0
00826 printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
00827 #endif
00828 puts ("\
00829 \n\
00830 #endif /* insn-modes.h */");
00831 }
00832
00833 static void
00834 emit_insn_modes_c_header (void)
00835 {
00836 printf ("/* Generated automatically from machmode.def%s%s\n",
00837 HAVE_EXTRA_MODES ? " and " : "",
00838 EXTRA_MODES_FILE);
00839
00840 puts ("\
00841 by genmodes. */\n\
00842 \n\
00843 #include \"config.h\"\n\
00844 #include \"system.h\"\n\
00845 #include \"coretypes.h\"\n\
00846 #include \"tm.h\"\n\
00847 #include \"machmode.h\"\n\
00848 #include \"real.h\"");
00849 }
00850
00851 static void
00852 emit_min_insn_modes_c_header (void)
00853 {
00854 printf ("/* Generated automatically from machmode.def%s%s\n",
00855 HAVE_EXTRA_MODES ? " and " : "",
00856 EXTRA_MODES_FILE);
00857
00858 puts ("\
00859 by genmodes. */\n\
00860 \n\
00861 #include \"bconfig.h\"\n\
00862 #include \"system.h\"\n\
00863 #include \"machmode.h\"");
00864 }
00865
00866 static void
00867 emit_mode_name (void)
00868 {
00869 int c;
00870 struct mode_data *m;
00871
00872 print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
00873
00874 for_all_modes (c, m)
00875 printf (" \"%s\",\n", m->name);
00876
00877 print_closer ();
00878 }
00879
00880 static void
00881 emit_mode_class (void)
00882 {
00883 int c;
00884 struct mode_data *m;
00885
00886 print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
00887
00888 for_all_modes (c, m)
00889 tagged_printf ("%s", mode_class_names[m->cl], m->name);
00890
00891 print_closer ();
00892 }
00893
00894 static void
00895 emit_mode_precision (void)
00896 {
00897 int c;
00898 struct mode_data *m;
00899
00900 print_decl ("unsigned short", "mode_precision", "NUM_MACHINE_MODES");
00901
00902 for_all_modes (c, m)
00903 if (m->precision != (unsigned int)-1)
00904 tagged_printf ("%u", m->precision, m->name);
00905 else
00906 tagged_printf ("%u*BITS_PER_UNIT", m->bytesize, m->name);
00907
00908 print_closer ();
00909 }
00910
00911 static void
00912 emit_mode_size (void)
00913 {
00914 int c;
00915 struct mode_data *m;
00916
00917 print_maybe_const_decl ("%sunsigned char", "mode_size",
00918 "NUM_MACHINE_MODES", bytesize);
00919
00920 for_all_modes (c, m)
00921 tagged_printf ("%u", m->bytesize, m->name);
00922
00923 print_closer ();
00924 }
00925
00926 static void
00927 emit_mode_nunits (void)
00928 {
00929 int c;
00930 struct mode_data *m;
00931
00932 print_decl ("unsigned char", "mode_nunits", "NUM_MACHINE_MODES");
00933
00934 for_all_modes (c, m)
00935 tagged_printf ("%u", m->ncomponents, m->name);
00936
00937 print_closer ();
00938 }
00939
00940 static void
00941 emit_mode_wider (void)
00942 {
00943 int c;
00944 struct mode_data *m;
00945
00946 print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
00947
00948 for_all_modes (c, m)
00949 tagged_printf ("%smode",
00950 m->wider ? m->wider->name : void_mode->name,
00951 m->name);
00952
00953 print_closer ();
00954 }
00955
00956 static void
00957 emit_mode_mask (void)
00958 {
00959 int c;
00960 struct mode_data *m;
00961
00962 print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array",
00963 "NUM_MACHINE_MODES");
00964 puts ("\
00965 #define MODE_MASK(m) \\\n\
00966 ((m) >= HOST_BITS_PER_WIDE_INT) \\\n\
00967 ? ~(unsigned HOST_WIDE_INT) 0 \\\n\
00968 : ((unsigned HOST_WIDE_INT) 1 << (m)) - 1\n");
00969
00970 for_all_modes (c, m)
00971 if (m->precision != (unsigned int)-1)
00972 tagged_printf ("MODE_MASK (%u)", m->precision, m->name);
00973 else
00974 tagged_printf ("MODE_MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
00975
00976 puts ("#undef MODE_MASK");
00977 print_closer ();
00978 }
00979
00980 static void
00981 emit_mode_inner (void)
00982 {
00983 int c;
00984 struct mode_data *m;
00985
00986 print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
00987
00988 for_all_modes (c, m)
00989 tagged_printf ("%smode",
00990 m->component ? m->component->name : void_mode->name,
00991 m->name);
00992
00993 print_closer ();
00994 }
00995
00996 static void
00997 emit_mode_base_align (void)
00998 {
00999 int c;
01000 struct mode_data *m;
01001
01002 print_maybe_const_decl ("%sunsigned char",
01003 "mode_base_align", "NUM_MACHINE_MODES",
01004 alignment);
01005
01006 for_all_modes (c, m)
01007 tagged_printf ("%u", m->alignment, m->name);
01008
01009 print_closer ();
01010 }
01011
01012 static void
01013 emit_class_narrowest_mode (void)
01014 {
01015 int c;
01016
01017 print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
01018
01019 for (c = 0; c < MAX_MODE_CLASS; c++)
01020
01021 tagged_printf ("MIN_%s", mode_class_names[c],
01022 modes[c]
01023 ? (modes[c]->precision != 1
01024 ? modes[c]->name
01025 : (modes[c]->next
01026 ? modes[c]->next->name
01027 : void_mode->name))
01028 : void_mode->name);
01029
01030 print_closer ();
01031 }
01032
01033 static void
01034 emit_real_format_for_mode (void)
01035 {
01036 struct mode_data *m;
01037
01038
01039
01040
01041
01042
01043
01044 #if 0
01045 print_maybe_const_decl ("const struct real_format *%s",
01046 "real_format_for_mode",
01047 "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1",
01048 format);
01049 #else
01050 print_decl ("struct real_format *\n", "real_format_for_mode",
01051 "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1");
01052 #endif
01053
01054 for (m = modes[MODE_FLOAT]; m; m = m->next)
01055 if (!strcmp (m->format, "0"))
01056 tagged_printf ("%s", m->format, m->name);
01057 else
01058 tagged_printf ("&%s", m->format, m->name);
01059
01060 print_closer ();
01061 }
01062
01063 static void
01064 emit_mode_adjustments (void)
01065 {
01066 struct mode_adjust *a;
01067 struct mode_data *m;
01068
01069 puts ("\
01070 \nvoid\
01071 \ninit_adjust_machine_modes (void)\
01072 \n{\
01073 \n size_t s ATTRIBUTE_UNUSED;");
01074
01075
01076
01077 for (a = adj_bytesize; a; a = a->next)
01078 {
01079 printf ("\n /* %s:%d */\n s = %s;\n",
01080 a->file, a->line, a->adjustment);
01081 printf (" mode_size[%smode] = s;\n", a->mode->name);
01082 printf (" mode_base_align[%smode] = s & (~s + 1);\n",
01083 a->mode->name);
01084
01085 for (m = a->mode->contained; m; m = m->next_cont)
01086 {
01087 switch (m->cl)
01088 {
01089 case MODE_COMPLEX_INT:
01090 case MODE_COMPLEX_FLOAT:
01091 printf (" mode_size[%smode] = 2*s;\n", m->name);
01092 printf (" mode_base_align[%smode] = s & (~s + 1);\n",
01093 m->name);
01094 break;
01095
01096 case MODE_VECTOR_INT:
01097 case MODE_VECTOR_FLOAT:
01098 printf (" mode_size[%smode] = %d*s;\n",
01099 m->name, m->ncomponents);
01100 printf (" mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
01101 m->name, m->ncomponents, m->ncomponents);
01102 break;
01103
01104 default:
01105 internal_error (
01106 "mode %s is neither vector nor complex but contains %s",
01107 m->name, a->mode->name);
01108
01109 }
01110 }
01111 }
01112
01113
01114
01115 for (a = adj_alignment; a; a = a->next)
01116 {
01117 printf ("\n /* %s:%d */\n s = %s;\n",
01118 a->file, a->line, a->adjustment);
01119 printf (" mode_base_align[%smode] = s;\n", a->mode->name);
01120
01121 for (m = a->mode->contained; m; m = m->next_cont)
01122 {
01123 switch (m->cl)
01124 {
01125 case MODE_COMPLEX_INT:
01126 case MODE_COMPLEX_FLOAT:
01127 printf (" mode_base_align[%smode] = s;\n", m->name);
01128 break;
01129
01130 case MODE_VECTOR_INT:
01131 case MODE_VECTOR_FLOAT:
01132 printf (" mode_base_align[%smode] = %d*s;\n",
01133 m->name, m->ncomponents);
01134 break;
01135
01136 default:
01137 internal_error (
01138 "mode %s is neither vector nor complex but contains %s",
01139 m->name, a->mode->name);
01140
01141 }
01142 }
01143 }
01144
01145
01146 for (a = adj_format; a; a = a->next)
01147 printf ("\n /* %s:%d */\n REAL_MODE_FORMAT (%smode) = %s;\n",
01148 a->file, a->line, a->mode->name, a->adjustment);
01149
01150 puts ("}");
01151 }
01152
01153 static void
01154 emit_insn_modes_c (void)
01155 {
01156 emit_insn_modes_c_header ();
01157 emit_mode_name ();
01158 emit_mode_class ();
01159 emit_mode_precision ();
01160 emit_mode_size ();
01161 emit_mode_nunits ();
01162 emit_mode_wider ();
01163 emit_mode_mask ();
01164 emit_mode_inner ();
01165 emit_mode_base_align ();
01166 emit_class_narrowest_mode ();
01167 emit_real_format_for_mode ();
01168 emit_mode_adjustments ();
01169 }
01170
01171 static void
01172 emit_min_insn_modes_c (void)
01173 {
01174 emit_min_insn_modes_c_header ();
01175 emit_mode_name ();
01176 emit_mode_class ();
01177 emit_mode_wider ();
01178 emit_class_narrowest_mode ();
01179 }
01180
01181
01182 int
01183 main(int argc, char **argv)
01184 {
01185 bool gen_header = false, gen_min = false;
01186 progname = argv[0];
01187
01188 if (argc == 1)
01189 ;
01190 else if (argc == 2 && !strcmp (argv[1], "-h"))
01191 gen_header = true;
01192 else if (argc == 2 && !strcmp (argv[1], "-m"))
01193 gen_min = true;
01194 else
01195 {
01196 error ("usage: %s [-h|-m] > file", progname);
01197 return FATAL_EXIT_CODE;
01198 }
01199
01200 modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
01201
01202 create_modes ();
01203 complete_all_modes ();
01204
01205 if (have_error)
01206 return FATAL_EXIT_CODE;
01207
01208 calc_wider_mode ();
01209
01210 if (gen_header)
01211 emit_insn_modes_h ();
01212 else if (gen_min)
01213 emit_min_insn_modes_c ();
01214 else
01215 emit_insn_modes_c ();
01216
01217 if (fflush (stdout) || fclose (stdout))
01218 return FATAL_EXIT_CODE;
01219 return SUCCESS_EXIT_CODE;
01220 }