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