diff options
author | Richard Henderson <rth@cygnus.com> | 1998-01-08 13:17:05 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-01-08 13:17:05 -0800 |
commit | 3b80f6ca69f78207e8fcf8e835a4a8aa2e4abfba (patch) | |
tree | c792e877a8974b6884a66403f5d9b9ee06c23290 /gcc | |
parent | f4a233434d41848d9ae3bcb0f9518dfd986143ba (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/Makefile.in | 29 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 203 | ||||
-rw-r--r-- | gcc/genemit.c | 8 | ||||
-rw-r--r-- | gcc/gengenrtl.c | 287 | ||||
-rw-r--r-- | gcc/rtl.h | 19 |
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); +} @@ -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 */ - |