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