* except.c (expand_start_catch_block): We only need the rethrow
[official-gcc.git] / gcc / rtl.c
bloba386f84cd0a8fb15ee19eee83adc4975c1ff2f12
1 /* Allocate and read RTL for GNU C Compiler.
2 Copyright (C) 1987, 1988, 1991, 1994, 1997 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include <ctype.h>
24 #include <stdio.h>
25 #include "rtl.h"
26 #include "real.h"
28 #include "obstack.h"
29 #define obstack_chunk_alloc xmalloc
30 #define obstack_chunk_free free
32 /* Obstack used for allocating RTL objects.
33 Between functions, this is the permanent_obstack.
34 While parsing and expanding a function, this is maybepermanent_obstack
35 so we can save it if it is an inline function.
36 During optimization and output, this is function_obstack. */
38 extern struct obstack *rtl_obstack;
40 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
41 extern long atol();
42 #endif
44 /* Indexed by rtx code, gives number of operands for an rtx with that code.
45 Does NOT include rtx header data (code and links).
46 This array is initialized in init_rtl. */
48 int rtx_length[NUM_RTX_CODE + 1];
50 /* Indexed by rtx code, gives the name of that kind of rtx, as a C string. */
52 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
54 char *rtx_name[] = {
55 #include "rtl.def" /* rtl expressions are documented here */
58 #undef DEF_RTL_EXPR
60 /* Indexed by machine mode, gives the name of that machine mode.
61 This name does not include the letters "mode". */
63 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) NAME,
65 char *mode_name[(int) MAX_MACHINE_MODE] = {
66 #include "machmode.def"
68 #ifdef EXTRA_CC_MODES
69 EXTRA_CC_NAMES
70 #endif
74 #undef DEF_MACHMODE
76 /* Indexed by machine mode, gives the length of the mode, in bytes.
77 GET_MODE_CLASS uses this. */
79 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) CLASS,
81 enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
82 #include "machmode.def"
85 #undef DEF_MACHMODE
87 /* Indexed by machine mode, gives the length of the mode, in bytes.
88 GET_MODE_SIZE uses this. */
90 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) SIZE,
92 int mode_size[(int) MAX_MACHINE_MODE] = {
93 #include "machmode.def"
96 #undef DEF_MACHMODE
98 /* Indexed by machine mode, gives the length of the mode's subunit.
99 GET_MODE_UNIT_SIZE uses this. */
101 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) UNIT,
103 int mode_unit_size[(int) MAX_MACHINE_MODE] = {
104 #include "machmode.def" /* machine modes are documented here */
107 #undef DEF_MACHMODE
109 /* Indexed by machine mode, gives next wider natural mode
110 (QI -> HI -> SI -> DI, etc.) Widening multiply instructions
111 use this. */
113 #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) \
114 (enum machine_mode) WIDER,
116 enum machine_mode mode_wider_mode[(int) MAX_MACHINE_MODE] = {
117 #include "machmode.def" /* machine modes are documented here */
120 #undef DEF_MACHMODE
122 /* Indexed by mode class, gives the narrowest mode for each class. */
124 enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
126 /* Indexed by rtx code, gives a sequence of operand-types for
127 rtx's of that code. The sequence is a C string in which
128 each character describes one operand. */
130 char *rtx_format[] = {
131 /* "*" undefined.
132 can cause a warning message
133 "0" field is unused (or used in a phase-dependent manner)
134 prints nothing
135 "i" an integer
136 prints the integer
137 "n" like "i", but prints entries from `note_insn_name'
138 "w" an integer of width HOST_BITS_PER_WIDE_INT
139 prints the integer
140 "s" a pointer to a string
141 prints the string
142 "S" like "s", but optional:
143 the containing rtx may end before this operand
144 "e" a pointer to an rtl expression
145 prints the expression
146 "E" a pointer to a vector that points to a number of rtl expressions
147 prints a list of the rtl expressions
148 "V" like "E", but optional:
149 the containing rtx may end before this operand
150 "u" a pointer to another insn
151 prints the uid of the insn. */
153 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
154 #include "rtl.def" /* rtl expressions are defined here */
155 #undef DEF_RTL_EXPR
158 /* Indexed by rtx code, gives a character representing the "class" of
159 that rtx code. See rtl.def for documentation on the defined classes. */
161 char rtx_class[] = {
162 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
163 #include "rtl.def" /* rtl expressions are defined here */
164 #undef DEF_RTL_EXPR
167 /* Names for kinds of NOTEs and REG_NOTEs. */
169 char *note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
170 "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
171 "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
172 "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
173 "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
174 "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
175 "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
176 "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
177 "NOTE_REPEATED_LINE_NUMBER" };
179 char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
180 "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
181 "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
182 "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
183 "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
184 "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
185 "REG_BR_PRED" };
187 /* Allocate an rtx vector of N elements.
188 Store the length, and initialize all elements to zero. */
190 rtvec
191 rtvec_alloc (n)
192 int n;
194 rtvec rt;
195 int i;
197 rt = (rtvec) obstack_alloc (rtl_obstack,
198 sizeof (struct rtvec_def)
199 + (( n - 1) * sizeof (rtunion)));
201 /* clear out the vector */
202 PUT_NUM_ELEM (rt, n);
204 for (i = 0; i < n; i++)
205 rt->elem[i].rtwint = 0;
207 return rt;
210 /* Allocate an rtx of code CODE. The CODE is stored in the rtx;
211 all the rest is initialized to zero. */
214 rtx_alloc (code)
215 RTX_CODE code;
217 rtx rt;
218 register struct obstack *ob = rtl_obstack;
219 register int nelts = GET_RTX_LENGTH (code);
220 register int length = sizeof (struct rtx_def)
221 + (nelts - 1) * sizeof (rtunion);
223 /* This function is called more than any other in GCC,
224 so we manipulate the obstack directly.
226 Even though rtx objects are word aligned, we may be sharing an obstack
227 with tree nodes, which may have to be double-word aligned. So align
228 our length to the alignment mask in the obstack. */
230 length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
232 if (ob->chunk_limit - ob->next_free < length)
233 _obstack_newchunk (ob, length);
234 rt = (rtx)ob->object_base;
235 ob->next_free += length;
236 ob->object_base = ob->next_free;
238 /* We want to clear everything up to the FLD array. Normally, this is
239 one int, but we don't want to assume that and it isn't very portable
240 anyway; this is. */
242 length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
243 for (; length >= 0; length--)
244 ((int *) rt)[length] = 0;
246 PUT_CODE (rt, code);
248 return rt;
251 /* Free the rtx X and all RTL allocated since X. */
253 void
254 rtx_free (x)
255 rtx x;
257 obstack_free (rtl_obstack, x);
260 /* Create a new copy of an rtx.
261 Recursively copies the operands of the rtx,
262 except for those few rtx codes that are sharable. */
265 copy_rtx (orig)
266 register rtx orig;
268 register rtx copy;
269 register int i, j;
270 register RTX_CODE code;
271 register char *format_ptr;
273 code = GET_CODE (orig);
275 switch (code)
277 case REG:
278 case QUEUED:
279 case CONST_INT:
280 case CONST_DOUBLE:
281 case SYMBOL_REF:
282 case CODE_LABEL:
283 case PC:
284 case CC0:
285 case SCRATCH:
286 /* SCRATCH must be shared because they represent distinct values. */
287 case ADDRESSOF:
288 return orig;
290 case CONST:
291 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
292 a LABEL_REF, it isn't sharable. */
293 if (GET_CODE (XEXP (orig, 0)) == PLUS
294 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
295 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
296 return orig;
297 break;
299 /* A MEM with a constant address is not sharable. The problem is that
300 the constant address may need to be reloaded. If the mem is shared,
301 then reloading one copy of this mem will cause all copies to appear
302 to have been reloaded. */
304 default:
305 break;
308 copy = rtx_alloc (code);
309 PUT_MODE (copy, GET_MODE (orig));
310 copy->in_struct = orig->in_struct;
311 copy->volatil = orig->volatil;
312 copy->unchanging = orig->unchanging;
313 copy->integrated = orig->integrated;
315 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
317 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
319 switch (*format_ptr++)
321 case 'e':
322 XEXP (copy, i) = XEXP (orig, i);
323 if (XEXP (orig, i) != NULL)
324 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
325 break;
327 case '0':
328 case 'u':
329 XEXP (copy, i) = XEXP (orig, i);
330 break;
332 case 'E':
333 case 'V':
334 XVEC (copy, i) = XVEC (orig, i);
335 if (XVEC (orig, i) != NULL)
337 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
338 for (j = 0; j < XVECLEN (copy, i); j++)
339 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
341 break;
343 case 'w':
344 XWINT (copy, i) = XWINT (orig, i);
345 break;
347 case 'i':
348 XINT (copy, i) = XINT (orig, i);
349 break;
351 case 's':
352 case 'S':
353 XSTR (copy, i) = XSTR (orig, i);
354 break;
356 default:
357 abort ();
360 return copy;
363 /* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
364 placed in the result directly, rather than being copied. */
367 copy_most_rtx (orig, may_share)
368 register rtx orig;
369 register rtx may_share;
371 register rtx copy;
372 register int i, j;
373 register RTX_CODE code;
374 register char *format_ptr;
376 if (orig == may_share)
377 return orig;
379 code = GET_CODE (orig);
381 switch (code)
383 case REG:
384 case QUEUED:
385 case CONST_INT:
386 case CONST_DOUBLE:
387 case SYMBOL_REF:
388 case CODE_LABEL:
389 case PC:
390 case CC0:
391 return orig;
392 default:
393 break;
396 copy = rtx_alloc (code);
397 PUT_MODE (copy, GET_MODE (orig));
398 copy->in_struct = orig->in_struct;
399 copy->volatil = orig->volatil;
400 copy->unchanging = orig->unchanging;
401 copy->integrated = orig->integrated;
403 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
405 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
407 switch (*format_ptr++)
409 case 'e':
410 XEXP (copy, i) = XEXP (orig, i);
411 if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
412 XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
413 break;
415 case '0':
416 case 'u':
417 XEXP (copy, i) = XEXP (orig, i);
418 break;
420 case 'E':
421 case 'V':
422 XVEC (copy, i) = XVEC (orig, i);
423 if (XVEC (orig, i) != NULL)
425 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
426 for (j = 0; j < XVECLEN (copy, i); j++)
427 XVECEXP (copy, i, j)
428 = copy_most_rtx (XVECEXP (orig, i, j), may_share);
430 break;
432 case 'w':
433 XWINT (copy, i) = XWINT (orig, i);
434 break;
436 case 'n':
437 case 'i':
438 XINT (copy, i) = XINT (orig, i);
439 break;
441 case 's':
442 case 'S':
443 XSTR (copy, i) = XSTR (orig, i);
444 break;
446 default:
447 abort ();
450 return copy;
453 /* Subroutines of read_rtx. */
455 /* Dump code after printing a message. Used when read_rtx finds
456 invalid data. */
458 static void
459 dump_and_abort (expected_c, actual_c, infile)
460 int expected_c, actual_c;
461 FILE *infile;
463 int c, i;
465 if (expected_c >= 0)
466 fprintf (stderr,
467 "Expected character %c. Found character %c.",
468 expected_c, actual_c);
469 fprintf (stderr, " At file position: %ld\n", ftell (infile));
470 fprintf (stderr, "Following characters are:\n\t");
471 for (i = 0; i < 200; i++)
473 c = getc (infile);
474 if (EOF == c) break;
475 putc (c, stderr);
477 fprintf (stderr, "Aborting.\n");
478 abort ();
481 /* Read chars from INFILE until a non-whitespace char
482 and return that. Comments, both Lisp style and C style,
483 are treated as whitespace.
484 Tools such as genflags use this function. */
487 read_skip_spaces (infile)
488 FILE *infile;
490 register int c;
491 while (c = getc (infile))
493 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
495 else if (c == ';')
497 while ((c = getc (infile)) && c != '\n') ;
499 else if (c == '/')
501 register int prevc;
502 c = getc (infile);
503 if (c != '*')
504 dump_and_abort ('*', c, infile);
506 prevc = 0;
507 while (c = getc (infile))
509 if (prevc == '*' && c == '/')
510 break;
511 prevc = c;
514 else break;
516 return c;
519 /* Read an rtx code name into the buffer STR[].
520 It is terminated by any of the punctuation chars of rtx printed syntax. */
522 static void
523 read_name (str, infile)
524 char *str;
525 FILE *infile;
527 register char *p;
528 register int c;
530 c = read_skip_spaces(infile);
532 p = str;
533 while (1)
535 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
536 break;
537 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
538 || c == '(' || c == '[')
540 ungetc (c, infile);
541 break;
543 *p++ = c;
544 c = getc (infile);
546 if (p == str)
548 fprintf (stderr, "missing name or number");
549 dump_and_abort (-1, -1, infile);
552 *p = 0;
555 /* Read an rtx in printed representation from INFILE
556 and return an actual rtx in core constructed accordingly.
557 read_rtx is not used in the compiler proper, but rather in
558 the utilities gen*.c that construct C code from machine descriptions. */
561 read_rtx (infile)
562 FILE *infile;
564 register int i, j, list_counter;
565 RTX_CODE tmp_code;
566 register char *format_ptr;
567 /* tmp_char is a buffer used for reading decimal integers
568 and names of rtx types and machine modes.
569 Therefore, 256 must be enough. */
570 char tmp_char[256];
571 rtx return_rtx;
572 register int c;
573 int tmp_int;
574 HOST_WIDE_INT tmp_wide;
576 /* Linked list structure for making RTXs: */
577 struct rtx_list
579 struct rtx_list *next;
580 rtx value; /* Value of this node... */
583 c = read_skip_spaces (infile); /* Should be open paren. */
584 if (c != '(')
585 dump_and_abort ('(', c, infile);
587 read_name (tmp_char, infile);
589 tmp_code = UNKNOWN;
591 for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
593 if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
595 tmp_code = (RTX_CODE) i; /* get value for name */
596 break;
599 if (tmp_code == UNKNOWN)
601 fprintf (stderr,
602 "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
603 tmp_char);
605 /* (NIL) stands for an expression that isn't there. */
606 if (tmp_code == NIL)
608 /* Discard the closeparen. */
609 while ((c = getc (infile)) && c != ')');
610 return 0;
613 return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
614 then we free this space below. */
615 format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
617 /* If what follows is `: mode ', read it and
618 store the mode in the rtx. */
620 i = read_skip_spaces (infile);
621 if (i == ':')
623 register int k;
624 read_name (tmp_char, infile);
625 for (k = 0; k < NUM_MACHINE_MODES; k++)
626 if (!strcmp (GET_MODE_NAME (k), tmp_char))
627 break;
629 PUT_MODE (return_rtx, (enum machine_mode) k );
631 else
632 ungetc (i, infile);
634 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
635 switch (*format_ptr++)
637 /* 0 means a field for internal use only.
638 Don't expect it to be present in the input. */
639 case '0':
640 break;
642 case 'e':
643 case 'u':
644 XEXP (return_rtx, i) = read_rtx (infile);
645 break;
647 case 'V':
648 /* 'V' is an optional vector: if a closeparen follows,
649 just store NULL for this element. */
650 c = read_skip_spaces (infile);
651 ungetc (c, infile);
652 if (c == ')')
654 XVEC (return_rtx, i) = 0;
655 break;
657 /* Now process the vector. */
659 case 'E':
661 register struct rtx_list *next_rtx, *rtx_list_link;
662 struct rtx_list *list_rtx;
664 c = read_skip_spaces (infile);
665 if (c != '[')
666 dump_and_abort ('[', c, infile);
668 /* add expressions to a list, while keeping a count */
669 next_rtx = NULL;
670 list_counter = 0;
671 while ((c = read_skip_spaces (infile)) && c != ']')
673 ungetc (c, infile);
674 list_counter++;
675 rtx_list_link = (struct rtx_list *)
676 alloca (sizeof (struct rtx_list));
677 rtx_list_link->value = read_rtx (infile);
678 if (next_rtx == 0)
679 list_rtx = rtx_list_link;
680 else
681 next_rtx->next = rtx_list_link;
682 next_rtx = rtx_list_link;
683 rtx_list_link->next = 0;
685 /* get vector length and allocate it */
686 XVEC (return_rtx, i) = (list_counter
687 ? rtvec_alloc (list_counter) : NULL_RTVEC);
688 if (list_counter > 0)
690 next_rtx = list_rtx;
691 for (j = 0; j < list_counter; j++,
692 next_rtx = next_rtx->next)
693 XVECEXP (return_rtx, i, j) = next_rtx->value;
695 /* close bracket gotten */
697 break;
699 case 'S':
700 /* 'S' is an optional string: if a closeparen follows,
701 just store NULL for this element. */
702 c = read_skip_spaces (infile);
703 ungetc (c, infile);
704 if (c == ')')
706 XSTR (return_rtx, i) = 0;
707 break;
710 case 's':
712 int saw_paren = 0;
713 register char *stringbuf;
715 c = read_skip_spaces (infile);
716 if (c == '(')
718 saw_paren = 1;
719 c = read_skip_spaces (infile);
721 if (c != '"')
722 dump_and_abort ('"', c, infile);
724 while (1)
726 c = getc (infile); /* Read the string */
727 if (c == '\\')
729 c = getc (infile); /* Read the string */
730 /* \; makes stuff for a C string constant containing
731 newline and tab. */
732 if (c == ';')
734 obstack_grow (rtl_obstack, "\\n\\t", 4);
735 continue;
738 else if (c == '"')
739 break;
741 obstack_1grow (rtl_obstack, c);
744 obstack_1grow (rtl_obstack, 0);
745 stringbuf = (char *) obstack_finish (rtl_obstack);
747 if (saw_paren)
749 c = read_skip_spaces (infile);
750 if (c != ')')
751 dump_and_abort (')', c, infile);
753 XSTR (return_rtx, i) = stringbuf;
755 break;
757 case 'w':
758 read_name (tmp_char, infile);
759 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
760 tmp_wide = atoi (tmp_char);
761 #else
762 tmp_wide = atol (tmp_char);
763 #endif
764 XWINT (return_rtx, i) = tmp_wide;
765 break;
767 case 'i':
768 case 'n':
769 read_name (tmp_char, infile);
770 tmp_int = atoi (tmp_char);
771 XINT (return_rtx, i) = tmp_int;
772 break;
774 default:
775 fprintf (stderr,
776 "switch format wrong in rtl.read_rtx(). format was: %c.\n",
777 format_ptr[-1]);
778 fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
779 abort ();
782 c = read_skip_spaces (infile);
783 if (c != ')')
784 dump_and_abort (')', c, infile);
786 return return_rtx;
789 /* This is called once per compilation, before any rtx's are constructed.
790 It initializes the vector `rtx_length', the extra CC modes, if any,
791 and computes certain commonly-used modes. */
793 void
794 init_rtl ()
796 int min_class_size[(int) MAX_MODE_CLASS];
797 enum machine_mode mode;
798 int i;
800 for (i = 0; i < NUM_RTX_CODE; i++)
801 rtx_length[i] = strlen (rtx_format[i]);
803 /* Make CONST_DOUBLE bigger, if real values are bigger than
804 it normally expects to have room for.
805 Note that REAL_VALUE_TYPE is not defined by default,
806 since tree.h is not included. But the default dfn as `double'
807 would do no harm. */
808 #ifdef REAL_VALUE_TYPE
809 i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
810 if (rtx_length[(int) CONST_DOUBLE] < i)
812 char *s = (char *) xmalloc (i + 1);
813 rtx_length[(int) CONST_DOUBLE] = i;
814 rtx_format[(int) CONST_DOUBLE] = s;
815 *s++ = 'e';
816 *s++ = '0';
817 /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
818 of as many `w's as we now have elements. Subtract two from
819 the size to account for the 'e' and the '0'. */
820 for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
821 *s++ = 'w';
822 *s++ = 0;
824 #endif
826 #ifdef EXTRA_CC_MODES
827 for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
829 mode_class[i] = MODE_CC;
830 mode_size[i] = mode_size[(int) CCmode];
831 mode_unit_size[i] = mode_unit_size[(int) CCmode];
832 mode_wider_mode[i - 1] = (enum machine_mode) i;
833 mode_wider_mode[i] = VOIDmode;
835 #endif
837 /* Find the narrowest mode for each class. */
839 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
840 min_class_size[i] = 1000;
842 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
843 mode = (enum machine_mode) ((int) mode + 1))
845 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
847 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
848 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
853 #ifdef memset
854 gcc_memset (dest, value, len)
855 char *dest;
856 int value;
857 int len;
859 while (len-- > 0)
860 *dest++ = value;
862 #endif /* memset */