]> gcc.gnu.org Git - gcc.git/blame - gcc/rtl.c
90th Cygnus<->FSF quick merge
[gcc.git] / gcc / rtl.c
CommitLineData
6f29feb1 1/* Allocate and read RTL for GNU C Compiler.
0df564e5 2 Copyright (C) 1987, 1988, 1991, 1994 Free Software Foundation, Inc.
6f29feb1
JW
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
e99215a3
RK
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
6f29feb1
JW
20
21
22#include "config.h"
23#include <ctype.h>
24#include <stdio.h>
25#include "rtl.h"
a19a1b5d 26#include "real.h"
6f29feb1
JW
27
28#include "obstack.h"
29#define obstack_chunk_alloc xmalloc
30#define obstack_chunk_free free
6f29feb1
JW
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
38extern struct obstack *rtl_obstack;
39
c166a311
CH
40#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
41extern long atol();
42#endif
6f29feb1
JW
43\f
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. */
47
48int rtx_length[NUM_RTX_CODE + 1];
49
50/* Indexed by rtx code, gives the name of that kind of rtx, as a C string. */
51
52#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) NAME ,
53
54char *rtx_name[] = {
55#include "rtl.def" /* rtl expressions are documented here */
56};
57
58#undef DEF_RTL_EXPR
59
60/* Indexed by machine mode, gives the name of that machine mode.
61 This name does not include the letters "mode". */
62
63#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) NAME,
64
65char *mode_name[(int) MAX_MACHINE_MODE] = {
66#include "machmode.def"
67
68#ifdef EXTRA_CC_MODES
69 EXTRA_CC_NAMES
70#endif
71
72};
73
74#undef DEF_MACHMODE
75
76/* Indexed by machine mode, gives the length of the mode, in bytes.
77 GET_MODE_CLASS uses this. */
78
79#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) CLASS,
80
81enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
82#include "machmode.def"
83};
84
85#undef DEF_MACHMODE
86
87/* Indexed by machine mode, gives the length of the mode, in bytes.
88 GET_MODE_SIZE uses this. */
89
90#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) SIZE,
91
92int mode_size[(int) MAX_MACHINE_MODE] = {
93#include "machmode.def"
94};
95
96#undef DEF_MACHMODE
97
98/* Indexed by machine mode, gives the length of the mode's subunit.
99 GET_MODE_UNIT_SIZE uses this. */
100
101#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) UNIT,
102
103int mode_unit_size[(int) MAX_MACHINE_MODE] = {
104#include "machmode.def" /* machine modes are documented here */
105};
106
107#undef DEF_MACHMODE
108
109/* Indexed by machine mode, gives next wider natural mode
110 (QI -> HI -> SI -> DI, etc.) Widening multiply instructions
111 use this. */
112
113#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) \
114 (enum machine_mode) WIDER,
115
116enum machine_mode mode_wider_mode[(int) MAX_MACHINE_MODE] = {
117#include "machmode.def" /* machine modes are documented here */
118};
119
120#undef DEF_MACHMODE
121
4a39a918
RK
122/* Indexed by mode class, gives the narrowest mode for each class. */
123
124enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
125
6f29feb1
JW
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
6dc42e49 128 each character describes one operand. */
6f29feb1
JW
129
130char *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'
c166a311
CH
138 "w" an integer of width HOST_BITS_PER_WIDE_INT
139 prints the integer
6f29feb1
JW
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. */
152
153#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) FORMAT ,
154#include "rtl.def" /* rtl expressions are defined here */
155#undef DEF_RTL_EXPR
156};
157
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. */
160
161char 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
165};
166
167/* Names for kinds of NOTEs and REG_NOTEs. */
168
a31efb86 169char *note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
6f29feb1
JW
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",
bdac5f58 173 "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
196cedd0 174 "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
3d195391
MS
175 "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
176 "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END"};
6f29feb1
JW
177
178char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
179 "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
180 "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
181 "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
182 "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
183
184/* Allocate an rtx vector of N elements.
185 Store the length, and initialize all elements to zero. */
186
187rtvec
188rtvec_alloc (n)
189 int n;
190{
191 rtvec rt;
192 int i;
193
194 rt = (rtvec) obstack_alloc (rtl_obstack,
195 sizeof (struct rtvec_def)
196 + (( n - 1) * sizeof (rtunion)));
197
198 /* clear out the vector */
395d53bb
RK
199 PUT_NUM_ELEM (rt, n);
200
201 for (i = 0; i < n; i++)
202 rt->elem[i].rtwint = 0;
6f29feb1
JW
203
204 return rt;
205}
206
207/* Allocate an rtx of code CODE. The CODE is stored in the rtx;
208 all the rest is initialized to zero. */
209
210rtx
211rtx_alloc (code)
212 RTX_CODE code;
213{
214 rtx rt;
215 register struct obstack *ob = rtl_obstack;
216 register int nelts = GET_RTX_LENGTH (code);
217 register int length = sizeof (struct rtx_def)
218 + (nelts - 1) * sizeof (rtunion);
219
220 /* This function is called more than any other in GCC,
221 so we manipulate the obstack directly.
222
223 Even though rtx objects are word aligned, we may be sharing an obstack
224 with tree nodes, which may have to be double-word aligned. So align
225 our length to the alignment mask in the obstack. */
226
227 length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
228
229 if (ob->chunk_limit - ob->next_free < length)
230 _obstack_newchunk (ob, length);
231 rt = (rtx)ob->object_base;
232 ob->next_free += length;
233 ob->object_base = ob->next_free;
234
2151a093
RK
235 /* We want to clear everything up to the FLD array. Normally, this is
236 one int, but we don't want to assume that and it isn't very portable
237 anyway; this is. */
238
239 length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
240 for (; length >= 0; length--)
241 ((int *) rt)[length] = 0;
242
6f29feb1
JW
243 PUT_CODE (rt, code);
244
245 return rt;
246}
9b404774
RS
247
248/* Free the rtx X and all RTL allocated since X. */
249
250void
251rtx_free (x)
252 rtx x;
253{
254 obstack_free (rtl_obstack, x);
255}
6f29feb1
JW
256\f
257/* Create a new copy of an rtx.
258 Recursively copies the operands of the rtx,
259 except for those few rtx codes that are sharable. */
260
261rtx
262copy_rtx (orig)
263 register rtx orig;
264{
265 register rtx copy;
266 register int i, j;
267 register RTX_CODE code;
268 register char *format_ptr;
269
270 code = GET_CODE (orig);
271
272 switch (code)
273 {
274 case REG:
275 case QUEUED:
276 case CONST_INT:
277 case CONST_DOUBLE:
278 case SYMBOL_REF:
279 case CODE_LABEL:
280 case PC:
281 case CC0:
cf526dcc 282 case SCRATCH:
0f41302f 283 /* SCRATCH must be shared because they represent distinct values. */
6f29feb1 284 return orig;
cf526dcc
RK
285
286 case CONST:
287 /* CONST can be shared if it contains a SYMBOL_REF. If it contains
288 a LABEL_REF, it isn't sharable. */
289 if (GET_CODE (XEXP (orig, 0)) == PLUS
290 && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
291 && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
292 return orig;
293 break;
294
cc81e625
JW
295 /* A MEM with a constant address is not sharable. The problem is that
296 the constant address may need to be reloaded. If the mem is shared,
297 then reloading one copy of this mem will cause all copies to appear
298 to have been reloaded. */
6f29feb1
JW
299 }
300
301 copy = rtx_alloc (code);
302 PUT_MODE (copy, GET_MODE (orig));
303 copy->in_struct = orig->in_struct;
304 copy->volatil = orig->volatil;
305 copy->unchanging = orig->unchanging;
306 copy->integrated = orig->integrated;
307
308 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
309
310 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
311 {
312 switch (*format_ptr++)
313 {
314 case 'e':
315 XEXP (copy, i) = XEXP (orig, i);
316 if (XEXP (orig, i) != NULL)
317 XEXP (copy, i) = copy_rtx (XEXP (orig, i));
318 break;
319
c166a311 320 case '0':
f1027406
RK
321 case 'u':
322 XEXP (copy, i) = XEXP (orig, i);
323 break;
324
6f29feb1
JW
325 case 'E':
326 case 'V':
327 XVEC (copy, i) = XVEC (orig, i);
328 if (XVEC (orig, i) != NULL)
329 {
330 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
331 for (j = 0; j < XVECLEN (copy, i); j++)
332 XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
333 }
334 break;
335
c166a311
CH
336 case 'w':
337 XWINT (copy, i) = XWINT (orig, i);
338 break;
339
340 case 'i':
6f29feb1
JW
341 XINT (copy, i) = XINT (orig, i);
342 break;
c166a311
CH
343
344 case 's':
345 case 'S':
346 XSTR (copy, i) = XSTR (orig, i);
347 break;
348
349 default:
350 abort ();
6f29feb1
JW
351 }
352 }
353 return copy;
354}
355
356/* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
357 placed in the result directly, rather than being copied. */
358
359rtx
360copy_most_rtx (orig, may_share)
361 register rtx orig;
362 register rtx may_share;
363{
364 register rtx copy;
365 register int i, j;
366 register RTX_CODE code;
367 register char *format_ptr;
368
369 if (orig == may_share)
370 return orig;
371
372 code = GET_CODE (orig);
373
374 switch (code)
375 {
376 case REG:
377 case QUEUED:
378 case CONST_INT:
379 case CONST_DOUBLE:
380 case SYMBOL_REF:
381 case CODE_LABEL:
382 case PC:
383 case CC0:
384 return orig;
385 }
386
387 copy = rtx_alloc (code);
388 PUT_MODE (copy, GET_MODE (orig));
389 copy->in_struct = orig->in_struct;
390 copy->volatil = orig->volatil;
391 copy->unchanging = orig->unchanging;
392 copy->integrated = orig->integrated;
393
394 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
395
396 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
397 {
398 switch (*format_ptr++)
399 {
400 case 'e':
401 XEXP (copy, i) = XEXP (orig, i);
402 if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
403 XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
404 break;
f1027406 405
c166a311 406 case '0':
f1027406
RK
407 case 'u':
408 XEXP (copy, i) = XEXP (orig, i);
409 break;
6f29feb1
JW
410
411 case 'E':
412 case 'V':
413 XVEC (copy, i) = XVEC (orig, i);
414 if (XVEC (orig, i) != NULL)
415 {
416 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
417 for (j = 0; j < XVECLEN (copy, i); j++)
418 XVECEXP (copy, i, j)
419 = copy_most_rtx (XVECEXP (orig, i, j), may_share);
420 }
421 break;
422
c166a311
CH
423 case 'w':
424 XWINT (copy, i) = XWINT (orig, i);
425 break;
426
427 case 'n':
428 case 'i':
6f29feb1
JW
429 XINT (copy, i) = XINT (orig, i);
430 break;
c166a311
CH
431
432 case 's':
433 case 'S':
434 XSTR (copy, i) = XSTR (orig, i);
435 break;
436
437 default:
438 abort ();
6f29feb1
JW
439 }
440 }
441 return copy;
442}
443\f
6f29feb1
JW
444/* Subroutines of read_rtx. */
445
446/* Dump code after printing a message. Used when read_rtx finds
447 invalid data. */
448
449static void
450dump_and_abort (expected_c, actual_c, infile)
451 int expected_c, actual_c;
452 FILE *infile;
453{
454 int c, i;
455
456 if (expected_c >= 0)
457 fprintf (stderr,
458 "Expected character %c. Found character %c.",
459 expected_c, actual_c);
460 fprintf (stderr, " At file position: %ld\n", ftell (infile));
461 fprintf (stderr, "Following characters are:\n\t");
462 for (i = 0; i < 200; i++)
463 {
464 c = getc (infile);
465 if (EOF == c) break;
466 putc (c, stderr);
467 }
468 fprintf (stderr, "Aborting.\n");
469 abort ();
470}
471
472/* Read chars from INFILE until a non-whitespace char
473 and return that. Comments, both Lisp style and C style,
474 are treated as whitespace.
475 Tools such as genflags use this function. */
476
477int
478read_skip_spaces (infile)
479 FILE *infile;
480{
481 register int c;
482 while (c = getc (infile))
483 {
484 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
485 ;
486 else if (c == ';')
487 {
488 while ((c = getc (infile)) && c != '\n') ;
489 }
490 else if (c == '/')
491 {
492 register int prevc;
493 c = getc (infile);
494 if (c != '*')
495 dump_and_abort ('*', c, infile);
496
497 prevc = 0;
498 while (c = getc (infile))
499 {
500 if (prevc == '*' && c == '/')
501 break;
502 prevc = c;
503 }
504 }
505 else break;
506 }
507 return c;
508}
509
510/* Read an rtx code name into the buffer STR[].
511 It is terminated by any of the punctuation chars of rtx printed syntax. */
512
513static void
514read_name (str, infile)
515 char *str;
516 FILE *infile;
517{
518 register char *p;
519 register int c;
520
521 c = read_skip_spaces(infile);
522
523 p = str;
524 while (1)
525 {
526 if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
527 break;
528 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
529 || c == '(' || c == '[')
530 {
531 ungetc (c, infile);
532 break;
533 }
534 *p++ = c;
535 c = getc (infile);
536 }
537 if (p == str)
538 {
539 fprintf (stderr, "missing name or number");
540 dump_and_abort (-1, -1, infile);
541 }
542
543 *p = 0;
544}
545\f
546/* Read an rtx in printed representation from INFILE
547 and return an actual rtx in core constructed accordingly.
548 read_rtx is not used in the compiler proper, but rather in
549 the utilities gen*.c that construct C code from machine descriptions. */
550
551rtx
552read_rtx (infile)
553 FILE *infile;
554{
555 register int i, j, list_counter;
556 RTX_CODE tmp_code;
557 register char *format_ptr;
558 /* tmp_char is a buffer used for reading decimal integers
559 and names of rtx types and machine modes.
560 Therefore, 256 must be enough. */
561 char tmp_char[256];
562 rtx return_rtx;
563 register int c;
564 int tmp_int;
c166a311 565 HOST_WIDE_INT tmp_wide;
6f29feb1
JW
566
567 /* Linked list structure for making RTXs: */
568 struct rtx_list
569 {
570 struct rtx_list *next;
571 rtx value; /* Value of this node... */
572 };
573
574 c = read_skip_spaces (infile); /* Should be open paren. */
575 if (c != '(')
576 dump_and_abort ('(', c, infile);
577
578 read_name (tmp_char, infile);
579
580 tmp_code = UNKNOWN;
581
582 for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
583 {
584 if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
585 {
586 tmp_code = (RTX_CODE) i; /* get value for name */
587 break;
588 }
589 }
590 if (tmp_code == UNKNOWN)
591 {
592 fprintf (stderr,
593 "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
594 tmp_char);
595 }
596 /* (NIL) stands for an expression that isn't there. */
597 if (tmp_code == NIL)
598 {
599 /* Discard the closeparen. */
600 while ((c = getc (infile)) && c != ')');
601 return 0;
602 }
603
604 return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
605 then we free this space below. */
606 format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
607
608 /* If what follows is `: mode ', read it and
609 store the mode in the rtx. */
610
611 i = read_skip_spaces (infile);
612 if (i == ':')
613 {
614 register int k;
615 read_name (tmp_char, infile);
616 for (k = 0; k < NUM_MACHINE_MODES; k++)
617 if (!strcmp (GET_MODE_NAME (k), tmp_char))
618 break;
619
620 PUT_MODE (return_rtx, (enum machine_mode) k );
621 }
622 else
623 ungetc (i, infile);
624
625 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
626 switch (*format_ptr++)
627 {
628 /* 0 means a field for internal use only.
629 Don't expect it to be present in the input. */
630 case '0':
631 break;
632
633 case 'e':
634 case 'u':
635 XEXP (return_rtx, i) = read_rtx (infile);
636 break;
637
638 case 'V':
639 /* 'V' is an optional vector: if a closeparen follows,
640 just store NULL for this element. */
641 c = read_skip_spaces (infile);
642 ungetc (c, infile);
643 if (c == ')')
644 {
645 XVEC (return_rtx, i) = 0;
646 break;
647 }
648 /* Now process the vector. */
649
650 case 'E':
651 {
652 register struct rtx_list *next_rtx, *rtx_list_link;
653 struct rtx_list *list_rtx;
654
655 c = read_skip_spaces (infile);
656 if (c != '[')
657 dump_and_abort ('[', c, infile);
658
659 /* add expressions to a list, while keeping a count */
660 next_rtx = NULL;
661 list_counter = 0;
662 while ((c = read_skip_spaces (infile)) && c != ']')
663 {
664 ungetc (c, infile);
665 list_counter++;
666 rtx_list_link = (struct rtx_list *)
667 alloca (sizeof (struct rtx_list));
668 rtx_list_link->value = read_rtx (infile);
669 if (next_rtx == 0)
670 list_rtx = rtx_list_link;
671 else
672 next_rtx->next = rtx_list_link;
673 next_rtx = rtx_list_link;
674 rtx_list_link->next = 0;
675 }
676 /* get vector length and allocate it */
677 XVEC (return_rtx, i) = (list_counter
c166a311 678 ? rtvec_alloc (list_counter) : NULL_RTVEC);
6f29feb1
JW
679 if (list_counter > 0)
680 {
681 next_rtx = list_rtx;
682 for (j = 0; j < list_counter; j++,
683 next_rtx = next_rtx->next)
684 XVECEXP (return_rtx, i, j) = next_rtx->value;
685 }
686 /* close bracket gotten */
687 }
688 break;
689
690 case 'S':
691 /* 'S' is an optional string: if a closeparen follows,
692 just store NULL for this element. */
693 c = read_skip_spaces (infile);
694 ungetc (c, infile);
695 if (c == ')')
696 {
697 XSTR (return_rtx, i) = 0;
698 break;
699 }
700
701 case 's':
702 {
703 int saw_paren = 0;
704 register char *stringbuf;
6f29feb1
JW
705
706 c = read_skip_spaces (infile);
707 if (c == '(')
708 {
709 saw_paren = 1;
710 c = read_skip_spaces (infile);
711 }
712 if (c != '"')
713 dump_and_abort ('"', c, infile);
6f29feb1
JW
714
715 while (1)
716 {
2dcb563f
RS
717 c = getc (infile); /* Read the string */
718 if (c == '\\')
6f29feb1 719 {
2dcb563f 720 c = getc (infile); /* Read the string */
6f29feb1
JW
721 /* \; makes stuff for a C string constant containing
722 newline and tab. */
2dcb563f 723 if (c == ';')
81dd58a6
RS
724 {
725 obstack_grow (rtl_obstack, "\\n\\t", 4);
726 continue;
727 }
6f29feb1 728 }
2dcb563f 729 else if (c == '"')
6f29feb1 730 break;
2dcb563f
RS
731
732 obstack_1grow (rtl_obstack, c);
6f29feb1
JW
733 }
734
2dcb563f
RS
735 obstack_1grow (rtl_obstack, 0);
736 stringbuf = (char *) obstack_finish (rtl_obstack);
6f29feb1
JW
737
738 if (saw_paren)
739 {
740 c = read_skip_spaces (infile);
741 if (c != ')')
742 dump_and_abort (')', c, infile);
743 }
744 XSTR (return_rtx, i) = stringbuf;
745 }
746 break;
747
c166a311
CH
748 case 'w':
749 read_name (tmp_char, infile);
750#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
751 tmp_wide = atoi (tmp_char);
752#else
753 tmp_wide = atol (tmp_char);
754#endif
755 XWINT (return_rtx, i) = tmp_wide;
756 break;
757
6f29feb1
JW
758 case 'i':
759 case 'n':
760 read_name (tmp_char, infile);
761 tmp_int = atoi (tmp_char);
762 XINT (return_rtx, i) = tmp_int;
763 break;
764
765 default:
766 fprintf (stderr,
767 "switch format wrong in rtl.read_rtx(). format was: %c.\n",
768 format_ptr[-1]);
769 fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
770 abort ();
771 }
772
773 c = read_skip_spaces (infile);
774 if (c != ')')
775 dump_and_abort (')', c, infile);
776
777 return return_rtx;
778}
779\f
780/* This is called once per compilation, before any rtx's are constructed.
4a39a918
RK
781 It initializes the vector `rtx_length', the extra CC modes, if any,
782 and computes certain commonly-used modes. */
6f29feb1
JW
783
784void
785init_rtl ()
786{
4a39a918
RK
787 int min_class_size[(int) MAX_MODE_CLASS];
788 enum machine_mode mode;
6f29feb1
JW
789 int i;
790
791 for (i = 0; i < NUM_RTX_CODE; i++)
792 rtx_length[i] = strlen (rtx_format[i]);
793
794 /* Make CONST_DOUBLE bigger, if real values are bigger than
795 it normally expects to have room for.
796 Note that REAL_VALUE_TYPE is not defined by default,
797 since tree.h is not included. But the default dfn as `double'
798 would do no harm. */
799#ifdef REAL_VALUE_TYPE
800 i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
801 if (rtx_length[(int) CONST_DOUBLE] < i)
802 {
803 char *s = (char *) xmalloc (i + 1);
804 rtx_length[(int) CONST_DOUBLE] = i;
805 rtx_format[(int) CONST_DOUBLE] = s;
806 *s++ = 'e';
807 *s++ = '0';
808 /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
262555e2
RS
809 of as many `w's as we now have elements. Subtract two from
810 the size to account for the 'e' and the '0'. */
811 for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
c166a311 812 *s++ = 'w';
6f29feb1
JW
813 *s++ = 0;
814 }
815#endif
816
817#ifdef EXTRA_CC_MODES
818 for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
819 {
820 mode_class[i] = MODE_CC;
821 mode_size[i] = mode_size[(int) CCmode];
822 mode_unit_size[i] = mode_unit_size[(int) CCmode];
823 mode_wider_mode[i - 1] = (enum machine_mode) i;
824 mode_wider_mode[i] = VOIDmode;
825 }
826#endif
4a39a918 827
d3d63026 828 /* Find the narrowest mode for each class. */
4a39a918
RK
829
830 for (i = 0; i < (int) MAX_MODE_CLASS; i++)
831 min_class_size[i] = 1000;
832
833 for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
834 mode = (enum machine_mode) ((int) mode + 1))
835 {
836 if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
837 {
838 class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
839 min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
840 }
4a39a918 841 }
6f29feb1 842}
e8aa1193
TW
843\f
844#ifdef memset
845gcc_memset (dest, value, len)
846 char *dest;
847 int value;
848 int len;
849{
850 while (len-- > 0)
851 *dest++ = value;
852}
853#endif /* memset */
This page took 0.484563 seconds and 5 git commands to generate.