aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-01-08 13:17:05 -0800
committerRichard Henderson <rth@gcc.gnu.org>1998-01-08 13:17:05 -0800
commit3b80f6ca69f78207e8fcf8e835a4a8aa2e4abfba (patch)
treec792e877a8974b6884a66403f5d9b9ee06c23290 /gcc
parentf4a233434d41848d9ae3bcb0f9518dfd986143ba (diff)
downloadgcc-3b80f6ca69f78207e8fcf8e835a4a8aa2e4abfba.zip
gcc-3b80f6ca69f78207e8fcf8e835a4a8aa2e4abfba.tar.gz
gcc-3b80f6ca69f78207e8fcf8e835a4a8aa2e4abfba.tar.bz2
Makefile.in (OBJ, GEN, RTL_H): Add genrtl.[oh] bits.
* Makefile.in (OBJ, GEN, RTL_H): Add genrtl.[oh] bits. * emit-rtl.c (gen_rtx): Move special code to ... (gen_rtx_CONST_INT): New function. (gen_rtx_REG): New function. (*): Update all calls to gen_rtx. * genemit.c (gen_exp): Emit calls to gen_rtx_FOO for constant FOO. * rtl.h: Include genrtl.h; prototype CONST_INT & REG generators. (GEN_INT): Call gen_rtx_CONST_INT. * gengenrtl.c: New file. From-SVN: r17312
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/Makefile.in29
-rw-r--r--gcc/emit-rtl.c203
-rw-r--r--gcc/genemit.c8
-rw-r--r--gcc/gengenrtl.c287
-rw-r--r--gcc/rtl.h19
6 files changed, 444 insertions, 114 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6dc60ed..3b8cf2b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+Thu Jan 8 21:06:54 1998 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (OBJ, GEN, RTL_H): Add genrtl.[oh] bits.
+ * emit-rtl.c (gen_rtx): Move special code to ...
+ (gen_rtx_CONST_INT): New function.
+ (gen_rtx_REG): New function.
+ (*): Update all calls to gen_rtx.
+ * genemit.c (gen_exp): Emit calls to gen_rtx_FOO for constant FOO.
+ * rtl.h: Include genrtl.h; prototype CONST_INT & REG generators.
+ (GEN_INT): Call gen_rtx_CONST_INT.
+ * gengenrtl.c: New file.
+
Mon Jan 5 13:00:18 1998 John F. Carr <jfc@mit.edu>
* alias.c (*_dependence): Call base_alias_check before canon_rtx.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index d4a682a..d79d58a 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -589,7 +589,7 @@ SCHED_CFLAGS = @sched_cflags@
# Language-independent object files.
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
- varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o regmove.o \
+ varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o regmove.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
@@ -600,7 +600,8 @@ OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
# GEN files are listed separately, so they can be built before doing parallel
# makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load
# them before rtl.o is compiled.
-GEN= genemit genoutput genrecog genextract genflags gencodes genconfig genpeep
+GEN= genemit genoutput genrecog genextract genflags gencodes genconfig \
+ genpeep gengenrtl
CCCP=cccp
# Uncomment this line if you want to use cppmain (w/cpplib) as cpp.
@@ -669,7 +670,8 @@ DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \
# If it is, rm *.o is an easy way to do it.
# CONFIG_H = $(host_xm_file) $(tm_file)
CONFIG_H =
-RTL_H = rtl.h rtl.def gansidecl.h machmode.h machmode.def
+RTL_BASE_H = rtl.h rtl.def gansidecl.h machmode.h machmode.def
+RTL_H = $(RTL_BASE_H) genrtl.h
TREE_H = tree.h real.h tree.def gansidecl.h machmode.h machmode.def
BYTECODE_H = bytecode.h bc-emit.h bc-optab.h
BASIC_BLOCK_H = basic-block.h bitmap.h
@@ -1242,8 +1244,8 @@ $(srcdir)/c-gperf.h: c-parse.gperf
c-decl.o : c-decl.c $(CONFIG_H) $(TREE_H) c-tree.h c-lex.h flags.h output.h
c-typeck.o : c-typeck.c $(CONFIG_H) $(TREE_H) c-tree.h flags.h output.h
c-lang.o : c-lang.c $(CONFIG_H) $(TREE_H)
-c-lex.o : c-lex.c $(CONFIG_H) $(TREE_H) c-lex.h c-tree.h $(srcdir)/c-parse.h \
- input.h flags.h $(srcdir)/c-gperf.h c-pragma.h
+c-lex.o : c-lex.c $(CONFIG_H) $(TREE_H) $(RTL_H) c-lex.h c-tree.h \
+ $(srcdir)/c-parse.h input.h flags.h $(srcdir)/c-gperf.h c-pragma.h
c-aux-info.o : c-aux-info.c $(CONFIG_H) $(TREE_H) c-tree.h flags.h
c-convert.o : c-convert.c $(CONFIG_H) $(TREE_H) flags.h
c-pragma.o: c-pragma.c $(CONFIG_H) $(TREE_H) except.h function.h \
@@ -1580,6 +1582,15 @@ stamp-output : $(md_file) genoutput $(srcdir)/move-if-change
./genoutput $(md_file) > tmp-output.c
$(srcdir)/move-if-change tmp-output.c insn-output.c
touch stamp-output
+
+genrtl.o : genrtl.c $(CONFIG_H) $(RTL_H)
+genrtl.c genrtl.h : stamp-genrtl
+stamp-genrtl: gengenrtl $(srcdir)/move-if-change $(RTL_BASE_H)
+ ./gengenrtl tmp-genrtl.h tmp-genrtl.c
+ $(srcdir)/move-if-change tmp-genrtl.h genrtl.h
+ $(srcdir)/move-if-change tmp-genrtl.c genrtl.c
+ touch stamp-genrtl
+
#
# Compile the programs that generate insn-* from the machine description.
# They are compiled with $(HOST_CC), and associated libraries,
@@ -1673,6 +1684,14 @@ genoutput : genoutput.o $(HOST_RTL) $(HOST_LIBDEPS)
genoutput.o : genoutput.c $(RTL_H) $(build_xm_file)
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genoutput.c
+
+gengenrtl : gengenrtl.o $(HOST_LIBDEPS)
+ $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
+ gengenrtl.o $(HOST_LIBS)
+
+gengenrtl.o : gengenrtl.c $(RTL_BASE_H)
+ $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gengenrtl.c
+
#
# Compile the libraries to be used by gen*.
# If we are not cross-building, gen* use the same .o's that cc1 will use,
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 7b114d6..ef85c41 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -259,6 +259,64 @@ static rtx make_jump_insn_raw PROTO((rtx));
static rtx make_call_insn_raw PROTO((rtx));
static rtx find_line_note PROTO((rtx));
+rtx
+gen_rtx_CONST_INT (mode, arg)
+ enum machine_mode mode;
+ HOST_WIDE_INT arg;
+{
+ if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
+ return &const_int_rtx[arg + MAX_SAVED_CONST_INT];
+
+#if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
+ if (const_true_rtx && arg == STORE_FLAG_VALUE)
+ return const_true_rtx;
+#endif
+
+ return gen_rtx_raw_CONST_INT (mode, arg);
+}
+
+rtx
+gen_rtx_REG (mode, regno)
+ enum machine_mode mode;
+ int regno;
+{
+ /* In case the MD file explicitly references the frame pointer, have
+ all such references point to the same frame pointer. This is
+ used during frame pointer elimination to distinguish the explicit
+ references to these registers from pseudos that happened to be
+ assigned to them.
+
+ If we have eliminated the frame pointer or arg pointer, we will
+ be using it as a normal register, for example as a spill
+ register. In such cases, we might be accessing it in a mode that
+ is not Pmode and therefore cannot use the pre-allocated rtx.
+
+ Also don't do this when we are making new REGs in reload, since
+ we don't want to get confused with the real pointers. */
+
+ if (mode == Pmode && !reload_in_progress)
+ {
+ if (regno == FRAME_POINTER_REGNUM)
+ return frame_pointer_rtx;
+#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+ if (regno == HARD_FRAME_POINTER_REGNUM)
+ return hard_frame_pointer_rtx;
+#endif
+#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+ if (regno == ARG_POINTER_REGNUM)
+ return arg_pointer_rtx;
+#endif
+#ifdef RETURN_ADDRESS_POINTER_REGNUM
+ if (regno == RETURN_ADDRESS_POINTER_REGNUM)
+ return return_address_pointer_rtx;
+#endif
+ if (regno == STACK_POINTER_REGNUM)
+ return stack_pointer_rtx;
+ }
+
+ return gen_rtx_raw_REG (mode, regno);
+}
+
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
**
** This routine generates an RTX of the size specified by
@@ -306,67 +364,9 @@ gen_rtx VPROTO((enum rtx_code code, enum machine_mode mode, ...))
#endif
if (code == CONST_INT)
- {
- HOST_WIDE_INT arg = va_arg (p, HOST_WIDE_INT);
-
- if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
- return &const_int_rtx[arg + MAX_SAVED_CONST_INT];
-
-#if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
- if (const_true_rtx && arg == STORE_FLAG_VALUE)
- return const_true_rtx;
-#endif
-
- rt_val = rtx_alloc (code);
- INTVAL (rt_val) = arg;
- }
+ rt_val = gen_rtx_CONST_INT (mode, va_arg (p, HOST_WIDE_INT));
else if (code == REG)
- {
- int regno = va_arg (p, int);
-
- /* In case the MD file explicitly references the frame pointer, have
- all such references point to the same frame pointer. This is used
- during frame pointer elimination to distinguish the explicit
- references to these registers from pseudos that happened to be
- assigned to them.
-
- If we have eliminated the frame pointer or arg pointer, we will
- be using it as a normal register, for example as a spill register.
- In such cases, we might be accessing it in a mode that is not
- Pmode and therefore cannot use the pre-allocated rtx.
-
- Also don't do this when we are making new REGs in reload,
- since we don't want to get confused with the real pointers. */
-
- if (regno == FRAME_POINTER_REGNUM && mode == Pmode
- && ! reload_in_progress)
- return frame_pointer_rtx;
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- if (regno == HARD_FRAME_POINTER_REGNUM && mode == Pmode
- && ! reload_in_progress)
- return hard_frame_pointer_rtx;
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- if (regno == ARG_POINTER_REGNUM && mode == Pmode
- && ! reload_in_progress)
- return arg_pointer_rtx;
-#endif
-#ifdef RETURN_ADDRESS_POINTER_REGNUM
- if (return_address_pointer_rtx && regno == RETURN_ADDRESS_POINTER_REGNUM
- && mode == Pmode && ! reload_in_progress)
- return return_address_pointer_rtx;
-#endif
- if (regno == STACK_POINTER_REGNUM && mode == Pmode
- && ! reload_in_progress)
- return stack_pointer_rtx;
- else
- {
- rt_val = rtx_alloc (code);
- rt_val->mode = mode;
- REGNO (rt_val) = regno;
- return rt_val;
- }
- }
+ rt_val = gen_rtx_REG (mode, va_arg (p, int));
else
{
rt_val = rtx_alloc (code); /* Allocate the storage space. */
@@ -517,7 +517,7 @@ gen_reg_rtx (mode)
realpart = gen_reg_rtx (partmode);
imagpart = gen_reg_rtx (partmode);
- return gen_rtx (CONCAT, mode, realpart, imagpart);
+ return gen_rtx_CONCAT (mode, realpart, imagpart);
}
/* Make sure regno_pointer_flag and regno_reg_rtx are large
@@ -547,7 +547,7 @@ gen_reg_rtx (mode)
regno_pointer_flag_length *= 2;
}
- val = gen_rtx (REG, mode, reg_rtx_no);
+ val = gen_rtx_raw_REG (mode, reg_rtx_no);
regno_reg_rtx[reg_rtx_no++] = val;
return val;
}
@@ -659,14 +659,14 @@ gen_lowpart_common (mode, x)
else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (XEXP (x, 0))))
return gen_lowpart_common (mode, XEXP (x, 0));
else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
- return gen_rtx (GET_CODE (x), mode, XEXP (x, 0));
+ return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
}
else if (GET_CODE (x) == SUBREG
&& (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
|| GET_MODE_SIZE (mode) == GET_MODE_UNIT_SIZE (GET_MODE (x))))
return (GET_MODE (SUBREG_REG (x)) == mode && SUBREG_WORD (x) == 0
? SUBREG_REG (x)
- : gen_rtx (SUBREG, mode, SUBREG_REG (x), SUBREG_WORD (x) + word));
+ : gen_rtx_SUBREG (mode, SUBREG_REG (x), SUBREG_WORD (x) + word));
else if (GET_CODE (x) == REG)
{
/* If the register is not valid for MODE, return 0. If we don't
@@ -690,9 +690,9 @@ gen_lowpart_common (mode, x)
&& x != arg_pointer_rtx
#endif
&& x != stack_pointer_rtx)
- return gen_rtx (REG, mode, REGNO (x) + word);
+ return gen_rtx_REG (mode, REGNO (x) + word);
else
- return gen_rtx (SUBREG, mode, x, word);
+ return gen_rtx_SUBREG (mode, x, word);
}
/* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
from the low-order part of the constant. */
@@ -984,8 +984,7 @@ gen_highpart (mode, x)
&& GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT
#endif
)
- return gen_rtx (CONST_INT, VOIDmode,
- CONST_DOUBLE_HIGH (x) & GET_MODE_MASK (mode));
+ return GEN_INT (CONST_DOUBLE_HIGH (x) & GET_MODE_MASK (mode));
else if (GET_CODE (x) == CONST_INT)
return const0_rtx;
else if (GET_CODE (x) == MEM)
@@ -1038,9 +1037,9 @@ gen_highpart (mode, x)
&& x != arg_pointer_rtx
#endif
&& x != stack_pointer_rtx)
- return gen_rtx (REG, mode, REGNO (x) + word);
+ return gen_rtx_REG (mode, REGNO (x) + word);
else
- return gen_rtx (SUBREG, mode, x, word);
+ return gen_rtx_SUBREG (mode, x, word);
}
else
abort ();
@@ -1131,12 +1130,12 @@ operand_subword (op, i, validate_address, mode)
|| op == arg_pointer_rtx
#endif
|| op == stack_pointer_rtx)
- return gen_rtx (SUBREG, word_mode, op, i);
+ return gen_rtx_SUBREG (word_mode, op, i);
else
- return gen_rtx (REG, word_mode, REGNO (op) + i);
+ return gen_rtx_REG (word_mode, REGNO (op) + i);
}
else if (GET_CODE (op) == SUBREG)
- return gen_rtx (SUBREG, word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
+ return gen_rtx_SUBREG (word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
else if (GET_CODE (op) == CONCAT)
{
int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
@@ -1163,7 +1162,7 @@ operand_subword (op, i, validate_address, mode)
addr = memory_address (word_mode, addr);
}
- new = gen_rtx (MEM, word_mode, addr);
+ new = gen_rtx_MEM (word_mode, addr);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (op);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (op);
@@ -1397,8 +1396,7 @@ reverse_comparison (insn)
}
else
{
- rtx new = gen_rtx (COMPARE, VOIDmode,
- CONST0_RTX (GET_MODE (comp)), comp);
+ rtx new = gen_rtx_COMPARE (VOIDmode, CONST0_RTX (GET_MODE (comp)), comp);
if (GET_CODE (body) == SET)
SET_SRC (body) = new;
else
@@ -1439,7 +1437,7 @@ change_address (memref, mode, addr)
if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
return memref;
- new = gen_rtx (MEM, mode, addr);
+ new = gen_rtx_MEM (mode, addr);
MEM_VOLATILE_P (new) = MEM_VOLATILE_P (memref);
RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (memref);
MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (memref);
@@ -1454,9 +1452,10 @@ gen_label_rtx ()
register rtx label;
label = (output_bytecode
- ? gen_rtx (CODE_LABEL, VOIDmode, NULL, bc_get_bytecode_label ())
- : gen_rtx (CODE_LABEL, VOIDmode, 0, NULL_RTX,
- NULL_RTX, label_num++, NULL_PTR));
+ ? gen_rtx_CODE_LABEL (VOIDmode, 0, bc_get_bytecode_label (),
+ NULL_RTX, 0, NULL_PTR)
+ : gen_rtx_CODE_LABEL (VOIDmode, 0, NULL_RTX,
+ NULL_RTX, label_num++, NULL_PTR));
LABEL_NUSES (label) = 0;
return label;
@@ -1488,16 +1487,17 @@ gen_inline_header_rtx (first_insn, first_parm_insn, first_labelno,
char *regno_align;
rtvec parm_reg_stack_loc;
{
- rtx header = gen_rtx (INLINE_HEADER, VOIDmode,
- cur_insn_uid++, NULL_RTX,
- first_insn, first_parm_insn,
- first_labelno, last_labelno,
- max_parm_regnum, max_regnum, args_size, pops_args,
- stack_slots, forced_labels, function_flags,
- outgoing_args_size, original_arg_vector,
- original_decl_initial,
- regno_rtx, regno_flag, regno_align,
- parm_reg_stack_loc);
+ rtx header = gen_rtx_INLINE_HEADER (VOIDmode,
+ cur_insn_uid++, NULL_RTX,
+ first_insn, first_parm_insn,
+ first_labelno, last_labelno,
+ max_parm_regnum, max_regnum, args_size,
+ pops_args, stack_slots, forced_labels,
+ function_flags, outgoing_args_size,
+ original_arg_vector,
+ original_decl_initial,
+ regno_rtx, regno_flag, regno_align,
+ parm_reg_stack_loc);
return header;
}
@@ -2092,9 +2092,8 @@ link_cc0_insns (insn)
if (GET_CODE (user) == INSN && GET_CODE (PATTERN (user)) == SEQUENCE)
user = XVECEXP (PATTERN (user), 0, 0);
- REG_NOTES (user) = gen_rtx (INSN_LIST, REG_CC_SETTER, insn,
- REG_NOTES (user));
- REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_CC_USER, user, REG_NOTES (insn));
+ REG_NOTES (user) = gen_rtx_INSN_LIST (REG_CC_SETTER, insn, REG_NOTES (user));
+ REG_NOTES (insn) = gen_rtx_INSN_LIST (REG_CC_USER, user, REG_NOTES (insn));
}
/* Return the next insn that uses CC0 after INSN, which is assumed to
@@ -3239,7 +3238,7 @@ gen_sequence ()
cache it. */
push_obstacks_nochange ();
rtl_in_saveable_obstack ();
- result = gen_rtx (SEQUENCE, VOIDmode, rtvec_alloc (len));
+ result = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (len));
pop_obstacks ();
}
@@ -3376,7 +3375,7 @@ init_emit_once (line_numbers)
&& STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
const_true_rtx = &const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
else
- const_true_rtx = gen_rtx (CONST_INT, VOIDmode, STORE_FLAG_VALUE);
+ const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);
dconst0 = REAL_VALUE_ATOF ("0", DFmode);
dconst1 = REAL_VALUE_ATOF ("1", DFmode);
@@ -3441,14 +3440,14 @@ init_emit_once (line_numbers)
PUT_MODE (virtual_outgoing_args_rtx, Pmode);
#ifdef RETURN_ADDRESS_POINTER_REGNUM
- return_address_pointer_rtx = gen_rtx (REG, Pmode,
- RETURN_ADDRESS_POINTER_REGNUM);
+ return_address_pointer_rtx = gen_rtx_REG (Pmode,
+ RETURN_ADDRESS_POINTER_REGNUM);
#endif
#ifdef STRUCT_VALUE
struct_value_rtx = STRUCT_VALUE;
#else
- struct_value_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_REGNUM);
+ struct_value_rtx = gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM);
#endif
#ifdef STRUCT_VALUE_INCOMING
@@ -3456,18 +3455,18 @@ init_emit_once (line_numbers)
#else
#ifdef STRUCT_VALUE_INCOMING_REGNUM
struct_value_incoming_rtx
- = gen_rtx (REG, Pmode, STRUCT_VALUE_INCOMING_REGNUM);
+ = gen_rtx_REG (Pmode, STRUCT_VALUE_INCOMING_REGNUM);
#else
struct_value_incoming_rtx = struct_value_rtx;
#endif
#endif
#ifdef STATIC_CHAIN_REGNUM
- static_chain_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
+ static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
#ifdef STATIC_CHAIN_INCOMING_REGNUM
if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
- static_chain_incoming_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_INCOMING_REGNUM);
+ static_chain_incoming_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
else
#endif
static_chain_incoming_rtx = static_chain_rtx;
@@ -3484,6 +3483,6 @@ init_emit_once (line_numbers)
#endif
#ifdef PIC_OFFSET_TABLE_REGNUM
- pic_offset_table_rtx = gen_rtx (REG, Pmode, PIC_OFFSET_TABLE_REGNUM);
+ pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
#endif
}
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 4b84852..9dacd52 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -188,7 +188,7 @@ gen_exp (x)
return;
case MATCH_SCRATCH:
- printf ("gen_rtx (SCRATCH, %smode, 0)", GET_MODE_NAME (GET_MODE (x)));
+ printf ("gen_rtx_SCRATCH (%smode)", GET_MODE_NAME (GET_MODE (x)));
return;
case ADDRESS:
@@ -230,9 +230,9 @@ gen_exp (x)
break;
}
- printf ("gen_rtx (");
+ printf ("gen_rtx_");
print_code (code);
- printf (", %smode", GET_MODE_NAME (GET_MODE (x)));
+ printf (" (%smode", GET_MODE_NAME (GET_MODE (x)));
fmt = GET_RTX_FORMAT (code);
len = GET_RTX_LENGTH (code);
@@ -371,7 +371,7 @@ gen_insn (insn)
}
else
{
- printf (" return gen_rtx (PARALLEL, VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1));
+ printf (" return gen_rtx_PARALLEL (VOIDmode, gen_rtvec (%d", XVECLEN (insn, 1));
for (i = 0; i < XVECLEN (insn, 1); i++)
{
printf (",\n\t\t");
diff --git a/gcc/gengenrtl.c b/gcc/gengenrtl.c
new file mode 100644
index 0000000..977305d
--- /dev/null
+++ b/gcc/gengenrtl.c
@@ -0,0 +1,287 @@
+/* Generate code to allocate RTL structures.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+
+#include "hconfig.h"
+#include <stdio.h>
+
+#include "obstack.h"
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
+#define NO_GENRTL_H
+#include "rtl.h"
+
+
+struct rtx_definition
+{
+ const char *enumname, *name, *format;
+};
+
+#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { # ENUM, NAME, FORMAT },
+
+struct rtx_definition defs[] =
+{
+#include "rtl.def" /* rtl expressions are documented here */
+};
+
+const char *formats[NUM_RTX_CODE];
+
+static const char *
+type_from_format (char c)
+{
+ switch (c)
+ {
+ case 'i':
+ return "int";
+ case 'w':
+ return "HOST_WIDE_INT";
+ case 's':
+ return "char *";
+ case 'e':
+ case 'u':
+ return "rtx";
+ case 'E':
+ return "rtvec";
+ default:
+ abort ();
+ }
+}
+
+static const char *
+accessor_from_format (char c)
+{
+ switch (c)
+ {
+ case 'i':
+ return "XINT";
+ case 'w':
+ return "XWINT";
+ case 's':
+ return "XSTR";
+ case 'e':
+ case 'u':
+ return "XEXP";
+ case 'E':
+ return "XVEC";
+ default:
+ abort ();
+ }
+}
+
+static int
+special_format (fmt)
+ const char *fmt;
+{
+ return (strchr (fmt, '*') != 0
+ || strchr (fmt, 'V') != 0
+ || strchr (fmt, 'S') != 0
+ || strchr (fmt, 'n') != 0);
+}
+
+static int
+special_rtx (idx)
+ int idx;
+{
+ return (strcmp (defs[idx].enumname, "CONST_INT") == 0
+ || strcmp (defs[idx].enumname, "REG") == 0);
+}
+
+static void
+find_formats ()
+{
+ int i;
+
+ for (i = 0; i < NUM_RTX_CODE; ++i)
+ {
+ const char **f;
+
+ if (special_format (defs[i].format))
+ continue;
+
+ for (f = formats; *f ; ++f)
+ if (!strcmp(*f, defs[i].format))
+ break;
+
+ if (!*f)
+ *f = defs[i].format;
+ }
+}
+
+static void
+gendecl (f, format)
+ FILE *f;
+ const char *format;
+{
+ const char *p;
+ int i;
+
+ fprintf (f, "extern rtx gen_rtx_fmt_%s PROTO((RTX_CODE, enum machine_mode mode",
+ format);
+ for (p = format, i = 0; *p ; ++p)
+ if (*p != '0')
+ fprintf (f, ", %s arg%d", type_from_format (*p), i++);
+ fprintf (f, "));\n");
+}
+
+static void
+genmacro (f, idx)
+ FILE *f;
+ int idx;
+{
+ const char *p;
+ int i;
+
+ fprintf (f, "#define gen_rtx_%s%s(mode",
+ (special_rtx (idx) ? "raw_" : ""), defs[idx].enumname);
+
+ for (p = defs[idx].format, i = 0; *p ; ++p)
+ if (*p != '0')
+ fprintf (f, ", arg%d", i++);
+ fprintf (f, ") ");
+
+ fprintf (f, "gen_rtx_fmt_%s(%s,(mode)", defs[idx].format, defs[idx].enumname);
+ for (p = defs[idx].format, i = 0; *p ; ++p)
+ if (*p != '0')
+ fprintf (f, ",(arg%d)", i++);
+ fprintf (f, ")\n");
+}
+
+static void
+gendef (f, format)
+ FILE *f;
+ const char *format;
+{
+ const char *p;
+ int i, j;
+
+ fprintf (f, "rtx\ngen_rtx_fmt_%s (code, mode", format);
+ for (p = format, i = 0; *p ; ++p)
+ if (*p != '0')
+ fprintf (f, ", arg%d", i++);
+
+ fprintf (f, ")\n RTX_CODE code;\n enum machine_mode mode;\n");
+ for (p = format, i = 0; *p ; ++p)
+ if (*p != '0')
+ fprintf (f, " %s arg%d;\n", type_from_format (*p), i++);
+
+ /* See rtx_alloc in rtl.c for comments. */
+ fprintf (f, "{\n");
+ fprintf (f, " register int length = sizeof (struct rtx_def)");
+ fprintf (f, " + %d * sizeof (rtunion);\n", strlen (format) - 1);
+ fprintf (f, " rtx rt = (rtx)obstack_alloc (rtl_obstack, length);\n");
+
+ fprintf (f, " if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(int))\n");
+ fprintf (f, " *(int *)rt = 0;\n");
+ fprintf (f, " else if (sizeof(struct rtx_def) - sizeof(rtunion) == sizeof(HOST_WIDE_INT))\n");
+ fprintf (f, " *(HOST_WIDE_INT *)rt = 0;\n");
+ fprintf (f, " else\n");
+ fprintf (f, " bzero(rt, sizeof(struct rtx_def) - sizeof(rtunion));\n\n");
+
+ fprintf (f, " PUT_CODE (rt, code);\n");
+ fprintf (f, " PUT_MODE (rt, mode);\n");
+
+ for (p = format, i = j = 0; *p ; ++p, ++i)
+ if (*p != '0')
+ {
+ fprintf (f, " %s (rt, %d) = arg%d;\n",
+ accessor_from_format (*p), i, j++);
+ }
+
+ fprintf (f, "\n return rt;\n}\n\n");
+}
+
+static void
+genlegend (f)
+ FILE *f;
+{
+ fprintf (f, "/* Generated automaticaly by the program `gengenrtl'\n");
+ fprintf (f, " from the RTL description file `rtl.def' */\n\n");
+}
+
+static void
+genheader (f)
+ FILE *f;
+{
+ int i;
+ const char **fmt;
+
+ for (fmt = formats; *fmt; ++fmt)
+ gendecl (f, *fmt);
+
+ fprintf(f, "\n");
+
+ for (i = 0; i < NUM_RTX_CODE; i++)
+ {
+ if (special_format (defs[i].format))
+ continue;
+ genmacro (f, i);
+ }
+}
+
+static void
+gencode (f)
+ FILE *f;
+{
+ const char **fmt;
+
+ fprintf(f, "#include \"config.h\"\n");
+ fprintf(f, "#include \"obstack.h\"\n");
+ fprintf(f, "#include \"rtl.h\"\n\n");
+ fprintf(f, "extern struct obstack *rtl_obstack;\n\n");
+
+ for (fmt = formats; *fmt; ++fmt)
+ gendef (f, *fmt);
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *f;
+
+ if (argc != 3)
+ exit (1);
+
+ find_formats ();
+
+ f = fopen (argv[1], "w");
+ if (f == NULL)
+ {
+ perror(argv[1]);
+ exit (1);
+ }
+ genlegend (f);
+ genheader (f);
+ fclose(f);
+
+ f = fopen (argv[2], "w");
+ if (f == NULL)
+ {
+ perror(argv[2]);
+ exit (1);
+ }
+ genlegend (f);
+ gencode (f);
+ fclose(f);
+
+ exit (0);
+}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 683546e..b7d7019 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -681,8 +681,6 @@ extern int ceil_log2 PROTO((unsigned HOST_WIDE_INT));
extern rtx plus_constant_wide PROTO((rtx, HOST_WIDE_INT));
extern rtx plus_constant_for_output_wide PROTO((rtx, HOST_WIDE_INT));
-#define GEN_INT(N) gen_rtx (CONST_INT, VOIDmode, (HOST_WIDE_INT) (N))
-
struct bc_label;
extern rtx bc_gen_rtx PROTO ((char *, int,
struct bc_label *));
@@ -934,6 +932,22 @@ extern rtx struct_value_incoming_rtx;
extern rtx static_chain_rtx;
extern rtx static_chain_incoming_rtx;
+
+/* Include the RTL generation functions. */
+
+#ifndef NO_GENRTL_H
+#include "genrtl.h"
+#endif
+
+/* There are two RTL codes that require special attention; the generation
+ functions included above do the raw handling. */
+
+extern rtx gen_rtx_CONST_INT PROTO((enum machine_mode, HOST_WIDE_INT));
+extern rtx gen_rtx_REG PROTO((enum machine_mode, int));
+
+#define GEN_INT(N) gen_rtx_CONST_INT (VOIDmode, (N))
+
+
/* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg
is used to represent the frame pointer. This is because the
hard frame pointer and the automatic variables are separated by an amount
@@ -1376,4 +1390,3 @@ extern void init_alias_analysis PROTO ((void));
extern void end_alias_analysis PROTO ((void));
#endif /* _RTL_H */
-