|
|
1.1 root 1: /* Allocate and read RTL for GNU C Compiler.
2: Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
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.
10:
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.
15:
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20:
21: #include "config.h"
22: #include <ctype.h>
23: #include <stdio.h>
24: #include "rtl.h"
25:
26: #include "obstack.h"
27: #define obstack_chunk_alloc xmalloc
28: #define obstack_chunk_free free
29: extern int xmalloc ();
30: extern void free ();
31:
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. */
37:
38: extern struct obstack *rtl_obstack;
39:
40: extern long ftell();
41:
42: /* Indexed by rtx code, gives number of operands for an rtx with that code.
43: Does NOT include rtx header data (code and links).
44: This array is initialized in init_rtl. */
45:
46: int rtx_length[NUM_RTX_CODE + 1];
47:
48: /* Indexed by rtx code, gives the name of that kind of rtx, as a C string. */
49:
50: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
51:
52: char *rtx_name[] = {
53: #include "rtl.def" /* rtl expressions are documented here */
54: };
55:
56: #undef DEF_RTL_EXPR
57:
58: /* Indexed by machine mode, gives the name of that machine mode.
59: This name does not include the letters "mode". */
60:
61: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) NAME,
62:
63: char *mode_name[(int) MAX_MACHINE_MODE] = {
64: #include "machmode.def"
65:
66: #ifdef EXTRA_CC_MODES
67: EXTRA_CC_NAMES
68: #endif
69:
70: };
71:
72: #undef DEF_MACHMODE
73:
74: /* Indexed by machine mode, gives the length of the mode, in bytes.
75: GET_MODE_CLASS uses this. */
76:
77: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) CLASS,
78:
79: enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
80: #include "machmode.def"
81: };
82:
83: #undef DEF_MACHMODE
84:
85: /* Indexed by machine mode, gives the length of the mode, in bytes.
86: GET_MODE_SIZE uses this. */
87:
88: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) SIZE,
89:
90: int mode_size[(int) MAX_MACHINE_MODE] = {
91: #include "machmode.def"
92: };
93:
94: #undef DEF_MACHMODE
95:
96: /* Indexed by machine mode, gives the length of the mode's subunit.
97: GET_MODE_UNIT_SIZE uses this. */
98:
99: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) UNIT,
100:
101: int mode_unit_size[(int) MAX_MACHINE_MODE] = {
102: #include "machmode.def" /* machine modes are documented here */
103: };
104:
105: #undef DEF_MACHMODE
106:
107: /* Indexed by machine mode, gives next wider natural mode
108: (QI -> HI -> SI -> DI, etc.) Widening multiply instructions
109: use this. */
110:
111: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) \
112: (enum machine_mode) WIDER,
113:
114: enum machine_mode mode_wider_mode[(int) MAX_MACHINE_MODE] = {
115: #include "machmode.def" /* machine modes are documented here */
116: };
117:
118: #undef DEF_MACHMODE
119:
120: /* Indexed by mode class, gives the narrowest mode for each class. */
121:
122: enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
123:
124: /* Commonly used modes. */
125:
126: enum machine_mode byte_mode; /* Mode whose width is BITS_PER_UNIT */
127: enum machine_mode word_mode; /* Mode whose width is BITS_PER_WORD */
128:
129: /* Indexed by rtx code, gives a sequence of operand-types for
130: rtx's of that code. The sequence is a C string in which
1.1.1.2 ! root 131: each character describes one operand. */
1.1 root 132:
133: char *rtx_format[] = {
134: /* "*" undefined.
135: can cause a warning message
136: "0" field is unused (or used in a phase-dependent manner)
137: prints nothing
138: "i" an integer
139: prints the integer
140: "n" like "i", but prints entries from `note_insn_name'
141: "s" a pointer to a string
142: prints the string
143: "S" like "s", but optional:
144: the containing rtx may end before this operand
145: "e" a pointer to an rtl expression
146: prints the expression
147: "E" a pointer to a vector that points to a number of rtl expressions
148: prints a list of the rtl expressions
149: "V" like "E", but optional:
150: the containing rtx may end before this operand
151: "u" a pointer to another insn
152: prints the uid of the insn. */
153:
154: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
155: #include "rtl.def" /* rtl expressions are defined here */
156: #undef DEF_RTL_EXPR
157: };
158:
159: /* Indexed by rtx code, gives a character representing the "class" of
160: that rtx code. See rtl.def for documentation on the defined classes. */
161:
162: char rtx_class[] = {
163: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
164: #include "rtl.def" /* rtl expressions are defined here */
165: #undef DEF_RTL_EXPR
166: };
167:
168: /* Names for kinds of NOTEs and REG_NOTEs. */
169:
170: char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",
171: "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
172: "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
173: "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
174: "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP" };
175:
176: char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
177: "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
178: "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
179: "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
180: "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
181:
182: /* Allocate an rtx vector of N elements.
183: Store the length, and initialize all elements to zero. */
184:
185: rtvec
186: rtvec_alloc (n)
187: int n;
188: {
189: rtvec rt;
190: int i;
191:
192: rt = (rtvec) obstack_alloc (rtl_obstack,
193: sizeof (struct rtvec_def)
194: + (( n - 1) * sizeof (rtunion)));
195:
196: /* clear out the vector */
197: PUT_NUM_ELEM(rt, n);
198: for (i=0; i < n; i++)
199: rt->elem[i].rtvec = NULL; /* @@ not portable due to rtunion */
200:
201: return rt;
202: }
203:
204: /* Allocate an rtx of code CODE. The CODE is stored in the rtx;
205: all the rest is initialized to zero. */
206:
207: rtx
208: rtx_alloc (code)
209: RTX_CODE code;
210: {
211: rtx rt;
212: register struct obstack *ob = rtl_obstack;
213: register int nelts = GET_RTX_LENGTH (code);
214: register int length = sizeof (struct rtx_def)
215: + (nelts - 1) * sizeof (rtunion);
216:
217: /* This function is called more than any other in GCC,
218: so we manipulate the obstack directly.
219:
220: Even though rtx objects are word aligned, we may be sharing an obstack
221: with tree nodes, which may have to be double-word aligned. So align
222: our length to the alignment mask in the obstack. */
223:
224: length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
225:
226: if (ob->chunk_limit - ob->next_free < length)
227: _obstack_newchunk (ob, length);
228: rt = (rtx)ob->object_base;
229: ob->next_free += length;
230: ob->object_base = ob->next_free;
231:
232: * (int *) rt = 0;
233: PUT_CODE (rt, code);
234:
235: return rt;
236: }
237:
238: /* Create a new copy of an rtx.
239: Recursively copies the operands of the rtx,
240: except for those few rtx codes that are sharable. */
241:
242: rtx
243: copy_rtx (orig)
244: register rtx orig;
245: {
246: register rtx copy;
247: register int i, j;
248: register RTX_CODE code;
249: register char *format_ptr;
250:
251: code = GET_CODE (orig);
252:
253: switch (code)
254: {
255: case REG:
256: case QUEUED:
257: case CONST_INT:
258: case CONST_DOUBLE:
259: case SYMBOL_REF:
260: case CODE_LABEL:
261: case PC:
262: case CC0:
263: return orig;
264: }
265:
266: copy = rtx_alloc (code);
267: PUT_MODE (copy, GET_MODE (orig));
268: copy->in_struct = orig->in_struct;
269: copy->volatil = orig->volatil;
270: copy->unchanging = orig->unchanging;
271: copy->integrated = orig->integrated;
272:
273: format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
274:
275: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
276: {
277: switch (*format_ptr++)
278: {
279: case 'e':
280: XEXP (copy, i) = XEXP (orig, i);
281: if (XEXP (orig, i) != NULL)
282: XEXP (copy, i) = copy_rtx (XEXP (orig, i));
283: break;
284:
285: case 'E':
286: case 'V':
287: XVEC (copy, i) = XVEC (orig, i);
288: if (XVEC (orig, i) != NULL)
289: {
290: XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
291: for (j = 0; j < XVECLEN (copy, i); j++)
292: XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
293: }
294: break;
295:
296: default:
297: XINT (copy, i) = XINT (orig, i);
298: break;
299: }
300: }
301: return copy;
302: }
303:
304: /* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
305: placed in the result directly, rather than being copied. */
306:
307: rtx
308: copy_most_rtx (orig, may_share)
309: register rtx orig;
310: register rtx may_share;
311: {
312: register rtx copy;
313: register int i, j;
314: register RTX_CODE code;
315: register char *format_ptr;
316:
317: if (orig == may_share)
318: return orig;
319:
320: code = GET_CODE (orig);
321:
322: switch (code)
323: {
324: case REG:
325: case QUEUED:
326: case CONST_INT:
327: case CONST_DOUBLE:
328: case SYMBOL_REF:
329: case CODE_LABEL:
330: case PC:
331: case CC0:
332: return orig;
333: }
334:
335: copy = rtx_alloc (code);
336: PUT_MODE (copy, GET_MODE (orig));
337: copy->in_struct = orig->in_struct;
338: copy->volatil = orig->volatil;
339: copy->unchanging = orig->unchanging;
340: copy->integrated = orig->integrated;
341:
342: format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
343:
344: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
345: {
346: switch (*format_ptr++)
347: {
348: case 'e':
349: XEXP (copy, i) = XEXP (orig, i);
350: if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
351: XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
352: break;
353:
354: case 'E':
355: case 'V':
356: XVEC (copy, i) = XVEC (orig, i);
357: if (XVEC (orig, i) != NULL)
358: {
359: XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
360: for (j = 0; j < XVECLEN (copy, i); j++)
361: XVECEXP (copy, i, j)
362: = copy_most_rtx (XVECEXP (orig, i, j), may_share);
363: }
364: break;
365:
366: default:
367: XINT (copy, i) = XINT (orig, i);
368: break;
369: }
370: }
371: return copy;
372: }
373:
374: /* Subroutines of read_rtx. */
375:
376: /* Dump code after printing a message. Used when read_rtx finds
377: invalid data. */
378:
379: static void
380: dump_and_abort (expected_c, actual_c, infile)
381: int expected_c, actual_c;
382: FILE *infile;
383: {
384: int c, i;
385:
386: if (expected_c >= 0)
387: fprintf (stderr,
388: "Expected character %c. Found character %c.",
389: expected_c, actual_c);
390: fprintf (stderr, " At file position: %ld\n", ftell (infile));
391: fprintf (stderr, "Following characters are:\n\t");
392: for (i = 0; i < 200; i++)
393: {
394: c = getc (infile);
395: if (EOF == c) break;
396: putc (c, stderr);
397: }
398: fprintf (stderr, "Aborting.\n");
399: abort ();
400: }
401:
402: /* Read chars from INFILE until a non-whitespace char
403: and return that. Comments, both Lisp style and C style,
404: are treated as whitespace.
405: Tools such as genflags use this function. */
406:
407: int
408: read_skip_spaces (infile)
409: FILE *infile;
410: {
411: register int c;
412: while (c = getc (infile))
413: {
414: if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
415: ;
416: else if (c == ';')
417: {
418: while ((c = getc (infile)) && c != '\n') ;
419: }
420: else if (c == '/')
421: {
422: register int prevc;
423: c = getc (infile);
424: if (c != '*')
425: dump_and_abort ('*', c, infile);
426:
427: prevc = 0;
428: while (c = getc (infile))
429: {
430: if (prevc == '*' && c == '/')
431: break;
432: prevc = c;
433: }
434: }
435: else break;
436: }
437: return c;
438: }
439:
440: /* Read an rtx code name into the buffer STR[].
441: It is terminated by any of the punctuation chars of rtx printed syntax. */
442:
443: static void
444: read_name (str, infile)
445: char *str;
446: FILE *infile;
447: {
448: register char *p;
449: register int c;
450:
451: c = read_skip_spaces(infile);
452:
453: p = str;
454: while (1)
455: {
456: if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
457: break;
458: if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
459: || c == '(' || c == '[')
460: {
461: ungetc (c, infile);
462: break;
463: }
464: *p++ = c;
465: c = getc (infile);
466: }
467: if (p == str)
468: {
469: fprintf (stderr, "missing name or number");
470: dump_and_abort (-1, -1, infile);
471: }
472:
473: *p = 0;
474: }
475:
476: /* Read an rtx in printed representation from INFILE
477: and return an actual rtx in core constructed accordingly.
478: read_rtx is not used in the compiler proper, but rather in
479: the utilities gen*.c that construct C code from machine descriptions. */
480:
481: rtx
482: read_rtx (infile)
483: FILE *infile;
484: {
485: register int i, j, list_counter;
486: RTX_CODE tmp_code;
487: register char *format_ptr;
488: /* tmp_char is a buffer used for reading decimal integers
489: and names of rtx types and machine modes.
490: Therefore, 256 must be enough. */
491: char tmp_char[256];
492: rtx return_rtx;
493: register int c;
494: int tmp_int;
495:
496: /* Linked list structure for making RTXs: */
497: struct rtx_list
498: {
499: struct rtx_list *next;
500: rtx value; /* Value of this node... */
501: };
502:
503: c = read_skip_spaces (infile); /* Should be open paren. */
504: if (c != '(')
505: dump_and_abort ('(', c, infile);
506:
507: read_name (tmp_char, infile);
508:
509: tmp_code = UNKNOWN;
510:
511: for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
512: {
513: if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
514: {
515: tmp_code = (RTX_CODE) i; /* get value for name */
516: break;
517: }
518: }
519: if (tmp_code == UNKNOWN)
520: {
521: fprintf (stderr,
522: "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
523: tmp_char);
524: }
525: /* (NIL) stands for an expression that isn't there. */
526: if (tmp_code == NIL)
527: {
528: /* Discard the closeparen. */
529: while ((c = getc (infile)) && c != ')');
530: return 0;
531: }
532:
533: return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
534: then we free this space below. */
535: format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
536:
537: /* If what follows is `: mode ', read it and
538: store the mode in the rtx. */
539:
540: i = read_skip_spaces (infile);
541: if (i == ':')
542: {
543: register int k;
544: read_name (tmp_char, infile);
545: for (k = 0; k < NUM_MACHINE_MODES; k++)
546: if (!strcmp (GET_MODE_NAME (k), tmp_char))
547: break;
548:
549: PUT_MODE (return_rtx, (enum machine_mode) k );
550: }
551: else
552: ungetc (i, infile);
553:
554: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
555: switch (*format_ptr++)
556: {
557: /* 0 means a field for internal use only.
558: Don't expect it to be present in the input. */
559: case '0':
560: break;
561:
562: case 'e':
563: case 'u':
564: XEXP (return_rtx, i) = read_rtx (infile);
565: break;
566:
567: case 'V':
568: /* 'V' is an optional vector: if a closeparen follows,
569: just store NULL for this element. */
570: c = read_skip_spaces (infile);
571: ungetc (c, infile);
572: if (c == ')')
573: {
574: XVEC (return_rtx, i) = 0;
575: break;
576: }
577: /* Now process the vector. */
578:
579: case 'E':
580: {
581: register struct rtx_list *next_rtx, *rtx_list_link;
582: struct rtx_list *list_rtx;
583:
584: c = read_skip_spaces (infile);
585: if (c != '[')
586: dump_and_abort ('[', c, infile);
587:
588: /* add expressions to a list, while keeping a count */
589: next_rtx = NULL;
590: list_counter = 0;
591: while ((c = read_skip_spaces (infile)) && c != ']')
592: {
593: ungetc (c, infile);
594: list_counter++;
595: rtx_list_link = (struct rtx_list *)
596: alloca (sizeof (struct rtx_list));
597: rtx_list_link->value = read_rtx (infile);
598: if (next_rtx == 0)
599: list_rtx = rtx_list_link;
600: else
601: next_rtx->next = rtx_list_link;
602: next_rtx = rtx_list_link;
603: rtx_list_link->next = 0;
604: }
605: /* get vector length and allocate it */
606: XVEC (return_rtx, i) = (list_counter
607: ? rtvec_alloc (list_counter)
608: : (struct rtvec_def *) NULL);
609: if (list_counter > 0)
610: {
611: next_rtx = list_rtx;
612: for (j = 0; j < list_counter; j++,
613: next_rtx = next_rtx->next)
614: XVECEXP (return_rtx, i, j) = next_rtx->value;
615: }
616: /* close bracket gotten */
617: }
618: break;
619:
620: case 'S':
621: /* 'S' is an optional string: if a closeparen follows,
622: just store NULL for this element. */
623: c = read_skip_spaces (infile);
624: ungetc (c, infile);
625: if (c == ')')
626: {
627: XSTR (return_rtx, i) = 0;
628: break;
629: }
630:
631: case 's':
632: {
633: int saw_paren = 0;
634: register char *stringbuf;
635: int stringbufsize;
636:
637: c = read_skip_spaces (infile);
638: if (c == '(')
639: {
640: saw_paren = 1;
641: c = read_skip_spaces (infile);
642: }
643: if (c != '"')
644: dump_and_abort ('"', c, infile);
645:
646: while (1)
647: {
1.1.1.2 ! root 648: c = getc (infile); /* Read the string */
! 649: if (c == '\\')
1.1 root 650: {
1.1.1.2 ! root 651: c = getc (infile); /* Read the string */
1.1 root 652: /* \; makes stuff for a C string constant containing
653: newline and tab. */
1.1.1.2 ! root 654: if (c == ';')
1.1 root 655: {
1.1.1.2 ! root 656: obstack_grow (rtl_obstack, "\\n\\t", 4);
! 657: continue;
1.1 root 658: }
659: }
1.1.1.2 ! root 660: else if (c == '"')
1.1 root 661: break;
1.1.1.2 ! root 662:
! 663: obstack_1grow (rtl_obstack, c);
1.1 root 664: }
665:
1.1.1.2 ! root 666: obstack_1grow (rtl_obstack, 0);
! 667: stringbuf = (char *) obstack_finish (rtl_obstack);
1.1 root 668:
669: if (saw_paren)
670: {
671: c = read_skip_spaces (infile);
672: if (c != ')')
673: dump_and_abort (')', c, infile);
674: }
675: XSTR (return_rtx, i) = stringbuf;
676: }
677: break;
678:
679: case 'i':
680: case 'n':
681: read_name (tmp_char, infile);
682: tmp_int = atoi (tmp_char);
683: XINT (return_rtx, i) = tmp_int;
684: break;
685:
686: default:
687: fprintf (stderr,
688: "switch format wrong in rtl.read_rtx(). format was: %c.\n",
689: format_ptr[-1]);
690: fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
691: abort ();
692: }
693:
694: c = read_skip_spaces (infile);
695: if (c != ')')
696: dump_and_abort (')', c, infile);
697:
698: return return_rtx;
699: }
700:
701: /* This is called once per compilation, before any rtx's are constructed.
702: It initializes the vector `rtx_length', the extra CC modes, if any,
703: and computes certain commonly-used modes. */
704:
705: void
706: init_rtl ()
707: {
708: int min_class_size[(int) MAX_MODE_CLASS];
709: enum machine_mode mode;
710: int i;
711:
712: for (i = 0; i < NUM_RTX_CODE; i++)
713: rtx_length[i] = strlen (rtx_format[i]);
714:
715: /* Make CONST_DOUBLE bigger, if real values are bigger than
716: it normally expects to have room for.
717: Note that REAL_VALUE_TYPE is not defined by default,
718: since tree.h is not included. But the default dfn as `double'
719: would do no harm. */
720: #ifdef REAL_VALUE_TYPE
721: i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
722: if (rtx_length[(int) CONST_DOUBLE] < i)
723: {
724: char *s = (char *) xmalloc (i + 1);
725: rtx_length[(int) CONST_DOUBLE] = i;
726: rtx_format[(int) CONST_DOUBLE] = s;
727: *s++ = 'e';
728: *s++ = '0';
729: /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
730: of as many `i's as we now have elements. */
731: for (i = 0; i < rtx_length[(int) CONST_DOUBLE]; i++)
732: *s++ = 'i';
733: *s++ = 0;
734: }
735: #endif
736:
737: #ifdef EXTRA_CC_MODES
738: for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
739: {
740: mode_class[i] = MODE_CC;
741: mode_size[i] = mode_size[(int) CCmode];
742: mode_unit_size[i] = mode_unit_size[(int) CCmode];
743: mode_wider_mode[i - 1] = (enum machine_mode) i;
744: mode_wider_mode[i] = VOIDmode;
745: }
746: #endif
747:
748: /* Find the narrowest mode for each class and compute the word and byte
749: modes. */
750:
751: for (i = 0; i < (int) MAX_MODE_CLASS; i++)
752: min_class_size[i] = 1000;
753:
1.1.1.2 ! root 754: byte_mode = VOIDmode;
! 755: word_mode = VOIDmode;
! 756:
1.1 root 757: for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
758: mode = (enum machine_mode) ((int) mode + 1))
759: {
760: if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
761: {
762: class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
763: min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
764: }
765: if (GET_MODE_CLASS (mode) == MODE_INT
1.1.1.2 ! root 766: && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
! 767: && byte_mode == VOIDmode)
1.1 root 768: byte_mode = mode;
769:
770: if (GET_MODE_CLASS (mode) == MODE_INT
1.1.1.2 ! root 771: && GET_MODE_BITSIZE (mode) == BITS_PER_WORD
! 772: && word_mode == VOIDmode)
1.1 root 773: word_mode = mode;
774: }
775: }
1.1.1.2 ! root 776:
! 777: #ifdef memset
! 778: gcc_memset (dest, value, len)
! 779: char *dest;
! 780: int value;
! 781: int len;
! 782: {
! 783: while (len-- > 0)
! 784: *dest++ = value;
! 785: }
! 786: #endif /* memset */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.