/* Allocate and read RTL for GNU C Compiler.
- Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1991, 1994 Free Software Foundation, Inc.
This file is part of GNU CC.
You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include "config.h"
#include <ctype.h>
#include <stdio.h>
#include "rtl.h"
+#include "real.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern int xmalloc ();
-extern void free ();
/* Obstack used for allocating RTL objects.
Between functions, this is the permanent_obstack.
extern struct obstack *rtl_obstack;
-extern long ftell();
+#if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
+extern long atol();
+#endif
\f
/* Indexed by rtx code, gives number of operands for an rtx with that code.
Does NOT include rtx header data (code and links).
enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
-/* Commonly used modes. */
-
-enum machine_mode byte_mode; /* Mode whose width is BITS_PER_UNIT */
-enum machine_mode word_mode; /* Mode whose width is BITS_PER_WORD */
-
/* Indexed by rtx code, gives a sequence of operand-types for
rtx's of that code. The sequence is a C string in which
each character describes one operand. */
"i" an integer
prints the integer
"n" like "i", but prints entries from `note_insn_name'
+ "w" an integer of width HOST_BITS_PER_WIDE_INT
+ prints the integer
"s" a pointer to a string
prints the string
"S" like "s", but optional:
/* Names for kinds of NOTEs and REG_NOTEs. */
-char *note_insn_name[] = { "NOTE_INSN_FUNCTION_BEG", "NOTE_INSN_DELETED",
+char *note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
"NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
"NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
"NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
- "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP" };
+ "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
+ "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
+ "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
+ "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END"};
char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
+ (( n - 1) * sizeof (rtunion)));
/* clear out the vector */
- PUT_NUM_ELEM(rt, n);
- for (i=0; i < n; i++)
- rt->elem[i].rtvec = NULL; /* @@ not portable due to rtunion */
+ PUT_NUM_ELEM (rt, n);
+
+ for (i = 0; i < n; i++)
+ rt->elem[i].rtwint = 0;
return rt;
}
ob->next_free += length;
ob->object_base = ob->next_free;
- * (int *) rt = 0;
+ /* We want to clear everything up to the FLD array. Normally, this is
+ one int, but we don't want to assume that and it isn't very portable
+ anyway; this is. */
+
+ length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
+ for (; length >= 0; length--)
+ ((int *) rt)[length] = 0;
+
PUT_CODE (rt, code);
return rt;
}
+
+/* Free the rtx X and all RTL allocated since X. */
+
+void
+rtx_free (x)
+ rtx x;
+{
+ obstack_free (rtl_obstack, x);
+}
\f
/* Create a new copy of an rtx.
Recursively copies the operands of the rtx,
case CODE_LABEL:
case PC:
case CC0:
+ case SCRATCH:
+ /* SCRATCH must be shared because they represent distinct values. */
return orig;
+
+ case CONST:
+ /* CONST can be shared if it contains a SYMBOL_REF. If it contains
+ a LABEL_REF, it isn't sharable. */
+ if (GET_CODE (XEXP (orig, 0)) == PLUS
+ && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
+ && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
+ return orig;
+ break;
+
+ /* A MEM with a constant address is not sharable. The problem is that
+ the constant address may need to be reloaded. If the mem is shared,
+ then reloading one copy of this mem will cause all copies to appear
+ to have been reloaded. */
}
copy = rtx_alloc (code);
XEXP (copy, i) = copy_rtx (XEXP (orig, i));
break;
+ case '0':
case 'u':
XEXP (copy, i) = XEXP (orig, i);
break;
}
break;
- default:
+ case 'w':
+ XWINT (copy, i) = XWINT (orig, i);
+ break;
+
+ case 'i':
XINT (copy, i) = XINT (orig, i);
break;
+
+ case 's':
+ case 'S':
+ XSTR (copy, i) = XSTR (orig, i);
+ break;
+
+ default:
+ abort ();
}
}
return copy;
XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
break;
+ case '0':
case 'u':
XEXP (copy, i) = XEXP (orig, i);
break;
}
break;
- default:
+ case 'w':
+ XWINT (copy, i) = XWINT (orig, i);
+ break;
+
+ case 'n':
+ case 'i':
XINT (copy, i) = XINT (orig, i);
break;
+
+ case 's':
+ case 'S':
+ XSTR (copy, i) = XSTR (orig, i);
+ break;
+
+ default:
+ abort ();
}
}
return copy;
rtx return_rtx;
register int c;
int tmp_int;
+ HOST_WIDE_INT tmp_wide;
/* Linked list structure for making RTXs: */
struct rtx_list
}
/* get vector length and allocate it */
XVEC (return_rtx, i) = (list_counter
- ? rtvec_alloc (list_counter)
- : (struct rtvec_def *) NULL);
+ ? rtvec_alloc (list_counter) : NULL_RTVEC);
if (list_counter > 0)
{
next_rtx = list_rtx;
{
int saw_paren = 0;
register char *stringbuf;
- int stringbufsize;
c = read_skip_spaces (infile);
if (c == '(')
}
break;
+ case 'w':
+ read_name (tmp_char, infile);
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+ tmp_wide = atoi (tmp_char);
+#else
+ tmp_wide = atol (tmp_char);
+#endif
+ XWINT (return_rtx, i) = tmp_wide;
+ break;
+
case 'i':
case 'n':
read_name (tmp_char, infile);
*s++ = 'e';
*s++ = '0';
/* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
- of as many `i's as we now have elements. */
- for (i = 0; i < rtx_length[(int) CONST_DOUBLE]; i++)
- *s++ = 'i';
+ of as many `w's as we now have elements. Subtract two from
+ the size to account for the 'e' and the '0'. */
+ for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
+ *s++ = 'w';
*s++ = 0;
}
#endif
}
#endif
- /* Find the narrowest mode for each class and compute the word and byte
- modes. */
+ /* Find the narrowest mode for each class. */
for (i = 0; i < (int) MAX_MODE_CLASS; i++)
min_class_size[i] = 1000;
- byte_mode = VOIDmode;
- word_mode = VOIDmode;
-
for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
mode = (enum machine_mode) ((int) mode + 1))
{
class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
}
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
- && byte_mode == VOIDmode)
- byte_mode = mode;
-
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_BITSIZE (mode) == BITS_PER_WORD
- && word_mode == VOIDmode)
- word_mode = mode;
}
}
\f