]> gcc.gnu.org Git - gcc.git/blob - gcc/rtl.c
# Fix misspellings in comments.
[gcc.git] / gcc / rtl.c
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
30 /* Obstack used for allocating RTL objects.
31 Between functions, this is the permanent_obstack.
32 While parsing and expanding a function, this is maybepermanent_obstack
33 so we can save it if it is an inline function.
34 During optimization and output, this is function_obstack. */
35
36 extern struct obstack *rtl_obstack;
37
38 #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
39 extern long atol();
40 #endif
41 \f
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
131 each character describes one operand. */
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 "w" an integer of width HOST_BITS_PER_WIDE_INT
142 prints the integer
143 "s" a pointer to a string
144 prints the string
145 "S" like "s", but optional:
146 the containing rtx may end before this operand
147 "e" a pointer to an rtl expression
148 prints the expression
149 "E" a pointer to a vector that points to a number of rtl expressions
150 prints a list of the rtl expressions
151 "V" like "E", but optional:
152 the containing rtx may end before this operand
153 "u" a pointer to another insn
154 prints the uid of the insn. */
155
156 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
157 #include "rtl.def" /* rtl expressions are defined here */
158 #undef DEF_RTL_EXPR
159 };
160
161 /* Indexed by rtx code, gives a character representing the "class" of
162 that rtx code. See rtl.def for documentation on the defined classes. */
163
164 char rtx_class[] = {
165 #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
166 #include "rtl.def" /* rtl expressions are defined here */
167 #undef DEF_RTL_EXPR
168 };
169
170 /* Names for kinds of NOTEs and REG_NOTEs. */
171
172 char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",
173 "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
174 "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
175 "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
176 "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
177 "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
178 "NOTE_INSN_DELETED_LABEL"};
179
180 char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
181 "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
182 "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
183 "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
184 "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
185
186 /* Allocate an rtx vector of N elements.
187 Store the length, and initialize all elements to zero. */
188
189 rtvec
190 rtvec_alloc (n)
191 int n;
192 {
193 rtvec rt;
194 int i;
195
196 rt = (rtvec) obstack_alloc (rtl_obstack,
197 sizeof (struct rtvec_def)
198 + (( n - 1) * sizeof (rtunion)));
199
200 /* clear out the vector */
201 PUT_NUM_ELEM(rt, n);
202 for (i=0; i < n; i++)
203 rt->elem[i].rtvec = NULL; /* @@ not portable due to rtunion */
204
205 return rt;
206 }
207
208 /* Allocate an rtx of code CODE. The CODE is stored in the rtx;
209 all the rest is initialized to zero. */
210
211 rtx
212 rtx_alloc (code)
213 RTX_CODE code;
214 {
215 rtx rt;
216 register struct obstack *ob = rtl_obstack;
217 register int nelts = GET_RTX_LENGTH (code);
218 register int length = sizeof (struct rtx_def)
219 + (nelts - 1) * sizeof (rtunion);
220
221 /* This function is called more than any other in GCC,
222 so we manipulate the obstack directly.
223
224 Even though rtx objects are word aligned, we may be sharing an obstack
225 with tree nodes, which may have to be double-word aligned. So align
226 our length to the alignment mask in the obstack. */
227
228 length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
229
230 if (ob->chunk_limit - ob->next_free < length)
231 _obstack_newchunk (ob, length);
232 rt = (rtx)ob->object_base;
233 ob->next_free += length;
234 ob->object_base = ob->next_free;
235
236 /* We want to clear everything up to the FLD array. Normally, this is
237 one int, but we don't want to assume that and it isn't very portable
238 anyway; this is. */
239
240 length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
241 for (; length >= 0; length--)
242 ((int *) rt)[length] = 0;
243
244 PUT_CODE (rt, code);
245
246 return rt;
247 }
248 \f
249 /* Create a new copy of an rtx.
250 Recursively copies the operands of the rtx,
251 except for those few rtx codes that are sharable. */
252
253 rtx
254 copy_rtx (orig)
255 register rtx orig;
256 {
257 register rtx copy;
258 register int i, j;
259 register RTX_CODE code;
260 register char *format_ptr;
261
262 code = GET_CODE (orig);
263
264 switch (code)
265 {
266 case REG:
267 case QUEUED:
268 case CONST_INT:
269 case CONST_DOUBLE:
270 case SYMBOL_REF:
271 case CODE_LABEL:
272 case PC:
273 case CC0:
274 case SCRATCH:
275 /* SCRATCH must be shared because they represent distinct values. */
276 return orig;
277
278 case CONST:
279 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
280 a LABEL_REF, it isn't sharable. */
281 if (GET_CODE (XEXP (orig, 0)) == PLUS
282 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
283 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
284 return orig;
285 break;
286
287 case MEM:
288 if (CONSTANT_ADDRESS_P (XEXP (orig, 0)))
289 return orig;
290 break;
291 }
292
293 copy = rtx_alloc (code);
294 PUT_MODE (copy, GET_MODE (orig));
295 copy->in_struct = orig->in_struct;
296 copy->volatil = orig->volatil;
297 copy->unchanging = orig->unchanging;
298 copy->integrated = orig->integrated;
299
300 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
301
302 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
303 {
304 switch (*format_ptr++)
305 {
306 case 'e':
307 XEXP (copy, i) = XEXP (orig, i);
308 if (XEXP (orig, i) != NULL)
309 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
310 break;
311
312 case '0':
313 case 'u':
314 XEXP (copy, i) = XEXP (orig, i);
315 break;
316
317 case 'E':
318 case 'V':
319 XVEC (copy, i) = XVEC (orig, i);
320 if (XVEC (orig, i) != NULL)
321 {
322 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
323 for (j = 0; j < XVECLEN (copy, i); j++)
324 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
325 }
326 break;
327
328 case 'w':
329 XWINT (copy, i) = XWINT (orig, i);
330 break;
331
332 case 'i':
333 XINT (copy, i) = XINT (orig, i);
334 break;
335
336 case 's':
337 case 'S':
338 XSTR (copy, i) = XSTR (orig, i);
339 break;
340
341 default:
342 abort ();
343 }
344 }
345 return copy;
346 }
347
348 /* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
349 placed in the result directly, rather than being copied. */
350
351 rtx
352 copy_most_rtx (orig, may_share)
353 register rtx orig;
354 register rtx may_share;
355 {
356 register rtx copy;
357 register int i, j;
358 register RTX_CODE code;
359 register char *format_ptr;
360
361 if (orig == may_share)
362 return orig;
363
364 code = GET_CODE (orig);
365
366 switch (code)
367 {
368 case REG:
369 case QUEUED:
370 case CONST_INT:
371 case CONST_DOUBLE:
372 case SYMBOL_REF:
373 case CODE_LABEL:
374 case PC:
375 case CC0:
376 return orig;
377 }
378
379 copy = rtx_alloc (code);
380 PUT_MODE (copy, GET_MODE (orig));
381 copy->in_struct = orig->in_struct;
382 copy->volatil = orig->volatil;
383 copy->unchanging = orig->unchanging;
384 copy->integrated = orig->integrated;
385
386 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
387
388 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
389 {
390 switch (*format_ptr++)
391 {
392 case 'e':
393 XEXP (copy, i) = XEXP (orig, i);
394 if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
395 XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
396 break;
397
398 case '0':
399 case 'u':
400 XEXP (copy, i) = XEXP (orig, i);
401 break;
402
403 case 'E':
404 case 'V':
405 XVEC (copy, i) = XVEC (orig, i);
406 if (XVEC (orig, i) != NULL)
407 {
408 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
409 for (j = 0; j < XVECLEN (copy, i); j++)
410 XVECEXP (copy, i, j)
411 = copy_most_rtx (XVECEXP (orig, i, j), may_share);
412 }
413 break;
414
415 case 'w':
416 XWINT (copy, i) = XWINT (orig, i);
417 break;
418
419 case 'n':
420 case 'i':
421 XINT (copy, i) = XINT (orig, i);
422 break;
423
424 case 's':
425 case 'S':
426 XSTR (copy, i) = XSTR (orig, i);
427 break;
428
429 default:
430 abort ();
431 }
432 }
433 return copy;
434 }
435 \f
436 /* Subroutines of read_rtx. */
437
438 /* Dump code after printing a message. Used when read_rtx finds
439 invalid data. */
440
441 static void
442 dump_and_abort (expected_c, actual_c, infile)
443 int expected_c, actual_c;
444 FILE *infile;
445 {
446 int c, i;
447
448 if (expected_c >= 0)
449 fprintf (stderr,
450 "Expected character %c. Found character %c.",
451 expected_c, actual_c);
452 fprintf (stderr, " At file position: %ld\n", ftell (infile));
453 fprintf (stderr, "Following characters are:\n\t");
454 for (i = 0; i < 200; i++)
455 {
456 c = getc (infile);
457 if (EOF == c) break;
458 putc (c, stderr);
459 }
460 fprintf (stderr, "Aborting.\n");
461 abort ();
462 }
463
464 /* Read chars from INFILE until a non-whitespace char
465 and return that. Comments, both Lisp style and C style,
466 are treated as whitespace.
467 Tools such as genflags use this function. */
468
469 int
470 read_skip_spaces (infile)
471 FILE *infile;
472 {
473 register int c;
474 while (c = getc (infile))
475 {
476 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
477 ;
478 else if (c == ';')
479 {
480 while ((c = getc (infile)) && c != '\n') ;
481 }
482 else if (c == '/')
483 {
484 register int prevc;
485 c = getc (infile);
486 if (c != '*')
487 dump_and_abort ('*', c, infile);
488
489 prevc = 0;
490 while (c = getc (infile))
491 {
492 if (prevc == '*' && c == '/')
493 break;
494 prevc = c;
495 }
496 }
497 else break;
498 }
499 return c;
500 }
501
502 /* Read an rtx code name into the buffer STR[].
503 It is terminated by any of the punctuation chars of rtx printed syntax. */
504
505 static void
506 read_name (str, infile)
507 char *str;
508 FILE *infile;
509 {
510 register char *p;
511 register int c;
512
513 c = read_skip_spaces(infile);
514
515 p = str;
516 while (1)
517 {
518 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
519 break;
520 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
521 || c == '(' || c == '[')
522 {
523 ungetc (c, infile);
524 break;
525 }
526 *p++ = c;
527 c = getc (infile);
528 }
529 if (p == str)
530 {
531 fprintf (stderr, "missing name or number");
532 dump_and_abort (-1, -1, infile);
533 }
534
535 *p = 0;
536 }
537 \f
538 /* Read an rtx in printed representation from INFILE
539 and return an actual rtx in core constructed accordingly.
540 read_rtx is not used in the compiler proper, but rather in
541 the utilities gen*.c that construct C code from machine descriptions. */
542
543 rtx
544 read_rtx (infile)
545 FILE *infile;
546 {
547 register int i, j, list_counter;
548 RTX_CODE tmp_code;
549 register char *format_ptr;
550 /* tmp_char is a buffer used for reading decimal integers
551 and names of rtx types and machine modes.
552 Therefore, 256 must be enough. */
553 char tmp_char[256];
554 rtx return_rtx;
555 register int c;
556 int tmp_int;
557 HOST_WIDE_INT tmp_wide;
558
559 /* Linked list structure for making RTXs: */
560 struct rtx_list
561 {
562 struct rtx_list *next;
563 rtx value; /* Value of this node... */
564 };
565
566 c = read_skip_spaces (infile); /* Should be open paren. */
567 if (c != '(')
568 dump_and_abort ('(', c, infile);
569
570 read_name (tmp_char, infile);
571
572 tmp_code = UNKNOWN;
573
574 for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
575 {
576 if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
577 {
578 tmp_code = (RTX_CODE) i; /* get value for name */
579 break;
580 }
581 }
582 if (tmp_code == UNKNOWN)
583 {
584 fprintf (stderr,
585 "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
586 tmp_char);
587 }
588 /* (NIL) stands for an expression that isn't there. */
589 if (tmp_code == NIL)
590 {
591 /* Discard the closeparen. */
592 while ((c = getc (infile)) && c != ')');
593 return 0;
594 }
595
596 return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
597 then we free this space below. */
598 format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
599
600 /* If what follows is `: mode ', read it and
601 store the mode in the rtx. */
602
603 i = read_skip_spaces (infile);
604 if (i == ':')
605 {
606 register int k;
607 read_name (tmp_char, infile);
608 for (k = 0; k < NUM_MACHINE_MODES; k++)
609 if (!strcmp (GET_MODE_NAME (k), tmp_char))
610 break;
611
612 PUT_MODE (return_rtx, (enum machine_mode) k );
613 }
614 else
615 ungetc (i, infile);
616
617 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
618 switch (*format_ptr++)
619 {
620 /* 0 means a field for internal use only.
621 Don't expect it to be present in the input. */
622 case '0':
623 break;
624
625 case 'e':
626 case 'u':
627 XEXP (return_rtx, i) = read_rtx (infile);
628 break;
629
630 case 'V':
631 /* 'V' is an optional vector: if a closeparen follows,
632 just store NULL for this element. */
633 c = read_skip_spaces (infile);
634 ungetc (c, infile);
635 if (c == ')')
636 {
637 XVEC (return_rtx, i) = 0;
638 break;
639 }
640 /* Now process the vector. */
641
642 case 'E':
643 {
644 register struct rtx_list *next_rtx, *rtx_list_link;
645 struct rtx_list *list_rtx;
646
647 c = read_skip_spaces (infile);
648 if (c != '[')
649 dump_and_abort ('[', c, infile);
650
651 /* add expressions to a list, while keeping a count */
652 next_rtx = NULL;
653 list_counter = 0;
654 while ((c = read_skip_spaces (infile)) && c != ']')
655 {
656 ungetc (c, infile);
657 list_counter++;
658 rtx_list_link = (struct rtx_list *)
659 alloca (sizeof (struct rtx_list));
660 rtx_list_link->value = read_rtx (infile);
661 if (next_rtx == 0)
662 list_rtx = rtx_list_link;
663 else
664 next_rtx->next = rtx_list_link;
665 next_rtx = rtx_list_link;
666 rtx_list_link->next = 0;
667 }
668 /* get vector length and allocate it */
669 XVEC (return_rtx, i) = (list_counter
670 ? rtvec_alloc (list_counter) : NULL_RTVEC);
671 if (list_counter > 0)
672 {
673 next_rtx = list_rtx;
674 for (j = 0; j < list_counter; j++,
675 next_rtx = next_rtx->next)
676 XVECEXP (return_rtx, i, j) = next_rtx->value;
677 }
678 /* close bracket gotten */
679 }
680 break;
681
682 case 'S':
683 /* 'S' is an optional string: if a closeparen follows,
684 just store NULL for this element. */
685 c = read_skip_spaces (infile);
686 ungetc (c, infile);
687 if (c == ')')
688 {
689 XSTR (return_rtx, i) = 0;
690 break;
691 }
692
693 case 's':
694 {
695 int saw_paren = 0;
696 register char *stringbuf;
697 int stringbufsize;
698
699 c = read_skip_spaces (infile);
700 if (c == '(')
701 {
702 saw_paren = 1;
703 c = read_skip_spaces (infile);
704 }
705 if (c != '"')
706 dump_and_abort ('"', c, infile);
707
708 while (1)
709 {
710 c = getc (infile); /* Read the string */
711 if (c == '\\')
712 {
713 c = getc (infile); /* Read the string */
714 /* \; makes stuff for a C string constant containing
715 newline and tab. */
716 if (c == ';')
717 {
718 obstack_grow (rtl_obstack, "\\n\\t", 4);
719 continue;
720 }
721 }
722 else if (c == '"')
723 break;
724
725 obstack_1grow (rtl_obstack, c);
726 }
727
728 obstack_1grow (rtl_obstack, 0);
729 stringbuf = (char *) obstack_finish (rtl_obstack);
730
731 if (saw_paren)
732 {
733 c = read_skip_spaces (infile);
734 if (c != ')')
735 dump_and_abort (')', c, infile);
736 }
737 XSTR (return_rtx, i) = stringbuf;
738 }
739 break;
740
741 case 'w':
742 read_name (tmp_char, infile);
743 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
744 tmp_wide = atoi (tmp_char);
745 #else
746 tmp_wide = atol (tmp_char);
747 #endif
748 XWINT (return_rtx, i) = tmp_wide;
749 break;
750
751 case 'i':
752 case 'n':
753 read_name (tmp_char, infile);
754 tmp_int = atoi (tmp_char);
755 XINT (return_rtx, i) = tmp_int;
756 break;
757
758 default:
759 fprintf (stderr,
760 "switch format wrong in rtl.read_rtx(). format was: %c.\n",
761 format_ptr[-1]);
762 fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
763 abort ();
764 }
765
766 c = read_skip_spaces (infile);
767 if (c != ')')
768 dump_and_abort (')', c, infile);
769
770 return return_rtx;
771 }
772 \f
773 /* This is called once per compilation, before any rtx's are constructed.
774 It initializes the vector `rtx_length', the extra CC modes, if any,
775 and computes certain commonly-used modes. */
776
777 void
778 init_rtl ()
779 {
780 int min_class_size[(int) MAX_MODE_CLASS];
781 enum machine_mode mode;
782 int i;
783
784 for (i = 0; i < NUM_RTX_CODE; i++)
785 rtx_length[i] = strlen (rtx_format[i]);
786
787 /* Make CONST_DOUBLE bigger, if real values are bigger than
788 it normally expects to have room for.
789 Note that REAL_VALUE_TYPE is not defined by default,
790 since tree.h is not included. But the default dfn as `double'
791 would do no harm. */
792 #ifdef REAL_VALUE_TYPE
793 i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
794 if (rtx_length[(int) CONST_DOUBLE] < i)
795 {
796 char *s = (char *) xmalloc (i + 1);
797 rtx_length[(int) CONST_DOUBLE] = i;
798 rtx_format[(int) CONST_DOUBLE] = s;
799 *s++ = 'e';
800 *s++ = '0';
801 /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
802 of as many `i's as we now have elements. */
803 for (i = 0; i < rtx_length[(int) CONST_DOUBLE]; i++)
804 *s++ = 'w';
805 *s++ = 0;
806 }
807 #endif
808
809 #ifdef EXTRA_CC_MODES
810 for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
811 {
812 mode_class[i] = MODE_CC;
813 mode_size[i] = mode_size[(int) CCmode];
814 mode_unit_size[i] = mode_unit_size[(int) CCmode];
815 mode_wider_mode[i - 1] = (enum machine_mode) i;
816 mode_wider_mode[i] = VOIDmode;
817 }
818 #endif
819
820 /* Find the narrowest mode for each class and compute the word and byte
821 modes. */
822
823 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
824 min_class_size[i] = 1000;
825
826 byte_mode = VOIDmode;
827 word_mode = VOIDmode;
828
829 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
830 mode = (enum machine_mode) ((int) mode + 1))
831 {
832 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
833 {
834 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
835 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
836 }
837 if (GET_MODE_CLASS (mode) == MODE_INT
838 && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
839 && byte_mode == VOIDmode)
840 byte_mode = mode;
841
842 if (GET_MODE_CLASS (mode) == MODE_INT
843 && GET_MODE_BITSIZE (mode) == BITS_PER_WORD
844 && word_mode == VOIDmode)
845 word_mode = mode;
846 }
847 }
848 \f
849 #ifdef memset
850 gcc_memset (dest, value, len)
851 char *dest;
852 int value;
853 int len;
854 {
855 while (len-- > 0)
856 *dest++ = value;
857 }
858 #endif /* memset */
This page took 0.075835 seconds and 5 git commands to generate.